1
0
Fork 0
mirror of https://git.sr.ht/~ashkeel/strimertul synced 2024-09-18 01:50:50 +00:00
strimertul/main.go

180 lines
4.4 KiB
Go
Raw Normal View History

2021-05-02 12:29:43 +00:00
package main
import (
"embed"
"flag"
"fmt"
"io/fs"
"math/rand"
"runtime"
2021-05-02 12:29:43 +00:00
"time"
"github.com/strimertul/strimertul/modules"
"github.com/strimertul/strimertul/modules/database"
"github.com/strimertul/strimertul/modules/http"
2021-05-02 12:29:43 +00:00
"github.com/strimertul/strimertul/modules/loyalty"
2021-05-14 14:37:54 +00:00
"github.com/strimertul/strimertul/modules/stulbe"
"github.com/strimertul/strimertul/modules/twitch"
2021-05-02 12:29:43 +00:00
"github.com/dgraph-io/badger/v3"
"github.com/mattn/go-colorable"
"github.com/pkg/browser"
"github.com/sirupsen/logrus"
2021-06-05 23:18:31 +00:00
_ "net/http/pprof"
2021-05-02 12:29:43 +00:00
)
const AppHeader = `
_ _ _ O O _
__| |_ _ _(_)_ __ ___ _ _| |_ _ _| |
(_-< _| '_| | ' \/ -_) '_| _| || | |
/__/\__|_| |_|_|_|_\___|_| \__|\_,_|_| `
2021-12-06 13:47:38 +00:00
var appVersion = "v0.0.0-UNKNOWN"
2021-05-02 12:29:43 +00:00
//go:embed frontend/dist/*
var frontend embed.FS
var log = logrus.New()
func parseLogLevel(level string) logrus.Level {
switch level {
case "error":
return logrus.ErrorLevel
case "warn", "warning":
return logrus.WarnLevel
case "info", "notice":
return logrus.InfoLevel
case "debug":
return logrus.DebugLevel
case "trace":
return logrus.TraceLevel
default:
return logrus.InfoLevel
2021-05-02 12:29:43 +00:00
}
}
type ModuleConstructor = func(manager *modules.Manager) error
var moduleList = map[modules.ModuleID]ModuleConstructor{
modules.ModuleTwitch: twitch.Register,
modules.ModuleStulbe: stulbe.Register,
modules.ModuleLoyalty: loyalty.Register,
}
2021-05-02 12:29:43 +00:00
func main() {
// Get cmd line parameters
noheader := flag.Bool("noheader", false, "Do not print the app header")
dbdir := flag.String("dbdir", "data", "Path to strimertül database dir")
loglevel := flag.String("loglevel", "info", "Logging level (debug, info, warn, error)")
cleanup := flag.Bool("run-gc", false, "Run garbage collection and exit immediately after")
2021-05-02 12:29:43 +00:00
flag.Parse()
rand.Seed(time.Now().UnixNano())
log.SetLevel(parseLogLevel(*loglevel))
// Ok this is dumb but listen, I like colors.
if runtime.GOOS == "windows" {
2021-12-07 00:22:45 +00:00
log.SetFormatter(&logrus.TextFormatter{ForceColors: true, FullTimestamp: true})
log.SetOutput(colorable.NewColorableStdout())
2021-12-07 00:22:45 +00:00
} else {
log.SetFormatter(&logrus.TextFormatter{FullTimestamp: true})
}
if !*noheader {
// Print the app header :D
fmt.Println(AppHeader)
2021-12-06 13:47:38 +00:00
// Print version info
fmt.Printf("\n %s - %s/%s (%s)\n\n", appVersion, runtime.GOOS, runtime.GOARCH, runtime.Version())
}
// Create module manager
manager := modules.NewManager(log)
2021-05-02 12:29:43 +00:00
// Loading routine
db, err := database.Open(badger.DefaultOptions(*dbdir), manager)
2021-05-02 12:29:43 +00:00
failOnError(err, "Could not open DB")
2021-12-09 12:32:58 +00:00
defer func() {
if err := db.Close(); err != nil {
log.WithError(err).Error("Could not close DB")
}
}()
2021-05-02 12:29:43 +00:00
if *cleanup {
// Run DB garbage collection until it's done
var err error
for err == nil {
err = db.Client().RunValueLogGC(0.5)
2021-05-02 12:29:43 +00:00
}
return
2021-05-02 12:29:43 +00:00
}
// Set meta keys
_ = db.PutKey("stul-meta/version", []byte(appVersion))
2021-05-02 12:29:43 +00:00
runMigrations(db)
2021-05-02 12:29:43 +00:00
for module, constructor := range moduleList {
err := constructor(manager)
if err != nil {
log.WithError(err).WithField("module", module).Error("Could not register module")
} else {
//goland:noinspection GoDeferInLoop
defer func() {
if err := manager.Modules[module].Close(); err != nil {
log.WithError(err).WithField("module", module).Error("Could not close module")
}
}()
2021-05-02 12:29:43 +00:00
}
}
// Create logger and endpoints
httpServer, err := http.NewServer(manager)
failOnError(err, "Could not initialize http server")
2021-12-09 12:32:58 +00:00
defer func() {
if err := httpServer.Close(); err != nil {
log.WithError(err).Error("Could not close DB")
}
}()
2021-05-02 12:29:43 +00:00
fedir, _ := fs.Sub(frontend, "frontend/dist")
httpServer.SetFrontend(fedir)
2021-05-02 12:29:43 +00:00
go func() {
time.Sleep(time.Second) // THIS IS STUPID
dashboardURL := fmt.Sprintf("http://%s/ui", httpServer.Config.Bind)
2021-10-28 09:01:52 +00:00
err := browser.OpenURL(dashboardURL)
if err != nil {
log.WithError(err).Warnf("could not open browser, dashboard URL available at: %s", dashboardURL)
}
2021-05-02 12:29:43 +00:00
}()
2021-12-05 21:17:52 +00:00
// Run garbage collection every once in a while
go func() {
ticker := time.NewTicker(15 * time.Minute)
defer ticker.Stop()
for range ticker.C {
// Run DB garbage collection until it's done
var err error
for err == nil {
err = db.Client().RunValueLogGC(0.5)
}
2021-12-05 21:17:52 +00:00
}
}()
2021-12-05 21:17:52 +00:00
2021-05-02 12:29:43 +00:00
// Start HTTP server
failOnError(httpServer.Listen(), "HTTP server stopped")
2021-05-02 12:29:43 +00:00
}
func failOnError(err error, text string) {
if err != nil {
fatalError(err, text)
}
}
func fatalError(err error, text string) {
log.Fatalf("FATAL ERROR OCCURRED: %s\n\n%s", text, err.Error())
}