all repos

smutok @ 63bd59715686ab1d144cdbce4b6e51d8dd896fdf

yet another tui rss reader (not abandoned, just paused development)

smutok/internal/freshrss/worker.go(view raw)

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
package freshrss

import (
	"context"
	"log/slog"
	"sync"
	"time"

	"olexsmir.xyz/smutok/internal/store"
)

type Worker struct {
	api   *Client
	store *store.Sqlite

	writeToken string
}

func NewWorker(api *Client, store *store.Sqlite, writeToken string) *Worker {
	return &Worker{
		api:        api,
		store:      store,
		writeToken: writeToken,
	}
}

func (w *Worker) Run(ctx context.Context) {
	// TODO: get tick time from config ???
	ticker := time.NewTicker(5 * time.Second)
	defer ticker.Stop()

	var wg sync.WaitGroup
	for {
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
			if !w.isNetworkAvailable(ctx) {
				slog.Info("worker: no internet connection")
				continue
			}

			wg.Go(func() {
				if err := w.pendingReads(ctx); err != nil {
					slog.Error("worker: read", "err", err)
				}
			})
			wg.Go(func() {
				if err := w.pendingUnreads(ctx); err != nil {
					slog.Error("worker: unread", "err", err)
				}
			})
			wg.Go(func() {
				if err := w.pendingStar(ctx); err != nil {
					slog.Error("worker: star", "err", err)
				}
			})
			wg.Go(func() {
				if err := w.pendingUnstar(ctx); err != nil {
					slog.Error("worker: unread", "err", err)
				}
			})
			wg.Wait()
		}
	}
}

// TODO: implement me
func (Worker) isNetworkAvailable(_ context.Context) bool {
	return true
}

func (w *Worker) pendingReads(ctx context.Context) error {
	slog.Debug("worker: pending read")
	return w.handle(ctx, store.Read, StateRead, "")
}

func (w *Worker) pendingUnreads(ctx context.Context) error {
	slog.Debug("worker: pending unread")
	return w.handle(ctx, store.Unread, StateKeptUnread, StateRead)
}

func (w *Worker) pendingStar(ctx context.Context) error {
	slog.Debug("worker: pending star")
	return w.handle(ctx, store.Star, StateStarred, "")
}

func (w *Worker) pendingUnstar(ctx context.Context) error {
	slog.Debug("worker: pending unstar")
	return w.handle(ctx, store.Unstar, "", StateStarred)
}

func (w *Worker) handle(ctx context.Context, action store.Action, addState, rmState string) error {
	articleIDs, err := w.store.GetPendingActions(ctx, action)
	if err != nil {
		return err
	}

	if len(articleIDs) == 0 {
		return nil
	}

	if err := w.api.EditTag(ctx, w.writeToken, EditTag{
		ItemID:      articleIDs,
		TagToAdd:    addState,
		TagToRemove: rmState,
	}); err != nil {
		return err
	}

	return w.store.DeletePendingActions(ctx, action, articleIDs)
}