forked from ziqing26/jiojiobot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
functions.py
350 lines (271 loc) · 13.4 KB
/
functions.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
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
from util import *
from telegram import InlineKeyboardMarkup, InlineKeyboardButton, ParseMode
import os
import redis
"""
Terminologies:
chat: the chat where the jio is created
jio: a collection of orders
jio_name: the title of the jio
user: the person who join the jio
orders: the line to be displayed (item + name + (paid))
=========
Workflow:
Start a jio -> Join jio (CRUD) -> Finalise jio -> Pay -> End jio
========
Tables:
meta [hmset]
- {'meta' + chat_id} ->
{'message_id' -> {message_id}
'finalised' -> {0 or 1} # 0 for Flase, 1 for True
'title' -> {jio_title}}
item [hmset]
- {'item' + chat_id} ->
{{'u'+user_id} -> {order_item_string}}
"""
def start(update, context):
context.bot.send_message(chat_id=update.effective_chat.id,
text="Hi! To start a jio, type '/start_jio'")
# Create a new jio with a title
def start_jio(update, context):
r = redis.from_url(os.environ.get("REDIS_URL"), decode_responses=True)
arguments, user_id, user_name, chat_id = parse(update, context)
chat_id_meta_string, chat_id_item_string, user_id_string = stringify_ids(chat_id, user_id)
if r.hget(chat_id_meta_string, 'message_id'):
context.bot.send_message(chat_id=chat_id,
text="There is an ongoing jio. To end the jio, use '/end_jio'")
return
if not arguments:
context.bot.send_message(chat_id=chat_id,
text="To start a jio, type '/start_jio <title>'")
return
# Send jio start message
jio_name = ' '.join(arguments)
reply = get_open_jio_name_string(jio_name)
message = context.bot.send_message(chat_id, text=reply,
parse_mode= 'html')
# Initialise jio name and meta values
metadata = {'title': jio_name, 'message_id': message.message_id, 'finalised': 0}
r.hmset(chat_id_meta_string, metadata)
# Delete any existing jio in the group chat
r.delete(chat_id_item_string)
# Edit the title of the jio
def edit_jio_title(update, context):
r = redis.from_url(os.environ.get("REDIS_URL"), decode_responses=True)
arguments, user_id, user_name, chat_id = parse(update, context)
chat_id_meta_string, chat_id_item_string, user_id_string = stringify_ids(chat_id, user_id)
# Guard clause against user edited message
if user_id == 0 or user_name == '':
return
if not r.hget(chat_id_meta_string, 'message_id'):
context.bot.send_message(chat_id=chat_id,
text="No jio currently. Start a jio with '/start_jio <title>'")
return
if not arguments:
context.bot.send_message(chat_id=chat_id,
text="To edit jio title, type '/edit_jio_title <new_jio_title>'")
else:
# Get updated jio title
jio_name = ' '.join(arguments)
message_id = int(r.hget(chat_id_meta_string, 'message_id'))
# Change jio name and meta values
metadata = r.hgetall(chat_id_meta_string)
metadata['title'] = jio_name
r.hmset(chat_id_meta_string, metadata)
# Form updated message
orders = r.hgetall(chat_id_item_string)
orders_string = '\n'.join(['%s' % value for value in orders.values()])
reply = get_open_jio_name_string(jio_name) + orders_string
context.bot.edit_message_text(chat_id=chat_id, message_id=message_id, text=reply, parse_mode= 'html')
# Join a jio or update user's jio item
def join_jio(update, context):
r = redis.from_url(os.environ.get("REDIS_URL"), decode_responses=True)
arguments, user_id, user_name, chat_id = parse(update, context)
chat_id_meta_string, chat_id_item_string, user_id_string = stringify_ids(chat_id, user_id)
# Guard clause against user edited message
if user_id == 0 or user_name == '':
return
if not r.hget(chat_id_meta_string, 'message_id'):
context.bot.send_message(chat_id=chat_id,
text="No jio currently. Start a jio with '/start_jio <title>'")
return
message_id = int(r.hget(chat_id_meta_string, 'message_id'))
finalised = int(r.hget(chat_id_meta_string, 'finalised'))
if finalised == 1:
context.bot.send_message(chat_id=chat_id,
text="Current jio is finalised, join the next jio!")
if not arguments:
context.bot.send_message(chat_id=chat_id,
text="To add an item to this jio, type '/join_jio <item>'")
else:
order_message = ' '.join(arguments) + ' ' + user_name
orders = r.hgetall(chat_id_item_string)
# Do nothing if updated item is the same as initial item
if user_id_string in orders and order_message == orders[user_id_string]:
return
# Update item
orders[user_id_string] = order_message
r.hmset(chat_id_item_string, orders)
# Form update message
updated_orders = '\n'.join(['%s' % value for value in orders.values()])
jio_name = r.hget(chat_id_meta_string, 'title')
reply = get_open_jio_name_string(jio_name) + updated_orders
context.bot.edit_message_text(chat_id=chat_id, message_id=message_id, text=reply, parse_mode= 'html')
# Quit a joined jio before it is finalised
def quit_jio(update, context):
r = redis.from_url(os.environ.get("REDIS_URL"), decode_responses=True)
arguments, user_id, user_name, chat_id = parse(update, context)
chat_id_meta_string, chat_id_item_string, user_id_string = stringify_ids(chat_id, user_id)
# Guard clause against user edited message
if user_id == 0 or user_name == '':
return
if not r.hget(chat_id_meta_string, 'message_id'):
context.bot.send_message(chat_id=chat_id,
text="No jio currently. Start a jio with '/start_jio <title>'")
return
orders = r.hgetall(chat_id_item_string)
message_id = int(r.hget(chat_id_meta_string, 'message_id'))
finalised = int(r.hget(chat_id_meta_string, 'finalised'))
if user_id_string not in orders:
context.bot.send_message(chat_id=chat_id,
text="Sorry, you are not in the current jio. 😢")
else:
original_message = orders[user_id_string]
if finalised:
context.bot.send_message(chat_id=chat_id,
text="You cannot quit a jio after it is finalised.")
else:
del orders[user_id_string]
r.hdel(chat_id_item_string, user_id_string)
# Form edited message
jio_name = r.hget(chat_id_meta_string, 'title')
updated_orders = '\n'.join(['%s' % value for value in orders.values()])
reply = get_open_jio_name_string(jio_name) + updated_orders
context.bot.edit_message_text(chat_id=chat_id, message_id=message_id, text=reply, parse_mode= 'html')
# Mark user's order as paid
def paid(update, context):
r = redis.from_url(os.environ.get("REDIS_URL"), decode_responses=True)
arguments, user_id, user_name, chat_id = parse(update, context)
chat_id_meta_string, chat_id_item_string, user_id_string = stringify_ids(chat_id, user_id)
# Guard clause against user edited message
if user_id == 0 or user_name == '':
return
if not r.hget(chat_id_meta_string, 'message_id'):
context.bot.send_message(chat_id=chat_id,
text="No jio currently. Start a jio with '/start_jio <title>'")
return
orders = r.hgetall(chat_id_item_string)
message_id = int(r.hget(chat_id_meta_string, 'message_id'))
finalised = int(r.hget(chat_id_meta_string, 'finalised'))
if user_id_string not in orders:
context.bot.send_message(chat_id=chat_id,
text="Sorry, you are not in the current jio. 😢")
elif finalised == 0:
context.bot.send_message(chat_id=chat_id,
text="Please wait for the jio to be finalised.")
else:
original_message = orders[user_id_string]
# Do nothing is user has paid
if '✅' in original_message:
return
# Mark as paid if user has not paid.
order_message = original_message + ' ✅'
orders[user_id_string] = order_message
r.hmset(chat_id_item_string, orders)
# Form updated message
jio_name = r.hget(chat_id_meta_string, 'title')
updated_orders = '\n'.join(['%s' % value for value in orders.values()])
reply = get_finalised_jio_name_string(jio_name) + updated_orders
context.bot.edit_message_text(chat_id=chat_id, message_id=message_id, text=reply, parse_mode= 'html')
# Check if everyone paid, if so, end the jio.
everyone_paid = True
for order in orders.values():
if '✅' not in order:
everyone_paid = False
if everyone_paid:
r.delete(chat_id_meta_string)
r.delete(chat_id_item_string)
context.bot.send_message(chat_id=update.effective_chat.id,
text="Everyone paid! Jio session ended. 🥳")
# End a jio in the group
def end_jio(update, context):
r = redis.from_url(os.environ.get("REDIS_URL"), decode_responses=True)
arguments, user_id, user_name, chat_id = parse(update, context)
chat_id_meta_string, chat_id_item_string, user_id_string = stringify_ids(chat_id, user_id)
# Guard clause against user edited message
if user_id == 0 or user_name == '':
return
if not r.hget(chat_id_meta_string, 'message_id'):
context.bot.send_message(chat_id=chat_id,
text="No jio currently. Start a jio with '/start_jio <title>'")
return
jio_name = r.hget(chat_id_meta_string, 'title')
# Delete existing data of the current jio
r.delete(chat_id_meta_string)
r.delete(chat_id_item_string)
context.bot.send_message(chat_id=update.effective_chat.id,
text="Your current jio " + "is terminated. See you next time!")
# Finalise the jio so that users can mark their orders as paid
def finalise_jio(update, context):
r = redis.from_url(os.environ.get("REDIS_URL"), decode_responses=True)
arguments, user_id, user_name, chat_id = parse(update, context)
chat_id_meta_string, chat_id_item_string, user_id_string = stringify_ids(chat_id, user_id)
# Guard clause against user edited message
if user_id == 0 or user_name == '':
return
if not r.hget(chat_id_meta_string, 'message_id'):
context.bot.send_message(chat_id=chat_id,
text="No jio currently. Start a jio with '/start_jio <title>'")
return
orders = r.hgetall(chat_id_item_string)
metadata = r.hgetall(chat_id_meta_string)
if metadata['finalised'] == 1:
context.bot.send_message(chat_id=chat_id,
text="The jio is empty. To end the jio, use '/end_jio'")
return
if not orders:
context.bot.send_message(chat_id=chat_id,
text="The jio is empty. To end the jio, use '/end_jio'")
return
# Form new message
# jio_name = r.hget(chat_id_meta_string, 'title')
# orders = '\n'.join(['%s' % value for value in orders.values()])
reply = "Are you sure you want to finalise the jio?"
keyboard = [
[
InlineKeyboardButton("Yes", callback_data='confirm_finalise'),
InlineKeyboardButton("No", callback_data='cancel')
]
]
reply_markup = InlineKeyboardMarkup(keyboard)
message = context.bot.send_message(chat_id, text=reply, parse_mode= 'html', reply_markup=reply_markup)
# Update message_id to the finalised message
metadata['message_id'] = message.message_id
r.hmset(chat_id_meta_string, metadata)
def cancel(update, context):
r = redis.from_url(os.environ.get("REDIS_URL"), decode_responses=True)
arguments, user_id, user_name, chat_id = parse(update, context)
chat_id_meta_string, chat_id_item_string, user_id_string = stringify_ids(chat_id, user_id)
message_id = int(r.hget(chat_id_meta_string, 'message_id'))
context.bot.edit_message_text(chat_id=chat_id, message_id=message_id, text="Don't play play ah! 😠")
# Confirmation to finalise jio, finalising a jio is irreversible
def confirm_finalise_jio(update, context):
r = redis.from_url(os.environ.get("REDIS_URL"), decode_responses=True)
arguments, user_id, user_name, chat_id = parse(update, context)
chat_id_meta_string, chat_id_item_string, user_id_string = stringify_ids(chat_id, user_id)
# # Guard clause against user edited message
# if user_id == 0 or user_name == '':
# return
orders = r.hgetall(chat_id_item_string)
metadata = r.hgetall(chat_id_meta_string)
# Form new message
jio_name = r.hget(chat_id_meta_string, 'title')
orders = '\n'.join(['%s' % value for value in orders.values()])
reply = get_finalised_jio_name_string(jio_name) + orders
message_id = int(r.hget(chat_id_meta_string, 'message_id'))
message = context.bot.edit_message_text(chat_id=chat_id, message_id=message_id, text=reply, parse_mode= 'html')
# Set finalised to true
metadata['finalised'] = 1
# Update message_id to the finalised message
metadata['message_id'] = message.message_id
r.hmset(chat_id_meta_string, metadata)