Files
xt/service.go

116 lines
1.7 KiB
Go
Raw Normal View History

2024-11-10 13:23:00 -07:00
package main
import (
2025-02-15 16:12:42 -07:00
"context"
2024-11-10 13:23:00 -07:00
"database/sql"
"fmt"
2024-11-11 19:13:34 -07:00
"iter"
2024-11-10 13:23:00 -07:00
"os"
"strings"
2025-02-15 16:12:42 -07:00
"sync"
2024-11-10 13:23:00 -07:00
_ "embed"
_ "github.com/mattn/go-sqlite3"
"go.yarn.social/lextwt"
2024-11-11 19:13:34 -07:00
"go.yarn.social/types"
2024-11-10 13:23:00 -07:00
)
func run(c console) error {
a := c.Args()
2025-02-15 16:12:42 -07:00
app := &appState{
args: a,
feeds: sync.Map{},
queue: FibHeap(func(a, b *Feed) bool {
return a.LastScanOn.Time.Before(b.LastScanOn.Time)
}),
2024-11-10 13:23:00 -07:00
}
2025-02-15 16:12:42 -07:00
// Setup DB
err := func(ctx context.Context) error {
db, err := app.DB()
2024-11-10 13:23:00 -07:00
if err != nil {
2025-02-15 16:12:42 -07:00
return err
2024-11-10 13:23:00 -07:00
}
2025-02-15 16:12:42 -07:00
defer db.Close()
2024-11-10 13:23:00 -07:00
2025-02-15 16:12:42 -07:00
for _, stmt := range strings.Split(initSQL, ";") {
_, err = db.ExecContext(ctx, stmt)
2024-11-10 13:23:00 -07:00
if err != nil {
2025-02-15 16:12:42 -07:00
return err
2024-11-10 13:23:00 -07:00
}
}
2025-02-15 16:12:42 -07:00
return nil
}(c.Context)
if err != nil {
return err
}
2024-11-11 19:13:34 -07:00
2025-02-15 16:12:42 -07:00
// Seed File
err = func() error {
f, err := os.Open(a.baseFeed)
2024-11-20 09:05:05 -07:00
if err != nil {
2025-02-15 16:12:42 -07:00
return err
2024-11-20 09:05:05 -07:00
}
2025-02-15 16:12:42 -07:00
defer f.Close()
2024-11-20 09:05:05 -07:00
2025-02-15 16:12:42 -07:00
twtfile, err := lextwt.ParseFile(f, &types.Twter{
Nick: a.Nick,
URI: a.URI,
})
2024-11-10 13:23:00 -07:00
if err != nil {
2025-02-15 16:12:42 -07:00
return fmt.Errorf("%w: %w", ErrParseFailed, err)
2024-11-11 19:13:34 -07:00
}
2025-02-15 16:12:42 -07:00
db, err := app.DB()
2024-11-11 19:13:34 -07:00
if err != nil {
2025-02-15 16:12:42 -07:00
return err
2024-11-20 09:05:05 -07:00
}
2025-02-15 16:12:42 -07:00
defer db.Close()
2024-11-20 09:05:05 -07:00
2025-02-15 16:12:42 -07:00
return storeFeed(db, twtfile)
}()
2024-11-20 09:05:05 -07:00
if err != nil {
return err
}
2025-02-15 16:12:42 -07:00
go refreshLoop(c, app)
go httpServer(c, app)
2024-11-20 09:05:05 -07:00
2025-02-15 16:12:42 -07:00
<-c.Done()
return c.Err()
2024-11-20 09:05:05 -07:00
}
2025-02-15 16:12:42 -07:00
type appState struct {
args args
feeds sync.Map
queue *fibHeap[Feed]
2024-11-11 19:13:34 -07:00
2025-02-15 16:12:42 -07:00
}
2024-11-11 19:13:34 -07:00
2025-02-15 16:12:42 -07:00
func (app *appState) DB() (*sql.DB, error) {
return sql.Open(app.args.dbtype, app.args.dbfile)
}
2024-11-11 19:13:34 -07:00
2025-02-15 16:12:42 -07:00
func (app *appState) Feed(feedID string) *Feed {
return nil
}
2024-11-10 13:23:00 -07:00
2025-02-15 16:12:42 -07:00
func (app *appState) Feeds() iter.Seq2[string, *Feed] {
return func(yield func(string, *Feed) bool) {
app.feeds.Range(func(k, v any) bool {
key, _ := k.(string)
value, ok := v.(*Feed)
if !ok {
return false
2024-11-11 19:13:34 -07:00
}
2025-02-15 16:12:42 -07:00
if !yield(key, value) {
return false
2024-11-11 19:13:34 -07:00
}
2025-02-15 16:12:42 -07:00
return true
})
}
2024-11-11 19:13:34 -07:00
}