diff options
Diffstat (limited to 'bot.py')
-rw-r--r-- | bot.py | 278 |
1 files changed, 90 insertions, 188 deletions
@@ -1,12 +1,7 @@ | |||
1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python |
2 | # pylint: disable=unused-argument, wrong-import-position | ||
3 | # This program is dedicated to the public domain under the CC0 license. | ||
4 | 2 | ||
5 | import logging | ||
6 | import io | ||
7 | import telegram.constants | 3 | import telegram.constants |
8 | from telegram import __version__ as TG_VER | 4 | from telegram import __version__ as TG_VER |
9 | from pprint import pprint | ||
10 | 5 | ||
11 | try: | 6 | try: |
12 | from telegram import __version_info__ | 7 | from telegram import __version_info__ |
@@ -20,46 +15,44 @@ if __version_info__ < (20, 0, 0, "alpha", 1): | |||
20 | f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html" | 15 | f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html" |
21 | ) | 16 | ) |
22 | 17 | ||
18 | import logging | ||
19 | from pprint import pprint | ||
20 | import io | ||
23 | from foursquare.poi import OSM_ENDPOINT | 21 | from foursquare.poi import OSM_ENDPOINT |
24 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup, KeyboardButton | 22 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup, KeyboardButton |
25 | from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, MessageHandler, filters, \ | 23 | from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, MessageHandler, filters, \ |
26 | ConversationHandler, CallbackContext | 24 | ConversationHandler, CallbackContext |
27 | from config import BOT_TOKEN | 25 | from config import BOT_TOKEN, MEDIA_GROUP_TIMEOUT |
28 | from foursquare.poi import query_poi | 26 | from foursquare.poi import query_poi |
29 | from dbstore.dbm_store import get_loc | 27 | from dbstore.dbm_store import get_loc |
30 | from toot import mastodon_client | 28 | from toot import mastodon_client |
31 | from typing import TypedDict, List, cast | 29 | from typing import TypedDict, List, cast |
30 | from prompt.string import * | ||
32 | 31 | ||
33 | scheduler = None | ||
34 | PRIVACY, TOOT = map(chr, range(8, 10)) | ||
35 | |||
36 | WAIT_LOC, LOCATION, LOCATION_SEARCH, PHOTO, PROCESS_PHOTO, COMMENT, SETTING = range(7) | ||
37 | 32 | ||
38 | # Enable logging | ||
39 | logging.basicConfig( | 33 | logging.basicConfig( |
40 | format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO | 34 | format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO |
41 | ) | 35 | ) |
42 | logger = logging.getLogger(__name__) | 36 | logger = logging.getLogger(__name__) |
43 | 37 | ||
38 | WAIT_LOCATION, LOCATION_SEARCH_KEYWORD, LOCATION_CONFIRMATION, ADD_MEDIA, ADD_COMMENT = range(5) | ||
39 | |||
44 | MAIN_MENU = ReplyKeyboardMarkup([ | 40 | MAIN_MENU = ReplyKeyboardMarkup([ |
45 | [KeyboardButton(text="Check-in here", request_location=True)], | 41 | [KeyboardButton(text="Check-in here", request_location=True)], |
46 | # [KeyboardButton(text="/cancel")], | ||
47 | # [KeyboardButton(text="/setting")] | ||
48 | ]) | 42 | ]) |
49 | 43 | ||
50 | SKIP_LOCATION_SEARCH = "skip_location_search" | 44 | SKIP_LOCATION_SEARCH = CALLBACK_SKIP |
51 | 45 | INLINE_SKIP_MENU = InlineKeyboardMarkup([ | |
52 | SKIP_MENU = InlineKeyboardMarkup([ | ||
53 | [telegram.InlineKeyboardButton("Skip", callback_data=SKIP_LOCATION_SEARCH)] | 46 | [telegram.InlineKeyboardButton("Skip", callback_data=SKIP_LOCATION_SEARCH)] |
54 | ]) | 47 | ]) |
55 | 48 | ||
56 | 49 | ||
57 | # SETTING_MENU = InlineKeyboardMarkup( | 50 | class MsgDict(TypedDict): |
58 | # [ | 51 | media_id: str |
59 | # [InlineKeyboardButton(text="/tos")], | 52 | caption: str |
60 | # [InlineKeyboardButton(text="/back")], | 53 | status_id: int |
61 | # ] | 54 | content: str |
62 | # ) | 55 | chat_id: int |
63 | 56 | ||
64 | 57 | ||
65 | async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 58 | async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
@@ -71,13 +64,12 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | |||
71 | "Start using this bot by sharing your location using Telegram context menu to it." | 64 | "Start using this bot by sharing your location using Telegram context menu to it." |
72 | 65 | ||
73 | await update.message.reply_text(hello, parse_mode=telegram.constants.ParseMode.MARKDOWN) | 66 | await update.message.reply_text(hello, parse_mode=telegram.constants.ParseMode.MARKDOWN) |
74 | await update.message.reply_text("Use bot keyboard to choose an action", reply_markup=MAIN_MENU) | 67 | await update.message.reply_text(PROMPT_CHOOSE_ACTION, reply_markup=MAIN_MENU) |
75 | 68 | ||
76 | return LOCATION | 69 | return WAIT_LOCATION |
77 | 70 | ||
78 | 71 | ||
79 | async def checkin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 72 | async def callback_location_sharing(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
80 | pprint(update.message.location) | ||
81 | if update.message.venue is not None: | 73 | if update.message.venue is not None: |
82 | fsq_id = update.message.venue.foursquare_id | 74 | fsq_id = update.message.venue.foursquare_id |
83 | title = update.message.venue.title | 75 | title = update.message.venue.title |
@@ -104,28 +96,22 @@ async def checkin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | |||
104 | parse_mode=telegram.constants.ParseMode.MARKDOWN, | 96 | parse_mode=telegram.constants.ParseMode.MARKDOWN, |
105 | ) | 97 | ) |
106 | 98 | ||
107 | prompt_attach_comment_msg = await update.message.reply_text( | 99 | prompt_attach_comment_msg = await update.message.reply_text(PROMPT_ADD_COMMENT, reply_markup=INLINE_SKIP_MENU) |
108 | "You can continue adding comments, or press skip to finish", reply_markup=SKIP_MENU) | 100 | context.user_data[PROMPT_ADD_COMMENT] = prompt_attach_comment_msg.message_id |
109 | context.user_data["prompt_attach_comment_msg_id"] = prompt_attach_comment_msg.message_id | ||
110 | 101 | ||
111 | return COMMENT | 102 | return ADD_COMMENT |
112 | else: | 103 | else: |
113 | context.user_data["latitude"] = update.message.location.latitude | 104 | context.user_data["latitude"] = update.message.location.latitude |
114 | context.user_data["longitude"] = update.message.location.longitude | 105 | context.user_data["longitude"] = update.message.location.longitude |
115 | 106 | ||
116 | await update.message.reply_text("Searching...", reply_markup=telegram.ReplyKeyboardRemove()) | 107 | await update.message.reply_text("Searching...", reply_markup=telegram.ReplyKeyboardRemove()) |
117 | prompt_msg = await update.message.reply_text("You can input location search keywords or press skip", | 108 | prompt_msg = await update.message.reply_text(PROMPT_LOCATION_KEYWORD, reply_markup=INLINE_SKIP_MENU) |
118 | reply_markup=SKIP_MENU) | ||
119 | 109 | ||
120 | context.user_data["prompt_msg_id"] = prompt_msg.message_id | 110 | context.user_data[PROMPT_LOCATION_KEYWORD] = prompt_msg.message_id |
121 | return LOCATION_SEARCH | 111 | return LOCATION_SEARCH_KEYWORD |
122 | 112 | ||
123 | 113 | ||
124 | async def manual_location_process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 114 | async def callback_manual_location(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
125 | # query = update.callback_query | ||
126 | # await query.answer() | ||
127 | # await query.delete_message() | ||
128 | |||
129 | loc = update.effective_message.text | 115 | loc = update.effective_message.text |
130 | osm_url = OSM_ENDPOINT.format(context.user_data["latitude"], context.user_data["longitude"]) | 116 | osm_url = OSM_ENDPOINT.format(context.user_data["latitude"], context.user_data["longitude"]) |
131 | media_id = [] | 117 | media_id = [] |
@@ -143,22 +129,19 @@ async def manual_location_process_callback(update: Update, context: ContextTypes | |||
143 | await update.message.reply_text( | 129 | await update.message.reply_text( |
144 | text=f"Manually selected place: {loc}, \nPosted to Mastodon: {status['url']}", | 130 | text=f"Manually selected place: {loc}, \nPosted to Mastodon: {status['url']}", |
145 | parse_mode=telegram.constants.ParseMode.MARKDOWN, | 131 | parse_mode=telegram.constants.ParseMode.MARKDOWN, |
146 | # reply_markup=MAIN_MENU | ||
147 | ) | 132 | ) |
148 | 133 | ||
149 | prompt_attach_comment_msg = await update.message.reply_text( | 134 | prompt_attach_comment_msg = await update.message.reply_text(PROMPT_ADD_COMMENT, reply_markup=INLINE_SKIP_MENU) |
150 | "You can continue adding comments, or press skip to finish", reply_markup=SKIP_MENU) | 135 | context.user_data[PROMPT_ADD_COMMENT] = prompt_attach_comment_msg.message_id |
151 | context.user_data["prompt_attach_comment_msg_id"] = prompt_attach_comment_msg.message_id | ||
152 | 136 | ||
153 | return COMMENT | 137 | return ADD_COMMENT |
154 | 138 | ||
155 | 139 | ||
156 | async def process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 140 | async def callback_location_confirmation(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
157 | print("process_callback") | ||
158 | query = update.callback_query | 141 | query = update.callback_query |
159 | await query.answer() | 142 | await query.answer() |
160 | print(query.data) | ||
161 | context.user_data["fsq_id"] = query.data | 143 | context.user_data["fsq_id"] = query.data |
144 | |||
162 | await query.delete_message() | 145 | await query.delete_message() |
163 | 146 | ||
164 | poi = get_loc(context.user_data["fsq_id"]) | 147 | poi = get_loc(context.user_data["fsq_id"]) |
@@ -177,18 +160,16 @@ async def process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) - | |||
177 | await query.message.reply_text( | 160 | await query.message.reply_text( |
178 | text=f"Selected place: {poi['name']}, `{query.data}`\nPosted to Mastodon: {status['url']}", | 161 | text=f"Selected place: {poi['name']}, `{query.data}`\nPosted to Mastodon: {status['url']}", |
179 | parse_mode=telegram.constants.ParseMode.MARKDOWN, | 162 | parse_mode=telegram.constants.ParseMode.MARKDOWN, |
180 | # reply_markup=MAIN_MENU | ||
181 | ) | 163 | ) |
182 | 164 | ||
183 | prompt_attach_comment_msg = await query.message.reply_text( | 165 | prompt_attach_comment_msg = await query.message.reply_text(PROMPT_ADD_COMMENT, reply_markup=INLINE_SKIP_MENU) |
184 | "You can continue adding comments, or press skip to finish", reply_markup=SKIP_MENU) | 166 | context.user_data[PROMPT_ADD_COMMENT] = prompt_attach_comment_msg.message_id |
185 | context.user_data["prompt_attach_comment_msg_id"] = prompt_attach_comment_msg.message_id | ||
186 | 167 | ||
187 | return COMMENT | 168 | return ADD_COMMENT |
188 | 169 | ||
189 | 170 | ||
190 | async def location_search_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 171 | async def callback_location_keyword_search(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
191 | await context.bot.delete_message(update.effective_chat.id, context.user_data["prompt_msg_id"]) | 172 | await context.bot.delete_message(update.effective_chat.id, context.user_data[PROMPT_LOCATION_KEYWORD]) |
192 | 173 | ||
193 | location_search = update.effective_message.text | 174 | location_search = update.effective_message.text |
194 | latitude = context.user_data["latitude"] | 175 | latitude = context.user_data["latitude"] |
@@ -199,26 +180,25 @@ async def location_search_callback(update: Update, context: ContextTypes.DEFAULT | |||
199 | if len(poi_result) == 0: | 180 | if len(poi_result) == 0: |
200 | poi_result = query_poi("", latitude, longitude) | 181 | poi_result = query_poi("", latitude, longitude) |
201 | 182 | ||
202 | # for poi in poi_result: | 183 | for poi in poi_result: |
203 | # keyboard.append([ | 184 | keyboard.append([ |
204 | # InlineKeyboardButton(poi["name"], callback_data=poi["fsq_id"]), | 185 | InlineKeyboardButton(poi["name"], callback_data=poi["fsq_id"]), |
205 | # ]) | 186 | ]) |
206 | 187 | ||
207 | if len(keyboard) == 0: | 188 | if len(keyboard) == 0: |
208 | await update.message.reply_text("No nearby places found. You can input location name manually") | 189 | await update.message.reply_text(PROMPT_NO_NEARBY_POI) |
209 | return WAIT_LOC | 190 | return LOCATION_CONFIRMATION |
210 | else: | 191 | else: |
211 | reply_markup = InlineKeyboardMarkup(keyboard) | 192 | reply_markup = InlineKeyboardMarkup(keyboard) |
212 | context.user_data["location_search"] = location_search | 193 | context.user_data["location_search"] = location_search |
213 | await update.message.reply_text("Where are you? ", reply_markup=reply_markup) | 194 | await update.message.reply_text(PROMPT_CHOOSE_POI_FROM_LIST, reply_markup=reply_markup) |
214 | 195 | ||
215 | return WAIT_LOC | 196 | return LOCATION_CONFIRMATION |
216 | 197 | ||
217 | 198 | ||
218 | async def skip_location_search(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 199 | async def callback_skip_location_keyword(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
219 | query = update.callback_query | 200 | query = update.callback_query |
220 | await query.answer() | 201 | await query.answer() |
221 | print("skip: ", query.data) | ||
222 | 202 | ||
223 | await query.message.delete() | 203 | await query.message.delete() |
224 | latitude = context.user_data["latitude"] | 204 | latitude = context.user_data["latitude"] |
@@ -232,13 +212,13 @@ async def skip_location_search(update: Update, context: ContextTypes.DEFAULT_TYP | |||
232 | ]) | 212 | ]) |
233 | 213 | ||
234 | reply_markup = InlineKeyboardMarkup(keyboard) | 214 | reply_markup = InlineKeyboardMarkup(keyboard) |
235 | await query.message.reply_text("Where are you? ", reply_markup=reply_markup) | 215 | await query.message.reply_text(PROMPT_CHOOSE_POI_FROM_LIST, reply_markup=reply_markup) |
236 | 216 | ||
237 | return WAIT_LOC | 217 | return LOCATION_CONFIRMATION |
238 | 218 | ||
239 | 219 | ||
240 | async def comment_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 220 | async def callback_add_comment(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
241 | await context.bot.delete_message(update.effective_chat.id, context.user_data["prompt_attach_comment_msg_id"]) | 221 | await context.bot.delete_message(update.effective_chat.id, context.user_data[PROMPT_ADD_COMMENT]) |
242 | comment = update.effective_message.text | 222 | comment = update.effective_message.text |
243 | 223 | ||
244 | mastodon_client.status_update( | 224 | mastodon_client.status_update( |
@@ -246,110 +226,39 @@ async def comment_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) - | |||
246 | id=context.user_data["status_id"]) | 226 | id=context.user_data["status_id"]) |
247 | 227 | ||
248 | context.user_data["status_content"] = f"{comment} " + context.user_data["status_content"] | 228 | context.user_data["status_content"] = f"{comment} " + context.user_data["status_content"] |
249 | prompt_attach_photo_msg = await update.message.reply_text( | 229 | prompt_attach_photo_msg = await update.message.reply_text(PROMPT_ADD_MEDIA, reply_markup=INLINE_SKIP_MENU) |
250 | "You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU) | 230 | context.user_data[PROMPT_ADD_MEDIA] = prompt_attach_photo_msg.message_id |
251 | context.user_data["prompt_attach_photo_msg_id"] = prompt_attach_photo_msg.message_id | ||
252 | |||
253 | return PHOTO | ||
254 | |||
255 | |||
256 | async def skip_comment_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | ||
257 | await context.bot.delete_message(update.effective_chat.id, context.user_data["prompt_attach_comment_msg_id"]) | ||
258 | prompt_attach_photo_msg = await update.message.reply_text( | ||
259 | "You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU) | ||
260 | context.user_data["prompt_attach_photo_msg_id"] = prompt_attach_photo_msg.message_id | ||
261 | return PHOTO | ||
262 | |||
263 | |||
264 | # async def tos(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: | ||
265 | # await update.message.reply_text("TOS", reply_markup=MAIN_MENU) | ||
266 | |||
267 | |||
268 | # async def setting(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: | ||
269 | # await update.message.reply_text("Setting", reply_markup=SETTING_MENU) | ||
270 | # return SETTING | ||
271 | |||
272 | |||
273 | # async def setting_process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): | ||
274 | # await update.message.reply_text("Setting Process Callback", reply_markup=SETTING_MENU) | ||
275 | # return ConversationHandler.END | ||
276 | |||
277 | |||
278 | # async def process_location(update: Update, context: ContextTypes.DEFAULT_TYPE): | ||
279 | # await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) | ||
280 | # | ||
281 | # fsq_id = context.user_data["fsq_id"] | ||
282 | # poi = get_loc(context.user_data["fsq_id"]) | ||
283 | # media_id = [] | ||
284 | # | ||
285 | # if context.user_data.get("photo") is not None: | ||
286 | # media = mastodon_client.media_post(context.user_data.get("photo"), mime_type="image/jpeg") | ||
287 | # media_id = [media["id"]] | ||
288 | # # else: | ||
289 | # # photo_url = get_poi_top_photo(context.user_data["fsq_id"]) | ||
290 | # # if photo_url is not None: | ||
291 | # # with urllib.request.urlopen(photo_url) as response: | ||
292 | # # data = response.read() | ||
293 | # # media = mastodon_client.media_post(data, mime_type="image/jpeg") | ||
294 | # # media_id = [media["id"]] | ||
295 | # | ||
296 | # mastodon_client.status_post( | ||
297 | # f"I'm at {poi['name']} in {poi['locality']}, {poi['region']}, {poi['osm_url']}", | ||
298 | # visibility="private", | ||
299 | # media_ids=media_id) | ||
300 | # | ||
301 | # await update.message.delete() | ||
302 | # return ConversationHandler.END | ||
303 | 231 | ||
232 | return ADD_MEDIA | ||
304 | 233 | ||
305 | async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: | ||
306 | """Displays info on how to use the bot.""" | ||
307 | await update.message.reply_text("Use /start to test this bot.") | ||
308 | 234 | ||
235 | async def callback_skip_comment(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | ||
236 | await context.bot.delete_message(update.effective_chat.id, context.user_data[PROMPT_ADD_COMMENT]) | ||
237 | prompt_attach_photo_msg = await update.message.reply_text(PROMPT_ADD_MEDIA, reply_markup=INLINE_SKIP_MENU) | ||
238 | context.user_data[PROMPT_ADD_MEDIA] = prompt_attach_photo_msg.message_id | ||
239 | return ADD_MEDIA | ||
309 | 240 | ||
310 | # async def setting_cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 241 | |
311 | # """Cancels and ends the conversation.""" | 242 | async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: |
312 | # user = update.message.from_user | 243 | await update.message.reply_text(PROMPT_HELP) |
313 | # logger.info("User %s canceled the conversation.", user.first_name) | ||
314 | # await update.message.reply_text( | ||
315 | # text="Setting canceled.", | ||
316 | # # "Bye! I hope we can talk again some day.", | ||
317 | # reply_markup=MAIN_MENU | ||
318 | # ) | ||
319 | # | ||
320 | # return ConversationHandler.END | ||
321 | 244 | ||
322 | 245 | ||
323 | async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 246 | async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
324 | """Cancels and ends the conversation.""" | 247 | await update.message.reply_text(text=PROMPT_CANCELED, reply_markup=MAIN_MENU) |
325 | user = update.message.from_user | ||
326 | logger.info("User %s canceled the conversation.", user.first_name) | ||
327 | await update.message.reply_text( | ||
328 | text="Canceled.", | ||
329 | # "Bye! I hope we can talk again some day.", | ||
330 | reply_markup=MAIN_MENU | ||
331 | ) | ||
332 | 248 | ||
333 | return ConversationHandler.END | 249 | return ConversationHandler.END |
334 | 250 | ||
335 | 251 | ||
336 | class MsgDict(TypedDict): | 252 | async def process_media_group(context: CallbackContext): |
337 | media_id: str | ||
338 | caption: str | ||
339 | status_id: int | ||
340 | content: str | ||
341 | chat_id: int | ||
342 | |||
343 | |||
344 | async def media_group_sender(context: CallbackContext): | ||
345 | context.job.data = cast(List[MsgDict], context.job.data) | 253 | context.job.data = cast(List[MsgDict], context.job.data) |
346 | 254 | ||
347 | media_id = [] | 255 | media_id = [] |
348 | chat_id = context.job.data[0].get("chat_id") | 256 | chat_id = context.job.data[0].get("chat_id") |
349 | for msg_dict in context.job.data: | 257 | for msg_dict in context.job.data: |
350 | if len(media_id) >= 4: | 258 | if len(media_id) >= 4: |
351 | print("Cannot attach more than 4 photos") | 259 | await context.bot.send_message(chat_id=chat_id, text=PROMPT_MAX_PHOTO_REACHED, reply_markup=MAIN_MENU) |
352 | break | 260 | return |
261 | |||
353 | file = await context.bot.get_file(msg_dict.get("media_id")) | 262 | file = await context.bot.get_file(msg_dict.get("media_id")) |
354 | img = io.BytesIO() | 263 | img = io.BytesIO() |
355 | await file.download_to_memory(img) | 264 | await file.download_to_memory(img) |
@@ -364,20 +273,17 @@ async def media_group_sender(context: CallbackContext): | |||
364 | id=msg_dict.get("status_id"), | 273 | id=msg_dict.get("status_id"), |
365 | media_ids=media_id) | 274 | media_ids=media_id) |
366 | 275 | ||
367 | await context.bot.send_message(chat_id=chat_id, text="Done", | 276 | await context.bot.send_message(chat_id=chat_id, text=PROMPT_DONE, reply_markup=MAIN_MENU) |
368 | reply_markup=MAIN_MENU | ||
369 | ) | ||
370 | 277 | ||
371 | 278 | ||
372 | async def photo(update: Update, context: CallbackContext): | 279 | async def callback_add_media(update: Update, context: CallbackContext): |
373 | """Stores the photo and asks for a location.""" | ||
374 | await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) | 280 | await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) |
375 | 281 | ||
376 | try: | 282 | try: |
377 | await context.bot.delete_message(chat_id=update.message.chat_id, message_id=context.user_data["prompt_attach_photo_msg_id"]) | 283 | await context.bot.delete_message(chat_id=update.message.chat_id, |
284 | message_id=context.user_data[PROMPT_ADD_MEDIA]) | ||
378 | except telegram.error.BadRequest as e: | 285 | except telegram.error.BadRequest as e: |
379 | if "not found" in str(e.message): | 286 | if "not found" in str(e.message): |
380 | print("prompt_attach_photo_msg already deleted") | ||
381 | pass | 287 | pass |
382 | 288 | ||
383 | status_id = context.user_data["status_id"] | 289 | status_id = context.user_data["status_id"] |
@@ -398,8 +304,8 @@ async def photo(update: Update, context: CallbackContext): | |||
398 | if jobs: | 304 | if jobs: |
399 | jobs[0].data.append(msg_dict) | 305 | jobs[0].data.append(msg_dict) |
400 | else: | 306 | else: |
401 | context.job_queue.run_once(callback=media_group_sender, when=5, data=[msg_dict], | 307 | context.job_queue.run_once(callback=process_media_group, when=MEDIA_GROUP_TIMEOUT, |
402 | name=str(message.media_group_id)) | 308 | data=[msg_dict], name=str(message.media_group_id)) |
403 | else: | 309 | else: |
404 | file = await update.message.effective_attachment[-1].get_file() | 310 | file = await update.message.effective_attachment[-1].get_file() |
405 | img = io.BytesIO() | 311 | img = io.BytesIO() |
@@ -412,19 +318,16 @@ async def photo(update: Update, context: CallbackContext): | |||
412 | id=status_id, | 318 | id=status_id, |
413 | media_ids=media["id"]) | 319 | media_ids=media["id"]) |
414 | 320 | ||
415 | await update.message.reply_text(text="Done", | 321 | await update.message.reply_text(text=PROMPT_DONE, reply_markup=MAIN_MENU) |
416 | reply_markup=MAIN_MENU | ||
417 | ) | ||
418 | 322 | ||
419 | 323 | ||
420 | async def skip_photo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 324 | async def callback_skip_media(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
421 | query = update.callback_query | 325 | query = update.callback_query |
422 | await query.answer() | 326 | await query.answer() |
423 | 327 | ||
424 | await query.delete_message() | 328 | await query.delete_message() |
425 | await query.message.reply_text( | 329 | await query.message.reply_text(text=PROMPT_DONE, reply_markup=MAIN_MENU) |
426 | text="Done.", reply_markup=MAIN_MENU | 330 | |
427 | ) | ||
428 | return ConversationHandler.END | 331 | return ConversationHandler.END |
429 | 332 | ||
430 | 333 | ||
@@ -434,35 +337,34 @@ def main() -> None: | |||
434 | checkin_handler = ConversationHandler( | 337 | checkin_handler = ConversationHandler( |
435 | entry_points=[ | 338 | entry_points=[ |
436 | CommandHandler("start", start), | 339 | CommandHandler("start", start), |
437 | MessageHandler(filters.LOCATION, checkin), | 340 | MessageHandler(filters.LOCATION, callback_location_sharing), |
438 | ], | 341 | ], |
439 | states={ | 342 | states={ |
440 | LOCATION: [ | 343 | WAIT_LOCATION: [ |
441 | MessageHandler(filters.LOCATION, checkin), | 344 | MessageHandler(filters.LOCATION, callback_location_sharing), |
442 | ], | 345 | ], |
443 | LOCATION_SEARCH: [ | 346 | LOCATION_SEARCH_KEYWORD: [ |
444 | MessageHandler(filters.TEXT, location_search_callback), | 347 | MessageHandler(filters.TEXT, callback_location_keyword_search), |
445 | CallbackQueryHandler(skip_location_search), | 348 | CallbackQueryHandler(callback_skip_location_keyword), |
446 | ], | 349 | ], |
447 | WAIT_LOC: [ | 350 | LOCATION_CONFIRMATION: [ |
448 | CallbackQueryHandler(process_callback), | 351 | CallbackQueryHandler(callback_location_confirmation), |
449 | MessageHandler(filters.TEXT, manual_location_process_callback) | 352 | MessageHandler(filters.TEXT, callback_manual_location) |
450 | ], | 353 | ], |
451 | COMMENT: [ | 354 | ADD_COMMENT: [ |
452 | MessageHandler(filters.TEXT, comment_callback), | 355 | MessageHandler(filters.TEXT, callback_add_comment), |
453 | CallbackQueryHandler(skip_comment_callback), | 356 | CallbackQueryHandler(callback_skip_comment), |
454 | ], | 357 | ], |
455 | PHOTO: [MessageHandler(filters.PHOTO, photo), | 358 | ADD_MEDIA: [MessageHandler(filters.PHOTO, callback_add_media), |
456 | CallbackQueryHandler(skip_photo)], | 359 | CallbackQueryHandler(callback_skip_media)], |
457 | }, | 360 | }, |
458 | fallbacks=[CommandHandler("cancel", cancel)], | 361 | fallbacks=[CommandHandler("cancel", cancel)], |
459 | per_message=False, | 362 | per_message=False, |
460 | allow_reentry=True, | 363 | allow_reentry=True, |
461 | ) | 364 | ) |
462 | 365 | ||
463 | application.add_handler(checkin_handler, 1) | 366 | application.add_handler(CommandHandler("help", help_command)) |
464 | 367 | application.add_handler(checkin_handler) | |
465 | # Run the bot until the user presses Ctrl-C | ||
466 | application.run_polling() | 368 | application.run_polling() |
467 | 369 | ||
468 | 370 | ||