From d505e4835a6275993be125611356d0d78aec2d16 Mon Sep 17 00:00:00 2001 From: Adelyne Maulideau Date: Fri, 5 May 2017 14:10:35 +0200 Subject: [PATCH] Configuration through command line and/or a file. The configuration file is in JSON. If no option is specified, dev-friendly defaults are used. --- README.md | 18 +++++++++ config.go | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 32 ++++++++++++--- os/nyaa.service | 12 ++++++ package.sh | 2 +- 5 files changed, 162 insertions(+), 7 deletions(-) create mode 100644 config.go create mode 100644 os/nyaa.service diff --git a/README.md b/README.md index 03ff9811..aeeed88f 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,24 @@ that anyone will be able to deploy locally or remotely. * `./nyaa` * You can now access your local site over on [localhost:9999](http://localhost:9999) +## Usage + +Type `./nyaa -h` for the list of options. + +## Systemd + +* Edit the unit file `os/nyaa.service` to your liking +* Copy the package's content so that your unit file can find them. +* Copy the unit file in `/usr/lib/systemd/system` +* `systemctl daemon-reload` +* `systemctl start nyaa` + +The provided unit file uses options directly; if you prefer a config file, do the following: + +* `./nyaa -print-defaults > /etc/nyaa.conf` +* Edit `nyaa.conf` to your liking +* Replace in the unit file the options by `-conf /etc/nyaa.conf` + ## TODO * RSS feeds(work in progress) * torrent sorting (work in progress) diff --git a/config.go b/config.go new file mode 100644 index 00000000..33b8f418 --- /dev/null +++ b/config.go @@ -0,0 +1,105 @@ +package main + +import ( + "bufio" + "encoding/json" + "errors" + "flag" + "fmt" + "io" + "os" +) + +type Config struct { + Host string `json: "host"` + Port int `json: "port"` + DBType string `json: "db_type"` + // This will be directly passed to Gorm, and its internal + // structure depends on the dialect for each db type + DBParams string `json: "db_type"` +} + +var Defaults = Config{"localhost", 9999, "sqlite3", "./nyaa.db"} + +var allowedDatabaseTypes = map[string]bool{ + "sqlite3": true, + "postgres": true, + "mysql": true, + "mssql": true, +} + +func NewConfig() *Config { + var config Config + config.Host = Defaults.Host + config.Port = Defaults.Port + config.DBType = Defaults.DBType + config.DBParams = Defaults.DBParams + return &config +} + +type processFlags func() error + +func (config *Config) BindFlags() processFlags { + // This function returns a function which is to be used after + // flag.Parse to check and copy the flags' values to the Config instance. + + conf_file := flag.String("conf", "", "path to the configuration file") + db_type := flag.String("dbtype", Defaults.DBType, "database backend") + host := flag.String("host", Defaults.Host, "binding address of the server") + port := flag.Int("port", Defaults.Port, "port of the server") + db_params := flag.String("dbparams", Defaults.DBParams, "parameters to open the database (see Gorm's doc)") + + return func() error { + err := config.handleConfFileFlag(*conf_file) + if err != nil { + return err + } + // You can override fields in the config file with flags. + config.Host = *host + config.Port = *port + config.DBParams = *db_params + err = config.setDBType(*db_type) + return err + } +} + +func (config *Config) handleConfFileFlag(path string) error { + if path != "" { + file, err := os.Open(path) + if err != nil { + return errors.New(fmt.Sprintf("Can't read file '%s'.", path)) + } + + err = config.Read(bufio.NewReader(file)) + if err != nil { + return errors.New(fmt.Sprintf("Failed to parse file '%s' (%s).", path, err)) + } + } + return nil +} + +func (config *Config) setDBType(db_type string) error { + if !allowedDatabaseTypes[db_type] { + return errors.New(fmt.Sprintf("Unknown database backend '%s'.", db_type)) + } + config.DBType = db_type + return nil +} + +func (config *Config) Read(input io.Reader) error { + return json.NewDecoder(input).Decode(config) +} + +func (config *Config) Write(output io.Writer) error { + return json.NewEncoder(output).Encode(config) +} + +func (config *Config) Pretty(output io.Writer) error { + data, err := json.MarshalIndent(config, "", "\t") + data = append(data, []byte("\n")...) + if err != nil { + return err + } + _, err = output.Write(data) + return err +} diff --git a/main.go b/main.go index b5927403..2915bbcf 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,12 @@ package main import ( + "bufio" "bytes" "compress/zlib" "encoding/json" + "fmt" + "flag" "github.com/gorilla/feeds" "github.com/gorilla/mux" "github.com/jinzhu/gorm" @@ -13,6 +16,7 @@ import ( "io/ioutil" "log" "net/http" + "os" "strconv" "strings" "time" @@ -32,8 +36,8 @@ var router *mux.Router var debugLogger *log.Logger var trackers = "&tr=udp://tracker.coppersurfer.tk:6969&tr=udp://zer0day.to:1337/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://explodie.org:6969&tr=udp://tracker.opentrackr.org:1337&tr=http://tracker.baka-sub.cf/announce" -func getDBHandle() *gorm.DB { - dbInit, err := gorm.Open("sqlite3", "./nyaa.db") +func getDBHandle(db_type string, db_params string) *gorm.DB { + dbInit, err := gorm.Open(db_type, db_params) // Migrate the schema of Torrents dbInit.AutoMigrate(&Torrents{}, &Categories{}, &Sub_Categories{}, &Statuses{}) @@ -304,9 +308,8 @@ func rootHandler(w http.ResponseWriter, r *http.Request) { } -func main() { - - db = getDBHandle() +func RunServer(conf *Config) { + db = getDBHandle(conf.DBType, conf.DBParams) router = mux.NewRouter() cssHandler := http.FileServer(http.Dir("./css/")) @@ -331,7 +334,7 @@ func main() { // Set up server, srv := &http.Server{ - Addr: "localhost:9999", + Addr: fmt.Sprintf("%s:%d", conf.Host, conf.Port), WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, } @@ -339,3 +342,20 @@ func main() { err := srv.ListenAndServe() checkErr(err) } + +func main() { + + conf := NewConfig() + conf_bind := conf.BindFlags() + defaults := flag.Bool("print-defaults", false, "print the default configuration file on stdout") + flag.Parse() + if *defaults { + stdout := bufio.NewWriter(os.Stdout) + conf.Pretty(stdout) + stdout.Flush() + os.Exit(0) + } else { + conf_bind() + RunServer(conf) + } +} diff --git a/os/nyaa.service b/os/nyaa.service new file mode 100644 index 00000000..fdac684f --- /dev/null +++ b/os/nyaa.service @@ -0,0 +1,12 @@ +[Unit] +Description=Torrent indexer for weebs +After=network.target + +[Service] +WorkingDirectory=/srv/nyaa/ +ExecStart=/usr/local/bin/nyaa -dbtype sqlite3 -dbparams ./nyaa.db +StandardOutput=syslog +Restart=on-failure + +[Install] +WantedBy=default.target diff --git a/package.sh b/package.sh index 973f219d..b02b73eb 100755 --- a/package.sh +++ b/package.sh @@ -16,5 +16,5 @@ for i in "${OSes[@]}"; do echo -e "\nBuilding $os..." echo GOOS=$os GOARCH=amd64 CC=$cc CGO_ENABLED=1 go build -v GOOS=$os GOARCH=amd64 CC=$cc CGO_ENABLED=1 go build -v - zip -9 -q nyaa-${version}_${os}_amd64.zip css js *.md *.html nyaa nyaa.exe + zip -9 -q nyaa-${version}_${os}_amd64.zip os css js *.md *.html nyaa nyaa.exe done