1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package main
import (
"context"
"errors"
"log/slog"
"os"
"olexsmir.xyz/smutok/internal/config"
"olexsmir.xyz/smutok/internal/freshrss"
"olexsmir.xyz/smutok/internal/store"
)
type app struct {
cfg *config.Config
store *store.Sqlite
freshrss *freshrss.Client
freshrssSyncer *freshrss.Syncer
freshrssWorker *freshrss.Worker
}
func bootstrap(ctx context.Context, outputToFile bool) (*app, error) {
cfg, err := config.New()
if err != nil {
return nil, err
}
if outputToFile {
if lerr := setupLogger(cfg); lerr != nil {
return nil, lerr
}
}
store, err := store.NewSQLite(cfg.DBPath)
if err != nil {
return nil, err
}
if merr := store.Migrate(ctx); merr != nil {
return nil, merr
}
fr := freshrss.NewClient(cfg.FreshRSS.Host)
token, err := getAuthToken(ctx, fr, store, cfg)
if err != nil {
return nil, err
}
fr.SetAuthToken(token)
fs := freshrss.NewSyncer(fr, store)
writeToken, err := getWriteToken(ctx, fr, store)
if err != nil {
return nil, err
}
fw := freshrss.NewWorker(fr, store, writeToken)
return &app{
cfg: cfg,
store: store,
freshrss: fr,
freshrssSyncer: fs,
freshrssWorker: fw,
}, nil
}
func getAuthToken(ctx context.Context, fr *freshrss.Client, db *store.Sqlite, cfg *config.Config) (string, error) {
token, err := db.GetToken(ctx)
if err == nil {
return token, nil
}
if !errors.Is(err, store.ErrNotFound) {
return "", err
}
slog.Info("requesting auth key")
token, err = fr.Login(ctx, cfg.FreshRSS.Username, cfg.FreshRSS.Password)
if err != nil {
return "", err
}
if serr := db.SetToken(ctx, token); serr != nil {
return "", serr
}
return token, nil
}
func getWriteToken(ctx context.Context, fr *freshrss.Client, db *store.Sqlite) (string, error) {
token, err := db.GetWriteToken(ctx)
if err == nil {
return token, nil
}
if !errors.Is(err, store.ErrNotFound) {
return "", err
}
slog.Info("requesting write token")
token, err = fr.GetWriteToken(ctx)
if err != nil {
return "", err
}
if serr := db.SetWriteToken(ctx, token); serr != nil {
return "", serr
}
return token, nil
}
func setupLogger(cfg *config.Config) error {
file, err := os.OpenFile(cfg.LogFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)
if err != nil {
return err
}
logger := slog.New(slog.NewTextHandler(file, nil))
slog.SetDefault(logger)
return nil
}
|