mirror of
https://git.sr.ht/~ashkeel/strimertul
synced 2024-09-30 02:40:33 +00:00
176 lines
4.7 KiB
Go
176 lines
4.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"embed"
|
|
"fmt"
|
|
"log"
|
|
_ "net/http/pprof"
|
|
"os"
|
|
|
|
"github.com/apenwarr/fixconsole"
|
|
jsoniter "github.com/json-iterator/go"
|
|
"github.com/urfave/cli/v2"
|
|
"github.com/wailsapp/wails/v2"
|
|
"github.com/wailsapp/wails/v2/pkg/options"
|
|
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
|
|
"github.com/wailsapp/wails/v2/pkg/runtime"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
|
|
"git.sr.ht/~ashkeel/strimertul/utils"
|
|
)
|
|
|
|
var json = jsoniter.ConfigFastest
|
|
|
|
var appVersion = "v0.0.0-UNKNOWN"
|
|
|
|
const (
|
|
crashReportURL = "https://crash.strimertul.stream/upload"
|
|
logFilename = "strimertul.log"
|
|
panicFilename = "strimertul-panic.log"
|
|
)
|
|
|
|
//go:embed frontend/dist
|
|
var frontend embed.FS
|
|
|
|
func main() {
|
|
err := fixconsole.FixConsoleIfNeeded()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
var panicLog *os.File
|
|
|
|
app := &cli.App{
|
|
Name: "strimertul",
|
|
Usage: "the small broadcasting suite for Twitch",
|
|
Version: appVersion,
|
|
Action: cliMain,
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{Name: "log-level", Usage: "logging level (debug,info,warn,error)", Value: "info"},
|
|
&cli.StringFlag{Name: "driver", Usage: "specify database driver", Value: "auto"},
|
|
&cli.StringFlag{Name: "database-dir", Aliases: []string{"db-dir"}, Usage: "specify database directory", Value: "data"},
|
|
&cli.StringFlag{Name: "backup-dir", Aliases: []string{"b-dir"}, Usage: "specify backup directory", Value: "backups"},
|
|
&cli.IntFlag{Name: "backup-interval", Aliases: []string{"b-i"}, Usage: "specify backup interval (in minutes, 0 to disable)", Value: 60},
|
|
&cli.IntFlag{Name: "max-backups", Aliases: []string{"b-max"}, Usage: "maximum number of backups to keep, older ones will be deleted, set to 0 to keep all", Value: 20},
|
|
},
|
|
Commands: []*cli.Command{
|
|
{
|
|
Name: "import",
|
|
Usage: "import database from JSON file",
|
|
ArgsUsage: "[-f input.json]",
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{Name: "file", Aliases: []string{"f"}, Usage: "file to open", DefaultText: "STDIN"},
|
|
},
|
|
Action: cliImport,
|
|
},
|
|
{
|
|
Name: "export",
|
|
Usage: "export database as JSON file",
|
|
ArgsUsage: "[-f output.json]",
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{Name: "file", Aliases: []string{"f"}, Usage: "file to save to", DefaultText: "STDOUT"},
|
|
},
|
|
Action: cliExport,
|
|
},
|
|
{
|
|
Name: "restore",
|
|
Usage: "restore database from backup",
|
|
ArgsUsage: "[-f backup.db]",
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{Name: "file", Aliases: []string{"f"}, Usage: "backup to open", DefaultText: "STDOUT"},
|
|
},
|
|
Action: cliRestore,
|
|
},
|
|
},
|
|
Before: func(ctx *cli.Context) error {
|
|
// Initialize logger with global flags
|
|
level, err := zapcore.ParseLevel(ctx.String("log-level"))
|
|
if err != nil {
|
|
level = zapcore.InfoLevel
|
|
}
|
|
initLogger(level)
|
|
|
|
// Create file for panics
|
|
panicLog, err = os.OpenFile(panicFilename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o666)
|
|
if err != nil {
|
|
logger.Warn("Could not create panic log", zap.Error(err))
|
|
} else {
|
|
utils.RedirectStderr(panicLog)
|
|
}
|
|
|
|
zap.RedirectStdLog(logger)()
|
|
|
|
ctx.Context = context.WithValue(ctx.Context, utils.ContextLogger, logger)
|
|
return nil
|
|
},
|
|
After: func(_ *cli.Context) error {
|
|
if panicLog != nil {
|
|
utils.Close(panicLog, logger)
|
|
}
|
|
|
|
_ = logger.Sync()
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
if err := app.Run(os.Args); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func cliMain(ctx *cli.Context) error {
|
|
// Create an instance of the app structure
|
|
app := NewApp(ctx)
|
|
|
|
// Create application with options
|
|
err := wails.Run(&options.App{
|
|
Title: "strimertul",
|
|
Width: 1024,
|
|
Height: 768,
|
|
MinWidth: 480,
|
|
MinHeight: 300,
|
|
AssetServer: &assetserver.Options{
|
|
Assets: frontend,
|
|
},
|
|
SingleInstanceLock: &options.SingleInstanceLock{
|
|
UniqueId: "d1272ae3-765a-4768-97cb-3203b788e7c5",
|
|
OnSecondInstanceLaunch: app.onSecondInstanceLaunch,
|
|
},
|
|
EnableDefaultContextMenu: true,
|
|
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
|
|
OnStartup: app.startup,
|
|
OnShutdown: app.stop,
|
|
OnBeforeClose: func(ctx context.Context) (prevent bool) {
|
|
dialog, err := runtime.MessageDialog(ctx, runtime.MessageDialogOptions{
|
|
Type: runtime.QuestionDialog,
|
|
Title: "Quit?",
|
|
Message: "Are you sure you want to quit?",
|
|
})
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return dialog != "Yes"
|
|
},
|
|
Bind: []any{
|
|
app,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return cli.Exit(fmt.Errorf("%s: %w", "App exited unexpectedly", err), 1)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func warnOnError(err error, text string, fields ...zap.Field) {
|
|
if err != nil {
|
|
fields = append(fields, zap.Error(err))
|
|
logger.Warn(text, fields...)
|
|
}
|
|
}
|
|
|
|
func fatalError(err error, text string) error {
|
|
return cli.Exit(fmt.Errorf("%s: %w", text, err), 1)
|
|
}
|