Local mode, Makefile, image fixes, Pete avatar
- Add -local flag: web/RSS-only mode that skips Matrix login and posting, so the web UI can be exercised against live feeds without credentials - Add Makefile (build/local/seed/test/clean) that handles Tailwind + go build in one shot - Fix Guardian thumbnails: NormalizeImageURL was rewriting width=1200 onto signed i.guim.co.uk URLs, invalidating the s= signature and returning 401. Leave signed URLs alone and pick the widest media:content variant up front instead - Use pete.avif as the header logo, favicon, and footer mark; drop the unused leaf.svg
This commit is contained in:
48
main.go
48
main.go
@@ -26,6 +26,7 @@ func main() {
|
||||
seed := flag.Bool("seed", false, "ingest current feed items as seen without posting, then exit")
|
||||
test := flag.Bool("test", false, "post one story to verify the full pipeline, then exit")
|
||||
testSource := flag.String("test-source", "", "source name to use for -test (default: first enabled)")
|
||||
local := flag.Bool("local", false, "web/RSS-only mode: poll feeds and serve the web UI, no Matrix login or posting")
|
||||
flag.Parse()
|
||||
|
||||
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
|
||||
@@ -62,6 +63,12 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
// Local mode: poll feeds + serve web UI only. No Matrix, no posting queue.
|
||||
if *local {
|
||||
runLocal(cfg)
|
||||
return
|
||||
}
|
||||
|
||||
// Create Matrix client
|
||||
mx, err := matrix.New(cfg.Matrix)
|
||||
if err != nil {
|
||||
@@ -209,6 +216,47 @@ func main() {
|
||||
slog.Info("pete stopped")
|
||||
}
|
||||
|
||||
func runLocal(cfg *config.Config) {
|
||||
cfg.Web.Enabled = true
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
processItem := func(_ context.Context, item *ingestion.FeedItem) {
|
||||
if item.DirectRoute == "" {
|
||||
slog.Info("local: item has no direct_route, discarding", "guid", item.GUID, "source", item.Source)
|
||||
storage.MarkClassified(item.GUID, "_discarded", "[]")
|
||||
return
|
||||
}
|
||||
storage.MarkClassified(item.GUID, item.DirectRoute, "[]")
|
||||
slog.Info("local: story classified",
|
||||
"guid", item.GUID, "source", item.Source, "channel", item.DirectRoute, "headline", item.Headline)
|
||||
}
|
||||
|
||||
poller := ingestion.NewPoller(cfg.Sources, processItem)
|
||||
poller.Start(ctx)
|
||||
slog.Info("local: pollers started")
|
||||
|
||||
ws, err := web.New(cfg.Web)
|
||||
if err != nil {
|
||||
slog.Error("local: web server init failed", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
go ws.Start(ctx)
|
||||
slog.Info("local: web UI listening", "addr", cfg.Web.ListenAddr)
|
||||
|
||||
storage.RunMaintenance()
|
||||
|
||||
sig := <-sigCh
|
||||
slog.Info("local: shutdown signal received", "signal", sig)
|
||||
cancel()
|
||||
poller.Wait()
|
||||
slog.Info("pete stopped")
|
||||
}
|
||||
|
||||
func runSeed(cfg *config.Config) {
|
||||
total := 0
|
||||
for _, src := range cfg.Sources {
|
||||
|
||||
Reference in New Issue
Block a user