class DemoBot:
   
    def __init__(self):
        self.__bot = Bot(config.bot_id)
        self.__handlers = {}
        self.__disp = Dispatcher(bot=self.__bot)
        
    async def __main(self):      
        try:            
            await self.__disp.start_polling()
        finally:
            await self.__bot.close()
                    
   
    def run(self):
        print('Bot run in polling mode. Please CTRL-Break for exit...')        
        asyncio.run(self.__main())  
        
    def register_start_handler(self,handler=None):
        async def internal_handler(event):
            if not handler is None:
                result = handler(event.text,self.__bot)
                await event.answer(result[0],parse_mode = types.ParseMode.HTML, reply_markup = result[1])
            else:
                await event.answer(f"Hello {event.from_user.get_mention(as_html=True)} :-)",parse_mode = types.ParseMode.HTML)
             
        self.__disp.register_message_handler(internal_handler,commands = {"start","restart"})
      
        
    def register_text_handler(self,handler,**aux):
        async def internal__handler(event,regexp):
                result = handler(event.text)            
                await event.answer(result,parse_mode = types.ParseMode.HTML)                    
        self.__disp.register_message_handler(internal__handler,**aux)
Exemple #2
0
    def main(self):
        log.info('run serve subcommand')

        token = Core.config.telegram.api_token()
        if type(token) is not str:
            log.critical(
                'Can not find "telegram:api_token" in config. Exiting.')
            exit(1)

        self._bot = Bot(token=Core.config.telegram.api_token())
        dp = Dispatcher(self._bot)

        self._processor = VolleyProcessor(
            YandexTranslate(Core.config.yandex_translate.api_key()),
            ChatScript(Core.config.chatscript.host(),
                       Core.config.chatscript.port(), 'botan'))

        dp.register_message_handler(self.send_welcome,
                                    commands=['start', 'help'])
        dp.register_message_handler(self.everything)

        start_polling(
            dp,
            skip_updates=True,
            # on_startup=self.on_startup,
            # on_shutdown=self.on_shutdown
        )
Exemple #3
0
def bot(config: ConfigParser) -> Dispatcher:
    bot = Bot(config['TELEGRAM']['TOKEN'])
    dispatcher = Dispatcher(bot)

    dispatcher.register_message_handler(partial(register, config),
                                        commands=["register"])

    return dispatcher
Exemple #4
0
def setup_handlers(dp: Dispatcher):
    dp.bind_filter(InChatIds)
    dp.register_message_handler(
        cmd_start,
        commands=['start'],
    )

    dp.register_message_handler(
        InChatIds(),
        current_chat_ids,
        commands=['chat_ids'],
    )
Exemple #5
0
def register_handlers_common(dp: Dispatcher):
    """Register common handlers in Dispatcher."""
    log.info('Configuring common handlers...')
    dp.register_message_handler(common.cmd_start, commands='start')
    dp.register_message_handler(common.cmd_about, commands='about')
    dp.register_message_handler(common.cmd_help, commands='help')
    dp.register_message_handler(common.cmd_cancel, commands='cancel', state='*')
    dp.register_message_handler(
        common.cmd_cancel, Text(equals='отмена', ignore_case=True), state='*'
    )
Exemple #6
0
    def __init__(self,
                 dispatcher: Dispatcher,
                 strings: any,
                 parse_mode=ParseMode.MARKDOWN):
        """Initialize ChatProvider object

        Args:
            dispatcher:
                A telegram bot dispatcher.
            strings:
                A locale strings class.
            parse_mode:
                A parse mode of telegram messages (aiogram.types.ParseMode).
                Default value: ParseMode.MARKDOWN
        """
        self.__dispatcher = dispatcher
        self.strings = strings
        self.parse_mode = parse_mode

        dispatcher.register_message_handler(self.cmd_start, commands=["start"])
        dispatcher.register_message_handler(self.cmd_help, commands=["help"])
Exemple #7
0
def register_poster_creation(dp: Dispatcher):
    dp.register_message_handler(in_queue_handler,
                                state=PosterCreation.confirmation)
    dp.register_message_handler(poster_create_start,
                                text="Make poster",
                                state="*")
    dp.register_message_handler(qsize_handler, commands=["qsize"], state="*")
Exemple #8
0
class TelegramMessenger(MessengerInterface):
    def __init__(self, kernel: Kernel, token: str):
        self.bot = Bot(token=token)
        self.dispatcher = Dispatcher(self.bot, storage=MemoryStorage())
        self.chat_dict = dict()
        self.dispatcher.register_message_handler(self.handler)
        self.kernel = kernel
        self.webhook_url = ''

    def start_listening(self):
        executor.start_polling(self.dispatcher)

    async def handler(self, message: types.Message):
        order = self.chat_dict.get(message.chat.id)
        if order is None:
            order = Order(
                TelegramMessageSender(message.chat.id, self.bot,
                                      self.chat_dict), self.kernel)
            self.chat_dict[message.chat.id] = order
        await order.proceed(message.text)

    async def on_startup(self, dp):
        await self.bot.set_webhook(self.webhook_url)

    async def on_shutdown(self, dp):
        await self.bot.delete_webhook()

    def start_webhook(self, webhook_path: str, webapp_host: str,
                      webapp_port: int, webhook_url: str):
        self.webhook_url = webhook_url
        start_webhook(
            dispatcher=self.dispatcher,
            webhook_path=webhook_path,
            on_startup=self.on_startup,
            on_shutdown=self.on_shutdown,
            skip_updates=True,
            host=webapp_host,
            port=webapp_port,
        )
Exemple #9
0
    def __init__(self,
                 dispatcher: Dispatcher,
                 state_manager: StateManager,
                 strings: any,
                 data_adapter: Union[ReserveDataAdapter, None] = None,
                 user_data_adapter: Union[UserDataAdapter, None] = None,
                 state_type: Union[str, int, None] = "sup"):
        """Initialize a class instance

        Args:
            dispatcher:
                A telegram bot dispatcher instance instance.
            state_manager:
                A state manager class instance
            strings:
                A locale strings class.
            data_adapter:
                Optional. A reservation storage data adapter
            user_data_adapter:
                Optional. An user storage data adapter
            state_type:
                Optional, A default state type.
                Default value: "sup"
            parse_mode:
                Optional. A parse mode of telegram messages (ParseMode).
                Default value: aiogram.types.ParseMode.MARKDOWN
        """
        super().__init__(dispatcher,
                         state_manager,
                         strings,
                         data_adapter=data_adapter,
                         user_data_adapter=user_data_adapter,
                         state_type=state_type)

        self.reserve_set_types["set"] = ReserveSetType("set", 30)

        dispatcher.register_message_handler(self.cmd_sup, commands=["sup"])

        self.book_handlers["apply"] = self.book_apply
Exemple #10
0
def register_common(dp: Dispatcher):
    dp.register_message_handler(cmd_start, commands=["start", "help"])
    dp.register_message_handler(
        cancel_state,
        state='*',
        commands=["cancel"],
    )
    dp.register_message_handler(
        cancel_state,
        filters.Text(equals='cancel', ignore_case=True),
        state='*',
    )
    dp.register_errors_handler(errors_handler)
Exemple #11
0
def setup(dp: Dispatcher):
    dp.register_message_handler(messages.send_start,
                                types.ChatType.is_private,
                                commands='start')
    dp.register_message_handler(messages.handle_settings,
                                types.ChatType.is_private,
                                text='⚙Settings')
    dp.register_message_handler(messages.handle_language,
                                types.ChatType.is_private,
                                text='🇺🇸Language')
    dp.register_message_handler(messages.handle_link,
                                types.ChatType.is_private,
                                regex=True)

    dp.register_callback_query_handler(
        callbacks.change_language, lambda call: call.data.startswith('lang'))
    dp.register_callback_query_handler(
        callbacks.change_client, lambda call: call.data.startswith('client'))

    dp.register_inline_handler(inlines.handle_inline_link,
                               regex=True,
                               len_restrict=True)
    dp.register_inline_handler(inlines.handle_wrong_inline_link, regex=True)
Exemple #12
0
def register_handlers_settings(dp: Dispatcher):
    """Register routes handlers in Dispatcher."""
    log.info('Configuring settings handlers...')
    dp.register_message_handler(settings.settings_list, commands='settings')
    dp.register_callback_query_handler(
        settings.settings_list, cd_settings.filter(action='list')
    )
    dp.register_callback_query_handler(
        settings.settings_tz, cd_settings.filter(action='tz')
    )
    dp.register_callback_query_handler(
        settings.settings_tz_change, cd_settings.filter(action='tz-change')
    )
    dp.register_message_handler(
        settings.settings_tz_set,
        Text(startswith='UTC', ignore_case=True),
        state=SetTimezone,
    )
    dp.register_message_handler(settings.settings_tz_error, state=SetTimezone)
Exemple #13
0
        result_msg.append(f"Username: {target.mention}")
    result_msg.append(f"User ID: {target.id}")

    result_msg.extend(
        [hbold('Chat:'), f"Type: {chat.type}", f"Chat ID: {chat.id}"])
    if chat.type != ChatType.PRIVATE:
        result_msg.append(f"Title: {chat.title}")
    else:
        result_msg.append(f"Title: {chat.full_name}")
    return SendMessage(message.chat.id,
                       '\n'.join(result_msg),
                       reply_to_message_id=message.message_id,
                       parse_mode=ParseMode.HTML)


dp.register_message_handler(cmd_start, commands=['start'])

# This handler is available in all states at any time.
dp.register_message_handler(cmd_about, commands=['help', 'about'], state='*')
dp.register_message_handler(
    unknown,
    content_types=BAD_CONTENT,
    func=lambda message: message.chat.type == ChatType.PRIVATE)

# You are able to register one function handler for multiple conditions
dp.register_message_handler(cancel, commands=['cancel'], state='*')
dp.register_message_handler(
    cancel,
    func=lambda message: message.text.lower().strip() in ['cancel'],
    state='*')
def setup_handlers(dispatcher: Dispatcher):
    # This example has only one messages handler
    dispatcher.register_message_handler(cmd_start, commands=['start', 'welcome'])
class PakreqBot(object):
    """pakreqBot main object"""

    def __init__(self, config):
        self.app = dict()
        self.app['config'] = config
        self.bot = Bot(token=self.app['config']['telegram']['token'])
        self.dp = Dispatcher(self.bot)

    async def init_db(self):
        """Init database connection"""
        await pakreq.db.init_db(self.app)

    async def link_account(self, message: types.Message):
        """Implementation of /link, link telegram account to pakreq account"""
        logger.info(
            'Received request to link telegram account: %s' %
            message.from_user.id
        )
        splitted = message.text.split(maxsplit=2)
        if len(splitted) < 3:
            await message.reply(
                pakreq.telegram_consts.TOO_FEW_ARGUMENTS,
                parse_mode='HTML'
            )
            return
        success = False
        async with self.app['db'].acquire() as conn:
            users = await pakreq.db.get_users(conn)
            for user in users:
                if user['username'] == splitted[1]:
                    if password_verify(
                            user['id'], splitted[2], user['password_hash']):
                        oauth_info = pakreq.db.OAuthInfo(
                            string=user['oauth_info']
                        ).edit(
                            telegram_id=message.from_user.id
                        ).output()
                        try:
                            await pakreq.db.update_user(
                                conn, user['id'], oauth_info=oauth_info
                            )
                            success = True
                        except Exception:
                            await message.reply(
                                pakreq.telegram_consts.error_msg(
                                    "Unable to update user info"
                                ),
                                parse_mode='HTML'
                            )
                        break
            if success:
                # Unlink this Telegram account from other pakreq accounts
                # TODO: Make this more elegant
                for user in users:
                    if user['username'] != splitted[1]:
                        if pakreq.db.OAuthInfo(string=user['oauth_info']) \
                                .info['telegram_id'] == message.from_user.id:
                            oauth_info = pakreq.db.OAuthInfo(
                                string=user['oauth_info']
                            ).edit(
                                telegram_id=None
                            ).output()
                            try:
                                await pakreq.db.update_user(
                                    conn,
                                    user['id'],
                                    oauth_info=oauth_info
                                )
                            except Exception:
                                await message.reply(
                                    pakreq.telegram_consts.error_msg(
                                        "Unable to update user info",
                                        "Failed to unlink other accounts."
                                    ),
                                    parse_mode='HTML'
                                )
                await message.reply(
                    pakreq.telegram_consts.LINK_SUCCESS.format(
                        username=splitted[1]
                    ),
                    parse_mode='HTML'
                )
            else:
                await message.reply(
                    pakreq.telegram_consts.INCORRECT_CREDENTIALS,
                    parse_mode='HTML'
                )

    async def list_requests(self, message: types.Message):
        """Implementation of /list, list requests"""
        logger.info('Received /list: %s' % message.text)
        splitted = message.text.split()
        result = ''
        if len(splitted) == 1:
            if message.chat.id < 0:
                await message.reply(
                    pakreq.telegram_consts.FULL_LIST_PRIVATE_ONLY,
                    parse_mode='HTML'
                )
                return
            async with self.app['db'].acquire() as conn:
                requests = await pakreq.db.get_requests(conn)
            count = 0
            for request in requests:
                if count < 10:
                    if request['status'] == pakreq.db.RequestStatus.OPEN:
                        result = result + \
                                 pakreq.telegram_consts.REQUEST_BRIEF_INFO.format(
                                     id=request['id'], name=escape(request['name']),
                                     rtype=get_type(request['type']),
                                     description=escape(request['description'])
                                 )
                        count += 1
                else:
                    break
            if count >= 10:
                result += pakreq.telegram_consts.FULL_LIST.format(
                    url=self.app['config']['base_url']
                )
            if result == '':
                result = pakreq.telegram_consts.NO_PENDING_REQUESTS
        elif len(splitted) <= 6:
            async with self.app['db'].acquire() as conn:
                for id in splitted[1:]:
                    try:
                        request = await pakreq.db.get_request_detail(
                            conn, int(id)
                        )
                        result += pakreq.telegram_consts.REQUEST_DETAIL.format(
                            name=escape(request['name']),
                            id=request['id'],
                            status=get_status(request['status']),
                            rtype=get_type(request['type']),
                            desc=escape(request['description']),
                            req_name=escape(request['requester']['username']),
                            req_id=request['requester']['id'],
                            pak_name=escape(request['packager']['username']),
                            pak_id=request['packager']['id'],
                            date=request['pub_date'].isoformat(),
                            eta=(request['note'] or 'Empty'))
                    except (pakreq.db.RecordNotFoundException, ValueError):
                        result += \
                            pakreq.telegram_consts.REQUEST_NOT_FOUND.format(
                                id=id
                            )
        else:
            result = pakreq.telegram_consts.TOO_MANY_ARUGMENTS
        await message.reply(result, parse_mode='HTML')

    # TODO: Simplify set_note and edit_desc
    async def set_note(self, message: types.Message):
        """Implementation of /note, set note for a request"""
        logger.info('Received request to set note: %s' % message.text)
        splitted = message.text.split(maxsplit=2)
        note = None
        if len(splitted) == 3:
            note = splitted[2]
        async with self.app['db'].acquire() as conn:
            users = await pakreq.db.get_users(conn)
            user_id = find_user(users, message.from_user.id)['id']
            if user_id is None:
                await message.reply(
                    pakreq.telegram_consts.REGISTER_FIRST,
                    parse_mode='HTML'
                )
                return
            try:
                request = await pakreq.db.get_request(conn, int(splitted[1]))
                if request['packager_id'] != user_id:
                    await message.reply(
                        pakreq.telegram_consts.CLAIM_FIRST.format(
                            id=int(splitted[1])
                        ),
                        parse_mode='HTML'
                    )
                    return
                await pakreq.db.update_request(
                    conn, int(splitted[1]), note=note
                )
                await message.reply(
                    pakreq.telegram_consts.PROCESS_SUCCESS.format(
                        id=splitted[1]
                    )
                )
            except (pakreq.db.RecordNotFoundException, ValueError):
                await message.reply(
                    pakreq.telegram_consts.REQUEST_NOT_FOUND.format(
                        id=splitted[1]
                    )
                )
            except Exception:
                await message.reply(
                    pakreq.telegram_consts.error_msg(
                        'Unable to edit request'
                    ),
                    parse_mode='HTML'
                )

    async def ping(self, message: types.Message):
        """Implementation of /ping, pong"""
        logger.info(
            'Received ping from Telegram user: %s' % message.from_user.id
        )
        await message.reply('<b>Pong</b>', parse_mode='HTML')

    async def set_password(self, message: types.Message):
        """Implementation of /passwd, set password for user"""
        logger.info(
            'Setting new password for Telegram user: %s' % message.from_user.id
        )
        splitted = message.text.split(maxsplit=1)
        if len(splitted) == 2:
            async with self.app['db'].acquire() as conn:
                users = await pakreq.db.get_users(conn)
                user_id = find_user(users, message.from_user.id)['id']
                if user_id is not None:
                    pw = password_hash(
                        user_id,
                        splitted[1]
                    )
                    try:
                        await pakreq.db.update_user(
                            conn, user_id,
                            password_hash=pw
                        )
                    except Exception:
                        await message.reply(
                            pakreq.telegram_consts.error_msg(
                                "Unable to set password"
                            )
                        )
                    await message.reply(
                        pakreq.telegram_consts.PASSWORD_UPDATE_SUCCESS,
                        parse_mode='HTML'
                    )
                    return
                else:
                    await message.reply(
                        pakreq.telegram_consts.REGISTER_FIRST,
                        parse_mode='HTML'
                    )
        else:
            await message.reply(
                pakreq.telegram_consts.TOO_FEW_ARGUMENTS,
                parse_mode='HTML'
            )

    async def search_requests(self, message: types.Message):
        """Implementation of /search, search requests"""
        logger.info('Received request to search requrest: %s' % message.text)
        splitted = message.text.split(maxsplit=2)
        if len(splitted) < 2:
            await message.reply(
                pakreq.telegram_consts.TOO_FEW_ARGUMENTS,
                parse_mode='HTML'
            )
            return
        async with self.app['db'].acquire() as conn:
            requests = await pakreq.db.get_requests(conn)
        name_match = deque(
            (request for request in requests
             if splitted[1] in request['name']),
            maxlen=10
        )
        desc_match = deque(
            (request for request in requests
             if splitted[1] in request['description']),
            maxlen=10
        )
        result_name_match = ''
        result_desc_match = ''
        while name_match:
            request = name_match.pop()
            result_name_match += \
                pakreq.telegram_consts.REQUEST_BRIEF_INFO.format(
                    id=request['id'], name=escape(request['name']),
                    rtype=get_type(request['type']),
                    description=escape(request['description'])
                )
        while desc_match:
            request = desc_match.pop()
            result_desc_match += \
                pakreq.telegram_consts.REQUEST_BRIEF_INFO.format(
                    id=request['id'], name=escape(request['name']),
                    rtype=get_type(request['type']),
                    description=escape(request['description']).replace(
                        escape(splitted[1]), '<b>%s</b>' % escape(splitted[1])
                    )
                )
        result_name_match = result_name_match or \
                            pakreq.telegram_consts.NO_MATCH_FOUND.format(keyword=splitted[1])
        result_desc_match = result_desc_match or \
                            pakreq.telegram_consts.NO_MATCH_FOUND.format(keyword=splitted[1])
        await message.reply(
            pakreq.telegram_consts.SEARCH_RESULT.format(
                name_match=result_name_match,
                description_match=result_desc_match,
                url=self.app['config']['base_url']
            ),
            parse_mode='HTML'
        )

    async def whoami(self, message: types.Message):
        """Implementation of /whoami, get user info"""
        logger.info('Received request to show who that is: %s' % message.text)
        async with self.app['db'].acquire() as conn:
            users = await pakreq.db.get_users(conn)
        user = find_user(users, message.from_user.id)
        if user:
            await message.reply(
                pakreq.telegram_consts.WHOAMI.format(
                    username=user['username'],
                    id=user['id']
                ),
                parse_mode='HTML'
            )
        else:
            await message.reply(
                pakreq.telegram_consts.REGISTER_FIRST.format,
                parse_mode='HTML'
            )

    async def register(self, message: types.Message):
        """Implementation of /register, register new user"""
        logger.info('Registering new user: %s' % message.from_user.id)
        splitted = message.text.split(maxsplit=2)
        if len(splitted) > 2:
            username = splitted[1]
            if len(splitted) == 3:
                pw = splitted[2]
            else:
                pw = None
        else:
            username = message.from_user.username or message.from_user.id
            pw = None
        async with self.app['db'].acquire() as conn:
            users = await pakreq.db.get_users(conn)
            for user in users:
                if pakreq.db.OAuthInfo(string=user['oauth_info']) \
                        .info['telegram_id'] == message.from_user.id:
                    await message.reply(
                        pakreq.telegram_consts.ALREADY_REGISTERED,
                        parse_mode='HTML'
                    )
                    return
                if user['username'] == username:
                    await message.reply(
                        pakreq.telegram_consts.USERNAME_ALREADY_TAKEN.format(
                            username=escape(username)
                        ),
                        parse_mode='HTML'
                    )
                    return
            oauth_info = pakreq.db.OAuthInfo(telegram_id=message.from_user.id)
            user_id = await pakreq.db.get_max_user_id(conn)
            user_id += 1
            if pw is not None:
                pw = password_hash(user_id, pw)
            try:
                await pakreq.db.new_user(
                    conn, id=user_id, username=username,
                    oauth_info=oauth_info, password_hash=pw
                )
                await message.reply(
                    pakreq.telegram_consts.REGISGER_SUCCESS.format(
                        username=escape(username)
                    ),
                    parse_mode='HTML'
                )
                if pw is None:
                    await message.reply(
                        pakreq.telegram_consts.PASSWORD_EMPTY,
                        parse_mode='HTML'
                    )
            except Exception:
                await message.reply(
                    pakreq.telegram_consts.error_msg(
                        'Unable to register'
                    ),
                    parse_mode='HTML'
                )

    async def edit_desc(self, message: types.Message):
        """Implementation of /edit_desc, edit description"""
        logger.info('Received request to edit description: %s' % message.text)
        splitted = message.text.split(maxsplit=2)
        desc = None
        if len(splitted) == 3:
            desc = splitted[2]
        async with self.app['db'].acquire() as conn:
            users = await pakreq.db.get_users(conn)
            user_id = find_user(users, message.from_user.id)['id']
            if user_id is None:
                await message.reply(
                    pakreq.telegram_consts.REGISTER_FIRST,
                    parse_mode='HTML'
                )
                return
            try:
                request = await pakreq.db.get_request(conn, int(splitted[1]))
                if request['requester_id'] != user_id:
                    await message.reply(
                        pakreq.telegram_consts.ONLY_REQUESTER_CAN_EDIT.format(
                            id=int(splitted[1])
                        ),
                        parse_mode='HTML'
                    )
                await pakreq.db.update_request(
                    conn, int(splitted[1]), description=desc
                )
                await message.reply(
                    pakreq.telegram_consts.PROCESS_SUCCESS.format(
                        id=splitted[1]
                    )
                )
            except (pakreq.db.RecordNotFoundException, ValueError):
                await message.reply(
                    pakreq.telegram_consts.REQUEST_NOT_FOUND.format(
                        id=splitted[1]
                    )
                )
            except Exception:
                await message.reply(
                    pakreq.telegram_consts.error_msg(
                        'Unable to edit request'
                    ),
                    parse_mode='HTML'
                )

    async def claim_request(self, message: types.Message):
        """Implementation of /claim and /unclaim, claim/unclaim request"""
        logger.info(
            'Received request to claim or unclaim request: %s' %
            message.text
        )
        splitted = message.text.split()
        if splitted[0].startswith('/claim'):
            claim = True
        else:
            claim = False
        result = ''
        ids = None
        async with self.app['db'].acquire() as conn:
            if len(splitted) < 2:
                requests = await pakreq.db.get_requests(conn)
                for request in requests:
                    if (request['status'] == pakreq.db.RequestStatus.OPEN) and \
                            (request['packager_id'] == 0):
                        ids = [request['id']]
                        break
                if ids is None:
                    await message.reply(
                        pakreq.telegram_consts.NO_PENDING_REQUESTS,
                        parse_mode='HTML'
                    )
                    return
            else:
                ids = splitted[1:]
            users = await pakreq.db.get_users(conn)
            user_id = find_user(users, message.from_user.id)['id']
            if user_id is None:
                await message.reply(
                    pakreq.telegram_consts.REGISTER_FIRST,
                    parse_mode='HTML'
                )
                return
            for request_id in ids:
                new_user_id = user_id
                try:
                    request = await pakreq.db.get_request(conn, int(request_id))
                    if not claim:
                        if user_id != request['packager_id']:
                            result += pakreq.telegram_consts.CLAIM_FIRST \
                                .format(
                                    id=id
                                )
                            continue
                        else:
                            new_user_id = None
                    await pakreq.db.update_request(
                        conn, int(request_id),
                        packager_id=new_user_id
                    )
                    result += pakreq.telegram_consts.ACTION_SUCCESSFUL.format(
                        action=splitted[0].split('@')[0][1:],
                        id=request_id
                    )
                except (pakreq.db.RecordNotFoundException, ValueError):
                    result += pakreq.telegram_consts.REQUEST_NOT_FOUND.format(
                        id=request_id
                    )
        await message.reply(
            result, parse_mode='HTML'
        )

    async def show_help(self, message: types.Message):
        """Implementation of /help, show help message"""
        logger.info('Received request to show help: %s' % message.text)
        await message.reply(
            pakreq.telegram_consts.HELP_CRUFT, parse_mode='HTML')

    async def set_status(self, message: types.Message):
        """Implementation of /done and /reject, set status for requests."""
        def handle_request(command):
            if command.startswith('/done'):
                return pakreq.db.RequestStatus.DONE
            elif command.startswith('/reject'):
                return pakreq.db.RequestStatus.REJECTED
            elif command.startswith('/reopen'):
                return pakreq.db.RequestStatus.OPEN
            else:
                return int(-1)  # There should be only 2 types of requests
        splitted = message.text.split()
        logger.info(
            'Received request to mark request(s) as %sed: %s' %
            (splitted[0][1:], message.text)
        )
        result = ''
        rtype = handle_request(splitted[0])
        if rtype == -1:
            logging.error('Unexpected request type: %s' % splitted[0])
            await message.reply(pakreq.telegram_consts.error_msg(
                'Unknown command'
            ))
            return
        async with self.app['db'].acquire() as conn:
            users = await pakreq.db.get_users(conn)
            user_id = find_user(users, message.from_user.id)['id']
            if user_id is None:
                await message.reply(
                    pakreq.telegram_consts.REGISTER_FIRST,
                    parse_mode='HTML'
                )
                return
            for id in splitted[1:]:
                try:
                    request = await pakreq.db.get_request(conn, int(id))
                    if (splitted[0].startswith('/done')) and \
                            (request['packager_id'] != user_id):
                        result += \
                            pakreq.telegram_consts.CLAIM_FIRST.format(
                                id=id
                            )
                        continue
                    await pakreq.db.update_request(conn, int(id), status=rtype)
                    result += pakreq.telegram_consts.PROCESS_SUCCESS.format(
                        id=id
                    )
                except (pakreq.db.RecordNotFoundException, ValueError):
                    result += pakreq.telegram_consts.REQUEST_NOT_FOUND.format(
                        id=id
                    )
        await message.reply(result, parse_mode='HTML')

    async def new_request(self, message: types.Message):
        """Implementation of /pakreq, /updreq, /optreq, add new request"""
        def handle_request(command):
            if command.startswith('/pakreq'):
                return pakreq.db.RequestType.PAKREQ
            elif command.startswith('/updreq'):
                return pakreq.db.RequestType.UPDREQ
            elif command.startswith('/optreq'):
                return pakreq.db.RequestType.OPTREQ
            else:
                return int(-1)  # There should be only 3 types of requests
        logger.info('Received request to add a new request: %s' % message.text)
        splitted = message.text.split(maxsplit=2)
        logger.info('Adding new request: %s' % splitted[1])
        description = 'Unavailable'
        if len(splitted) < 2:
            await message.reply(
                pakreq.telegram_consts.TOO_FEW_ARGUMENTS,
                parse_mode='HTML'
            )
            return
        elif len(splitted) == 3:
            description = splitted[2]
        rtype = handle_request(splitted[0])
        if rtype == -1:
            logging.error('Unexpected request type: %s' % splitted[0])
            await message.reply(
                pakreq.telegram_consts.error_msg(
                    err='Unexpected request type',
                    err_detail=splitted[0]
                ),
                parse_mode='HTML'
            )
            return
        async with self.app['db'].acquire() as conn:
            users = await pakreq.db.get_users(conn)
            user_id = find_user(users, message.from_user.id)['id']
            if user_id is None:
                await message.reply(
                    pakreq.telegram_consts.REGISTER_FIRST,
                    parse_mode='HTML'
                )
                return
            requests = await pakreq.db.get_requests(conn)
            for request in requests:
                if (request['name'] == splitted[1]) and\
                        (request['type'] == rtype):
                    await message.reply(
                        pakreq.telegram_consts.IS_ALREADY_IN_THE_LIST
                        .format(
                            rtype=escape(splitted[0].split('@')[0][1:].capitalize()),
                            name=escape(str(splitted[1]))
                        ),
                        parse_mode='HTML'
                    )
                    return
            id = await pakreq.db.get_max_request_id(conn) + 1
            await pakreq.db.new_request(
                conn, id=id, rtype=rtype,
                name=splitted[1],
                description=description,
                requester_id=user_id
            )
        await message.reply(
            pakreq.telegram_consts.SUCCESSFULLY_ADDED.format(
                rtype=escape(splitted[0].split('@')[0][1:]),
                name=escape(str(splitted[1])),
                id=str(id)
            )
        )

    def start(self):
        """Register message handlers, and start the bot"""
        commands_mapping = [
            (['link'], self.link_account),
            (['list'], self.list_requests),
            (['note'], self.set_note),
            (['ping'], self.ping),
            (['passwd'], self.set_password),
            (['search'], self.search_requests),
            (['whoami'], self.whoami),
            (['register'], self.register),
            (['edit_desc'], self.edit_desc),
            (['claim', 'unclaim'], self.claim_request),
            (['start', 'help'], self.show_help),
            (['done', 'reject', 'reopen'], self.set_status),
            (['pakreq', 'updreq', 'optreq'], self.new_request)
        ]
        for command in commands_mapping:
            logging.info('Registering command: %s' % command[0])
            self.dp.register_message_handler(command[1], commands=command[0])
        executor.start_polling(self.dp)
Exemple #16
0
def register_handlers(dp: Dispatcher):
    dp.register_message_handler(start_command, commands=['start'])
    dp.register_message_handler(help_command, commands=['help'])
    dp.register_message_handler(add_command, commands=['add'])
    dp.register_message_handler(list_command, commands=['list'])
    dp.register_message_handler(stat_command, commands=['stat'])
    dp.register_message_handler(check_command, commands=['check'])
    dp.register_message_handler(del_command, commands=['del'])
Exemple #17
0
def register_trade_handlers(dp: Dispatcher):
    dp.register_message_handler(cmd_balances, commands=['balances'])
    dp.register_message_handler(cmd_cancel, commands=['cancel'])
Exemple #18
0
class CodeRunBot:
    def __init__(self, token, host, port, webhook_host, webhook_path):
        self.token = token
        self.host = host
        self.port = port
        self.webhook_path = webhook_path
        self.webhook_url = f"{webhook_host}{webhook_path}"

        loop = asyncio.get_event_loop()
        self.bot = AiogramBot(token=token, loop=loop)
        self.dispatcher = Dispatcher(self.bot)

        self.sessions: {int: CodingSession} = dict()
        self.default_session = CodingSession()

        self.__handlers = {
            self.__help: ['help'],
            self.__echo: ['echo', 'e'],
            self.__handle_code: ['code', 'c'],
            self.__install_package: ['add', 'a'],
            self.__get_history: ['history', 'h'],
            self.__save_history: ['save', 's'],
            self.__clear_history: ['clear', 'c'],
            self.__load_history: ['load', 'l'],
        }

    def run(self):
        logging.basicConfig(level=logging.DEBUG)
        start_webhook(dispatcher=self.dispatcher,
                      webhook_path=self.webhook_path,
                      on_startup=self.__on_startup,
                      on_shutdown=self.__on_shutdown,
                      skip_updates=True,
                      host=self.host,
                      port=self.port)

    async def __on_startup(self, dispatcher):
        await self.bot.set_webhook(self.webhook_url)
        self.__register_commands()
        logging.info("Starting up.")

    async def __on_shutdown(self, dispatcher):
        logging.info("Shutting down.")

    def __register_commands(self):
        for handler, commands in self.__handlers.items():
            self.dispatcher.register_message_handler(handler,
                                                     commands=commands)

    async def __help(self, message: types.Message):
        """Get this help message."""
        help_text = str()
        for handler, commands in self.__handlers.items():
            help_text += " ".join(f"/{command}" for command in commands)
            help_text += f" - {inspect.getdoc(handler)}\n"

        if help_text:
            help_text = f"List of bot's commands:\n{help_text}"
            await self.bot.send_message(message.chat.id, help_text)

    async def __echo(self, message: types.Message):
        """Repeats your message."""
        await self.bot.send_message(message.chat.id, message.get_args())

    async def __handle_code(self, message: types.Message):
        """Executes code, prints it's result if not None and saves it to current session."""
        chat_id = message.chat.id
        if chat_id not in self.sessions:
            self.sessions[chat_id] = CodingSession()

        code = message.get_args()
        result = self.sessions[chat_id].code_run(code)
        if result:
            await self.bot.send_message(chat_id, result)

    async def __install_package(self, message: types.Message):
        """Installs package using pip."""
        package_name = message.get_args()
        self.default_session.add_library(package_name)
        await self.bot.send_message(
            message.chat.id, f"Package {package_name} has been installed.")

    async def __get_history(self, message: types.Message):
        """Prints code history from current session."""
        chat_id = message.chat.id
        if chat_id not in self.sessions:
            return await self.bot.send_message(chat_id, "History not found :(")

        history = self.sessions[chat_id].history()
        if not history:
            return await self.bot.send_message(
                chat_id, "Session has been created, but no history recorded.")

        hashtags = self.__get_hashtags(message)
        if hashtags:
            history = f"{hashtags}{history}"
            await self.__update_session(chat_id, history)

        await self.bot.send_message(chat_id, history)

    async def __save_history(self, message: types.Message):
        """Saves history via specified method."""
        chat_id = message.chat.id
        if chat_id not in self.sessions:
            return await self.bot.send_message(chat_id, "No code to save :(")

        savers: {
            str: Saver
        } = {
            "text": PlaintextSaver,
            "html": HtmlSaver,
            "telegraph": TelegraphSaver
        }
        available_types = f"Available types: {', '.join(savers)}"

        args = message.get_args().split()
        if len(args) != 2:
            return await self.bot.send_message(
                chat_id,
                f"Specify type of saving and filename. {available_types}")

        saving_type, filename = args
        if saving_type in savers:
            saver = savers[saving_type](filename)
            if isinstance(saver, HighlightingSaver):
                saver.set_highlighter(PythonHighlighter())
        else:
            return await self.bot.send_message(
                chat_id,
                f"Specify type of saving and filename. {available_types}")

        result = self.sessions[chat_id].save(saver)
        await self.bot.send_message(message.chat.id,
                                    f"Saving result:\n{result}")

    async def __clear_history(self, message: types.Message):
        """Clears current session and creates new."""
        chat_id = message.chat.id
        if chat_id not in self.sessions:
            await self.bot.send_message(chat_id, "No history to clear :(")
            return

        await self.__update_session(chat_id, "")
        await self.bot.send_message(chat_id, "History has been cleared!")

    async def __load_history(self, message: types.Message):
        """Loads code from replied message to session wiping old code."""
        chat_id = message.chat.id
        reply = message.reply_to_message
        if not reply:
            return await self.bot.send_message(
                chat_id,
                "Reply to the history message with /load command to load it.")

        if chat_id in self.sessions:
            del self.sessions[chat_id]
            await self.bot.send_message(chat_id,
                                        "Old history has been cleared!")

        await self.__update_session(chat_id, reply.text)
        await self.bot.send_message(chat_id, "Code has been loaded.")

    async def __update_session(self, chat_id, code):
        if chat_id in self.sessions:
            del self.sessions[chat_id]

        self.sessions[chat_id] = CodingSession()
        result = self.sessions[chat_id].code_run(code)
        if result:
            await self.bot.send_message(chat_id, result)

    def __get_hashtags(self, message: types.Message):
        hashtags = str()
        entities = message.entities
        for entity in entities:
            if entity.type == "hashtag":
                hashtags += f"{entity.get_text(message.text)}\n"
        return hashtags
Exemple #19
0
def register_handlers_routes(dp: Dispatcher):
    """Register routes handlers in Dispatcher."""
    log.info('Configuring routes handlers...')
    dp.register_message_handler(routes.route_list, commands='routes')
    dp.register_message_handler(routes.route_add, commands='routeadd')
    dp.register_message_handler(
        routes.route_add_error, is_name=False, state=CreateRoute.name
    )
    dp.register_message_handler(
        routes.route_add_name, is_name=True, state=CreateRoute.name
    )
    dp.register_message_handler(
        routes.route_add_error, is_url=False, state=CreateRoute.url
    )
    dp.register_message_handler(
        routes.route_add_url, is_url=True, state=CreateRoute.url
    )
    dp.register_callback_query_handler(
        routes.route_list, cd_routes.filter(action='list')
    )
    dp.register_callback_query_handler(
        routes.route_select, cd_routes.filter(action='select')
    )
    dp.register_callback_query_handler(
        routes.route_select, cd_routes.filter(action='toggle')
    )
    dp.register_callback_query_handler(
        routes.route_show, cd_routes.filter(action='show')
    )
    dp.register_callback_query_handler(
        routes.route_delete, cd_routes.filter(action='delete')
    )
    dp.register_callback_query_handler(
        routes.route_select, cd_routes.filter(action='delete_no')
    )
    dp.register_callback_query_handler(
        routes.route_delete_confirm, cd_routes.filter(action='delete_confirm')
    )
Exemple #20
0
def register_testlisting_handlers(dp: Dispatcher):
    dp.register_message_handler(cmd_delete_coin,
                                commands=['delete_coin', 'dc'])
    dp.register_message_handler(cmd_fake_coin, commands=['fake_coin', 'fk'])
Exemple #21
0
def setup_handlers(dispatcher: Dispatcher):
    dispatcher.middleware.setup(context_data)

    # start/welcome commands
    dispatcher.register_message_handler(cmd_start, commands=['start', 'help'])

    # mycalendar
    dispatcher.register_message_handler(my_calendar, commands=['mycalendar'])

    dispatcher.register_message_handler(show_jobs, commands=['show_jobs'])

    # voice handlers
    dispatcher.register_message_handler(received_voice,
                                        content_types=ContentType.VOICE)
    # location
    dispatcher.register_message_handler(send_location,
                                        commands=['settimezone'])
    dispatcher.register_message_handler(set_timezone_by_location_from_voice,
                                        content_types=ContentType.LOCATION,
                                        state=STATE_LOCATION_FROM_VOICE)
    dispatcher.register_message_handler(set_timezone_by_location_from_voice,
                                        content_types=ContentType.TEXT,
                                        state=STATE_LOCATION_FROM_VOICE)
    dispatcher.register_message_handler(set_timezone_by_location,
                                        content_types=ContentType.LOCATION,
                                        state=STATE_LOCATION)
    dispatcher.register_message_handler(set_timezone_by_location,
                                        content_types=ContentType.TEXT,
                                        state=STATE_LOCATION)

    # calendar
    dispatcher.register_callback_query_handler(
        callback_calendar_previous_month,
        func=lambda query: query.data == 'callback_previous_month')
    dispatcher.register_callback_query_handler(
        callback_calendar_next_month,
        func=lambda query: query.data == 'callback_next_month')
    dispatcher.register_callback_query_handler(
        callback_calendar_select_day,
        func=lambda query: bool(
            re.search('^calendar-day-[0-9]{1,2}$',
                      query.data,
                      flags=re.IGNORECASE | re.MULTILINE)))
    dispatcher.register_callback_query_handler(
        callback_watch_select_time,
        func=lambda query: bool(
            re.search('^calendar-time-[0-9]{1,2}$',
                      query.data,
                      flags=re.IGNORECASE | re.MULTILINE)))

    # calendar history
    dispatcher.register_callback_query_handler(
        callback_calendar_previous_month_history,
        func=lambda query: query.data == 'callback_previous_month_history')
    dispatcher.register_callback_query_handler(
        callback_calendar_next_month_history,
        func=lambda query: query.data == 'callback_next_month_history')
    dispatcher.register_callback_query_handler(
        callback_calendar_select_day_history,
        func=lambda query: bool(
            re.search('^calendar-day-history-[0-9]{1,2}$',
                      query.data,
                      flags=re.IGNORECASE | re.MULTILINE)))
    dispatcher.register_callback_query_handler(
        callback_watch_history_select_time,
        func=lambda query: bool(
            re.search('^calendar-time-history-[0-9]{1,2}$',
                      query.data,
                      flags=re.IGNORECASE | re.MULTILINE)))

    dispatcher.register_callback_query_handler(
        callback_ignore, func=lambda query: query.data == 'ignore')

    dispatcher.register_callback_query_handler(
        callback_close_keyboard,
        func=lambda query: query.data == 'close_keyboard')