refactoring, adding cli to edit config
This commit is contained in:
85
cmd/cli/commands/add/add.go
Normal file
85
cmd/cli/commands/add/add.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package add
|
||||
|
||||
import (
|
||||
"context"
|
||||
customflag "downloadhub/cmd/cli/flag"
|
||||
"downloadhub/pkg/data"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/google/subcommands"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type (
|
||||
AddCmd struct {
|
||||
slug string
|
||||
description string
|
||||
version string
|
||||
iconURL string
|
||||
out string
|
||||
screenshotURLs customflag.Array
|
||||
}
|
||||
)
|
||||
|
||||
func (*AddCmd) Name() string { return "add" }
|
||||
func (*AddCmd) Synopsis() string { return "add an entry" }
|
||||
func (*AddCmd) Usage() string {
|
||||
return `Usage: ./cli add [OPTIONS] NAME
|
||||
|
||||
Options:
|
||||
`
|
||||
}
|
||||
|
||||
func (p *AddCmd) SetFlags(f *flag.FlagSet) {
|
||||
f.StringVar(&p.slug, "slug", "", "")
|
||||
f.StringVar(&p.description, "description", "", "")
|
||||
f.StringVar(&p.version, "version", "0.0.0", "")
|
||||
f.StringVar(&p.iconURL, "icon", "", "an url or a path to the icon")
|
||||
f.StringVar(&p.out, "out", "./config.json", "path to the configuration file")
|
||||
f.Var(&p.screenshotURLs, "screenshot", "an url or a path to a screenshot file")
|
||||
}
|
||||
|
||||
func (p *AddCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||
if len(p.slug) == 0 {
|
||||
p.slug = uuid.NewString()
|
||||
}
|
||||
|
||||
if len(p.screenshotURLs) == 0 {
|
||||
p.screenshotURLs = make(customflag.Array, 0)
|
||||
}
|
||||
|
||||
if f.NArg() == 0 {
|
||||
fmt.Fprintln(os.Stderr, "error: name cannot be empty")
|
||||
return subcommands.ExitUsageError
|
||||
}
|
||||
|
||||
if f.NArg() > 1 {
|
||||
fmt.Fprintln(os.Stderr, "error: this command cannot take more than 1 argument")
|
||||
return subcommands.ExitUsageError
|
||||
}
|
||||
|
||||
d, err := data.Load(p.out)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
d.Softwares = append(d.Softwares, data.Software{
|
||||
Slug: p.slug,
|
||||
Name: f.Arg(0),
|
||||
Description: p.description,
|
||||
Version: p.version,
|
||||
IconURL: p.iconURL,
|
||||
ScreenshotURLs: p.screenshotURLs,
|
||||
DownloadLinks: make([]data.DownloadLink, 0),
|
||||
})
|
||||
|
||||
if err := data.Save(d, p.out); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
99
cmd/cli/commands/edit/edit.go
Normal file
99
cmd/cli/commands/edit/edit.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package edit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"downloadhub/pkg/data"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/google/subcommands"
|
||||
)
|
||||
|
||||
type (
|
||||
EditCmd struct {
|
||||
slug string
|
||||
name string
|
||||
description string
|
||||
version string
|
||||
iconURL string
|
||||
out string
|
||||
}
|
||||
)
|
||||
|
||||
func (*EditCmd) Name() string { return "edit" }
|
||||
func (*EditCmd) Synopsis() string { return "edit an entry" }
|
||||
func (*EditCmd) Usage() string {
|
||||
return `Usage: ./cli edit [OPTIONS] SLUG
|
||||
|
||||
Options:
|
||||
`
|
||||
}
|
||||
|
||||
func (p *EditCmd) SetFlags(f *flag.FlagSet) {
|
||||
f.StringVar(&p.slug, "slug", "", "")
|
||||
f.StringVar(&p.name, "name", "", "")
|
||||
f.StringVar(&p.description, "description", "", "")
|
||||
f.StringVar(&p.version, "version", "0.0.0", "")
|
||||
f.StringVar(&p.iconURL, "icon", "", "an url or a path to the icon")
|
||||
f.StringVar(&p.out, "out", "./config.json", "path to the configuration file")
|
||||
}
|
||||
|
||||
func (p *EditCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||
if f.NArg() == 0 {
|
||||
fmt.Fprintln(os.Stderr, "error: slug cannot be empty")
|
||||
return subcommands.ExitUsageError
|
||||
}
|
||||
|
||||
if f.NArg() > 1 {
|
||||
fmt.Fprintln(os.Stderr, "error: this command cannot take more than 1 argument")
|
||||
return subcommands.ExitUsageError
|
||||
}
|
||||
|
||||
d, err := data.Load(p.out)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
var found bool
|
||||
for i, soft := range d.Softwares {
|
||||
if soft.Slug == f.Arg(0) {
|
||||
if len(p.slug) > 0 {
|
||||
soft.Slug = p.slug
|
||||
}
|
||||
|
||||
if len(p.name) > 0 {
|
||||
soft.Name = p.name
|
||||
}
|
||||
|
||||
if len(p.description) > 0 {
|
||||
soft.Description = p.description
|
||||
}
|
||||
|
||||
if len(p.version) > 0 {
|
||||
soft.Version = p.version
|
||||
}
|
||||
|
||||
if len(p.iconURL) > 0 {
|
||||
soft.IconURL = p.iconURL
|
||||
}
|
||||
|
||||
d.Softwares[i] = soft
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
fmt.Fprintf(os.Stderr, "error: slug '%s' cannot be found\n", f.Arg(0))
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
if err := data.Save(d, p.out); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
196
cmd/cli/commands/link/link.go
Normal file
196
cmd/cli/commands/link/link.go
Normal file
@@ -0,0 +1,196 @@
|
||||
package link
|
||||
|
||||
import (
|
||||
"context"
|
||||
"downloadhub/pkg/data"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/google/subcommands"
|
||||
)
|
||||
|
||||
type (
|
||||
LinkCmd struct {
|
||||
os string
|
||||
arch string
|
||||
out string
|
||||
}
|
||||
)
|
||||
|
||||
func (*LinkCmd) Name() string { return "link" }
|
||||
func (*LinkCmd) Synopsis() string { return "add/edit/remove a download link" }
|
||||
func (*LinkCmd) Usage() string {
|
||||
return `Usage: ./cli link ACTION LINK SLUG
|
||||
|
||||
Actions: add, edit, rm
|
||||
|
||||
Options:
|
||||
`
|
||||
}
|
||||
|
||||
func (p *LinkCmd) SetFlags(f *flag.FlagSet) {
|
||||
f.StringVar(&p.os, "os", "", "set the operating system")
|
||||
f.StringVar(&p.arch, "architecture", "", "set the instruction set")
|
||||
f.StringVar(&p.out, "out", "./config.json", "path to the configuration file")
|
||||
}
|
||||
|
||||
func (p *LinkCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||
if f.NArg() != 3 {
|
||||
fmt.Fprintln(os.Stderr, "error: bad usage")
|
||||
return subcommands.ExitUsageError
|
||||
}
|
||||
|
||||
switch strings.ToLower(f.Arg(0)) {
|
||||
case "add":
|
||||
return p.add(f.Arg(1), f.Arg(2))
|
||||
case "edit":
|
||||
return p.edit(f.Arg(1), f.Arg(2))
|
||||
case "rm":
|
||||
return p.rm(f.Arg(1), f.Arg(2))
|
||||
default:
|
||||
{
|
||||
fmt.Fprintln(os.Stderr, "error: unknown command")
|
||||
return subcommands.ExitUsageError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *LinkCmd) add(link, slug string) subcommands.ExitStatus {
|
||||
d, err := data.Load(p.out)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
var found bool
|
||||
for i, soft := range d.Softwares {
|
||||
if soft.Slug == slug {
|
||||
if exists(link, soft) {
|
||||
fmt.Fprintln(os.Stderr, "error: link already exists")
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
soft.DownloadLinks = append(soft.DownloadLinks, data.DownloadLink{
|
||||
OS: p.os,
|
||||
Arch: p.arch,
|
||||
URL: link,
|
||||
})
|
||||
d.Softwares[i] = soft
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
fmt.Fprintf(os.Stderr, "error: slug '%s' cannot be found\n", slug)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
if err := data.Save(d, p.out); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
|
||||
func (p *LinkCmd) edit(link, slug string) subcommands.ExitStatus {
|
||||
d, err := data.Load(p.out)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
var foundSlug, foundLink bool
|
||||
for i, soft := range d.Softwares {
|
||||
if soft.Slug == slug {
|
||||
for y, l := range soft.DownloadLinks {
|
||||
if l.URL == link {
|
||||
if len(p.os) > 0 {
|
||||
l.OS = p.os
|
||||
}
|
||||
|
||||
if len(p.os) > 0 {
|
||||
l.Arch = p.arch
|
||||
}
|
||||
|
||||
soft.DownloadLinks[y] = l
|
||||
foundLink = true
|
||||
break
|
||||
}
|
||||
}
|
||||
d.Softwares[i] = soft
|
||||
foundSlug = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !foundSlug {
|
||||
fmt.Fprintf(os.Stderr, "error: slug '%s' cannot be found\n", slug)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
if !foundLink {
|
||||
fmt.Fprintf(os.Stderr, "error: link '%s' cannot be found\n", link)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
if err := data.Save(d, p.out); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
|
||||
func (p *LinkCmd) rm(link, slug string) subcommands.ExitStatus {
|
||||
d, err := data.Load(p.out)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
var foundSlug, foundLink bool
|
||||
for i, soft := range d.Softwares {
|
||||
if soft.Slug == slug {
|
||||
var index int
|
||||
for y, l := range soft.DownloadLinks {
|
||||
if l.URL == link {
|
||||
index = y
|
||||
foundLink = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if foundLink {
|
||||
soft.DownloadLinks = append(soft.DownloadLinks[:index], soft.DownloadLinks[index+1:]...)
|
||||
}
|
||||
d.Softwares[i] = soft
|
||||
foundSlug = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !foundSlug {
|
||||
fmt.Fprintf(os.Stderr, "error: slug '%s' cannot be found\n", slug)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
if !foundLink {
|
||||
fmt.Fprintf(os.Stderr, "error: link '%s' cannot be found\n", link)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
if err := data.Save(d, p.out); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
|
||||
func exists(link string, soft data.Software) bool {
|
||||
for _, l := range soft.DownloadLinks {
|
||||
if l.URL == link {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
39
cmd/cli/commands/version/version.go
Normal file
39
cmd/cli/commands/version/version.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"context"
|
||||
"downloadhub/pkg/constants"
|
||||
"flag"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/google/subcommands"
|
||||
)
|
||||
|
||||
type (
|
||||
VersionCmd struct {
|
||||
}
|
||||
)
|
||||
|
||||
func (*VersionCmd) Name() string { return "version" }
|
||||
func (*VersionCmd) Synopsis() string { return "show version and system information" }
|
||||
func (*VersionCmd) Usage() string {
|
||||
return `Usage: ./cli version
|
||||
|
||||
Print the version of the software
|
||||
|
||||
Options:
|
||||
`
|
||||
}
|
||||
|
||||
func (p *VersionCmd) SetFlags(f *flag.FlagSet) {
|
||||
}
|
||||
|
||||
func (p *VersionCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||
fmt.Println("Client: downloadhub cli")
|
||||
fmt.Println(" Version: " + constants.Version)
|
||||
fmt.Println(" Go version: " + runtime.Version())
|
||||
fmt.Println(" OS/Arch: " + runtime.GOOS + "/" + runtime.GOARCH)
|
||||
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
18
cmd/cli/flag/flag.go
Normal file
18
cmd/cli/flag/flag.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package flag
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Array []string
|
||||
|
||||
// String is an implementation of the flag.Value interface
|
||||
func (i *Array) String() string {
|
||||
return strings.Join(*i, ", ")
|
||||
}
|
||||
|
||||
// Set is an implementation of the flag.Value interface
|
||||
func (i *Array) Set(value string) error {
|
||||
*i = append(*i, value)
|
||||
return nil
|
||||
}
|
||||
29
cmd/cli/main.go
Normal file
29
cmd/cli/main.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"downloadhub/cmd/cli/commands/add"
|
||||
"downloadhub/cmd/cli/commands/edit"
|
||||
"downloadhub/cmd/cli/commands/link"
|
||||
"downloadhub/cmd/cli/commands/version"
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"github.com/google/subcommands"
|
||||
)
|
||||
|
||||
func main() {
|
||||
subcommands.Register(subcommands.HelpCommand(), "help")
|
||||
subcommands.Register(subcommands.FlagsCommand(), "help")
|
||||
subcommands.Register(subcommands.CommandsCommand(), "help")
|
||||
subcommands.Register(&version.VersionCmd{}, "help")
|
||||
|
||||
subcommands.Register(&add.AddCmd{}, "management")
|
||||
subcommands.Register(&edit.EditCmd{}, "management")
|
||||
subcommands.Register(&link.LinkCmd{}, "management")
|
||||
|
||||
flag.Parse()
|
||||
ctx := context.Background()
|
||||
|
||||
os.Exit(int(subcommands.Execute(ctx)))
|
||||
}
|
||||
73
cmd/server/api/api.go
Normal file
73
cmd/server/api/api.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"downloadhub/pkg/data"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
)
|
||||
|
||||
type (
|
||||
Server struct {
|
||||
r chi.Router
|
||||
d data.Service
|
||||
port uint16
|
||||
}
|
||||
)
|
||||
|
||||
//go:embed templates/index.html
|
||||
var index string
|
||||
|
||||
//go:embed templates/description.html
|
||||
var description string
|
||||
|
||||
func New(port uint16, d data.Service) *Server {
|
||||
indexTemplate := template.New("index")
|
||||
indexTemplate.Parse(index)
|
||||
|
||||
descTemplate := template.New("description")
|
||||
descTemplate.Parse(description)
|
||||
|
||||
r := chi.NewRouter()
|
||||
r.Use(middleware.Logger)
|
||||
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
err := indexTemplate.Execute(w, d.Softwares)
|
||||
if err != nil {
|
||||
slog.Error(fmt.Sprintf("failed to execute template index: %s", err))
|
||||
}
|
||||
})
|
||||
r.Get("/d/{softID}", func(w http.ResponseWriter, r *http.Request) {
|
||||
softID := chi.URLParam(r, "softID")
|
||||
var soft data.Software
|
||||
var found bool
|
||||
for _, s := range d.Softwares {
|
||||
if s.UUID == softID {
|
||||
soft = s
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
w.Header().Add("Location", "/")
|
||||
w.WriteHeader(http.StatusTemporaryRedirect)
|
||||
return
|
||||
}
|
||||
err := descTemplate.Execute(w, soft)
|
||||
if err != nil {
|
||||
slog.Error(fmt.Sprintf("failed to execute template index: %s", err))
|
||||
}
|
||||
})
|
||||
return &Server{
|
||||
r: r,
|
||||
d: d,
|
||||
port: port,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Serve() error {
|
||||
return http.ListenAndServe(fmt.Sprintf(":%d", s.port), s.r)
|
||||
}
|
||||
40
cmd/server/api/templates/description.html
Normal file
40
cmd/server/api/templates/description.html
Normal file
@@ -0,0 +1,40 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>DownloadHub - {{.Name}}</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-light bg-light">
|
||||
<a style="margin-left: 1rem;" class="navbar-brand mb-0 h1" href="/">DownloadHub</a>
|
||||
</nav>
|
||||
<div class="container" style="margin-top: 1rem; margin-bottom: 1rem;">
|
||||
<h2>{{.Name}} ({{.Version}})</h2>
|
||||
<img width="100%" src="{{index .ScreenshotURLs 0}}" />
|
||||
<p>{{.Description}}</p>
|
||||
<hr />
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Download
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
{{range .DownloadLinks}}
|
||||
<a href="{{.URL}}">
|
||||
<li class="list-group-item">
|
||||
{{.OS}} ({{.Arch}})
|
||||
</li>
|
||||
</a>
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
|
||||
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
</html>
|
||||
34
cmd/server/api/templates/index.html
Normal file
34
cmd/server/api/templates/index.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>DownloadHub</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-light bg-light">
|
||||
<span style="margin-left: 1rem;" class="navbar-brand mb-0 h1">DownloadHub</span>
|
||||
</nav>
|
||||
<div class="container" style="margin-top: 1rem;">
|
||||
{{range .}}
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<img width="100%" src="{{index .ScreenshotURLs 0}}" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<h2><a href="/d/{{.UUID}}">{{.Name}}</a></h2>
|
||||
<p>{{.Description}}</p>
|
||||
</div>
|
||||
<hr style="margin-top: 1rem;" />
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
|
||||
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
</html>
|
||||
28
cmd/server/main.go
Normal file
28
cmd/server/main.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"downloadhub/cmd/server/api"
|
||||
"downloadhub/pkg/data"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var configFile string
|
||||
var port int
|
||||
flag.StringVar(&configFile, "c", "config.json", "configuration file path")
|
||||
flag.IntVar(&port, "p", 3000, "port of the server")
|
||||
flag.Parse()
|
||||
|
||||
slog.Info("loading configuration...")
|
||||
d := data.Load(configFile)
|
||||
slog.Info("configuration loaded!")
|
||||
|
||||
slog.Info(fmt.Sprintf("starting server on :%d", port))
|
||||
s := api.New(uint16(port), d)
|
||||
err := s.Serve()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user