From b3786171167337685c21d64f4eed4a7cc1c5b130 Mon Sep 17 00:00:00 2001 From: clarkzjw Date: Wed, 22 Feb 2023 11:43:10 -0800 Subject: more code formatting --- callback.py | 246 +++++++++++++++++++++++++++---------------------------- command.py | 11 +-- config.py | 6 ++ prompt/string.py | 11 ++- 4 files changed, 136 insertions(+), 138 deletions(-) diff --git a/callback.py b/callback.py index 6a09421..9b82d78 100644 --- a/callback.py +++ b/callback.py @@ -13,43 +13,39 @@ from foursquare.poi import query_poi from toot import mastodon_client -async def callback_skip_media(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - query = update.callback_query - await query.answer() - - await query.delete_message() - await query.message.reply_text(text=PROMPT_DONE, reply_markup=MAIN_MENU) - - return ConversationHandler.END +def generate_toot_text(poi_name, poi_locality, poi_region, poi_lat, poi_lon): + osm_url = OSM_ENDPOINT.format(poi_lat, poi_lon) + + location = "" + if poi_locality: + location = poi_locality + if poi_region: + location += ", " + poi_region + if location: + return f"I'm at {poi_name} in {location}, {osm_url}" + else: + return f"I'm at {poi_name}, {osm_url}" async def callback_location_sharing(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: if update.message.venue is not None: - fsq_id = update.message.venue.foursquare_id - title = update.message.venue.title - context.user_data["fsq_id"] = fsq_id - context.user_data["title"] = title + context.user_data["fsq_id"] = update.message.venue.foursquare_id + context.user_data["title"] = update.message.venue.title context.user_data["latitude"] = update.message.venue.location.latitude context.user_data["longitude"] = update.message.venue.location.longitude - poi = get_loc(context.user_data["fsq_id"]) - media_id = [] - content = f"I'm at {poi['name']} in {poi['locality']}, {poi['region']}, {poi['osm_url']}" - status = mastodon_client.status_post( - content, - visibility="private", - media_ids=media_id) + poi = get_loc(context.user_data.get("fsq_id")) + content = generate_toot_text(poi["name"], poi["locality"], poi["region"], poi["latitude"], poi["longitude"]) + status = mastodon_client.status_post(content, visibility=DEFAULT_TOOT_VISIBILITY, media_ids=[]) - context.user_data["status_id"] = status["id"] - context.user_data["status_content"] = content + context.user_data[KEY_TOOT_STATUS_ID] = status["id"] + context.user_data[KEY_TOOT_STATUS_CONTENT] = content - await update.message.reply_text( - text=f"Selected place: {poi['name']}, \nPosted to Mastodon: {status['url']}", - parse_mode=ParseMode.MARKDOWN, - ) + await update.message.reply_text(text=f"Selected place: {poi['name']}, \nPosted to Mastodon: {status['url']}", + parse_mode=ParseMode.MARKDOWN) - prompt_attach_comment_msg = await update.message.reply_text(PROMPT_ADD_COMMENT, reply_markup=INLINE_SKIP_MENU) - context.user_data[PROMPT_ADD_COMMENT] = prompt_attach_comment_msg.message_id + msg = await update.message.reply_text(PROMPT_ADD_COMMENT, reply_markup=INLINE_SKIP_MENU) + context.user_data[PROMPT_ADD_COMMENT] = msg.message_id return ADD_COMMENT else: @@ -57,71 +53,18 @@ async def callback_location_sharing(update: Update, context: ContextTypes.DEFAUL context.user_data["longitude"] = update.message.location.longitude await update.message.reply_text("Searching...", reply_markup=ReplyKeyboardRemove()) - prompt_msg = await update.message.reply_text(PROMPT_LOCATION_KEYWORD, reply_markup=INLINE_SKIP_MENU) + msg = await update.message.reply_text(PROMPT_LOCATION_KEYWORD, reply_markup=INLINE_SKIP_MENU) - context.user_data[PROMPT_LOCATION_KEYWORD] = prompt_msg.message_id + context.user_data[PROMPT_LOCATION_KEYWORD] = msg.message_id return LOCATION_SEARCH_KEYWORD -async def callback_manual_location(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - 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 - - await update.message.reply_text( - text=f"Manually selected place: {loc}, \nPosted to Mastodon: {status['url']}", - parse_mode=ParseMode.MARKDOWN, - ) - - prompt_attach_comment_msg = await update.message.reply_text(PROMPT_ADD_COMMENT, reply_markup=INLINE_SKIP_MENU) - context.user_data[PROMPT_ADD_COMMENT] = prompt_attach_comment_msg.message_id - - return ADD_COMMENT - - -async def callback_location_confirmation(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - query = update.callback_query - await query.answer() - context.user_data["fsq_id"] = query.data - - await query.delete_message() - - poi = get_loc(context.user_data["fsq_id"]) - media_id = [] - content = f"I'm at {poi['name']} in {poi['locality']}, {poi['region']}, {poi['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 - - await query.message.reply_text( - text=f"Selected place: {poi['name']}, `{query.data}`\nPosted to Mastodon: {status['url']}", - parse_mode=ParseMode.MARKDOWN, - ) - - prompt_attach_comment_msg = await query.message.reply_text(PROMPT_ADD_COMMENT, reply_markup=INLINE_SKIP_MENU) - context.user_data[PROMPT_ADD_COMMENT] = prompt_attach_comment_msg.message_id - - return ADD_COMMENT - - async def callback_location_keyword_search(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - await context.bot.delete_message(update.effective_chat.id, context.user_data[PROMPT_LOCATION_KEYWORD]) + await context.bot.delete_message(update.effective_chat.id, context.user_data.get(PROMPT_LOCATION_KEYWORD)) location_search_keyword = update.effective_message.text - latitude = context.user_data["latitude"] - longitude = context.user_data["longitude"] + latitude = context.user_data.get("latitude") + longitude = context.user_data.get("longitude") keyboard = [] poi_result = query_poi(location_search_keyword, latitude, longitude) @@ -134,13 +77,13 @@ async def callback_location_keyword_search(update: Update, context: ContextTypes ]) if len(keyboard) == 0: - msg = await update.message.reply_text(PROMPT_NO_NEARBY_POI) + msg = await update.message.reply_text(PROMPT_WAIT_LOCATION_CONFIRMATION_NO_NEARBY_POI) else: - reply_markup = InlineKeyboardMarkup(keyboard) context.user_data["location_search"] = location_search_keyword - msg = await update.message.reply_text(PROMPT_CHOOSE_POI_FROM_LIST, reply_markup=reply_markup) + msg = await update.message.reply_text(PROMPT_WAIT_LOCATION_CONFIRMATION, + reply_markup=InlineKeyboardMarkup(keyboard)) - context.user_data[PROMPT_CHOOSE_POI_FROM_LIST] = msg.message_id + context.user_data[PROMPT_WAIT_LOCATION_CONFIRMATION] = msg.message_id return LOCATION_CONFIRMATION @@ -149,8 +92,8 @@ async def callback_skip_location_keyword(update: Update, context: ContextTypes.D await query.answer() await query.message.delete() - latitude = context.user_data["latitude"] - longitude = context.user_data["longitude"] + latitude = context.user_data.get("latitude") + longitude = context.user_data.get("longitude") keyboard = [] @@ -159,21 +102,64 @@ async def callback_skip_location_keyword(update: Update, context: ContextTypes.D InlineKeyboardButton(poi["name"], callback_data=poi["fsq_id"]), ]) - reply_markup = InlineKeyboardMarkup(keyboard) - await query.message.reply_text(PROMPT_CHOOSE_POI_FROM_LIST, reply_markup=reply_markup) + await query.message.reply_text(PROMPT_WAIT_LOCATION_CONFIRMATION, reply_markup=InlineKeyboardMarkup(keyboard)) return LOCATION_CONFIRMATION +async def callback_location_confirmation(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + query = update.callback_query + await query.answer() + + context.user_data["fsq_id"] = query.data + await query.delete_message() + + poi = get_loc(context.user_data.get("fsq_id")) + content = generate_toot_text(poi["name"], poi["locality"], poi["region"], poi["latitude"], poi["longitude"]) + status = mastodon_client.status_post(content, visibility=DEFAULT_TOOT_VISIBILITY, media_ids=[]) + + context.user_data[KEY_TOOT_STATUS_ID] = status["id"] + context.user_data[KEY_TOOT_STATUS_CONTENT] = content + + await query.message.reply_text( + text=f"Selected place: {poi['name']}, `{query.data}`\nPosted to Mastodon: {status['url']}", + parse_mode=ParseMode.MARKDOWN, + ) + + msg = await query.message.reply_text(PROMPT_ADD_COMMENT, reply_markup=INLINE_SKIP_MENU) + context.user_data[PROMPT_ADD_COMMENT] = msg.message_id + + return ADD_COMMENT + + +async def callback_manual_location(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + manual_poi_name = update.effective_message.text + content = generate_toot_text(manual_poi_name, "", "", context.user_data.get("latitude"), + context.user_data.get("longitude")) + status = mastodon_client.status_post(content, visibility=DEFAULT_TOOT_VISIBILITY, media_ids=[]) + + context.user_data[KEY_TOOT_STATUS_ID] = status["id"] + context.user_data[KEY_TOOT_STATUS_CONTENT] = content + + await update.message.reply_text( + text=f"Manually selected place: {manual_poi_name}, \nPosted to Mastodon: {status['url']}", + parse_mode=ParseMode.MARKDOWN, + ) + + msg = await update.message.reply_text(PROMPT_ADD_COMMENT, reply_markup=INLINE_SKIP_MENU) + context.user_data[PROMPT_ADD_COMMENT] = msg.message_id + + return ADD_COMMENT + + async def callback_add_comment(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - await context.bot.delete_message(update.effective_chat.id, context.user_data[PROMPT_ADD_COMMENT]) + await context.bot.delete_message(update.effective_chat.id, context.user_data.get(PROMPT_ADD_COMMENT)) comment = update.effective_message.text - mastodon_client.status_update( - status=f"{comment} " + context.user_data["status_content"], - id=context.user_data["status_id"]) + mastodon_client.status_update(id=context.user_data.get(KEY_TOOT_STATUS_ID), + status=f"{comment} " + context.user_data.get(KEY_TOOT_STATUS_CONTENT)) - context.user_data["status_content"] = f"{comment} " + context.user_data["status_content"] + context.user_data[KEY_TOOT_STATUS_CONTENT] = f"{comment} " + context.user_data.get(KEY_TOOT_STATUS_CONTENT) prompt_attach_photo_msg = await update.message.reply_text(PROMPT_ADD_MEDIA, reply_markup=INLINE_SKIP_MENU) context.user_data[PROMPT_ADD_MEDIA] = prompt_attach_photo_msg.message_id @@ -181,7 +167,7 @@ async def callback_add_comment(update: Update, context: ContextTypes.DEFAULT_TYP async def callback_skip_comment(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - await context.bot.delete_message(update.effective_chat.id, context.user_data[PROMPT_ADD_COMMENT]) + await context.bot.delete_message(update.effective_chat.id, context.user_data.get(PROMPT_ADD_COMMENT)) prompt_attach_photo_msg = await context.bot.send_message(chat_id=update.effective_chat.id, text=PROMPT_ADD_MEDIA, reply_markup=INLINE_SKIP_MENU) @@ -189,45 +175,44 @@ async def callback_skip_comment(update: Update, context: ContextTypes.DEFAULT_TY return ADD_MEDIA -async def process_media_group(context: CallbackContext): - context.job.data = cast(List[MsgDict], context.job.data) - - media_id = [] - chat_id = context.job.data[0].get("chat_id") - for msg_dict in context.job.data: - if len(media_id) >= 4: - await context.bot.send_message(chat_id=chat_id, text=PROMPT_MAX_PHOTO_REACHED, reply_markup=MAIN_MENU) - return +async def callback_add_media(update: Update, context: CallbackContext): + async def process_media_group(context: CallbackContext): + context.job.data = cast(List[MsgDict], context.job.data) - file = await context.bot.get_file(msg_dict.get("media_id")) - img = io.BytesIO() - await file.download_to_memory(img) + _media_id = [] + chat_id = context.job.data[0].get("chat_id") + for _msg_dict in context.job.data: + if len(_media_id) >= 4: + await context.bot.send_message(chat_id=chat_id, text=PROMPT_MAX_PHOTO_REACHED, reply_markup=MAIN_MENU) + return - img.seek(0) + _file = await context.bot.get_file(_msg_dict.get("media_id")) + _img = io.BytesIO() + await _file.download_to_memory(_img) - media = mastodon_client.media_post(img.read(), mime_type="image/jpeg") - media_id.append(media["id"]) + _img.seek(0) - mastodon_client.status_update( - status=msg_dict.get("content"), - id=msg_dict.get("status_id"), - media_ids=media_id) + _media = mastodon_client.media_post(_img.read(), mime_type="image/jpeg") + _media_id.append(_media["id"]) - await context.bot.send_message(chat_id=chat_id, text=PROMPT_DONE, reply_markup=MAIN_MENU) + mastodon_client.status_update( + status=_msg_dict.get("content"), + id=_msg_dict.get("status_id"), + media_ids=_media_id) + await context.bot.send_message(chat_id=chat_id, text=PROMPT_DONE, reply_markup=MAIN_MENU) -async def callback_add_media(update: Update, context: CallbackContext): await update.message.reply_chat_action(ChatAction.TYPING) try: await context.bot.delete_message(chat_id=update.message.chat_id, - message_id=context.user_data[PROMPT_ADD_MEDIA]) + message_id=context.user_data.get(PROMPT_ADD_MEDIA)) except BadRequest as e: if "not found" in str(e.message): pass - status_id = context.user_data["status_id"] - status_content = context.user_data["status_content"] + status_id = context.user_data.get(KEY_TOOT_STATUS_ID) + status_content = context.user_data.get(KEY_TOOT_STATUS_CONTENT) message = update.effective_message context.user_data["media"] = [] @@ -253,9 +238,16 @@ async def callback_add_media(update: Update, context: CallbackContext): img.seek(0) media = mastodon_client.media_post(img.read(), mime_type="image/jpeg") - mastodon_client.status_update( - status=status_content, - id=status_id, - media_ids=media["id"]) + mastodon_client.status_update(status=status_content, id=status_id, media_ids=media["id"]) await update.message.reply_text(text=PROMPT_DONE, reply_markup=MAIN_MENU) + + +async def callback_skip_media(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + query = update.callback_query + await query.answer() + + await query.delete_message() + await query.message.reply_text(text=PROMPT_DONE, reply_markup=MAIN_MENU) + + return ConversationHandler.END diff --git a/command.py b/command.py index 579fa48..72e1820 100644 --- a/command.py +++ b/command.py @@ -7,14 +7,7 @@ from config import * async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - hello = "Hello, this is `checkin.bot`. \n\n" \ - "This is a Telegram bot with functionality similar to Foursquare Swarm, " \ - "but check in and post your location to the Fediverse (Mastodon/Pleroma) instead of Twitter.\n\n" \ - "Aware of privacy concerns, this bot will not store your location data." \ - "*Be safe and cautious when sharing your real time location on the web.* \n\n" \ - "Start using this bot by sharing your location using Telegram context menu to it." - - await update.message.reply_text(hello, parse_mode=ParseMode.MARKDOWN) + await update.message.reply_text(PROMPT_START, parse_mode=ParseMode.MARKDOWN) await update.message.reply_text(PROMPT_CHOOSE_ACTION, reply_markup=MAIN_MENU) return WAIT_LOCATION @@ -25,7 +18,7 @@ async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No async def cancel_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - for prompt in [PROMPT_LOCATION_KEYWORD, PROMPT_CHOOSE_POI_FROM_LIST, PROMPT_ADD_COMMENT, PROMPT_ADD_MEDIA]: + for prompt in [PROMPT_LOCATION_KEYWORD, PROMPT_WAIT_LOCATION_CONFIRMATION, PROMPT_ADD_COMMENT, PROMPT_ADD_MEDIA]: try: if context.user_data.get(prompt): await context.bot.delete_message(chat_id=update.message.chat_id, diff --git a/config.py b/config.py index ea50a77..a412784 100644 --- a/config.py +++ b/config.py @@ -16,6 +16,8 @@ TOOT_CLIENT_ID = config["TOOT"]["CLIENT_ID"] TOOT_CLIENT_SECRET = config["TOOT"]["CLIENT_SECRET"] TOOT_ACCESS_TOKEN = config["TOOT"]["ACCESS_TOKEN"] +DEFAULT_TOOT_VISIBILITY = "private" + MEDIA_GROUP_TIMEOUT = 3 WAIT_LOCATION, LOCATION_SEARCH_KEYWORD, LOCATION_CONFIRMATION, ADD_MEDIA, ADD_COMMENT = range(5) @@ -36,3 +38,7 @@ class MsgDict(TypedDict): status_id: int content: str chat_id: int + + +KEY_TOOT_STATUS_ID = "toot_status_id" +KEY_TOOT_STATUS_CONTENT = "toot_status_content" diff --git a/prompt/string.py b/prompt/string.py index af3363a..9a5a357 100644 --- a/prompt/string.py +++ b/prompt/string.py @@ -1,9 +1,16 @@ +PROMPT_START = "Hello, this is `checkin.bot`. \n\n" \ + "This is a Telegram bot with functionality similar to Foursquare Swarm, " \ + "but check in and post your location to the Fediverse (Mastodon/Pleroma) instead of Twitter.\n\n" \ + "Aware of privacy concerns, this bot will not store your location data." \ + "*Be safe and cautious when sharing your real time location on the web.* \n\n" \ + "Start using this bot by sharing your location using Telegram context menu to it." + PROMPT_CHOOSE_ACTION = "Use bot keyboard to choose an action" PROMPT_ADD_COMMENT = "You can continue adding comments, or press skip" PROMPT_ADD_MEDIA = "You can continue adding photos, or press skip" PROMPT_LOCATION_KEYWORD = "You can input location search keywords or press skip" -PROMPT_NO_NEARBY_POI = "No nearby places found. You can input location name manually" -PROMPT_CHOOSE_POI_FROM_LIST = "Where are you?" +PROMPT_WAIT_LOCATION_CONFIRMATION_NO_NEARBY_POI = "No nearby places found. But you can input location name manually." +PROMPT_WAIT_LOCATION_CONFIRMATION = "Where are you?" PROMPT_HELP = "Use /start to test this bot." PROMPT_CANCELED = "Canceled" PROMPT_MAX_PHOTO_REACHED = "Cannot attach more than 4 medias, only first 4 will be posted" -- cgit v1.2.3