feat: add daemon mode flag
Adds a `-daemon` flag to run the application in the background without the interactive terminal UI. It outputs log lines to standard output instead of utilizing `charmbracelet/bubbletea`.
This commit is contained in:
@@ -2,3 +2,4 @@ config.toml
|
|||||||
cookies.json
|
cookies.json
|
||||||
dist/
|
dist/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
parasocial
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@@ -16,10 +17,13 @@ import (
|
|||||||
|
|
||||||
// main sets up process cancellation and reports fatal startup errors to stderr.
|
// main sets up process cancellation and reports fatal startup errors to stderr.
|
||||||
func main() {
|
func main() {
|
||||||
|
daemon := flag.Bool("daemon", false, "run as daemon without interactive TUI")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||||
defer stop()
|
defer stop()
|
||||||
|
|
||||||
if err := app.Run(ctx); err != nil {
|
if err := app.Run(ctx, *daemon); err != nil {
|
||||||
if errors.Is(err, context.Canceled) {
|
if errors.Is(err, context.Canceled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -9,10 +9,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Run loads configuration and starts the terminal UI.
|
// Run loads configuration and starts the terminal UI.
|
||||||
func Run(ctx context.Context) error {
|
func Run(ctx context.Context, daemon bool) error {
|
||||||
cfg, err := config.LoadDefault()
|
cfg, err := config.LoadDefault()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if daemon {
|
||||||
|
return tui.RunDaemon(ctx, tui.Options{Streamers: cfg.Streamers})
|
||||||
|
}
|
||||||
return tui.Run(ctx, tui.Options{Streamers: cfg.Streamers})
|
return tui.Run(ctx, tui.Options{Streamers: cfg.Streamers})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package tui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RunDaemon starts the daemon mode which just logs everything instead of UI.
|
||||||
|
func RunDaemon(ctx context.Context, options Options) error {
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
rt := newRuntime(ctx, options)
|
||||||
|
state := options.AuthState
|
||||||
|
if state == nil {
|
||||||
|
var err error
|
||||||
|
state, err = rt.reuseAuth()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if state == nil {
|
||||||
|
fmt.Println("Starting authentication...")
|
||||||
|
authChan := make(chan AuthUpdate)
|
||||||
|
rt.startAuth(authChan)
|
||||||
|
|
||||||
|
var authErr error
|
||||||
|
for authMsg := range authChan {
|
||||||
|
if authMsg.Line != "" {
|
||||||
|
fmt.Println(authMsg.Line)
|
||||||
|
}
|
||||||
|
if authMsg.Done {
|
||||||
|
if authMsg.Err != nil {
|
||||||
|
authErr = authMsg.Err
|
||||||
|
} else if authMsg.State != nil {
|
||||||
|
state = authMsg.State
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if authErr != nil {
|
||||||
|
return fmt.Errorf("authentication failed: %w", authErr)
|
||||||
|
}
|
||||||
|
fmt.Println("Authentication complete.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Starting streamer resolution...")
|
||||||
|
streamerChan := make(chan StreamerUpdate)
|
||||||
|
rt.startResolve(state, streamerChan)
|
||||||
|
|
||||||
|
for streamerMsg := range streamerChan {
|
||||||
|
if streamerMsg.Done {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if streamerMsg.Err != nil {
|
||||||
|
fmt.Printf("Error: %v\n", streamerMsg.Err)
|
||||||
|
}
|
||||||
|
if streamerMsg.IRC != nil {
|
||||||
|
if message, ok := formatIRCChatLine(streamerMsg.IRC.Line); ok {
|
||||||
|
fmt.Printf("[IRC] %s: %s\n", streamerMsg.IRC.Login, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if streamerMsg.Miner != nil {
|
||||||
|
line := strings.TrimSpace(streamerMsg.Miner.Line)
|
||||||
|
if line != "" {
|
||||||
|
fmt.Printf("[Miner] %s: %s\n", streamerMsg.Miner.Login, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user