Libraryless. Click here for Pure Java version (3185L/20K/67K).
1 | !759 |
2 | |
3 | static PersistentMap<S, S> theories; // name -> text |
4 | static new MultiMap<S, S> signMap; |
5 | |
6 | static new Map<S, S> icCache; // lower case name -> text |
7 | |
8 | static class Sign { |
9 | S user, theory, as; |
10 | long since; |
11 | } |
12 | |
13 | static new L<Sign> signList; // v2 of signMap |
14 | |
15 | static boolean printTimings = false; |
16 | |
17 | p { |
18 | theories = new PersistentMap("theories"); |
19 | for (S name : getTheoryNames()) icCache.put(name.toLowerCase(), theories.get(name)); |
20 | load("signMap"); |
21 | load("signList"); |
22 | } |
23 | |
24 | static synchronized L<S> getTheoryNames() { |
25 | ret new ArrayList(theories.keySet()); |
26 | } |
27 | |
28 | static synchronized boolean hasTheory(S name) { |
29 | ret icCache.containsKey(name.toLowerCase()); |
30 | } |
31 | |
32 | static synchronized S getTheoryOpt(S name) { |
33 | ret icCache.get(name.toLowerCase()); |
34 | } |
35 | |
36 | static synchronized S getTheory(S name) { |
37 | S text = getTheoryOpt(name); |
38 | if (text == null) fail("Theory * not found", name); |
39 | ret text; |
40 | } |
41 | |
42 | static synchronized L<S> getTheoriesSignedByAs(S user, S as) { |
43 | new L<S> l; |
44 | for (Sign s : signList) |
45 | if (eq(s.user, user) && eq(s.as, as)) |
46 | l.add(s.theory); |
47 | ret l; |
48 | } |
49 | |
50 | static synchronized Sign findSigning(S user, S as, S theory) { |
51 | for (Sign s : signList) |
52 | if (eq(s.user, user) && eq(s.as, as) && eq(s.theory, theory)) |
53 | ret s; |
54 | ret null; |
55 | } |
56 | |
57 | static synchronized void theoriesPut(S name, S text) { |
58 | theories.put(name, text); |
59 | icCache.put(name.toLowerCase(), text); |
60 | } |
61 | |
62 | static synchronized void theoriesRemove(S name) { |
63 | theories.remove(name); |
64 | icCache.remove(name.toLowerCase()); |
65 | } |
66 | |
67 | static S signTheory(S user, S theory, S as) { |
68 | if (empty(user)) ret "go to slack please"; |
69 | if (!hasTheory(theory)) ret "Theory not found"; |
70 | if (getTheoriesSignedByAs(user, as).contains(theory)) |
71 | ret "You have already signed this theory as " + as + "!"; |
72 | new Sign sign; |
73 | sign.user = user; |
74 | sign.theory = theory; |
75 | sign.as = as; |
76 | sign.since = now(); |
77 | signList.add(sign); |
78 | save("signList"); |
79 | ret format("OK, signed * as *!", theory, as); |
80 | } |
81 | |
82 | static S unsignTheory(S user, S theory, S as) { |
83 | if (empty(user)) ret "go to slack please"; |
84 | if (!hasTheory(theory)) ret "Theory not found"; |
85 | Sign sign = findSigning(user, as, theory); |
86 | if (sign == null) |
87 | ret "You have not signed this theory as " + as + "."; |
88 | signList.remove(sign); |
89 | save("signList"); |
90 | ret format("OK, unsigned * as *.", theory, as); |
91 | } |
92 | |
93 | synchronized answer { |
94 | //if (!attn()) ret null; |
95 | |
96 | if "count theories" |
97 | ret lstr(theories); |
98 | |
99 | if "list theories" |
100 | ret structure(keys(theories)); |
101 | |
102 | if "show theory *" exceptionToUser { |
103 | ret showTheories(litlist(m.unq(0))); |
104 | } |
105 | |
106 | if (matchStart("show theories", s, m)) exceptionToUser { |
107 | ret showTheories(codeTokensOnly(javaTok(m.rest()))); |
108 | } |
109 | |
110 | if "modify theory * *" exceptionToUser { |
111 | S name = m.unq(0), text = m.unq(1); |
112 | ret saveTheory(name, text, true); |
113 | } |
114 | |
115 | if "add theory * *" exceptionToUser { |
116 | S name = m.unq(0), text = m.unq(1); |
117 | ret saveTheory(name, text, false); |
118 | } |
119 | |
120 | S line = firstLine(s).trim(); |
121 | if (startsWithIgnoreCase(line, "theory ") && l(toLines(s)) > 1) exceptionToUser { |
122 | line = dropPrefixIgnoreCase("theory ", line); |
123 | line = dropSuffix(":", line).trim(); |
124 | S name = unquote(line), text = dropFirstLine(s); |
125 | ret saveTheory(name, text, false); |
126 | } |
127 | |
128 | if (match("inc theory * *", s, m) || match("increment theory * *", s, m)) exceptionToUser { |
129 | S name = m.unq(0), text = m.unq(1); |
130 | ret incrementTheory(name, text); |
131 | } |
132 | |
133 | if "sign theory *" exceptionToUser { |
134 | S user = getUserName(); |
135 | ret signTheory(user, m.unq(0), "default"); |
136 | } |
137 | |
138 | if "unsign theory *" exceptionToUser { |
139 | S user = getUserName(); |
140 | ret unsignTheory(user, m.unq(0), "default"); |
141 | } |
142 | |
143 | if "sign theory * as *" exceptionToUser { |
144 | S user = getUserName(); |
145 | ret signTheory(user, m.unq(0), m.unq(1)); |
146 | } |
147 | |
148 | if "unsign theory * as *" exceptionToUser { |
149 | S user = getUserName(); |
150 | ret unsignTheory(user, m.unq(0), m.unq(1)); |
151 | } |
152 | |
153 | if "my signed theories" exceptionToUser { |
154 | S user = getUserName(); |
155 | if (empty(user)) ret "go to slack please"; |
156 | ret structure(getTheoriesSignedByAs(user, "default")); |
157 | } |
158 | |
159 | if "my theories signed as *" exceptionToUser { |
160 | S user = getUserName(); |
161 | if (empty(user)) ret "go to slack please"; |
162 | ret structure(getTheoriesSignedByAs(user, m.unq(0))); |
163 | } |
164 | |
165 | if "theories signed by *" exceptionToUser { |
166 | S user = m.unq(0); |
167 | ret structure(getTheoriesSignedByAs(user, "default")); |
168 | } |
169 | |
170 | if (match("theories page", s) || match("theories url", s)) |
171 | ret getBotURL(); |
172 | |
173 | if (!master()) ret null; |
174 | |
175 | if "delete theory *" exceptionToUser { |
176 | S name = m.unq(0); |
177 | if (hasTheory(name)) { |
178 | S text = getTheoryOpt(name); |
179 | logMap("deleted", "name", name, "text", text, "time", now(), "signers", signMap.get(name)); |
180 | logMap("deleted", "name", name, "signers", signMap.get(name)); |
181 | theoriesRemove(name); |
182 | |
183 | signMap.remove(name); |
184 | save("signMap"); |
185 | |
186 | ret format("Theory * backed up & deleted", name); |
187 | } else |
188 | ret format("Theory * not found", name); |
189 | } |
190 | |
191 | if "rename theory * to *" exceptionToUser { |
192 | S name = m.unq(0), newName = m.unq(1); |
193 | if (hasTheory(newName)) |
194 | ret format("A theory named * already exists", newName); |
195 | if (hasTheory(name)) { |
196 | S text = getTheoryOpt(name); |
197 | theoriesPut(newName, text); |
198 | theoriesRemove(name); |
199 | |
200 | // update signMap |
201 | L<S> signers = signMap.get(name); |
202 | signMap.addAll(newName, signers); |
203 | signMap.remove(name); |
204 | save("signMap"); |
205 | |
206 | ret format("Theory * renamed to *", name, newName); |
207 | } else |
208 | ret format("Theory * not found", name); |
209 | } |
210 | } |
211 | |
212 | static S showTheories(L<S> theoryNames) { |
213 | new StringBuilder buf; |
214 | for (S name: theoryNames) { |
215 | if (!hasTheory(name)) |
216 | buf.append(format("Theory * not found\n", name)); |
217 | else { |
218 | buf.append(quote(name) + "\n" + slackSnippet(getTheoryOpt(name)) + "\n\n"); |
219 | } |
220 | } |
221 | ret str(buf).trim(); |
222 | } |
223 | |
224 | static S html(S uri, Map<S, S> params) { |
225 | if (eq(uri, "/signList")) |
226 | ret htmlencode(structure(signList)); |
227 | |
228 | if (eq(uri, "/theories")) |
229 | ret htmlencode(structure(theories)); |
230 | |
231 | if (eq(uri, "/theoriesInc")) { |
232 | int n = parseInt(or(params.get("n"), "0")); |
233 | S id = params.get("id"); |
234 | |
235 | if (nempty(id) && neq(id, theories.id())) |
236 | n = 0; |
237 | |
238 | int m = (int) theories.file.length(); |
239 | S text = unnull(loadTextFileStartingFrom(theories.file, n)); |
240 | //text = substr(text, n); |
241 | ret theories.id() + "\n" + m + "\n" + htmlencode(text); |
242 | } |
243 | |
244 | boolean showMulti = false; |
245 | new L data; |
246 | MultiMap<S, Sign> signs = getSigningsByTheory(); |
247 | for (S name : getTheoryNames()) { |
248 | S text = unnull(getTheoryOpt(name)); |
249 | boolean multi = false; |
250 | Exception error = null; |
251 | L<Sign> signings = signs.get(name); |
252 | new L<S> bla; |
253 | for (Sign sign : signings) |
254 | bla.add(sign.user + " as " + sign.as); |
255 | Map map = litmap( |
256 | "Name", htmlencode(name), |
257 | "Theory", pre(htmlencode(minitrim(rtrim(text)))), |
258 | "Signed by", htmlencode(join(", ", bla))); |
259 | if (showMulti) { |
260 | map.put("Multiple rules?", multi); |
261 | try { |
262 | multi = nlIsMultipleStatements(text); |
263 | } catch (Exception e) { |
264 | error = e; |
265 | } |
266 | } |
267 | if (error != null) |
268 | map.put("Parse Error", str(error)); |
269 | data.add(map); |
270 | } |
271 | ret h3("Theories!") + htmlTable(data, false); |
272 | } |
273 | |
274 | // preserves formatting of first line |
275 | static S minitrim(S s) { |
276 | L<S> l = toLines(s); |
277 | while (!empty(l) && empty(trim(first(l)))) |
278 | l.remove(0); |
279 | ret autoUnindent(fromLines(l)); |
280 | } |
281 | |
282 | static S saveTheory(S name, S text, boolean autoModify) { |
283 | boolean has = hasTheory(name); |
284 | S oldText = getTheoryOpt(name); |
285 | S origName = name; |
286 | int counter = 0; |
287 | while (has && !autoModify) { |
288 | name = origName + "." + (char) (((int) 'a') + (++counter)); |
289 | has = hasTheory(name); |
290 | } |
291 | logMap(has ? "modified" : "added", "name", name, "text", text, "time", now(), "oldText", oldText); |
292 | theoriesPut(name, text); |
293 | ret format((has ? "OK, modified theory *" : "OK, added theory *"), name); |
294 | } |
295 | |
296 | static synchronized long getTheoryCounter(S name) { |
297 | S text = getTheoryOpt(name + ".count"); |
298 | ret isEmpty(text) ? 0 : parseLong(text); |
299 | } |
300 | |
301 | // returns inc'ed value |
302 | static synchronized long incTheoryCounter(S name) { |
303 | long c = getTheoryCounter(name); |
304 | ++c; |
305 | theoriesPut(name + ".count", str(c)); |
306 | ret c; |
307 | } |
308 | |
309 | // returned list might include null elements |
310 | static L<S> getIncrements(S name) { |
311 | new L<S> l; |
312 | long n = getTheoryCounter(name); |
313 | for (long i = 1; i <= n; i++) |
314 | l.add(getTheoryOpt(name + "." + i)); |
315 | ret l; |
316 | } |
317 | |
318 | static synchronized S incrementTheory(S name, S newText) { |
319 | long n = incTheoryCounter(name); |
320 | ret saveTheory(name + "." + n, newText, false); |
321 | } |
322 | |
323 | static synchronized MultiMap<S, Sign> getSigningsByTheory() { |
324 | new MultiMap<S, Sign> map; |
325 | for (Sign s : signList) |
326 | map.put(s.theory, s); |
327 | ret map; |
328 | } |
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1002762 |
Snippet name: | Theories Storing Bot (LIVE) |
Eternal ID of this version: | #1002762/1 |
Text MD5: | f235db8b76b3e31ef4b3667e35e7c40d |
Transpilation MD5: | 141fc2f9712f7d8c8756b98e3aab8911 |
Author: | stefan |
Category: | eleu / nl |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-03-24 19:55:37 |
Source code size: | 9189 bytes / 328 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 1086 / 2284 |
Referenced in: | [show references] |