Download Jar. Libraryless. Click here for Pure Java version (13483L/95K).
1 | !7 |
2 | |
3 | sS dbBotID = #1026323; |
4 | |
5 | static Env env; |
6 | static new ThreadLocal<Session> session; |
7 | static new ThreadLocal<Out> out; |
8 | |
9 | sclass Out { |
10 | S buttonsIntro; |
11 | LS buttons; |
12 | S placeholder; |
13 | S defaultInput; |
14 | } |
15 | |
16 | sbool testFunctions = false; |
17 | |
18 | static interface Env { |
19 | void sayAsync(S session, S msg); |
20 | } |
21 | |
22 | concept Session { |
23 | S cookie; |
24 | S language; |
25 | S lastQuestion; |
26 | FormInFlight form, lastForm; |
27 | |
28 | void cancelForm { |
29 | cset(this, lastForm := form, form := null); |
30 | } |
31 | |
32 | S language() { ret or2(language, 'en); } |
33 | } |
34 | |
35 | sclass FormStep { |
36 | S key; |
37 | S displayText, desc; |
38 | S defaultValue; |
39 | S placeholder; // null for same as displayText, "" for none |
40 | LS buttons; |
41 | S value; |
42 | |
43 | void update(Runnable onChange) {} |
44 | } |
45 | |
46 | sclass FormInFlight { |
47 | S hashTag; |
48 | new L<FormStep> steps; |
49 | int stepIndex; // in steps list |
50 | |
51 | FormStep currentStep() { |
52 | ret get(steps, stepIndex); |
53 | } |
54 | |
55 | void update(Runnable onChange) { |
56 | if (currentStep() != null) currentStep().update(onChange); |
57 | } |
58 | |
59 | S complete() { ret "Form complete"; } |
60 | S cancel() { ret "Request cancelled"; } |
61 | |
62 | bool shouldCancel() { false; } |
63 | } |
64 | |
65 | sclass MainForm > FormInFlight { |
66 | FormStep stepInterested, stepMailAddress, stepDevice, stepConfirm; |
67 | |
68 | *() { |
69 | hashTag = "#mainForm"; |
70 | } |
71 | |
72 | bool shouldCancel() { |
73 | ret isNo(stepInterested.value); |
74 | } |
75 | } |
76 | |
77 | sbool debug; |
78 | |
79 | svoid setSession(S cookie, SS params) { |
80 | session.set(uniq_sync(Session, +cookie)); |
81 | S lang = mapGet(params, 'language); |
82 | if (nempty(lang)) |
83 | cset(session!, language := lang); |
84 | S lang_default = mapGet(params, 'language_default); |
85 | if (nempty(lang_default)) { |
86 | print("lang_default=" + lang_default + ", have: " + session->language); |
87 | if (empty(session->language)) { |
88 | print("Setting language."); |
89 | cset(session!, language := lang_default); |
90 | } |
91 | } |
92 | } |
93 | |
94 | svoid clearSession(S cookie) { |
95 | deleteConcepts(Session, +cookie); |
96 | } |
97 | |
98 | p { |
99 | db(); |
100 | |
101 | // for testing on desktop |
102 | if (isMain()) { veryBigConsole(); bot(); } |
103 | } |
104 | |
105 | sS returnQuestion(S q) { |
106 | cset(session!, lastQuestion := q); |
107 | ret q; |
108 | } |
109 | |
110 | sS answer(S s) { |
111 | if (session! == null) setSession("default", new Map); |
112 | out.set(new Out); |
113 | if (creator() == null) if "debug" set debug; |
114 | |
115 | S lq = session->lastQuestion; |
116 | cset(session!, lastQuestion := null); |
117 | |
118 | FormInFlight form = session->form; |
119 | if (form != null && form.currentStep() != null) { |
120 | if (eqicOneOf(s, "cancel", "Abbrechen", unicode_crossProduct())) { |
121 | S answer = form.cancel(); |
122 | session->cancelForm(); |
123 | ret answer; |
124 | } |
125 | else if (eqicOneOf(s, "back", "zurück", unicode_undoArrow()) && form.stepIndex > 0) { |
126 | --form.stepIndex; |
127 | session->change(); |
128 | ret deliverAnswerAndFormStep(""); |
129 | } else { |
130 | FormStep step = form.currentStep(); |
131 | if (nempty(step.buttons) && !cic(step.buttons, s)) |
132 | ret deliverAnswerAndFormStep(de() ? "Bitte wählen Sie eine Option!" : "Please choose an option."); |
133 | |
134 | step.value = s; |
135 | ++form.stepIndex; |
136 | session->change(); |
137 | if (form.currentStep() == null) { |
138 | S answer = form.complete(); |
139 | session->cancelForm(); |
140 | ret answer; |
141 | } |
142 | ret deliverAnswerAndFormStep(""); |
143 | } |
144 | } |
145 | |
146 | if (testFunctions) { |
147 | if (eq(lq, "Would you like some tea?")) { |
148 | if "yes" ret "Here's your tea."; |
149 | if "no" ret "Very well then."; |
150 | } |
151 | |
152 | if "test buttons" { |
153 | out->buttons = ll("Yes", "No"); |
154 | ret returnQuestion("Would you like some tea?"); |
155 | } |
156 | |
157 | if "say something later" { |
158 | if (env == null) ret("No env"); |
159 | final S mySession = session->cookie; |
160 | thread { |
161 | sleepSeconds(5); |
162 | env.sayAsync(mySession, "Here it is."); |
163 | } |
164 | ret "OK, will do it in 5 seconds"; |
165 | } |
166 | } |
167 | |
168 | // call special input processors |
169 | |
170 | try answer processURLInInput(s); |
171 | |
172 | // get answer from bot, switch language |
173 | |
174 | O bot = dbBot(); |
175 | S a = (S) call(bot, 'answer, s, session->language()); |
176 | S lang = cast getThreadLocal(((ThreadLocal) get(bot, 'language_out))); |
177 | if (nempty(lang)) cset(session!, language := lang); |
178 | |
179 | S a2 = replaceAll(a, "\\s*#mainForm\\b", ""); |
180 | if (neq(a, a2)) { |
181 | form = new MainForm; |
182 | print("Made form for cookie " + session->cookie + ": " + sfu(form)); |
183 | cset(session!, +form); |
184 | } |
185 | |
186 | ret deliverAnswerAndFormStep(a2); |
187 | } |
188 | |
189 | sS deliverAnswerAndFormStep(S answer) { |
190 | FormInFlight form = session->form; |
191 | if (form == null) ret answer; |
192 | |
193 | form.update(r { session->change() }); |
194 | if (form.shouldCancel()) { |
195 | session->cancelForm(); |
196 | ret answer; |
197 | } |
198 | |
199 | if (form.currentStep() == null) ret answer; |
200 | |
201 | FormStep step = form.currentStep(); |
202 | if (empty(answer)) |
203 | answer = step.displayText; |
204 | else |
205 | out->buttonsIntro = step.displayText; |
206 | out->placeholder = or(step.placeholder, step.displayText); |
207 | print("Step " + form.stepIndex + ": " + sfu(step)); |
208 | out->defaultInput = or2(step.value, step.defaultValue); |
209 | out->buttons = cloneList(step.buttons); |
210 | if (form.stepIndex > 0) out->buttons.add(de() ? "Zurück" : "Back"); |
211 | out->buttons.add(de() ? "Abbrechen" : "Cancel"); |
212 | ret answer; |
213 | } |
214 | |
215 | sS initialMessage() { |
216 | print("initialMessage, lang=" + session->language()); |
217 | ret or2(answer("#greeting"), "Hello"); |
218 | } |
219 | |
220 | sO dbBot() { |
221 | ret getBot(dbBotID); |
222 | } |
223 | |
224 | sbool de() { |
225 | ret eqic(session->language(), "de"); |
226 | } |
227 | |
228 | sbool botOn() { |
229 | ret isTrue(call(dbBot(), "botOn")); |
230 | } |
231 | |
232 | sbool botAutoOpen() { |
233 | ret isTrue(call(dbBot(), "botAutoOpen")); |
234 | } |
235 | |
236 | sS processURLInInput(S s) { |
237 | LS urls = regexpAllMatches(urlFinderRegexp(), s); |
238 | if (empty(urls)) null; |
239 | ret "URLs found:\n" + lines(urls); |
240 | } |
Began life as a copy of #1026246
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1026321 |
Snippet name: | abots.space Thought Bot |
Eternal ID of this version: | #1026321/3 |
Text MD5: | 40ea90aa1099709f130d35595419c375 |
Transpilation MD5: | 8c613b9fe0680c09a257152b88e9507a |
Author: | stefan |
Category: | javax / a.i. |
Type: | JavaX source code (desktop) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2019-12-19 11:14:34 |
Source code size: | 5764 bytes / 240 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 294 / 1170 |
Version history: | 2 change(s) |
Referenced in: | [show references] |