memberstore.gno
4.39 Kb ยท 182 lines
1package memberstore
2
3import (
4 "chain/runtime"
5 "strings"
6
7 "gno.land/p/demo/svg"
8 "gno.land/p/moul/md"
9 "gno.land/p/nt/avl"
10 "gno.land/p/nt/mux"
11 "gno.land/p/nt/ufmt"
12 "gno.land/r/gov/dao"
13)
14
15var members MembersByTier
16var Tiers TiersByName
17var router *mux.Router
18
19const (
20 T1 = "T1"
21 T2 = "T2"
22 T3 = "T3"
23)
24
25func init() {
26 members = NewMembersByTier()
27
28 Tiers = TiersByName{avl.NewTree()}
29 Tiers.Set(T1, Tier{
30 InvitationPoints: 3,
31 MinSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
32 return 70
33 },
34 MaxSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
35 return 0
36 },
37 BasePower: 3,
38 PowerHandler: func(membersByTier MembersByTier, tiersByName TiersByName) float64 {
39 return 3
40 },
41 })
42
43 Tiers.Set(T2, Tier{
44 InvitationPoints: 2,
45 MaxSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
46 return membersByTier.GetTierSize(T1) * 2
47 },
48 MinSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
49 return membersByTier.GetTierSize(T1) / 4
50 },
51 BasePower: 2,
52 PowerHandler: func(membersByTier MembersByTier, tiersByName TiersByName) float64 {
53 t1ms := float64(membersByTier.GetTierSize(T1))
54 t1, _ := tiersByName.GetTier(T1)
55 t2ms := float64(membersByTier.GetTierSize(T2))
56 t2, _ := tiersByName.GetTier(T2)
57
58 t1p := t1.BasePower * t1ms
59 t2p := t2.BasePower * t2ms
60
61 // capped to 2/3 of tier 1
62 t1ptreshold := t1p * (2.0 / 3.0)
63 if t2p > t1ptreshold {
64 return t1ptreshold / t2ms
65 }
66
67 return t2.BasePower
68 },
69 })
70
71 Tiers.Set(T3, Tier{
72 InvitationPoints: 1,
73 MaxSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
74 return 0
75 },
76 MinSize: func(membersByTier MembersByTier, tiersByName TiersByName) int {
77 return 0
78 },
79 BasePower: 1,
80 PowerHandler: func(membersByTier MembersByTier, tiersByName TiersByName) float64 {
81 t1ms := float64(membersByTier.GetTierSize(T1))
82 t1, _ := tiersByName.GetTier(T1)
83 t3ms := float64(membersByTier.GetTierSize(T3))
84 t3, _ := tiersByName.GetTier(T3)
85
86 t1p := t1.BasePower * t1ms
87 t3p := t3.BasePower * t3ms
88
89 //capped to 1/3 of tier 1
90 t1ptreshold := t1p * (1.0 / 3.0)
91 if t3p > t1ptreshold {
92 return t1ptreshold / t3ms
93 }
94
95 return t3.BasePower
96 },
97 })
98
99 initRouter()
100}
101
102// initRouter initializes the router for the memberstore.
103func initRouter() {
104 router = mux.NewRouter()
105 router.HandleFunc("", renderHome)
106 router.HandleFunc("members", renderMembers)
107 router.NotFoundHandler = renderNotFound
108}
109
110// renderHome displays the tiers data (Number of members and powers) and tiers charts.
111func renderHome(res *mux.ResponseWriter, req *mux.Request) {
112 var sb strings.Builder
113 sb.WriteString(md.Link("> Go to Members list <", "/r/gov/dao/v3/memberstore:members") + "\n")
114
115 members.Iterate("", "", func(tn string, ti interface{}) bool {
116 tree, ok := ti.(*avl.Tree)
117 if !ok {
118 return false
119 }
120
121 tier, ok := Tiers.GetTier(tn)
122 if !ok {
123 return false
124 }
125
126 tp := (tier.PowerHandler(members, Tiers) * float64(members.GetTierSize(tn)))
127
128 sb.WriteString(ufmt.Sprintf("- %v Tier %v contains %v members with power: %v\n", tierColoredChip(tn), tn, tree.Size(), tp))
129
130 return false
131 })
132
133 sb.WriteString("\n" + RenderCharts(members))
134 res.Write(sb.String())
135}
136
137// renderMembers displays the members list.
138func renderMembers(res *mux.ResponseWriter, req *mux.Request) {
139 path := strings.Replace(req.RawPath, "members", "", 1) // We have to clean the path
140 res.Write(RenderMembers(path, members))
141}
142
143func renderNotFound(res *mux.ResponseWriter, req *mux.Request) {
144 res.Write("# 404\n\nThat page was not found. Would you like to [**go home**?](/r/gov/dao/v3/memberstore)")
145}
146
147func tierColor(tn string) string {
148 switch tn {
149 case T1:
150 return "#329175"
151 case T2:
152 return "#21577A"
153 case T3:
154 return "#F3D3BC"
155 default:
156 return "#FFF"
157 }
158}
159
160// tierColoredChip returns a colored chip svg for the given tier name.
161func tierColoredChip(tn string) string {
162 canvas := svg.NewCanvas(16, 16)
163 canvas.Append(svg.NewRectangle(0, 0, 16, 16, tierColor(tn)))
164 return canvas.Render(tn + " colored chip")
165}
166
167func Render(path string) string {
168 var sb strings.Builder
169 sb.WriteString(md.H1("Memberstore Govdao v3"))
170 sb.WriteString(router.Render(path))
171 return sb.String()
172}
173
174// Get gets the Members store
175func Get() MembersByTier {
176 currealm := runtime.CurrentRealm().PkgPath()
177 if !dao.InAllowedDAOs(currealm) {
178 panic("this Realm is not allowed to get the Members data: " + currealm)
179 }
180
181 return members
182}