async def test_fail_conversation(client: TelegramClient): """Tests the create conversation when the user inputs some invalid text when asked for the image Args: client (TelegramClient): client used to simulate the user """ conv: Conversation async with client.conversation(bot_tag, timeout=TIMEOUT) as conv: await conv.send_message("/create") # send a command resp: Message = await conv.get_response() await resp.click(text="DMI") # click inline keyboard resp: Message = await conv.get_edit() await conv.send_message("Test titolo") # send a message resp: Message = await conv.get_response() await conv.send_message("Test descrizione") # send a message resp: Message = await conv.get_response() await resp.click(text="Ridimensiona") # click inline keyboard resp: Message = await conv.get_edit() await conv.send_message("Fail message") # send a message resp: Message = await conv.get_response() assert read_md("fail") == get_telegram_md(resp.text) await conv.send_message("/cancel") # send a command resp: Message = await conv.get_response() assert read_md("cancel") == get_telegram_md(resp.text)
def create_cmd(update: Update, context: CallbackContext) -> int: """Handles the /settings command Start the process aimed to create the requested image Puts the conversation in the "template" state if all goes well, "end" state otherwise Args: update (Update): update event context (CallbackContext): context passed by the handler Returns: int: new state of the conversation """ info = get_message_info(update, context) inline_keyboard = None return_state = STATE['end'] if config_map['groups'] and info['chat_id'] not in config_map[ 'groups']: # the group is not among the allowed ones text = "Questo gruppo/chat non è fra quelli supportati" elif os.path.exists( f"data/img/{str(info['sender_id'])}.png" ): # if the bot is already making an image for the user text = read_md("create_fail") else: text = read_md("create") return_state = STATE['template'] inline_keyboard = InlineKeyboardMarkup([ [ InlineKeyboardButton(text="DMI", callback_data="template_DMI"), InlineKeyboardButton(text="DMI vuoto", callback_data="template_DMI_vuoto") ], [ InlineKeyboardButton(text="Informatica", callback_data="template_informatica"), InlineKeyboardButton( text="Informatica vuoto", callback_data="template_informatica_vuoto") ], [ InlineKeyboardButton(text="Matematica", callback_data="template_matematica"), InlineKeyboardButton(text="Matematica vuoto", callback_data="template_matematica_vuoto") ] ]) info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2, reply_markup=inline_keyboard) return return_state
def background_msg(update: Update, context: CallbackContext) -> int: """Handles the background message Saves the photo so it can be used as the background of the image Args: update (Update): update event context (CallbackContext): context passed by the handler Returns: int: new state of the conversation """ info = get_message_info(update, context) text = read_md("background") photo = update.message.photo resize_mode = context.user_data['resize_mode'] if photo: # if an actual photo was sent bg_image = info['bot'].getFile(photo[-1].file_id) bg_image.download(build_bg_path(info['sender_id'])) info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2) generate_photo(info, context.user_data) if resize_mode == "crop": return STATE['crop'] elif resize_mode == "random": return STATE['random'] else: return STATE['end']
def settings_cmd(update: Update, context: CallbackContext): """Handles the /settings command Let the user set some values used to create the image. Those settings apply to all users Args: update (Update): update event context (CallbackContext): context passed by the handler """ info = get_message_info(update, context) text = read_md("settings") inline_keyboard = InlineKeyboardMarkup([ [InlineKeyboardButton(" -- Impostazioni --", callback_data="_")], [ InlineKeyboardButton("Sfocatura", callback_data="settings_blur"), ], [ InlineKeyboardButton("️Dimensione titolo", callback_data="settings_font_size_title"), InlineKeyboardButton("Dimensione descrizione", callback_data="settings_font_size_caption") ], ]) info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2, reply_markup=inline_keyboard)
def alter_setting_callback(update: Update, context: CallbackContext): """Handles the alter setting callback Modify the setting based on the button pressed or finalize it Args: update (Update): update event context (CallbackContext): context passed by the handler """ info = get_callback_info(update, context) setting, action = info["query_data"][14:].split(",") text = read_md("settings") reply_markup = None if action == "-": # decrease value (it must always remain >= 0) if config_map['image'][setting] > 0: config_map['image'][setting] -= 1 reply_markup = get_keyboard_setting(setting=setting) else: return elif action == "+": # increase value config_map['image'][setting] += 1 reply_markup = get_keyboard_setting(setting=setting) elif action == "save": # save changes in the settings.yaml file update_settings_file() text = "*Impostazioni*\nLe modifiche sono state salvate su file con successo" elif action == "cancel": # the changes will last untill the bot is reboted text = "*Impostazioni*\nLe modifiche saranno in vigore fino al prossimo riavvio del bot" info['bot'].edit_message_text(chat_id=info['chat_id'], message_id=info['message_id'], text=text, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN_V2)
def image_resize_mode_callback(update: Update, context: CallbackContext) -> int: """Handles the image resize mode crop callback Sets the resize mode of the image ('crop', 'scale', 'random') Puts the conversation in the "background" state Args: update (Update): update event context (CallbackContext): context passed by the handler Returns: int: new state of the conversation """ info = get_callback_info(update, context) context.user_data['resize_mode'] = info["query_data"][18:] if info["query_data"][18:] in ("crop", "scale&crop"): # set default crop offset context.user_data['background_offset'] = { 'x': 0, 'y': 0, } text = read_md("resize_mode") info['bot'].edit_message_text(chat_id=info['chat_id'], message_id=info['message_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2) return STATE['background']
def help_cmd(update: Update, context: CallbackContext): """Handles the /help command Args: update (Update): update event context (CallbackContext): context passed by the handler """ info = get_message_info(update, context) if info['chat_id'] == config_map['meme']['group_id']: # if you are in the admin group text = read_md("meme_instructions") else: # you are NOT in the admin group text = read_md("meme_help") info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2, disable_web_page_preview=True)
def caption_msg(update: Update, context: CallbackContext) -> int: """Handles the caption message Saves the caption so it can be used as the caption of the image Args: update (Update): update event context (CallbackContext): context passed by the handler Returns: int: new state of the conversation """ info = get_message_info(update, context) context.user_data['caption'] = info['text'] text = read_md("caption") inline_keyboard = InlineKeyboardMarkup( [[ InlineKeyboardButton(text="Ritaglia", callback_data="image_resize_mode_crop"), InlineKeyboardButton(text="Ridimensiona", callback_data="image_resize_mode_scale") ], [ InlineKeyboardButton(text="Mi sento 🍀", callback_data="image_resize_mode_random") ]]) info['bot'].send_message(chat_id=info['chat_id'], text=text, reply_markup=inline_keyboard, parse_mode=ParseMode.MARKDOWN_V2) return STATE['resize_mode']
def cancel_cmd(update: Update, context: CallbackContext) -> int: """Handles the /cancel command Cancels the current cretion of the image Puts the conversation in the "end" state Args: update (Update): update event context (CallbackContext): context passed by the handler Returns: int: new state of the conversation """ info = get_message_info(update, context) text = read_md("cancel") # Clear the disk space used by the images, if present bg_path = build_bg_path(info['sender_id']) photo_path = build_photo_path(info['sender_id']) if os.path.exists(bg_path): os.remove(bg_path) if os.path.exists(photo_path): os.remove(photo_path) info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2) return STATE['end']
async def test_create_scale_conversation(client: TelegramClient): """Tests the whole flow of the create conversation with the default image The image creation is handled by the main thread Args: client (TelegramClient): client used to simulate the user """ config_map['image']['thread'] = False conv: Conversation async with client.conversation(bot_tag, timeout=TIMEOUT * 2) as conv: await conv.send_message("/create") # send a command resp: Message = await conv.get_response() assert read_md("create") == get_telegram_md(resp.text) await resp.click(text="DMI") # click inline keyboard resp: Message = await conv.get_edit() assert read_md("template") == get_telegram_md(resp.text) await conv.send_message("Test titolo") # send a message resp: Message = await conv.get_response() assert read_md("title") == get_telegram_md(resp.text) await conv.send_message("Test descrizione") # send message resp: Message = await conv.get_response() assert read_md("caption") == get_telegram_md(resp.text) await resp.click(text="Ridimensiona") # click inline keyboard resp: Message = await conv.get_edit() await conv.send_file("data/img/bg_test.png") # send message resp: Message = await conv.get_response() assert read_md("background") == get_telegram_md(resp.text) resp: Message = await conv.get_response() assert resp.photo is not None
async def test_help_cmd(client: TelegramClient): """Tests the help command Args: client (TelegramClient): client used to simulate the user """ conv: Conversation async with client.conversation(bot_tag, timeout=TIMEOUT) as conv: await conv.send_message("/help") # send a command resp: Message = await conv.get_response() assert read_md("help") == get_telegram_md(resp.text)
async def test_templates_conversation(client: TelegramClient): """Tests the selection of all the possible templates in the create conversation Args: client (TelegramClient): client used to simulate the user """ conv: Conversation async with client.conversation(bot_tag, timeout=TIMEOUT) as conv: for template in ('Vuoto', 'DMI', 'Informatica', 'Matematica'): await conv.send_message("/create") # send a command resp: Message = await conv.get_response() await resp.click( text=template ) # click inline keyboard (Vuoto, DMI, Informatica, Matematica) resp: Message = await conv.get_edit() assert read_md("template") == get_telegram_md(resp.text) await conv.send_message("/cancel") # send a command resp: Message = await conv.get_response() assert read_md("cancel") == get_telegram_md(resp.text)
def rules_cmd(update: Update, context: CallbackContext): """Handles the /rules command Args: update (Update): update event context (CallbackContext): context passed by the handler """ info = get_message_info(update, context) text = read_md("meme_rules") info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2, disable_web_page_preview=True)
async def test_settings_cmd(client: TelegramClient): """Tests the settings command Args: client (TelegramClient): client used to simulate the user """ config_map['image']['blur'] = config_map['image'][ 'font_size_title'] = config_map['image']['font_size_caption'] = 30 conv: Conversation async with client.conversation(bot_tag, timeout=TIMEOUT) as conv: for button_index in (1, 2, 3): await conv.send_message("/settings") # send a command resp: Message = await conv.get_response() assert read_md("settings") == get_telegram_md(resp.text) await resp.click( button_index ) # click inline keyboard (Sfocatura, Dimensioni testo, Caratteri per linea) resp: Message = await conv.get_edit() assert read_md("settings") == get_telegram_md(resp.text) await resp.click(text="➕") # click inline keyboard (➕) resp: Message = await conv.get_edit() assert read_md("settings") == get_telegram_md(resp.text) await resp.click(text="➖") # click inline keyboard (➖) resp: Message = await conv.get_edit() assert read_md("settings") == get_telegram_md(resp.text) await resp.click(text="Chiudi") # click inline keyboard (Chiudi) resp: Message = await conv.get_edit() assert 30 == config_map['image']['blur'] == \ config_map['image']['font_size_title'] == \ config_map['image']['font_size_caption']
def help_cmd(update: Update, context: CallbackContext): """Handles the /help command Sends a short summary of the bot's commands Args: update (Update): update event context (CallbackContext): context passed by the handler """ info = get_message_info(update, context) text = read_md("help") info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2)
def start_cmd(update: Update, context: CallbackContext): """Handles the /start command Sends a short welcoming message Args: update (Update): update event context (CallbackContext): context passed by the handler """ info = get_message_info(update, context) text = read_md("start") info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2)
def settings_callback(update: Update, context: CallbackContext): """Handles the settings callback Select which setting the user wants to modify Args: update (Update): update event context (CallbackContext): context passed by the handler """ info = get_callback_info(update, context) setting = info["query_data"][9:] text = read_md("settings") info['bot'].edit_message_text(chat_id=info['chat_id'], message_id=info['message_id'], text=text, reply_markup=get_keyboard_setting(setting=setting), parse_mode=ParseMode.MARKDOWN_V2)
def fail_msg(update: Update, context: CallbackContext) -> None: """Handles the fail message The message sent during the creation of the image was not valid The state of the conversation stays the same Args: update (Update): update event context (CallbackContext): context passed by the handler Returns: None: new state of the conversation """ info = get_message_info(update, context) text = read_md("fail") info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2)
async def test_create_random_thread_conversation(client: TelegramClient): """Tests the whole flow of the create conversation with the user provided image The image creation is handled by the main thread Args: client (TelegramClient): client used to simulate the user """ config_map['image']['thread'] = True conv: Conversation async with client.conversation(bot_tag, timeout=TIMEOUT * 2) as conv: await conv.send_message("/create") # send a command resp: Message = await conv.get_response() assert read_md("create") == get_telegram_md(resp.text) await resp.click(text="DMI") # click inline keyboard resp: Message = await conv.get_edit() assert read_md("template") == get_telegram_md(resp.text) await conv.send_message("Test titolo") # send a message resp: Message = await conv.get_response() assert read_md("title") == get_telegram_md(resp.text) await conv.send_message("Test descrizione") # send message resp: Message = await conv.get_response() assert read_md("caption") == get_telegram_md(resp.text) await resp.click(text="Mi sento 🍀") # click inline keyboard resp: Message = await conv.get_edit() assert read_md("resize_mode") == get_telegram_md(resp.text) await conv.send_message("none") # send message resp: Message = await conv.get_response() assert read_md("background") == get_telegram_md(resp.text) resp: Message = await conv.get_response() assert resp.photo is not None await resp.click(text="No, ritenta") # click inline keyboard resp: Message = await conv.get_response() assert resp.photo is not None await resp.click(text="Si") # click inline keyboard resp: Message = await conv.get_edit() assert resp.photo is not None
def title_msg(update: Update, context: CallbackContext) -> int: """Handles the title message Saves the title so it can be used as the title of the image Args: update (Update): update event context (CallbackContext): context passed by the handler Returns: int: new state of the conversation """ info = get_message_info(update, context) context.user_data['title'] = info['text'].upper() text = read_md("title") info['bot'].send_message(chat_id=info['chat_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2) return STATE['caption']
def template_callback(update: Update, context: CallbackContext) -> int: """Handles the template callback Select the desidered template Puts the conversation in the "title" state Args: update (Update): update event context (CallbackContext): context passed by the handler Returns: int: new state of the conversation """ info = get_callback_info(update, context) context.user_data['template'] = info["query_data"][9:] text = read_md("template") info['bot'].edit_message_text(chat_id=info['chat_id'], message_id=info['message_id'], text=text, parse_mode=ParseMode.MARKDOWN_V2) return STATE['title']