-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathusercommands.py
312 lines (267 loc) · 13.2 KB
/
usercommands.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# coding: utf-8
import vertretungsplan
import sqlite3
from dsbbot import DSBBot, UserCommand
from orgafunctions import update_user_profile, get_support
class Start(UserCommand):
short = "Starthilfe"
detail = "{usage_string} beschreibt den Bot und gibt Vorschlage, welche Befehle du als naechstes nutzen koenntest."
msg = """Dieser Bot liest den Vertretungsplan deiner Schule aus und sucht dir deine relevanten Eintraege heraus.
Registriere dich mit /register oder lass dir eine Liste der verfuegbaren Befehle mit /help ausgeben."""
def main(self,
update_text: str,
chat_id: int,
database_name: str):
return {chat_id: {"text": self.msg}}
class Register(UserCommand):
short = "Registriere dich mit diesem Befehl."
detail = "Mit {usage_string} kannst du dich fuer diesen Bot registrieren."
success = "Deine Registrierung war erfolgreich."
already_registered = "Du hast dich bereits bei diesem Bot registriert."
def main(self,
update_text: str,
chat_id: int,
database_name: str):
db = sqlite3.connect(database_name)
# Prepare database if it does not exist
# db.execute(f"CREATE TABLE IF NOT EXISTS users({', '.join([x.split()[0] for x in DSBBot.columns])})")
# Store user data
kwargs = {a.split("=")[0]: a.split("=")[1] for a in update_text.split(" ")[1:]
if len(a.split("=")) == 2
and not (a.startswith("=") or a.endswith("="))}
kwargs["chat_id"] = chat_id
columns = str.join(', ', [str(x) for x in kwargs])
values = str.join(', ', [str(kwargs[x]) for x in kwargs])
try:
db.execute(f"INSERT INTO users({columns}) VALUES({values});")
except sqlite3.IntegrityError:
return {chat_id: {"text": self.already_registered}}
# Create lessons table
columns = DSBBot.columns_timetable
columns_str = str.join(', ', columns)
cmd = f"CREATE TABLE IF NOT EXISTS lessons_{chat_id}({columns_str});".replace("-", "u")
db.execute(cmd)
db.commit()
# Set a supporter
update_user_profile(
chat_id=chat_id,
parameters={"support": get_support(chat_id, database_name)},
database_name=database_name,
)
db.close()
return {chat_id: {"text": self.success}}
class UpdateProfile(UserCommand):
short = "Bearbeite dein Profil."
detail = """Mit {usage_string} kannst du dein Profil bearbeiten.
bspw.: {usage_string} dsb_user=213061 dsb_pswd=dsbgak"""
success = "Dein Profil wurde erfolgreich bearbeitet."
def main(self,
update_text: str,
chat_id: int,
database_name: str):
kwargs = {a.split("=")[0]: a.split("=")[1] for a in update_text.split(" ")[1:]
if len(a.split("=")) == 2
and not (a.startswith("=") or a.endswith("="))
and not a.split("=")[0] == "support"
and not a.split("=")[0] == "chat_id"}
update_user_profile(chat_id,
database_name,
kwargs)
return {chat_id: {"text": self.success}}
class DeleteProfile(UserCommand):
short = "Loescht alle Daten, die ueber dich bekannt sind."
success = "Deine Daten wurden erfolgreich geloescht."
detail = """{usage_string} loescht alle Daten, die dem Bot ueber dich bekannt sind.
Um sicher zu gehen, dass du deine Daten wirklich loeschen willst, schreibe \"ja wirklich\" dahinter.
bspw.: {usage_string} ja wirklich"""
def main(self,
update_text: str,
chat_id: int,
database_name: str,
*args, **kwargs):
if update_text.endswith("ja wirklich"):
db = sqlite3.connect(database_name)
# Delete from users table
db.execute(f"DELETE FROM users WHERE chat_id={chat_id};")
# Delete individual timetable table
db.execute(f"DROP TABLE lessons_{chat_id};".replace("-", "u"))
db.commit()
db.close()
return {chat_id: {"text": self.success}}
else:
return {chat_id: {"text": self.detail.replace("{usage_string}", self.usage_string)}}
class AddLesson(UserCommand):
short = "Fuege Stunden zu deinem Stundenplan hinzu."
success = "Stunden wurden erfolgreich deinem Stundenplan hinzugefuegt."
detail = """{usage_string} fuegt Stunden zu deinem Stundenplan hinzu.
Gib folgende Daten an:
Klasse (bspw.: '05A', '12')
Wochentag (bspw.: 'Montag')
Stunde (bspw.: '1', '1-2')
Fach (bspw.: 'Deu')
Raum (bspw.: '1.23')
[Optional:] Wochentyp (bspw.: 'A', 'B')
Du kannst auch mehrere Stunden auf einmal eintragen, indem du jede Stunde in eine neue Zeile schreibst.
{usage_string} 12 Mo 3 Bio Nm2
12 Mo 4 Bio Nm2
12 Mo 7-8 Ma 1.46 B
12 Mo 7-8 Phy Nm1 A"""
def main(self,
update_text: str,
chat_id: int,
database_name: str):
db = sqlite3.connect(database_name)
parameters = update_text.split(" ")[1:]
if not parameters:
return self.help(update_text=update_text,
chat_id=chat_id,
database_name=database_name)
columns = DSBBot.columns_timetable
for line in str.join(" ", update_text.split(" ")[1:]).split("\n"):
used_values = line.split(" ")
while len(used_values) < len(columns) - 1:
used_values.append("")
used_column = [x.split()[0] for x in columns[:-1]]
while len(used_column) < len(columns) - 1:
used_column.append("")
for lesson in used_values[2].split("-"):
used_values[2] = lesson
used_values_str = ", ".join(["'" + str(x) + "'" for x in used_values])
used_column_str = ", ".join(["'" + str(x) + "'" for x in used_column])
cmd = f"INSERT INTO lessons_{chat_id}({used_column_str}) VALUES({used_values_str});".replace("-", "u")
db.execute(cmd)
db.commit()
db.close()
return {chat_id: {"text": str(len(str.join(" ", update_text.split(" ")[1:]).split("\n"))) + " " + self.success}}
class ViewLessons(UserCommand):
short = "Sieh dir deinen Stundenplan an."
detail = "{usage_string} gibt dir eine Liste der Stunden in deinem Stundenplan zurueck."
header = "Hier ist dein Stundenplan:"
def main(self,
update_text: str,
chat_id: int,
database_name: str):
msg = self.header + "\n" * 2
db = sqlite3.connect(database_name)
lessons = [x for x in db.execute(f"SELECT * FROM lessons_{chat_id};".replace("-", "u"))]
msg = msg + str.join("\n", [str.join(" ", [str(y) for y in x if y is not None])
for x in lessons])
db.close()
return {chat_id: {"text": msg}}
class UpdateLesson(UserCommand):
short = "Experimental: Update a lesson from your timetable."
detail = """{usage_string} allows you to update a lesson in your timetable.
eg.: {usage_string} 1 room='1.23' subject='Bio'"""
success = "Your timetable has been updated."
def main(self,
update_text: str,
chat_id: int,
database_name: str,
*args, **kwargs):
db = sqlite3.connect(database_name)
for line in str.join(" ", update_text.split(" ")[1:]).split("\n"):
cmd = f"UPDATE lessons_{chat_id} SET {str.join(', ', line.split(' ')[1:])} WHERE id={line.split(' ')[0]};"
cmd = cmd.replace("-", "u")
db.execute(cmd)
return {chat_id: {"text": self.success}}
class RemoveLesson(UserCommand):
short = "Entfernt eine Stunde von deinem Stundenplan."
detail = """{usage_string} loescht Eintraege von deinem Stundenplan fuer jede Zahl, die du dahinter schreibst.
Nutze {usage_string} um die ID der Stunden zu sehen.
bspw.: /remove_lesson 1 5 13"""
success = """Die Stunden wurden erfolgreich von deinem Stundenplan geloescht.
Nutze /view_lessons um deinen Stundenplan zu ueberpruefen."""
def main(self,
update_text: str,
chat_id: int,
database_name: str):
if not str.join(" ", update_text.split(" ")[1:]):
return {chat_id: {"text": self.detail.replace("{usage_string}", self.usage_string)}}
db = sqlite3.connect(database_name)
for lesson_id in update_text.split(" ")[1:]:
db.execute(f"DELETE FROM lessons_{chat_id} WHERE id={lesson_id};".replace("-", "u"))
db.commit()
db.close()
return {chat_id: {"text": self.success}}
class Information(UserCommand):
short = "Listet deinen Vertretungsplan auf."
detail = "{usage_string} sucht dir die fuer dich relevanten Eintraege aus deinem Vertretungsplan heraus."
msg_relevant = "Fuer dich relevante Eintraege:"
msg_news_for_today = "Folgende Nachrichten liegen fuer heute vor:"
no_relevants = "Fuer deinen Stundenplan liegen keine Eintraege vor."
no_news_for_today = "Es liegen heute keine Nachrichten zum Tag vor."
no_timetable = "Du hast noch keinen Stundenplan eingerichtet."
def main(self,
update_text,
chat_id: int,
database_name):
output = {chat_id: {"text": ""}}
db = sqlite3.connect(database_name)
db_user = [x for x in db.execute(f"SELECT dsb_user, dsb_pswd FROM users WHERE chat_id={chat_id};")][0]
columns = [x.split()[0] for x in DSBBot.columns_timetable[:-1]]
list_lessons = [vertretungsplan.Lesson('').from_list([str(y) for y in x])
for x in db.execute(f"SELECT {', '.join(columns)} FROM lessons_{chat_id};".replace("-", "u"))]
week_day_abbreviations = {"Mo": "Montag",
"Di": "Dienstag",
"Mi": "Mittwoch",
"Do": "Donnerstag",
"Fr": "Freitag"}
for abbr in week_day_abbreviations:
for lesson in list_lessons:
lesson.week_day = lesson.week_day.replace(abbr, week_day_abbreviations[abbr])
username = db_user[0]
password = db_user[1]
url = vertretungsplan.get_url(username=username,
password=password)
doc = vertretungsplan.get_doc(url=url)
if list_lessons:
vertretungen = vertretungsplan.vertretungsplan(doc=doc)
relevant_entries = vertretungsplan.get_relevant(kursliste=list_lessons,
vertretungs_plan=vertretungen)
text_rel = str.join('\n', [str.join(" ", e) for e in relevant_entries]) or self.no_relevants
output[chat_id]["text"] = output[chat_id]["text"] + "\n" + text_rel
else:
output[chat_id]["text"] = output[chat_id]["text"] + "\n" + self.no_timetable
news_for_today = [str.join(": ", [d, t]) for d, t in vertretungsplan.get_news(doc=doc)]
text_mft = str.join('\n', news_for_today) or self.no_news_for_today
output[chat_id]["text"] = output[chat_id]["text"] + "\n" + str.join("\n", [self.msg_news_for_today,
text_mft])
db.execute(f"UPDATE users SET last_notification='{output[chat_id]['text']}'".replace("-", "u"))
db.commit()
db.close()
return output
class Test(UserCommand):
short = "Fuehrt alle Tests des Bots durch."
detail = "{usage_string} fuehrt alle Tests durch, die fuer diesen Bot geschrieben wurden."
def main(self,
update_text,
chat_id: int,
database_name):
from tests import Test
return {chat_id: {'text': "\n".join(Test().run())}}
class UserInfo(UserCommand):
short = "Zeigt die Informationen zu deinem Profil an."
detail = "{usage_string} zeigt alle Informationen an, die der Bot ueber dich gespeichert hat."
msg = "Die Folgenden Informationen sind dem Bot ueber dich bekannt."
def main(self,
update_text,
chat_id,
database_name):
db = sqlite3.connect(database_name)
data = db.execute(f"SELECT {str.join(', ', [DSBBot.columns])} FROM users WHERE id={chat_id};")
text = str.join('\n', [str.join(': ', [DSBBot[column], value]) for column, value in enumerate(data)
if column != "support"])
return {chat_id: {"text": self.msg + "\n" * 2 + text}}
class Support(UserCommand):
short = "Experimental: Versendet eine Nachricht an den Support."
detail = """{usage_string} versendet eine Nachricht an den Support.
Bisher ist keine Funktion implementiert, die es dem Support erlaubt, zu antworten. Druecke dich also praezise aus.
bspw.: {usage_string} Hallo Welt!"""
success = "Dein Anliegen wurde an den Support versendet."
def main(self,
update_text: str,
chat_id: int,
database_name: str):
if str.join(", ", update_text.split(" ")):
return {chat_id: {"text": self.success},
get_support(chat_id, database_name): {"text": "Support: " + " ".join(update_text.split(" ")[1:])}}