diff options
-rw-r--r-- | bot.py | 183 |
1 files changed, 121 insertions, 62 deletions
@@ -20,6 +20,7 @@ if __version_info__ < (20, 0, 0, "alpha", 1): | |||
20 | f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html" | 20 | f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html" |
21 | ) | 21 | ) |
22 | 22 | ||
23 | from foursquare.poi import OSM_ENDPOINT | ||
23 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup, KeyboardButton | 24 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup, KeyboardButton |
24 | from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, MessageHandler, filters, \ | 25 | from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, MessageHandler, filters, \ |
25 | ConversationHandler, CallbackContext | 26 | ConversationHandler, CallbackContext |
@@ -32,7 +33,7 @@ from typing import TypedDict, List, cast | |||
32 | scheduler = None | 33 | scheduler = None |
33 | PRIVACY, TOOT = map(chr, range(8, 10)) | 34 | PRIVACY, TOOT = map(chr, range(8, 10)) |
34 | 35 | ||
35 | WAIT_LOC, LOCATION, LOCATION_SEARCH, PHOTO, PROCESS_PHOTO, FINAL, SETTING = range(7) | 36 | WAIT_LOC, LOCATION, LOCATION_SEARCH, PHOTO, PROCESS_PHOTO, COMMENT, SETTING = range(7) |
36 | 37 | ||
37 | # Enable logging | 38 | # Enable logging |
38 | logging.basicConfig( | 39 | logging.basicConfig( |
@@ -103,11 +104,11 @@ async def checkin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | |||
103 | parse_mode=telegram.constants.ParseMode.MARKDOWN, | 104 | parse_mode=telegram.constants.ParseMode.MARKDOWN, |
104 | ) | 105 | ) |
105 | 106 | ||
106 | prompt_attach_photo_msg = await update.message.reply_text( | 107 | prompt_attach_comment_msg = await update.message.reply_text( |
107 | "You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU) | 108 | "You can continue adding comments, or press skip to finish", reply_markup=SKIP_MENU) |
108 | context.user_data["prompt_attach_photo_msg_id"] = prompt_attach_photo_msg.message_id | 109 | context.user_data["prompt_attach_comment_msg_id"] = prompt_attach_comment_msg.message_id |
109 | 110 | ||
110 | return PHOTO | 111 | return COMMENT |
111 | else: | 112 | else: |
112 | context.user_data["latitude"] = update.message.location.latitude | 113 | context.user_data["latitude"] = update.message.location.latitude |
113 | context.user_data["longitude"] = update.message.location.longitude | 114 | context.user_data["longitude"] = update.message.location.longitude |
@@ -120,6 +121,38 @@ async def checkin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | |||
120 | return LOCATION_SEARCH | 121 | return LOCATION_SEARCH |
121 | 122 | ||
122 | 123 | ||
124 | async def manual_location_process_callback(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 | ||
130 | osm_url = OSM_ENDPOINT.format(context.user_data["latitude"], context.user_data["longitude"]) | ||
131 | media_id = [] | ||
132 | content = f"I'm at {loc}, {osm_url}" | ||
133 | status = mastodon_client.status_post( | ||
134 | content, | ||
135 | visibility="private", | ||
136 | media_ids=media_id) | ||
137 | |||
138 | context.user_data["status_id"] = status["id"] | ||
139 | context.user_data["status_content"] = content | ||
140 | |||
141 | print("status_id", context.user_data["status_id"]) | ||
142 | |||
143 | await update.message.reply_text( | ||
144 | text=f"Manually selected place: {loc}, \nPosted to Mastodon: {status['url']}", | ||
145 | parse_mode=telegram.constants.ParseMode.MARKDOWN, | ||
146 | # reply_markup=MAIN_MENU | ||
147 | ) | ||
148 | |||
149 | prompt_attach_comment_msg = await update.message.reply_text( | ||
150 | "You can continue adding comments, or press skip to finish", reply_markup=SKIP_MENU) | ||
151 | context.user_data["prompt_attach_comment_msg_id"] = prompt_attach_comment_msg.message_id | ||
152 | |||
153 | return COMMENT | ||
154 | |||
155 | |||
123 | async def process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 156 | async def process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
124 | print("process_callback") | 157 | print("process_callback") |
125 | query = update.callback_query | 158 | query = update.callback_query |
@@ -147,32 +180,37 @@ async def process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) - | |||
147 | # reply_markup=MAIN_MENU | 180 | # reply_markup=MAIN_MENU |
148 | ) | 181 | ) |
149 | 182 | ||
150 | prompt_attach_photo_msg = await query.message.reply_text( | 183 | prompt_attach_comment_msg = await query.message.reply_text( |
151 | "You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU) | 184 | "You can continue adding comments, or press skip to finish", reply_markup=SKIP_MENU) |
152 | context.user_data["prompt_attach_photo_msg_id"] = prompt_attach_photo_msg.message_id | 185 | context.user_data["prompt_attach_comment_msg_id"] = prompt_attach_comment_msg.message_id |
153 | 186 | ||
154 | return PHOTO | 187 | return COMMENT |
155 | 188 | ||
156 | 189 | ||
157 | async def location_search_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: | 190 | async def location_search_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: |
158 | await context.bot.delete_message(update.effective_chat.id, context.user_data["prompt_msg_id"]) | 191 | await context.bot.delete_message(update.effective_chat.id, context.user_data["prompt_msg_id"]) |
159 | # query = update.callback_query | ||
160 | # await query.message.delete() | ||
161 | 192 | ||
162 | location_search = update.effective_message.text | 193 | location_search = update.effective_message.text |
163 | latitude = context.user_data["latitude"] | 194 | latitude = context.user_data["latitude"] |
164 | longitude = context.user_data["longitude"] | 195 | longitude = context.user_data["longitude"] |
165 | 196 | ||
166 | keyboard = [] | 197 | keyboard = [] |
167 | 198 | poi_result = query_poi(location_search, latitude, longitude) | |
168 | for poi in query_poi(location_search, latitude, longitude): | 199 | if len(poi_result) == 0: |
169 | keyboard.append([ | 200 | poi_result = query_poi("", latitude, longitude) |
170 | InlineKeyboardButton(poi["name"], callback_data=poi["fsq_id"]), | 201 | |
171 | ]) | 202 | # for poi in poi_result: |
172 | 203 | # keyboard.append([ | |
173 | reply_markup = InlineKeyboardMarkup(keyboard) | 204 | # InlineKeyboardButton(poi["name"], callback_data=poi["fsq_id"]), |
174 | context.user_data["location_search"] = location_search | 205 | # ]) |
175 | await update.message.reply_text("Where are you? ", reply_markup=reply_markup) | 206 | |
207 | if len(keyboard) == 0: | ||
208 | await update.message.reply_text("No nearby places found. You can input location name manually") | ||
209 | return WAIT_LOC | ||
210 | else: | ||
211 | reply_markup = InlineKeyboardMarkup(keyboard) | ||
212 | context.user_data["location_search"] = location_search | ||
213 | await update.message.reply_text("Where are you? ", reply_markup=reply_markup) | ||
176 | 214 | ||
177 | return WAIT_LOC | 215 | return WAIT_LOC |
178 | 216 | ||
@@ -199,6 +237,30 @@ async def skip_location_search(update: Update, context: ContextTypes.DEFAULT_TYP | |||
199 | return WAIT_LOC | 237 | return WAIT_LOC |
200 | 238 | ||
201 | 239 | ||
240 | async def comment_callback(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"]) | ||
242 | comment = update.effective_message.text | ||
243 | |||
244 | mastodon_client.status_update( | ||
245 | status=f"{comment} " + context.user_data["status_content"], | ||
246 | id=context.user_data["status_id"]) | ||
247 | |||
248 | context.user_data["status_content"] = f"{comment} " + context.user_data["status_content"] | ||
249 | prompt_attach_photo_msg = await update.message.reply_text( | ||
250 | "You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU) | ||
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 | |||
202 | # async def tos(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: | 264 | # async def tos(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: |
203 | # await update.message.reply_text("TOS", reply_markup=MAIN_MENU) | 265 | # await update.message.reply_text("TOS", reply_markup=MAIN_MENU) |
204 | 266 | ||
@@ -213,31 +275,31 @@ async def skip_location_search(update: Update, context: ContextTypes.DEFAULT_TYP | |||
213 | # return ConversationHandler.END | 275 | # return ConversationHandler.END |
214 | 276 | ||
215 | 277 | ||
216 | async def process_location(update: Update, context: ContextTypes.DEFAULT_TYPE): | 278 | # async def process_location(update: Update, context: ContextTypes.DEFAULT_TYPE): |
217 | await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) | 279 | # await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) |
218 | 280 | # | |
219 | fsq_id = context.user_data["fsq_id"] | 281 | # fsq_id = context.user_data["fsq_id"] |
220 | poi = get_loc(context.user_data["fsq_id"]) | 282 | # poi = get_loc(context.user_data["fsq_id"]) |
221 | media_id = [] | 283 | # media_id = [] |
222 | 284 | # | |
223 | if context.user_data.get("photo") is not None: | 285 | # if context.user_data.get("photo") is not None: |
224 | media = mastodon_client.media_post(context.user_data.get("photo"), mime_type="image/jpeg") | 286 | # media = mastodon_client.media_post(context.user_data.get("photo"), mime_type="image/jpeg") |
225 | media_id = [media["id"]] | 287 | # media_id = [media["id"]] |
226 | # else: | 288 | # # else: |
227 | # photo_url = get_poi_top_photo(context.user_data["fsq_id"]) | 289 | # # photo_url = get_poi_top_photo(context.user_data["fsq_id"]) |
228 | # if photo_url is not None: | 290 | # # if photo_url is not None: |
229 | # with urllib.request.urlopen(photo_url) as response: | 291 | # # with urllib.request.urlopen(photo_url) as response: |
230 | # data = response.read() | 292 | # # data = response.read() |
231 | # media = mastodon_client.media_post(data, mime_type="image/jpeg") | 293 | # # media = mastodon_client.media_post(data, mime_type="image/jpeg") |
232 | # media_id = [media["id"]] | 294 | # # media_id = [media["id"]] |
233 | 295 | # | |
234 | mastodon_client.status_post( | 296 | # mastodon_client.status_post( |
235 | f"I'm at {poi['name']} in {poi['locality']}, {poi['region']}, {poi['osm_url']}", | 297 | # f"I'm at {poi['name']} in {poi['locality']}, {poi['region']}, {poi['osm_url']}", |
236 | visibility="private", | 298 | # visibility="private", |
237 | media_ids=media_id) | 299 | # media_ids=media_id) |
238 | 300 | # | |
239 | await update.message.delete() | 301 | # await update.message.delete() |
240 | return ConversationHandler.END | 302 | # return ConversationHandler.END |
241 | 303 | ||
242 | 304 | ||
243 | async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: | 305 | async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: |
@@ -311,7 +373,12 @@ async def photo(update: Update, context: CallbackContext): | |||
311 | """Stores the photo and asks for a location.""" | 373 | """Stores the photo and asks for a location.""" |
312 | await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) | 374 | await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) |
313 | 375 | ||
314 | await context.bot.delete_message(chat_id=update.message.chat_id, message_id=context.user_data["prompt_attach_photo_msg_id"]) | 376 | try: |
377 | await context.bot.delete_message(chat_id=update.message.chat_id, message_id=context.user_data["prompt_attach_photo_msg_id"]) | ||
378 | except telegram.error.BadRequest as e: | ||
379 | if "not found" in str(e.message): | ||
380 | print("prompt_attach_photo_msg already deleted") | ||
381 | pass | ||
315 | 382 | ||
316 | status_id = context.user_data["status_id"] | 383 | status_id = context.user_data["status_id"] |
317 | status_content = context.user_data["status_content"] | 384 | status_content = context.user_data["status_content"] |
@@ -377,8 +444,14 @@ def main() -> None: | |||
377 | MessageHandler(filters.TEXT, location_search_callback), | 444 | MessageHandler(filters.TEXT, location_search_callback), |
378 | CallbackQueryHandler(skip_location_search), | 445 | CallbackQueryHandler(skip_location_search), |
379 | ], | 446 | ], |
380 | WAIT_LOC: [CallbackQueryHandler(process_callback)], | 447 | WAIT_LOC: [ |
381 | 448 | CallbackQueryHandler(process_callback), | |
449 | MessageHandler(filters.TEXT, manual_location_process_callback) | ||
450 | ], | ||
451 | COMMENT: [ | ||
452 | MessageHandler(filters.TEXT, comment_callback), | ||
453 | CallbackQueryHandler(skip_comment_callback), | ||
454 | ], | ||
382 | PHOTO: [MessageHandler(filters.PHOTO, photo), | 455 | PHOTO: [MessageHandler(filters.PHOTO, photo), |
383 | CallbackQueryHandler(skip_photo)], | 456 | CallbackQueryHandler(skip_photo)], |
384 | }, | 457 | }, |
@@ -387,20 +460,6 @@ def main() -> None: | |||
387 | allow_reentry=True, | 460 | allow_reentry=True, |
388 | ) | 461 | ) |
389 | 462 | ||
390 | # setting_conv_handler = ConversationHandler( | ||
391 | # entry_points=[CommandHandler("setting", setting)], | ||
392 | # states={ | ||
393 | # SETTING: [ | ||
394 | # CallbackQueryHandler(setting_process_callback), | ||
395 | # ], | ||
396 | # }, | ||
397 | # fallbacks=[CommandHandler("back", setting_cancel)], | ||
398 | # per_message=False, | ||
399 | # allow_reentry=True, | ||
400 | # ) | ||
401 | |||
402 | # application.add_handler(CommandHandler("tos", tos)) | ||
403 | # application.add_handler(setting_conv_handler, 2) | ||
404 | application.add_handler(checkin_handler, 1) | 463 | application.add_handler(checkin_handler, 1) |
405 | 464 | ||
406 | # Run the bot until the user presses Ctrl-C | 465 | # Run the bot until the user presses Ctrl-C |