From 2b7af2b46dd99767e02079b7d55603acc8015739 Mon Sep 17 00:00:00 2001 From: clarkzjw Date: Tue, 21 Feb 2023 22:42:04 -0800 Subject: support manually adding places --- bot.py | 183 +++++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 121 insertions(+), 62 deletions(-) diff --git a/bot.py b/bot.py index 05483ca..c7a3180 100644 --- a/bot.py +++ b/bot.py @@ -20,6 +20,7 @@ if __version_info__ < (20, 0, 0, "alpha", 1): f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html" ) +from foursquare.poi import OSM_ENDPOINT from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup, KeyboardButton from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, MessageHandler, filters, \ ConversationHandler, CallbackContext @@ -32,7 +33,7 @@ from typing import TypedDict, List, cast scheduler = None PRIVACY, TOOT = map(chr, range(8, 10)) -WAIT_LOC, LOCATION, LOCATION_SEARCH, PHOTO, PROCESS_PHOTO, FINAL, SETTING = range(7) +WAIT_LOC, LOCATION, LOCATION_SEARCH, PHOTO, PROCESS_PHOTO, COMMENT, SETTING = range(7) # Enable logging logging.basicConfig( @@ -103,11 +104,11 @@ async def checkin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: parse_mode=telegram.constants.ParseMode.MARKDOWN, ) - prompt_attach_photo_msg = await update.message.reply_text( - "You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU) - context.user_data["prompt_attach_photo_msg_id"] = prompt_attach_photo_msg.message_id + prompt_attach_comment_msg = await update.message.reply_text( + "You can continue adding comments, or press skip to finish", reply_markup=SKIP_MENU) + context.user_data["prompt_attach_comment_msg_id"] = prompt_attach_comment_msg.message_id - return PHOTO + return COMMENT else: context.user_data["latitude"] = update.message.location.latitude context.user_data["longitude"] = update.message.location.longitude @@ -120,6 +121,38 @@ async def checkin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: return LOCATION_SEARCH +async def manual_location_process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + # query = update.callback_query + # await query.answer() + # await query.delete_message() + + loc = update.effective_message.text + osm_url = OSM_ENDPOINT.format(context.user_data["latitude"], context.user_data["longitude"]) + media_id = [] + content = f"I'm at {loc}, {osm_url}" + status = mastodon_client.status_post( + content, + visibility="private", + media_ids=media_id) + + context.user_data["status_id"] = status["id"] + context.user_data["status_content"] = content + + print("status_id", context.user_data["status_id"]) + + await update.message.reply_text( + text=f"Manually selected place: {loc}, \nPosted to Mastodon: {status['url']}", + parse_mode=telegram.constants.ParseMode.MARKDOWN, + # reply_markup=MAIN_MENU + ) + + prompt_attach_comment_msg = await update.message.reply_text( + "You can continue adding comments, or press skip to finish", reply_markup=SKIP_MENU) + context.user_data["prompt_attach_comment_msg_id"] = prompt_attach_comment_msg.message_id + + return COMMENT + + async def process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: print("process_callback") query = update.callback_query @@ -147,32 +180,37 @@ async def process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) - # reply_markup=MAIN_MENU ) - prompt_attach_photo_msg = await query.message.reply_text( - "You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU) - context.user_data["prompt_attach_photo_msg_id"] = prompt_attach_photo_msg.message_id + prompt_attach_comment_msg = await query.message.reply_text( + "You can continue adding comments, or press skip to finish", reply_markup=SKIP_MENU) + context.user_data["prompt_attach_comment_msg_id"] = prompt_attach_comment_msg.message_id - return PHOTO + return COMMENT async def location_search_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: await context.bot.delete_message(update.effective_chat.id, context.user_data["prompt_msg_id"]) - # query = update.callback_query - # await query.message.delete() location_search = update.effective_message.text latitude = context.user_data["latitude"] longitude = context.user_data["longitude"] keyboard = [] - - for poi in query_poi(location_search, latitude, longitude): - keyboard.append([ - InlineKeyboardButton(poi["name"], callback_data=poi["fsq_id"]), - ]) - - reply_markup = InlineKeyboardMarkup(keyboard) - context.user_data["location_search"] = location_search - await update.message.reply_text("Where are you? ", reply_markup=reply_markup) + poi_result = query_poi(location_search, latitude, longitude) + if len(poi_result) == 0: + poi_result = query_poi("", latitude, longitude) + + # for poi in poi_result: + # keyboard.append([ + # InlineKeyboardButton(poi["name"], callback_data=poi["fsq_id"]), + # ]) + + if len(keyboard) == 0: + await update.message.reply_text("No nearby places found. You can input location name manually") + return WAIT_LOC + else: + reply_markup = InlineKeyboardMarkup(keyboard) + context.user_data["location_search"] = location_search + await update.message.reply_text("Where are you? ", reply_markup=reply_markup) return WAIT_LOC @@ -199,6 +237,30 @@ async def skip_location_search(update: Update, context: ContextTypes.DEFAULT_TYP return WAIT_LOC +async def comment_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + await context.bot.delete_message(update.effective_chat.id, context.user_data["prompt_attach_comment_msg_id"]) + comment = update.effective_message.text + + mastodon_client.status_update( + status=f"{comment} " + context.user_data["status_content"], + id=context.user_data["status_id"]) + + context.user_data["status_content"] = f"{comment} " + context.user_data["status_content"] + prompt_attach_photo_msg = await update.message.reply_text( + "You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU) + context.user_data["prompt_attach_photo_msg_id"] = prompt_attach_photo_msg.message_id + + return PHOTO + + +async def skip_comment_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + await context.bot.delete_message(update.effective_chat.id, context.user_data["prompt_attach_comment_msg_id"]) + prompt_attach_photo_msg = await update.message.reply_text( + "You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU) + context.user_data["prompt_attach_photo_msg_id"] = prompt_attach_photo_msg.message_id + return PHOTO + + # async def tos(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: # await update.message.reply_text("TOS", reply_markup=MAIN_MENU) @@ -213,31 +275,31 @@ async def skip_location_search(update: Update, context: ContextTypes.DEFAULT_TYP # return ConversationHandler.END -async def process_location(update: Update, context: ContextTypes.DEFAULT_TYPE): - await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) - - fsq_id = context.user_data["fsq_id"] - poi = get_loc(context.user_data["fsq_id"]) - media_id = [] - - if context.user_data.get("photo") is not None: - media = mastodon_client.media_post(context.user_data.get("photo"), mime_type="image/jpeg") - media_id = [media["id"]] - # else: - # photo_url = get_poi_top_photo(context.user_data["fsq_id"]) - # if photo_url is not None: - # with urllib.request.urlopen(photo_url) as response: - # data = response.read() - # media = mastodon_client.media_post(data, mime_type="image/jpeg") - # media_id = [media["id"]] - - mastodon_client.status_post( - f"I'm at {poi['name']} in {poi['locality']}, {poi['region']}, {poi['osm_url']}", - visibility="private", - media_ids=media_id) - - await update.message.delete() - return ConversationHandler.END +# async def process_location(update: Update, context: ContextTypes.DEFAULT_TYPE): +# await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) +# +# fsq_id = context.user_data["fsq_id"] +# poi = get_loc(context.user_data["fsq_id"]) +# media_id = [] +# +# if context.user_data.get("photo") is not None: +# media = mastodon_client.media_post(context.user_data.get("photo"), mime_type="image/jpeg") +# media_id = [media["id"]] +# # else: +# # photo_url = get_poi_top_photo(context.user_data["fsq_id"]) +# # if photo_url is not None: +# # with urllib.request.urlopen(photo_url) as response: +# # data = response.read() +# # media = mastodon_client.media_post(data, mime_type="image/jpeg") +# # media_id = [media["id"]] +# +# mastodon_client.status_post( +# f"I'm at {poi['name']} in {poi['locality']}, {poi['region']}, {poi['osm_url']}", +# visibility="private", +# media_ids=media_id) +# +# await update.message.delete() +# return ConversationHandler.END async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: @@ -311,7 +373,12 @@ async def photo(update: Update, context: CallbackContext): """Stores the photo and asks for a location.""" await update.message.reply_chat_action(telegram.constants.ChatAction.TYPING) - await context.bot.delete_message(chat_id=update.message.chat_id, message_id=context.user_data["prompt_attach_photo_msg_id"]) + try: + await context.bot.delete_message(chat_id=update.message.chat_id, message_id=context.user_data["prompt_attach_photo_msg_id"]) + except telegram.error.BadRequest as e: + if "not found" in str(e.message): + print("prompt_attach_photo_msg already deleted") + pass status_id = context.user_data["status_id"] status_content = context.user_data["status_content"] @@ -377,8 +444,14 @@ def main() -> None: MessageHandler(filters.TEXT, location_search_callback), CallbackQueryHandler(skip_location_search), ], - WAIT_LOC: [CallbackQueryHandler(process_callback)], - + WAIT_LOC: [ + CallbackQueryHandler(process_callback), + MessageHandler(filters.TEXT, manual_location_process_callback) + ], + COMMENT: [ + MessageHandler(filters.TEXT, comment_callback), + CallbackQueryHandler(skip_comment_callback), + ], PHOTO: [MessageHandler(filters.PHOTO, photo), CallbackQueryHandler(skip_photo)], }, @@ -387,20 +460,6 @@ def main() -> None: allow_reentry=True, ) - # setting_conv_handler = ConversationHandler( - # entry_points=[CommandHandler("setting", setting)], - # states={ - # SETTING: [ - # CallbackQueryHandler(setting_process_callback), - # ], - # }, - # fallbacks=[CommandHandler("back", setting_cancel)], - # per_message=False, - # allow_reentry=True, - # ) - - # application.add_handler(CommandHandler("tos", tos)) - # application.add_handler(setting_conv_handler, 2) application.add_handler(checkin_handler, 1) # Run the bot until the user presses Ctrl-C -- cgit v1.2.3