activity.gno
2.48 Kb · 80 lines
1package radio
2
3import (
4 "strings"
5
6 "gno.land/p/nym-alexiscolin000/gnoradio/store/v0"
7 "gno.land/p/nym-alexiscolin000/gnoradio/text/v0"
8)
9
10const activitySize = 64
11
12// Activity is one programming action on a station.
13type Activity struct {
14 Kind string // queue | curator | sponsored
15 By address
16 Track int
17 Station int
18 Start int64
19 At int64
20}
21
22// recordActivity writes the next slot of the fixed-size ring (storage
23// never grows): Rec(kind, by, numbers), the numbers the track (4 digits),
24// the station (1), the start (6) and the time (6). The head is in the flow
25// record.
26func recordActivity(t *tx, kind string, by address, track, station int, start int64) {
27 h := t.flowAt(fHead, 1)
28 n := store.AppendFixed(store.AppendFixed(store.AppendFixed(store.AppendFixed(make([]byte, 0, 17), int64(track), 4), int64(station), 1), start, 6), now(), 6)
29 t.put(cActivity, store.Pad(h), store.Rec(kind, by.String(), string(n)))
30 t.setFlowAt(fHead, 1, (h+1)%activitySize)
31}
32
33func activityOf(rec string) Activity {
34 f := store.Fields(rec)
35 n := f[2]
36 return Activity{Kind: f[0], By: address(f[1]), Track: int(store.Num(n, 0, 4)), Station: int(store.Num(n, 4, 1)), Start: store.Num(n, 5, 6), At: store.Num(n, 11, 6)}
37}
38
39// activities returns up to limit records, newest first: the ring's slots
40// before its head, read one by one (the ring fills from slot 0 and no slot
41// is ever deleted, so the first empty one ends it).
42func activities(limit int) []string {
43 limit = store.Limit(limit, activitySize)
44 t := rd()
45 head := t.flowAt(fHead, 1)
46 out := make([]string, 0, limit)
47 for i := 1; i <= limit; i++ {
48 rec := t.val(cActivity, store.Pad((head-i+activitySize)%activitySize))
49 if rec == "" {
50 break // the ring is not full yet
51 }
52 out = append(out, rec)
53 }
54 return out
55}
56
57// Activities returns up to limit entries, newest first.
58func Activities(limit int) []Activity {
59 var out []Activity
60 for _, rec := range activities(limit) {
61 out = append(out, activityOf(rec))
62 }
63 return out
64}
65
66// ActivityJSON returns the programming feed, newest first (limit <= 64).
67func ActivityJSON(limit int) string {
68 var b strings.Builder
69 b.WriteString("[")
70 for i, rec := range activities(limit) {
71 a := activityOf(rec)
72 if i > 0 {
73 b.WriteString(",")
74 }
75 b.WriteString(`{"kind":` + text.Str(a.Kind) + `,"by":` + text.Str(a.By.String()) + `,"track":` + text.Itoa(a.Track) +
76 `,"station":` + text.Itoa(a.Station) + `,"start":` + text.Itoa64(a.Start) + `,"at":` + text.Itoa64(a.At) + `}`)
77 }
78 b.WriteString("]")
79 return b.String()
80}