render.gno
2.92 Kb · 88 lines
1package sugarproxy
2
3import (
4 "strconv"
5 "strings"
6 "time"
7)
8
9// Render shows the rules as people read them on gno.land.
10func Render(path string) string {
11 now := time.Now().Unix()
12 var b strings.Builder
13 b.WriteString("# sugar proxy\n\nHome internet connections, shared on purpose and paid in GNOT. Sharers run the sugar proxy app; " +
14 "it carries only what these rules allow, checked against this realm through a light client. See sugar.video/proxy.\n\n")
15 if paused {
16 b.WriteString("**Paused.** Apps carry nothing until GovDAO or the guardian resumes it.\n\n")
17 }
18 sections := []struct{ kind, title string }{
19 {KindSite, "Sites"}, {KindCustomer, "Customers"}, {KindRelease, "App releases"}, {KindHub, "Hubs"}, {KindPayer, "Payers"},
20 }
21 for _, s := range sections {
22 b.WriteString("## " + s.title + "\n\n")
23 n := 0
24 for _, it := range items {
25 if it.Kind != s.kind {
26 continue
27 }
28 n++
29 b.WriteString("- **" + strconv.Itoa(it.ID) + "** `" + joinFields(it.Fields) + "`: ")
30 switch {
31 case it.State != StateApproved:
32 b.WriteString(it.Note)
33 case now < it.After:
34 b.WriteString("approved by " + it.By + "; counts from " + time.Unix(it.After, 0).UTC().Format(time.RFC3339) +
35 " unless vetoed")
36 default:
37 b.WriteString("counts (approved by " + it.By + ")")
38 }
39 b.WriteString("\n")
40 }
41 if n == 0 {
42 b.WriteString("None yet.\n")
43 }
44 b.WriteString("\n")
45 }
46 b.WriteString("## Who decides\n\n")
47 b.WriteString("- SUGAR holders, by the governor: propose `" + kindAdd + "` with `kind|field|...`, or `" + kindRemove + "` with an item's number.\n")
48 if delegate != "" {
49 b.WriteString("- The delegate realm `" + delegate + "` adds and removes sites.\n")
50 } else {
51 b.WriteString("- No delegate realm is named.\n")
52 }
53 b.WriteString("- GovDAO adds and removes anything at once, vetoes, pauses, and names the delegate and the guardian.\n")
54 if guardian != "" {
55 b.WriteString("- The guardian, " + guardian.String() + ", may veto and pause.\n")
56 }
57 b.WriteString("- Veto windows: sites " + days(vetoWin[KindSite]) + ", releases " + days(vetoWin[KindRelease]) + ", hubs, customers and payers " +
58 days(vetoWin[KindHub]) + ".\n\n")
59 open := 0
60 for _, r := range requests {
61 if !r.Done {
62 if open == 0 {
63 b.WriteString("## Suggestions\n\n")
64 }
65 open++
66 b.WriteString("- " + strconv.Itoa(r.ID) + " `" + r.Payload + "` by " + r.By.String() + ": " + r.Reason + "\n")
67 }
68 }
69 if open > 0 {
70 b.WriteString("\n")
71 }
72 if len(payouts) > 0 {
73 var paid int64
74 for _, p := range payouts {
75 paid += p.Ugnot
76 }
77 b.WriteString("## Payouts\n\n" + strconv.Itoa(len(payouts)) + " payouts, " + strconv.FormatInt(paid/1_000_000, 10) + " GNOT in all.\n\n")
78 }
79 b.WriteString("The rules apps read: params `doc`, sha256 " + digest + ", version " + strconv.Itoa(docSeq) + ".\n")
80 return b.String()
81}
82
83func days(s int64) string {
84 if s%86400 == 0 {
85 return strconv.FormatInt(s/86400, 10) + " days"
86 }
87 return strconv.FormatInt(s/3600, 10) + " hours"
88}