Best Python code snippet using hypothesis
telegrambot.py
Source:telegrambot.py  
1import io2import json3import logging4import os5import random6import re7import uuid8from collections import namedtuple9from django.core.paginator import Paginator10import telegram11from django_telegrambot.apps import DjangoTelegramBot12from telegram.ext import (CallbackQueryHandler, CommandHandler,13                          ConversationHandler, Filters, InlineQueryHandler,14                          MessageHandler, RegexHandler)15from . import tasks, utils16from .bot_filters import GroupFilters17from .models import Chat, Keyword, NegativeKeyword, User, KeywordsGroup18# Config logging19debug = os.environ.get('DEBUG', 0)20level = logging.DEBUG if debug else logging.INFO21logging.basicConfig(level=level)22logger = logging.getLogger(__name__)23# Open text responses and other static stuff24with open('bot/text.json', encoding='utf8') as file:25    text_object = lambda d: namedtuple('text_object', d.keys())(*d.values())26    text = json.load(file, object_hook=text_object)27# Keyboards28menu_keyboard = telegram.InlineKeyboardMarkup([29        # Keywords30        # Add31        [telegram.InlineKeyboardButton(text=text.buttons.menu.add_key, callback_data=text.buttons.menu.add_key)],32        # Pin key33        [telegram.InlineKeyboardButton(text=text.buttons.menu.pin_key_to_chat, switch_inline_query_current_chat=text.buttons.menu.pin_key_to_chat[:-2])],34        # Unpin key35        [telegram.InlineKeyboardButton(text=text.buttons.menu.unpin_key_from_chat, switch_inline_query_current_chat=text.buttons.menu.unpin_key_from_chat[:-2])],36        # Delete key37        [telegram.InlineKeyboardButton(text=text.buttons.menu.delete_key, switch_inline_query_current_chat=text.buttons.menu.delete_key[:-2])],38        # Negative Keywords39        # Add40        [telegram.InlineKeyboardButton(text=text.buttons.menu.add_neg_key, callback_data=text.buttons.menu.add_neg_key)],41        # Pin neg key42        [telegram.InlineKeyboardButton(text=text.buttons.menu.pin_neg_key, switch_inline_query_current_chat=text.buttons.menu.pin_neg_key[:-2])],43        # Unpin neg key44        [telegram.InlineKeyboardButton(text=text.buttons.menu.unpin_neg_key, switch_inline_query_current_chat=text.buttons.menu.unpin_neg_key[:-2])],45        # Delete neg key46        [telegram.InlineKeyboardButton(text=text.buttons.menu.delete_neg_key, switch_inline_query_current_chat=text.buttons.menu.delete_neg_key[:-2])],47        # Keywords' Groups48        # Create49        [telegram.InlineKeyboardButton(text=text.buttons.menu.create_group, callback_data=text.buttons.menu.create_group)],50        # Add51        [telegram.InlineKeyboardButton(text=text.buttons.menu.add_key_to_group, switch_inline_query_current_chat=text.buttons.menu.add_key_to_group)],52        # Delete from group53        [telegram.InlineKeyboardButton(text=text.buttons.menu.del_key_from_group, switch_inline_query_current_chat=text.buttons.menu.del_key_from_group)],54        # Switch on\off55        [telegram.InlineKeyboardButton(text=text.buttons.menu.switch_groups, switch_inline_query_current_chat=text.buttons.menu.switch_groups)],56        # Chat switcher57        [telegram.InlineKeyboardButton(text=text.buttons.menu.chat_monitor, callback_data=text.buttons.menu.chat_monitor)],58        # Settings59        [telegram.InlineKeyboardButton(text=text.buttons.menu.settings, callback_data=text.buttons.menu.settings)],60    ])61def start(bot, update):62    "Start conversation with bot"63    user = User.objects.get_or_none(chat_id=update.message.chat.id)64    if not user:65        username = update.message.from_user.username if update.message.from_user.username else ''66        user = User(chat_id=update.message.chat.id, name=update.message.from_user.full_name, username=username)67        user.save()68        logger.debug("New user created: `{}`".format(user))69    else:70        logger.debug("User `{}` already exist.".format(user))71    # Looking for common chats with the user72    for chat in Chat.objects.all():73        try:74            in_chat = bot.getChatMember(chat.chat_id, user.chat_id)75            if in_chat.status not in ('left', 'kicked'):76                logger.debug("{} in {}. Relating them.".format(user, chat))77                chat.user.add(user)78            else:79                logger.debug("{} not in {}. Skipping.".format(user, chat))80        except telegram.TelegramError:81            logger.debug("{} not in {}. Skipping.".format(user, chat))82    bot.sendMessage(update.message.chat_id, text=text.content.greeting, parse_mode=telegram.ParseMode.MARKDOWN, reply_markup=menu_keyboard)83def menu(bot, update):84    "Show up the menu"85    bot.sendMessage(update.message.chat.id, text=text.content.menu, reply_markup=menu_keyboard)86def default_fallback(bot, update):87    "When no message passes"88    bot.sendMessage(update.effective_message.chat.id, text=text.context.dont_understand)89# Handle adding bot to chats90def chat_created(bot, update):91    "Handling chat creation with bot in it"92    # Bot shouldn't be in any of chats below93    if update.message.chat.type in ('private', 'channel'):94        return95    # Defining chat type96    for literal, ltype in Chat.CHATS:97        if update.message.chat.type == ltype:98            chat_type = literal99    chat = Chat(chat_id=update.message.chat.id, chat_type=chat_type, title=update.message.chat.title)100    chat.save()101    # Looking for users with common chat102    for user in User.objects.all():103        try:104            if bot.getChatMember(chat.chat_id, user.chat_id):105                logger.debug("{} in {}. Relating them...".format(user, chat))106                chat.user.add(user)107        except telegram.TelegramError:108            logger.debug("{} not in {}. Skipping...".format(user, chat))109def new_chat_members(bot, update):110    "Handling new chat members"111    # Bot shouldn't be in any of chats below112    if update.message.chat.type in ('private', 'channel'):113        return114    chat = Chat.objects.get_or_none(chat_id=update.message.chat.id)115    for member in update.message.new_chat_members:116        # If the bot is added to the chat, then...117        if member.username == bot.username:118            if chat:119                chat.bot_in_chat = True120            else:121                # Defining chat type122                for literal, ltype in Chat.CHATS:123                    if update.message.chat.type == ltype:124                        chat_type = literal125                chat = Chat(chat_id=update.message.chat.id, chat_type=chat_type, title=update.message.chat.title)126            chat.save()127            # Looking for users with common chat128            for user in User.objects.all():129                try:130                    in_chat = bot.getChatMember(chat.chat_id, user.chat_id)131                    if in_chat.status not in ('left', 'kicked'):132                        logger.debug("{} in {}. Relating them.".format(user, chat))133                        chat.user.add(user)134                    else:135                        logger.debug("{} not in {}. Skipping.".format(user, chat))136                except telegram.TelegramError:137                    logger.debug("{} not in {}. Skipping.".format(user, chat))138        else:139            # If the user is in db, add chat to his chats in bot's db140            user = User.objects.get_or_none(chat_id=member.id)141            if user:142                logger.debug("{} in {}. Relating them.".format(user, chat))143                chat.user.add(user)144def left_chat_member(bot, update):145    "Handling user_left"146    # We do not monitor these chats147    if update.message.chat.type in ('private', 'channel'):148        return149    chat = Chat.objects.get(chat_id=update.message.chat.id)150    # If bot was kicked or whatever!151    if update.message.left_chat_member.username == bot.username:152        chat.bot_in_chat = False153        chat.save()154    # If any other user was kicked delete this chat from his list155    else:156        user = User.objects.get_or_none(chat_id=update.message.left_chat_member.id)157        if user:158            user.chats.remove(chat)159# ACTIONS160# Add key161def ask_new_key(bot, update):162    bot.sendMessage(update.effective_message.chat.id, text=random.choice(text.actions.add_key.ask_new_key))163    return PROCESS_KEY164def add_key(bot, update):165    user = User.objects.get(chat_id=update.effective_user.id)166    # Store unique-in-user-scope keys167    keys = set(update.message.text.split('\n'))168    for k in keys:169        if not Keyword.objects.filter(key=k, user=user) and k:170            key = Keyword(key=k, user=user)171            key.save()172    keyboard = telegram.InlineKeyboardMarkup([173        [telegram.InlineKeyboardButton(text=text.buttons.menu.pin_key_to_chat, switch_inline_query_current_chat=text.buttons.menu.pin_key_to_chat[:-2])],174    ])175    bot.sendMessage(user.chat_id, text=text.actions.add_key.success, reply_markup=keyboard)176    return -1177# Add negative key178def ask_negative_key(bot, update):179    bot.sendMessage(update.effective_message.chat.id, text=random.choice(text.actions.add_neg_key.ask_new_key) + '\n\n' + text.actions.add_neg_key.warn)180    return PROCESS_NEG_KEY181def add_negative_key(bot, update):182    user = User.objects.get(chat_id=update.effective_user.id)183    # Store unique-in-user-scope keys184    keys = set(update.message.text.split('\n'))185    for k in keys:186        if not NegativeKeyword.objects.filter(key=k, user=user) and k:187            nkey = NegativeKeyword(key=k, user=user)188            nkey.save()189    keyboard = telegram.InlineKeyboardMarkup([190        [telegram.InlineKeyboardButton(text=text.buttons.menu.pin_neg_key, switch_inline_query_current_chat=text.buttons.menu.pin_neg_key[:-2])],191    ])192    bot.sendMessage(user.chat_id, text=text.actions.add_neg_key.success, reply_markup=keyboard)193    return -1194# Pin key195def get_keys_for_pinning(bot, update):196    "Shows all user's keys answering to inline query"197    logger.debug("Processing in function get_keys_for_pinning")198    user = User.objects.get(chat_id=update.effective_user.id)199    # Due to the restriction of number of objects we can send in response we need to paginate the data200    objects = user.keywords.all()201    offset = 1 if not update.inline_query.offset else update.inline_query.offset202    paginator = Paginator(objects, 40)203    keywords = paginator.page(int(offset))204    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''205    update.inline_query.answer(206        results=[207            telegram.InlineQueryResultArticle(208                id=uuid.uuid4(),209                title='ÐÑе клÑÑи',210                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.pin_key.choose_pin_key.format(text.actions.pin_key.all_keys)))211        ] + [212            telegram.InlineQueryResultArticle(213                id=uuid.uuid4(),214                title=keyword.key,215                description=keyword.prepare_description(),216                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.pin_key.choose_pin_key.format(keyword.key))217            ) for keyword in keywords218        ],219        cache_time=3,220        is_personal=True,221        next_offset=next_offset,222    )223    logger.debug("Processing finished in function get_keys_for_pinning")224def get_chat_list_button_for_pinning_key(bot, update):225    "Shows a message with button to switch inline query with available chats on"226    user = User.objects.get(chat_id=update.effective_user.id)227    key = re.match(text.re.choose_pin_key, update.message.text).group(1)228    update.message.delete()229    keyboard = telegram.InlineKeyboardMarkup([230        [telegram.InlineKeyboardButton(text=text.buttons.pin_key_to_chat.pin_to_chat, switch_inline_query_current_chat=text.buttons.pin_key_to_chat.choose_chat_to_pin_pattern.format(key))]231    ])232    bot.sendMessage(user.chat_id, text=text.actions.pin_key.choose_chat, reply_markup=keyboard)233def get_chat_list_for_pinning_key(bot, update):234    "Shows all user's chats answering to inline query"235    user = User.objects.get(chat_id=update.effective_user.id)236    key = re.match(text.re.choose_chat_to_pin, update.inline_query.query).group(1)237    # Due to the restriction of number of objects we can send in response we need to paginate the data238    objects = user.chats.filter(bot_in_chat=True)239    offset = 1 if not update.inline_query.offset else update.inline_query.offset240    paginator = Paginator(objects, 40)241    chats = paginator.page(int(offset))242    next_offset = str(chats.next_page_number()) if chats.has_next() else ''243    update.inline_query.answer(244        results=[245            telegram.InlineQueryResultArticle(246                id=uuid.uuid4(),247                title=chat.title,248                description=chat.get_keys(user),249                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.pin_key.pin_key_to_chat.format(chat=chat.id, key=key))250            ) for chat in chats251        ],252        cache_time=3,253        is_personal=True,254        next_offset=next_offset,255    )256def pin_key_to_chat(bot, update):257    "Pin key to chat, nothing more.."258    user = User.objects.get(chat_id=update.effective_user.id)259    match = re.match(text.re.pin_key_to_chat, update.message.text)260    chat_id = match.group(1)261    key = match.group(2)262    chat = Chat.objects.get(id=chat_id)263    if key == text.actions.pin_key.all_keys:264        utils.pin_all_to_chat(user, chat)265        # for kw in user.keywords.all():266        #     chat.keywords.add(kw)267    else:268        try:269            kw = user.keywords.filter(key=key)[0]270        except IndexError:271            logger.debug("Cannot pin key {} to chat {}. This key does not exist.".format(key, chat))272            return273        chat.keywords.add(kw)274    bot.sendMessage(user.chat_id, text=random.choice(text.actions.pin_key.success))275# Unpin key276def get_chat_list_for_unpinning_key(bot, update):277    "Show user's chats list answering to inline query"278    user = User.objects.get(chat_id=update.effective_user.id)279    objects = user.chats.filter(bot_in_chat=True)280    offset = 1 if not update.inline_query.offset else update.inline_query.offset281    paginator = Paginator(objects, 40)282    chats = paginator.page(int(offset))283    next_offset = str(chats.next_page_number()) if chats.has_next() else ''284    update.inline_query.answer(285        results=[286            telegram.InlineQueryResultArticle(287                id=uuid.uuid4(),288                title=chat.title,289                description=chat.get_keys(user),290                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.unpin_key.select_chat.format(chat.id))291            ) for chat in chats292        ],293        cache_time=3,294        is_personal=True,295        next_offset=next_offset,296    )297def get_key_list_button_for_unpinning_key(bot, update):298    "Show message with button that switches inline mode on to show all keys for specified chat"299    user = User.objects.get(chat_id=update.effective_user.id)300    chat = re.match(text.re.unpin_key_select_chat, update.message.text).group(1)301    update.message.delete()302    keyboard = telegram.InlineKeyboardMarkup([303        [telegram.InlineKeyboardButton(text=text.buttons.unpin_key_from_chat.unpin_from_chat, switch_inline_query_current_chat=text.buttons.unpin_key_from_chat.choose_key_pattern.format(chat=chat))]304    ])305    bot.sendMessage(user.chat_id, text=text.actions.unpin_key.choose_key, reply_markup=keyboard)306def get_key_list_for_pinning_key(bot, update):307    "Show all keys for specified chat in inline mode"308    user = User.objects.get(chat_id=update.effective_user.id)309    chat_id = re.match(text.re.unpin_key_choose_key, update.inline_query.query).group(1)310    chat = Chat.objects.get(id=chat_id)311    objects = chat.keywords.filter(user=user)312    offset = 1 if not update.inline_query.offset else update.inline_query.offset313    paginator = Paginator(objects, 40)314    keywords = paginator.page(int(offset))315    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''316    update.inline_query.answer(317        results=[318            telegram.InlineQueryResultArticle(319                id=uuid.uuid4(),320                title='ÐÑе клÑÑи',321                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.unpin_key.unpin.format(chat=chat.id, key=text.actions.unpin_key.all_keys)))322        ] + [323            telegram.InlineQueryResultArticle(324                id=uuid.uuid4(),325                title=kw.key,326                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.unpin_key.unpin.format(chat=chat.id, key=kw.key))327            ) for kw in keywords328        ],329        cache_time=3,330        is_personal=True,331        next_offset=next_offset,332    )333def unpin_key_from_chat(bot, update):334    "Just unpin key from chat"335    user = User.objects.get(chat_id=update.effective_user.id)336    match = re.match(text.re.unpin_key_from_chat, update.message.text)337    chat_id = match.group(1)338    key = match.group(2)339    chat = Chat.objects.get(id=chat_id)340    if key == text.actions.unpin_key.all_keys:341        utils.unpin_all_from_chat(user, chat)342        # for kw in chat.keywords.filter(user=user):343        #     chat.keywords.remove(kw)344    else:345        try:346            kw = chat.keywords.filter(key=key, user=user)[0]347        except IndexError:348            logger.debug("Cannot unpin key {} from chat {}. This key does not exist.".format(key, chat))349            return350        chat.keywords.remove(kw)351    bot.sendMessage(user.chat_id, text=random.choice(text.actions.unpin_key.success))352# Delete Keywords353def get_keys_list_for_deletion(bot, update):354    "Shows all keys list in inline mode"355    user = User.objects.get(chat_id=update.effective_user.id)356    objects = user.keywords.all()357    offset = 1 if not update.inline_query.offset else update.inline_query.offset358    paginator = Paginator(objects, 40)359    keywords = paginator.page(int(offset))360    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''361    update.inline_query.answer(362        results=[363            telegram.InlineQueryResultArticle(364                id=uuid.uuid4(),365                title=kw.key,366                description=kw.prepare_description(),367                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.key_deletion.delete.format(key=kw.key))368            ) for kw in keywords369        ],370        cache_time=3,371        is_personal=True,372        next_offset=next_offset,373    )374def delete_key(bot, update):375    "Key deletion"376    user = User.objects.get(chat_id=update.effective_user.id)377    key = re.match(text.re.delete_key, update.message.text).group(1)378    try:379        key = user.keywords.filter(key=key)[0]380    except IndexError:381        logger.debug("No match for {}. Deletion declined.".format(key))382        return383    key.delete()384    bot.sendMessage(user.chat_id, text=random.choice(text.actions.key_deletion.success))385# Pin negative key386def get_negative_keys_list_for_pinning(bot, update):387    "Show a list of negative keywords in inline mode"388    user = User.objects.get(chat_id=update.effective_user.id)389    objects = user.negativekeyword.all()390    offset = 1 if not update.inline_query.offset else update.inline_query.offset391    paginator = Paginator(objects, 40)392    keywords = paginator.page(int(offset))393    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''394    update.inline_query.answer(395        results=[396            telegram.InlineQueryResultArticle(397                id=uuid.uuid4(),398                title='ÐÑе клÑÑи',399                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.pin_neg_key.choose_pin_key.format(text.actions.pin_neg_key.all_keys)))400        ] + [401            telegram.InlineQueryResultArticle(402                id=uuid.uuid4(),403                title=keyword.key,404                description=keyword.prepare_description(),405                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.pin_neg_key.choose_pin_key.format(keyword.key))406            ) for keyword in keywords407        ],408        cache_time=3,409        is_personal=True,410        next_offset=next_offset,411    )412def get_key_list_button_for_pinning_negative_key(bot, update):413    "Shows a message with button to switch to show keys list"414    user = User.objects.get(chat_id=update.effective_user.id)415    key = re.match(text.re.choose_pin_neg_key, update.message.text).group(1)416    update.message.delete()417    keyboard = telegram.InlineKeyboardMarkup([418        [telegram.InlineKeyboardButton(text=text.buttons.pin_neg_key.pin, switch_inline_query_current_chat=text.buttons.pin_neg_key.choose_key_to_pin_pattern.format(key))]419    ])420    bot.sendMessage(user.chat_id, text=text.actions.pin_neg_key.choose_key, reply_markup=keyboard)421def get_keys_list_for_pinning_negative_key(bot, update):422    "Shows a list of keys in inline mode"423    user = User.objects.get(chat_id=update.effective_user.id)424    keyword = re.match(text.re.choose_key_to_pin, update.inline_query.query).group(1)425    objects = user.keywords.all()426    offset = 1 if not update.inline_query.offset else update.inline_query.offset427    paginator = Paginator(objects, 40)428    keywords = paginator.page(int(offset))429    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''430    update.inline_query.answer(431        results=[432            telegram.InlineQueryResultArticle(433                id=uuid.uuid4(),434                title='ÐÑе клÑÑи',435                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.pin_neg_key.pin_key_to_key.format(key=0, nkey=keyword))436            )437        ] + [438            telegram.InlineQueryResultArticle(439                id=uuid.uuid4(),440                title=key.key,441                description=key.prepare_description(),442                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.pin_neg_key.pin_key_to_key.format(key=key.id, nkey=keyword))443            ) for key in keywords444        ],445        cache_time=3,446        is_personal=True,447        next_offset=next_offset,448    )449def pin_negative_key_to_key(bot, update):450    "Pin negative key to key, that's all!"451    user = User.objects.get(chat_id=update.effective_user.id)452    match = re.match(text.re.pin_key_to_key, update.message.text)453    key_id = match.group(1)454    nkey = match.group(2)455    if nkey == text.actions.pin_neg_key.all_keys:456        if int(key_id) == 0:457            utils.pin_all_negative_to_all(user)458            # for key in user.keywords.all():459            #     for kw in user.negativekeyword.all():460            #         key.negativekeyword.add(kw)461        else:462            key = Keyword.objects.get(id=key_id)463            utils.pin_all_negative_to_one(user, key)464            # for kw in user.negativekeyword.all():465            #     key.negativekeyword.add(kw)466    else:467        try:468            kw = user.negativekeyword.filter(key=nkey)[0]469        except IndexError:470            logger.debug("No objects for negative key {}. Pinning declined.".format(nkey))471            return472        if int(key_id) == 0:473            utils.pin_one_negative_to_all(user, kw)474            # for key in user.keywords.all():475            #     key.negativekeyword.add(kw)476        else:477            key = Keyword.objects.get(id=key_id)478            key.negativekeyword.add(kw)479    bot.sendMessage(user.chat_id, text=random.choice(text.actions.pin_neg_key.success))480# Unpin negative key481def get_key_list_for_unpinning_negative_key(bot, update):482    "Shows a list of keywords in inline mode"483    user = User.objects.get(chat_id=update.effective_user.id)484    objects = user.keywords.all()485    offset = 1 if not update.inline_query.offset else update.inline_query.offset486    paginator = Paginator(objects, 40)487    keywords = paginator.page(int(offset))488    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''489    update.inline_query.answer(490        results=[491            telegram.InlineQueryResultArticle(492                id=uuid.uuid4(),493                title=keyword.key,494                description=keyword.nkeys_description(),495                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.unpin_neg_key.select_key.format(keyword.id))496            ) for keyword in keywords497        ],498        cache_time=3,499        is_personal=True,500        next_offset=next_offset,501    )502def get_negative_key_list_button_for_unpinning_key(bot, update):503    "Shows message with the button to switch to inline query for negative key selection"504    user = User.objects.get(chat_id=update.effective_user.id)505    key = re.match(text.re.unpin_neg_key, update.message.text).group(1)506    update.message.delete()507    keyboard = telegram.InlineKeyboardMarkup([508        [telegram.InlineKeyboardButton(text=text.buttons.unpin_neg_key.unpin, switch_inline_query_current_chat=text.buttons.unpin_neg_key.choose_key.format(key=key))]509    ])510    bot.sendMessage(user.chat_id, text=text.actions.unpin_neg_key.choose_key, reply_markup=keyboard)511def get_negative_keys_for_unpinning_negative_key(bot, update):512    "Shows a list of negative keywords in inline mode"513    user = User.objects.get(chat_id=update.effective_user.id)514    key_id = re.match(text.re.unpin_neg_key_choose_key, update.inline_query.query).group(1)515    key = Keyword.objects.get(id=key_id)516    objects = key.negativekeyword.all()517    offset = 1 if not update.inline_query.offset else update.inline_query.offset518    paginator = Paginator(objects, 40)519    keywords = paginator.page(int(offset))520    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''521    update.inline_query.answer(522        results=[523            telegram.InlineQueryResultArticle(524                id=uuid.uuid4(),525                title='ÐÑе клÑÑи',526                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.unpin_neg_key.unpin.format(key=key_id, nkey=text.actions.unpin_key.all_keys)))527        ] + [528            telegram.InlineQueryResultArticle(529                id=uuid.uuid4(),530                title=kw.key,531                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.unpin_neg_key.unpin.format(key=key_id, nkey=kw.key))532            ) for kw in keywords533        ],534        cache_time=3,535        is_personal=True,536        next_offset=next_offset,537    )538def unpin_negative_key_from_key(bot, update):539    "Just unpin negative key from key"540    user = User.objects.get(chat_id=update.effective_user.id)541    match = re.match(text.re.unpin_neg_key_from_key, update.message.text)542    key_id = match.group(1)543    nkey = match.group(2)544    key = Keyword.objects.get(id=key_id)545    if nkey == text.actions.unpin_neg_key.all_keys:546        for kw in key.negativekeyword.filter(user=user):547            key.negativekeyword.remove(kw)548    else:549        try:550            kw = key.negativekeyword.filter(key=nkey, user=user)[0]551        except IndexError:552            logger.debug("No match for negative key {}. Unpinning declined.".format(key))553            return554        key.negativekeyword.remove(kw)555    bot.sendMessage(user.chat_id, text=random.choice(text.actions.unpin_neg_key.success))556# Delete negative Keywords557def negative_key_deletion_choose_keyword(bot, update):558    "Shows the list of negative keywords in inline mode"559    user = User.objects.get(chat_id=update.effective_user.id)560    objects = user.negativekeyword.all()561    offset = 1 if not update.inline_query.offset else update.inline_query.offset562    paginator = Paginator(objects, 40)563    keywords = paginator.page(int(offset))564    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''565    update.inline_query.answer(566        results=[567            telegram.InlineQueryResultArticle(568                id=uuid.uuid4(),569                title=kw.key,570                description=kw.prepare_description(),571                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.negative_key_deletion.delete.format(key=kw.key))572            ) for kw in keywords573        ],574        cache_time=3,575        is_personal=True,576        next_offset=next_offset,577    )578def delete_neg_key(bot, update):579    "Hey, you! Delete a negative key for me!"580    user = User.objects.get(chat_id=update.effective_user.id)581    key = re.match(text.re.delete_neg_key, update.message.text).group(1)582    try:583        nkw = user.negativekeyword.filter(key=key)[0]584    except IndexError:585        logger.debug("No match for negative key {}. Deletion declined.".format(key))586        return587    nkw.delete()588    bot.sendMessage(user.chat_id, text=random.choice(text.actions.negative_key_deletion.success))589# Keywords' Groups590# Create group591def ask_keywords_group_name(bot, update):592    "Ask a name for the new group"593    bot.sendMessage(update.effective_message.chat.id, text=text.actions.create_group.ask_new_group)594    return PROCESS_GROUP595def create_new_group(bot, update):596    "Process given name of the group and create it"597    user = User.objects.get(chat_id=update.effective_user.id)598    group = KeywordsGroup.objects.create(name=update.message.text, user=user)599    bot.sendMessage(user.chat_id, text=text.actions.create_group.success)600    return -1601# Add key to group602def show_groups_list_for_adding_to_group(bot, update):603    "Show's group list"604    user = User.objects.get(chat_id=update.effective_user.id)605    objects = user.groups.all()606    offset = 1 if not update.inline_query.offset else update.inline_query.offset607    paginator = Paginator(objects, 40)608    groups = paginator.page(int(offset))609    next_offset = str(groups.next_page_number()) if groups.has_next() else ''610    update.inline_query.answer(611        results=[612            telegram.InlineQueryResultArticle(613                id=uuid.uuid4(),614                title=group.name + group.prepare_state(),615                description=group.prepare_description(),616                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.add_key_to_group.choose_group.format(group.id))617            ) for group in groups618        ],619        cache_time=3,620        is_personal=True,621        next_offset=next_offset,622    )623def get_button_to_show_keywords_for_groups(bot, update):624    "Shows a message with button to switch inline query for picking a keyword for the group"625    user = User.objects.get(chat_id=update.effective_user.id)626    group_id = re.match(text.re.choose_group, update.message.text).group(1)627    update.message.delete()628    keyboard = telegram.InlineKeyboardMarkup([629        [telegram.InlineKeyboardButton(text=text.buttons.add_key_to_group.choose_key_button, switch_inline_query_current_chat=text.buttons.add_key_to_group.choose_key_pattern.format(group_id))]630    ])631    bot.sendMessage(user.chat_id, text=text.actions.add_key_to_group.choose_key, reply_markup=keyboard)632def show_keys_for_adding_to_group(bot, update):633    user = User.objects.get(chat_id=update.effective_user.id)634    group_id = re.match(text.re.choose_key_to_group, update.inline_query.query).group(1)635    group = KeywordsGroup.objects.get(id=group_id)636    # keyword_in_group = user.keywords.filter(groups__in=[group])637    objects = user.keywords.exclude(groups__in=[group])638    offset = 1 if not update.inline_query.offset else update.inline_query.offset639    paginator = Paginator(objects, 40)640    keywords = paginator.page(int(offset))641    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''642    update.inline_query.answer(643        results=[644            telegram.InlineQueryResultArticle(645                id=uuid.uuid4(),646                title=keyword.key,647                description=keyword.prepare_description(),648                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.add_key_to_group.add_key_to_group.format(group_id=group.id, key=keyword.key))649            ) for keyword in keywords650        ],651        cache_time=3,652        is_personal=True,653        next_offset=next_offset,654    )655def add_key_to_group(bot, update):656    user = User.objects.get(chat_id=update.effective_user.id)657    match = re.match(text.re.add_key_to_group, update.message.text)658    group_id = match.group(1)659    keyword = match.group(2)660    key = Keyword.objects.get(key=keyword, user=user)661    group = KeywordsGroup.objects.get(id=group_id)662    group.keys.add(key)663    # update.message.delete()664    bot.sendMessage(user.chat_id, text=text.actions.add_key_to_group.success)665# Delete key from group666def show_groups_for_del_key_from_group(bot, update):667    "Show's groups list"668    user = User.objects.get(chat_id=update.effective_user.id)669    objects = user.groups.all()670    offset = 1 if not update.inline_query.offset else update.inline_query.offset671    paginator = Paginator(objects, 40)672    groups = paginator.page(int(offset))673    next_offset = str(groups.next_page_number()) if groups.has_next() else ''674    update.inline_query.answer(675        results=[676            telegram.InlineQueryResultArticle(677                id=uuid.uuid4(),678                title=group.name + group.prepare_state(),679                description=group.prepare_description(),680                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.del_key_from_group.choose_group.format(group.id))681            ) for group in groups682        ],683        cache_time=3,684        is_personal=True,685        next_offset=next_offset,686    )687def get_button_to_show_keys_for_deletion_from_group(bot, update):688    "Shows a message with button to switch inline query for picking a keyword for deletion from group"689    user = User.objects.get(chat_id=update.effective_user.id)690    group_id = re.match(text.re.choose_group_for_key_deletion, update.message.text).group(1)691    update.message.delete()692    keyboard = telegram.InlineKeyboardMarkup([693        [telegram.InlineKeyboardButton(text=text.buttons.del_key_from_group.choose_key, switch_inline_query_current_chat=text.buttons.del_key_from_group.choose_key_pattern.format(group_id))]694    ])695    bot.sendMessage(user.chat_id, text=text.actions.del_key_from_group.choose_key, reply_markup=keyboard)696def show_keys_for_deleting_from_group(bot, update):697    "Show keys from group for deletion"698    user = User.objects.get(chat_id=update.effective_user.id)699    group_id = re.match(text.re.choose_key_for_key_from_group_deletion, update.inline_query.query).group(1)700    group = KeywordsGroup.objects.get(id=group_id)701    objects = user.keywords.filter(groups__in=[group])702    offset = 1 if not update.inline_query.offset else update.inline_query.offset703    paginator = Paginator(objects, 40)704    keywords = paginator.page(int(offset))705    next_offset = str(keywords.next_page_number()) if keywords.has_next() else ''706    update.inline_query.answer(707        results=[708            telegram.InlineQueryResultArticle(709                id=uuid.uuid4(),710                title=keyword.key,711                description=keyword.prepare_description(),712                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.del_key_from_group.del_key_from_group.format(group_id=group.id, key=keyword.key))713            ) for keyword in keywords714        ],715        cache_time=3,716        is_personal=True,717        next_offset=next_offset,718    )719def delete_key_from_group(bot, update):720    user = User.objects.get(chat_id=update.effective_user.id)721    match = re.match(text.re.del_key_from_group, update.message.text)722    group_id = match.group(1)723    keyword = match.group(2)724    group = KeywordsGroup.objects.get(id=group_id)725    key = group.keys.get(key=keyword)726    group.keys.remove(key)727    # update.message.delete()728    bot.sendMessage(user.chat_id, text=text.actions.del_key_from_group.success)729# Switch groups on and off730def show_groups_for_switching(bot, update):731    user = User.objects.get(chat_id=update.effective_user.id)732    objects = user.groups.all()733    offset = 1 if not update.inline_query.offset else update.inline_query.offset734    paginator = Paginator(objects, 40)735    groups = paginator.page(int(offset))736    next_offset = str(groups.next_page_number()) if groups.has_next() else ''737    update.inline_query.answer(738        results=[739            telegram.InlineQueryResultArticle(740                id=uuid.uuid4(),741                title=group.name + group.prepare_state(),742                description=group.prepare_description(),743                input_message_content=telegram.InputTextMessageContent(message_text=text.actions.group_switch.switch.format(group_id=group.id))744            ) for group in groups745        ],746        cache_time=3,747        is_personal=True,748        next_offset=next_offset,749    )750def switch_group(bot, update):751    user = User.objects.get(chat_id=update.effective_user.id)752    group_id = re.match(text.re.switch_group, update.message.text).group(1)753    group = KeywordsGroup.objects.get_or_none(id=group_id)754    if not group:755        bot.sendMessage(user.chat_id, text=text.actions.group_switch.group_not_found)756        return -1757    if group.state:758        group.state = False759        utils.switch_group_off(group)760        group.save()761        bot.sendMessage(user.chat_id, text=text.actions.group_switch.success_off.format(group.name))762    else:763        group.state = True764        utils.switch_group_on(group)765        group.save()766        bot.sendMessage(user.chat_id, text=text.actions.group_switch.success_on.format(group.name))767# Monitoring chat's activity768def show_all_chats(bot, update):769    "Show all possible common chats for user in a message using InlineKeyboard"770    user = User.objects.get(chat_id=update.effective_user.id)771    # Check whether a user has common chats772    if user.chats.count() == 0:773        bot.sendMessage(user.chat_id, text=text.actions.chats.no_chats)774        return775    keyboard = telegram.InlineKeyboardMarkup([776        [telegram.InlineKeyboardButton(text=chat.represent(user), callback_data=text.buttons.chats.switch.format(chat=chat.id))] for chat in user.chats.all()[:99]777    ])778    bot.sendMessage(user.chat_id, text=text.actions.chats.show_all, reply_markup=keyboard)779def switch_chat(bot, update):780    "Switch chat activity"781    user = User.objects.get(chat_id=update.effective_user.id)782    chat_id = re.match(text.re.switch, update.callback_query.data).group(1)783    chat = Chat.objects.get(id=chat_id)784    if chat in user.chats.all():785        if chat.bot_in_chat:786            relation = chat.relation_set.filter(user=user)[0]787            relation.active = not relation.active788            relation.save()789            if relation.active:790                update.callback_query.answer(text=text.actions.chats.switch_success + ' ' + text.actions.chats.switch_unactive)791            else:792                update.callback_query.answer(text=text.actions.chats.switch_success + ' ' + text.actions.chats.switch_active)793            keyboard = telegram.InlineKeyboardMarkup([794                [telegram.InlineKeyboardButton(text=chat.represent(user), callback_data=text.buttons.chats.switch.format(chat=chat.id))] for chat in user.chats.all()795            ])796            update.callback_query.edit_message_reply_markup(reply_markup=keyboard)797        else:798            update.callback_query.answer(text=text.actions.chats.switch_fail, show_alert=True)799# Settings800def show_settings(bot, update):801    user = User.objects.get(chat_id=update.effective_user.id)802    settings_keyboard = telegram.InlineKeyboardMarkup([803        [telegram.InlineKeyboardButton(text=text.buttons.settings.debug_mode + ' ' + user.prepare_debug_state(), callback_data=text.buttons.settings.debug_mode)],804        [telegram.InlineKeyboardButton(text=text.buttons.settings.settings_up, callback_data=text.buttons.settings.settings_up)],805        [telegram.InlineKeyboardButton(text=text.buttons.settings.settings_down, callback_data=text.buttons.settings.settings_down)],806        [telegram.InlineKeyboardButton(text=text.buttons.settings.delete_all_keywords, callback_data=text.buttons.settings.delete_all_keywords)],807    ])808    update.callback_query.message.edit_text(text=text.actions.settings.debug_msg_text, reply_markup=settings_keyboard, parse_mode=telegram.ParseMode.MARKDOWN)809def switch_debug_mode(bot, update):810    user = User.objects.get(chat_id=update.effective_user.id)811    if user.debug:812        user.debug = False813        user.save()814        update.callback_query.answer(text.actions.settings.debug_off)815    else:816        user.debug = True817        user.save()818        update.callback_query.answer(text.actions.settings.debug_on)819    settings_keyboard = telegram.InlineKeyboardMarkup([820        [telegram.InlineKeyboardButton(text=text.buttons.settings.debug_mode + ' ' + user.prepare_debug_state(), callback_data=text.buttons.settings.debug_mode)],821    ])822    update.callback_query.edit_message_reply_markup(reply_markup=settings_keyboard)823def upload_settings_to_user(bot, update):824    user = User.objects.get(chat_id=update.effective_user.id)825    data = utils.gen_users_dataprint(user)826    filename = str(uuid.uuid4()) + '.xml'827    with open(filename, "w+") as data_file:828        data_file.write(data)829    bot.sendDocument(user.chat_id, document=open(filename, 'rb'), caption=text.actions.settings.settings_up_text, timeout=60)830def ask_file_to_download_settings(bot, update):831    bot.sendMessage(update.effective_user.id, text.actions.settings.settings_down_request)832    return PROCESS_SETTINGS_FILE833def process_settings_down_saving(bot, update):834    user = User.objects.get(chat_id=update.effective_user.id)835    file = update.message.document.get_file()836    data_stream = io.BytesIO()837    file.download(out=data_stream)838    data = data_stream.getvalue().decode("utf-8")839    repl_state = utils.replicate_users_dataprint(user, data)840    if repl_state:841        bot.sendMessage(user.chat_id, text.actions.settings.settings_down_text_success)842    else:843        bot.sendMessage(user.chat_id, "Ooops... Something gone wrong")844    return -1845def delete_all_keys_confirm(bot, update):846    # user = User.objects.get(chat_id=update.effective_user.id)847    keyboard = telegram.InlineKeyboardMarkup([848        [telegram.InlineKeyboardButton(text=text.buttons.settings.delete_yes, callback_data=text.buttons.settings.delete_yes_cb)],849        [telegram.InlineKeyboardButton(text=text.buttons.settings.delete_no, callback_data=text.buttons.settings.delete_no_cb)],850    ])851    # bot.sendMessage(update.callback_query.from_user.id, text.actions.settings.delete_all_keywords_confirm, reply_markup=keyboard)852    update.callback_query.message.edit_text(text.actions.settings.delete_all_keywords_confirm, reply_markup=keyboard)853def delete_all_keys(bot, update):854    user = User.objects.get(chat_id=update.effective_user.id)855    update.callback_query.answer('Deleting...')856    user.delete_all_keywords()857    # update.callback_query.message.edit_reply_markup(none)858    update.callback_query.message.edit_text(text.actions.settings.deleted, reply_markup=None)859def delete_not_keywords(bot, update):860    update.callback_query.answer('Canceled')861    # update.callback_query.message.edit_reply_markup(none)862    update.callback_query.message.edit_text(text.actions.settings.not_deleted, reply_markup=None)863# Group messages864def handle_group_message(bot, update):865    "Handle group messages"866    if update.message.text:867        tasks.check_message_for_keywords.delay(868        update.message.chat.id,869        update.message.message_id,870        update.message.text,871        str(update.message.from_user.id),872        int(update.message.date.timestamp()),873        )874    elif update.message.caption:875        tasks.check_message_for_keywords.delay(876        update.message.chat.id,877        update.message.message_id,878        update.message.caption,879        str(update.message.from_user.id),880        int(update.message.date.timestamp()),881        )882# MAIN FUNCTION883PROCESS_KEY = range(1)884PROCESS_NEG_KEY = range(1)885PROCESS_GROUP = range(1)886PROCESS_SETTINGS_FILE = range(1)887def main():888    dp = DjangoTelegramBot.dispatcher889    logger.info("Loading handlers for telegram bot")890    dp.add_handler(CommandHandler("start", start))891    dp.add_handler(CommandHandler("menu", menu))892    # Handling adding and deleteing bot to/from the chat893    dp.add_handler(MessageHandler(Filters.status_update.new_chat_members, new_chat_members))894    dp.add_handler(MessageHandler(Filters.status_update.chat_created, chat_created))895    dp.add_handler(MessageHandler(Filters.status_update.left_chat_member, left_chat_member))896    # Handle group messages897    dp.add_handler(MessageHandler(GroupFilters.allowed_groups, handle_group_message))898    # Add key handler899    dp.add_handler(ConversationHandler(900        allow_reentry=True,901        entry_points=[902            CommandHandler('addkey', ask_new_key),903            CallbackQueryHandler(callback=ask_new_key, pattern=text.buttons.menu.add_key)904        ],905        states={906            PROCESS_KEY: [MessageHandler(Filters.text, add_key)],907        },908        fallbacks=[909            MessageHandler(Filters.all, default_fallback)910        ]911    ))912    # Add negative key handler913    dp.add_handler(ConversationHandler(914        allow_reentry=True,915        entry_points=[916            CommandHandler('addnegkey', ask_negative_key),917            CallbackQueryHandler(callback=ask_negative_key, pattern=text.buttons.menu.add_neg_key)918        ],919        states={920            PROCESS_NEG_KEY: [MessageHandler(Filters.text, add_negative_key)],921        },922        fallbacks=[923            MessageHandler(Filters.all, default_fallback)924        ]925    ))926    # Create keywords' group927    dp.add_handler(ConversationHandler(928        allow_reentry=True,929        entry_points=[930            CommandHandler('creategroup', ask_keywords_group_name),931            CallbackQueryHandler(callback=ask_keywords_group_name, pattern=text.buttons.menu.create_group),932        ],933        states={934            PROCESS_GROUP: [MessageHandler(Filters.text, create_new_group)],935        },936        fallbacks=[MessageHandler(Filters.all, default_fallback)]937    ))938    # Pin key to the chat through inline query939    dp.add_handler(InlineQueryHandler(callback=get_keys_for_pinning,pattern=text.buttons.menu.pin_key_to_chat[:-2]))940    dp.add_handler(RegexHandler(callback=get_chat_list_button_for_pinning_key, pattern=text.re.choose_pin_key))941    dp.add_handler(InlineQueryHandler(callback=get_chat_list_for_pinning_key, pattern=text.re.choose_chat_to_pin))942    dp.add_handler(RegexHandler(callback=pin_key_to_chat, pattern=text.re.pin_key_to_chat))943    # Pin negative key through inline query944    dp.add_handler(InlineQueryHandler(callback=get_negative_keys_list_for_pinning,pattern=text.buttons.menu.pin_neg_key[:-2]))945    dp.add_handler(RegexHandler(callback=get_key_list_button_for_pinning_negative_key, pattern=text.re.choose_pin_neg_key))946    dp.add_handler(InlineQueryHandler(callback=get_keys_list_for_pinning_negative_key, pattern=text.re.choose_key_to_pin))947    dp.add_handler(RegexHandler(callback=pin_negative_key_to_key, pattern=text.re.pin_key_to_key))948    # Add keyword to group949    dp.add_handler(InlineQueryHandler(callback=show_groups_list_for_adding_to_group, pattern=text.buttons.menu.add_key_to_group))950    dp.add_handler(RegexHandler(callback=get_button_to_show_keywords_for_groups, pattern=text.re.choose_group))951    dp.add_handler(InlineQueryHandler(callback=show_keys_for_adding_to_group, pattern=text.re.choose_key_to_group))952    dp.add_handler(RegexHandler(callback=add_key_to_group, pattern=text.re.add_key_to_group))953    # Unpin key from the chat954    dp.add_handler(InlineQueryHandler(callback=get_chat_list_for_unpinning_key, pattern=text.buttons.menu.unpin_key_from_chat[:-2]))955    dp.add_handler(RegexHandler(callback=get_key_list_button_for_unpinning_key, pattern=text.re.unpin_key_select_chat))956    dp.add_handler(InlineQueryHandler(callback=get_key_list_for_pinning_key, pattern=text.re.unpin_key_choose_key))957    dp.add_handler(RegexHandler(callback=unpin_key_from_chat, pattern=text.re.unpin_key_from_chat))958    # Unpin neg key from the key959    dp.add_handler(InlineQueryHandler(callback=get_key_list_for_unpinning_negative_key, pattern=text.buttons.menu.unpin_neg_key[:-2]))960    dp.add_handler(RegexHandler(callback=get_negative_key_list_button_for_unpinning_key, pattern=text.re.unpin_neg_key))961    dp.add_handler(InlineQueryHandler(callback=get_negative_keys_for_unpinning_negative_key, pattern=text.re.unpin_neg_key_choose_key))962    dp.add_handler(RegexHandler(callback=unpin_negative_key_from_key, pattern=text.re.unpin_neg_key_from_key))963    # Delete key from group964    dp.add_handler(InlineQueryHandler(callback=show_groups_for_del_key_from_group, pattern = text.buttons.menu.del_key_from_group))965    dp.add_handler(RegexHandler(callback=get_button_to_show_keys_for_deletion_from_group, pattern=text.re.choose_group_for_key_deletion))966    dp.add_handler(InlineQueryHandler(callback=show_keys_for_deleting_from_group, pattern=text.re.choose_key_for_key_from_group_deletion))967    dp.add_handler(RegexHandler(callback=delete_key_from_group, pattern=text.re.del_key_from_group))968    # Delete key969    dp.add_handler(InlineQueryHandler(callback=get_keys_list_for_deletion, pattern=text.buttons.menu.delete_key[:-2]))970    dp.add_handler(RegexHandler(callback=delete_key, pattern=text.re.delete_key))971    # Delete negative key972    dp.add_handler(InlineQueryHandler(callback=negative_key_deletion_choose_keyword, pattern=text.buttons.menu.delete_neg_key[:-2]))973    dp.add_handler(RegexHandler(callback=delete_neg_key, pattern=text.re.delete_neg_key))974    # Groups switching975    dp.add_handler(InlineQueryHandler(callback=show_groups_for_switching, pattern=text.buttons.menu.switch_groups))976    dp.add_handler(RegexHandler(callback=switch_group, pattern=text.re.switch_group))977    # Chat monitoring978    dp.add_handler(CallbackQueryHandler(callback=show_all_chats , pattern=text.buttons.menu.chat_monitor))979    dp.add_handler(CallbackQueryHandler(callback=switch_chat, pattern=text.re.switch))980    # Settings981    dp.add_handler(CallbackQueryHandler(callback=show_settings, pattern=text.buttons.menu.settings))982    dp.add_handler(CallbackQueryHandler(callback=switch_debug_mode, pattern=text.buttons.settings.debug_mode))983    dp.add_handler(CallbackQueryHandler(callback=upload_settings_to_user, pattern=text.buttons.settings.settings_up))984    dp.add_handler(ConversationHandler(985        allow_reentry=True,986        entry_points=[987            CallbackQueryHandler(callback=ask_file_to_download_settings, pattern=text.buttons.settings.settings_down)988        ],989        states={990            PROCESS_SETTINGS_FILE: [MessageHandler(Filters.document, process_settings_down_saving)],991        },992        fallbacks=[MessageHandler(Filters.all, default_fallback)]993    ))994    # Delete all keys995    dp.add_handler(CallbackQueryHandler(callback=delete_all_keys_confirm, pattern=text.buttons.settings.delete_all_keywords))996    dp.add_handler(CallbackQueryHandler(callback=delete_all_keys, pattern=text.buttons.settings.delete_yes_cb))...test_cache_implementation.py
Source:test_cache_implementation.py  
...73            if self.__pins[key] == 0:74                self.__total_pins += 175            self.__pins[key] += 176    @rule(key=keys)77    def unpin_key(self, key):78        if self.__pins[key] > 0:79            self.cache.unpin(key)80            self.__pins[key] -= 181            if self.__pins[key] == 0:82                self.__total_pins -= 183                assert self.__total_pins >= 0...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
