add configand command line parsing
This commit is contained in:
parent
4ea3e656d6
commit
c6c68aa443
5 changed files with 221 additions and 15 deletions
|
@ -154,20 +154,28 @@ func apiUploadMapImg(next http.Handler, udb auth.UserStore, dbAdapter mongodb.Db
|
||||||
// respond with URL?
|
// respond with URL?
|
||||||
}
|
}
|
||||||
|
|
||||||
return handlerFunc
|
return http.HandlerFunc(handlerFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateAdminInterface(udb auth.UserStore, dbAdapter mongodb.DbAdapter) http.Handler {
|
func CreateAdminInterface(udb auth.UserStore, dbAdapter mongodb.DbAdapter, uploads string, uploadMaxMB int) http.Handler {
|
||||||
// create quartzgun router
|
// create quartzgun router
|
||||||
rtr := &router.Router{Fallback: *template.Must(template.ParseFiles("static/error.html"))}
|
rtr := &router.Router{Fallback: *template.Must(template.ParseFiles("static/error.html"))}
|
||||||
|
|
||||||
scopes := map[string]string{}
|
scopes := map[string]string{}
|
||||||
|
|
||||||
rtr.Post("/api/auth/", Provision(udb, 84))
|
rtr.Post("/api/auth/", Provision(udb, 84))
|
||||||
|
|
||||||
|
// table management
|
||||||
rtr.Get("/api/table/", Validate(apiGetTableList(renderer.JSON("tableList"), udb), udb, scopes))
|
rtr.Get("/api/table/", Validate(apiGetTableList(renderer.JSON("tableList"), udb), udb, scopes))
|
||||||
rtr.Get(`/api/table/(?P<Slug>\S+)`, Validate(apiGetTableData(renderer.JSON("tableData"), udb, dbAdapter), udb, scopes))
|
rtr.Get(`/api/table/(?P<Slug>\S+)`, Validate(apiGetTableData(renderer.JSON("tableData"), udb, dbAdapter), udb, scopes))
|
||||||
rtr.Post("/api/table/", Validate(apiCreateTable(renderer.JSON("result"), udb, dbAdapter), udb, scopes))
|
rtr.Post("/api/table/", Validate(apiCreateTable(renderer.JSON("result"), udb, dbAdapter), udb, scopes))
|
||||||
rtr.Delete(`/api/table/(?P<Slug>\S+)`, Validate(apiDestroyTable(renderer.JSON("result"), udb, dbAdapter), udb, scopes))
|
rtr.Delete(`/api/table/(?P<Slug>\S+)`, Validate(apiDestroyTable(renderer.JSON("result"), udb, dbAdapter), udb, scopes))
|
||||||
|
|
||||||
|
// asset management
|
||||||
|
// POST /api/upload/<table>/map/
|
||||||
|
// DELETE /api/upload/<table>/map/<map>
|
||||||
|
// POST /api/upload/<table>/token/
|
||||||
|
// DELETE /api/upload/<table>/token/<token>
|
||||||
|
|
||||||
return http.HandlerFunc(rtr.ServeHTTP)
|
return http.HandlerFunc(rtr.ServeHTTP)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
_ "fmt"
|
||||||
"hacklab.nilfm.cc/quartzgun/auth"
|
"hacklab.nilfm.cc/quartzgun/auth"
|
||||||
"strings"
|
_ "strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProcessCmd(args []string, userStore auth.UserStore, cfg *Config) bool {
|
func ProcessCmd(args []string, userStore auth.UserStore) bool {
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
187
config/config.go
Normal file
187
config/config.go
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Port int
|
||||||
|
Uploads string
|
||||||
|
UploadMaxMB int
|
||||||
|
MongoURI string
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConfigLocation() string {
|
||||||
|
home := os.Getenv("HOME")
|
||||||
|
appdata := os.Getenv("APPDATA")
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "windows":
|
||||||
|
return filepath.Join(appdata, "felt")
|
||||||
|
case "darwin":
|
||||||
|
return filepath.Join(home, "Library", "Application Support", "felt")
|
||||||
|
case "plan9":
|
||||||
|
return filepath.Join(home, "lib", "felt")
|
||||||
|
default:
|
||||||
|
return filepath.Join(home, ".config", "felt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureConfigLocationExists() {
|
||||||
|
fileInfo, err := os.Stat(GetConfigLocation())
|
||||||
|
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
os.MkdirAll(GetConfigLocation(), os.ModePerm)
|
||||||
|
} else if !fileInfo.IsDir() {
|
||||||
|
panic("Config location is not a directory!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadConfig() *Config {
|
||||||
|
ensureConfigLocationExists()
|
||||||
|
return parseConfig(filepath.Join(GetConfigLocation(), "felt.conf"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Config) Write() error {
|
||||||
|
ensureConfigLocationExists()
|
||||||
|
return writeConfig(self, filepath.Join(GetConfigLocation(), "felt.conf"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Config) IsNull() bool {
|
||||||
|
return self.Port == 0 || self.UploadMaxMB == 0 || self.Uploads == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Config) RunWizard() {
|
||||||
|
fmt.Printf("All options are required.\n")
|
||||||
|
defer func(cfg *Config) {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
fmt.Printf("Invalid selection, starting over...")
|
||||||
|
cfg.RunWizard()
|
||||||
|
}
|
||||||
|
}(self)
|
||||||
|
inputBuf := ""
|
||||||
|
|
||||||
|
fmt.Printf("MongoDB URI? ")
|
||||||
|
ensureNonEmptyOption(&inputBuf)
|
||||||
|
self.MongoURI = inputBuf
|
||||||
|
|
||||||
|
inputBuf = ""
|
||||||
|
fmt.Printf("TCP port? ")
|
||||||
|
self.Port = ensurePortOption(&inputBuf)
|
||||||
|
|
||||||
|
fmt.Printf("file uploads location? ")
|
||||||
|
ensureNonEmptyOption(&inputBuf)
|
||||||
|
self.Uploads = inputBuf
|
||||||
|
|
||||||
|
inputBuf = ""
|
||||||
|
fmt.Printf("Max file upload size (MB)? ")
|
||||||
|
self.UploadMaxMB = ensureNumberOption(&inputBuf)
|
||||||
|
|
||||||
|
fmt.Printf("Configuration complete!\n")
|
||||||
|
self.Write()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureNonEmptyOption(buffer *string) {
|
||||||
|
for {
|
||||||
|
fmt.Scanln(buffer)
|
||||||
|
if len(strings.TrimSpace(*buffer)) != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fmt.Println("Please enter a nonempty value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureBooleanOption(buffer *string) bool {
|
||||||
|
for {
|
||||||
|
fmt.Scanln(buffer)
|
||||||
|
trimmedBuf := strings.TrimSpace(*buffer)
|
||||||
|
v, err := strconv.ParseBool(trimmedBuf)
|
||||||
|
if err == nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
fmt.Println("Please enter a true or false value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureNumberOption(buffer *string) int {
|
||||||
|
for {
|
||||||
|
fmt.Scanln(buffer)
|
||||||
|
trimmedBuf := strings.TrimSpace(*buffer)
|
||||||
|
v, err := strconv.ParseInt(trimmedBuf, 10, 32)
|
||||||
|
if err == nil && v > 0 {
|
||||||
|
return int(v)
|
||||||
|
}
|
||||||
|
fmt.Println("Please enter a positive integer")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensurePortOption(buffer *string) int {
|
||||||
|
for {
|
||||||
|
fmt.Scanln(buffer)
|
||||||
|
trimmedBuf := strings.TrimSpace(*buffer)
|
||||||
|
v, err := strconv.ParseInt(trimmedBuf, 10, 32)
|
||||||
|
if err == nil && v > 0 && v <= 65536 {
|
||||||
|
return int(v)
|
||||||
|
}
|
||||||
|
fmt.Println("Please enter a valid port [1, 65536]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeConfig(cfg *Config, configFile string) error {
|
||||||
|
f, err := os.Create(configFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
f.WriteString("mongoURI=" + cfg.MongoURI + "\n")
|
||||||
|
f.WriteString("uploads=" + cfg.Uploads + "\n")
|
||||||
|
f.WriteString("uploadMaxMB=" + strconv.FormatInt(int64(cfg.UploadMaxMB), 10) + "\n")
|
||||||
|
f.WriteString("port=" + strconv.FormatInt(int64(cfg.Port), 10) + "\n")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseConfig(configFile string) *Config {
|
||||||
|
f, err := os.ReadFile(configFile)
|
||||||
|
cfg := &Config{}
|
||||||
|
if err != nil {
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
fileData := string(f[:])
|
||||||
|
|
||||||
|
lines := strings.Split(fileData, "\n")
|
||||||
|
|
||||||
|
for _, l := range lines {
|
||||||
|
if len(l) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !strings.Contains(l, "=") {
|
||||||
|
panic("Malformed config not in INI format")
|
||||||
|
}
|
||||||
|
|
||||||
|
kvp := strings.Split(l, "=")
|
||||||
|
k := strings.TrimSpace(kvp[0])
|
||||||
|
v := strings.TrimSpace(kvp[1])
|
||||||
|
switch k {
|
||||||
|
case "mongoURI":
|
||||||
|
cfg.MongoURI = v
|
||||||
|
case "uploads":
|
||||||
|
cfg.Uploads = v
|
||||||
|
case "port":
|
||||||
|
port, _ := strconv.ParseInt(v, 10, 32)
|
||||||
|
cfg.Port = int(port)
|
||||||
|
case "uploadMaxMB":
|
||||||
|
maxUpload, _ := strconv.ParseInt(v, 10, 32)
|
||||||
|
cfg.UploadMaxMB = int(maxUpload)
|
||||||
|
default:
|
||||||
|
panic("Unrecognized config option: " + k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cfg
|
||||||
|
}
|
|
@ -36,7 +36,7 @@ type GameTableServer struct {
|
||||||
dbAdapter mongodb.DbAdapter
|
dbAdapter mongodb.DbAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(adapter mongodb.DbAdapter, udb auth.UserStore) *GameTableServer {
|
func New(adapter mongodb.DbAdapter, udb auth.UserStore, uploads string, uploadMaxMB int) *GameTableServer {
|
||||||
srvr := &GameTableServer{
|
srvr := &GameTableServer{
|
||||||
subscribeMessageBuffer: 16,
|
subscribeMessageBuffer: 16,
|
||||||
logf: log.Printf,
|
logf: log.Printf,
|
||||||
|
@ -45,7 +45,7 @@ func New(adapter mongodb.DbAdapter, udb auth.UserStore) *GameTableServer {
|
||||||
dbAdapter: adapter,
|
dbAdapter: adapter,
|
||||||
}
|
}
|
||||||
srvr.serveMux.Handle("/table/", http.StripPrefix("/table/", renderer.Subtree("./static")))
|
srvr.serveMux.Handle("/table/", http.StripPrefix("/table/", renderer.Subtree("./static")))
|
||||||
srvr.serveMux.Handle("/admin/", http.StripPrefix("/admin", admin.CreateAdminInterface(udb, adapter)))
|
srvr.serveMux.Handle("/admin/", http.StripPrefix("/admin", admin.CreateAdminInterface(udb, adapter, uploads, uploadMaxMB)))
|
||||||
srvr.serveMux.HandleFunc("/subscribe", srvr.subscribeHandler)
|
srvr.serveMux.HandleFunc("/subscribe", srvr.subscribeHandler)
|
||||||
srvr.serveMux.HandleFunc("/publish", srvr.publishHandler)
|
srvr.serveMux.HandleFunc("/publish", srvr.publishHandler)
|
||||||
|
|
||||||
|
|
27
main.go
27
main.go
|
@ -2,6 +2,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"hacklab.nilfm.cc/felt/cmd"
|
||||||
|
"hacklab.nilfm.cc/felt/config"
|
||||||
"hacklab.nilfm.cc/felt/gametable"
|
"hacklab.nilfm.cc/felt/gametable"
|
||||||
"hacklab.nilfm.cc/felt/mongodb"
|
"hacklab.nilfm.cc/felt/mongodb"
|
||||||
"hacklab.nilfm.cc/quartzgun/indentalUserDB"
|
"hacklab.nilfm.cc/quartzgun/indentalUserDB"
|
||||||
|
@ -10,6 +12,8 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,23 +25,30 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func run() error {
|
func run() error {
|
||||||
l, err := net.Listen("tcp", os.Args[1])
|
cfg := config.ReadConfig()
|
||||||
|
if cfg.IsNull() {
|
||||||
|
cfg.RunWizard()
|
||||||
|
}
|
||||||
|
|
||||||
|
udb := indentalUserDB.CreateIndentalUserDB(
|
||||||
|
filepath.Join(config.GetConfigLocation(), "user.db"))
|
||||||
|
|
||||||
|
if cmd.ProcessCmd(os.Args, udb) {
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err := net.Listen("tcp", ":"+strconv.FormatInt(int64(cfg.Port), 10))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dbEngine := &mongodb.DbEngine{}
|
dbEngine := &mongodb.DbEngine{}
|
||||||
err = dbEngine.Init(os.Args[2])
|
err = dbEngine.Init(cfg.MongoURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
udb := indentalUserDB.CreateIndentalUserDB(
|
gt := gametable.New(dbEngine, udb, cfg.Uploads, cfg.UploadMaxMB)
|
||||||
"./user.db")
|
|
||||||
|
|
||||||
udb.AddUser("nilix", "questing")
|
|
||||||
|
|
||||||
gt := gametable.New(dbEngine, udb)
|
|
||||||
s := &http.Server{
|
s := &http.Server{
|
||||||
Handler: gt,
|
Handler: gt,
|
||||||
ReadTimeout: time.Second * 10,
|
ReadTimeout: time.Second * 10,
|
||||||
|
|
Loading…
Reference in a new issue