Ejemplo n.º 1
0
def check_permission(bot, user, min_value=Permission.USER):
    try:
        value = get_permission(user)
    except sqlite3.ProgrammingError:
        get_permission_ = Promise.wrap(get_permission, ptype=PT.MANUAL)
        bot.queue.put(get_permission_)
        get_permission_.wait()
        value = get_permission_.value
    if not isinstance(value, int):
        bot.logger.error('check_permission: %r', value)
        return False, True
    return value >= min_value, value > Permission.IGNORED
Ejemplo n.º 2
0
    def _search(self, update, query, reset=False):
        chat = update.effective_chat
        chat_id = chat.id
        settings = self.state.get_chat_settings(chat)

        if update.callback_query:
            user = update.callback_query.from_user
            reply_to = None
        else:
            user = update.message.from_user
            reply_to = update.message.message_id

        primary_bot = self.state.bot.primary.bot
        if chat.type == chat.PRIVATE:
            bot = primary_bot
        else:
            bot = self.state.bot.updaters[-1].bot

        try:
            enabled = settings['search_enabled']
        except KeyError:
            enabled = False
        if not enabled:
            if reply_to is not None:
                primary_bot.send_message(chat_id,
                                         '"search_enabled": false',
                                         quote=True,
                                         reply_to_message_id=reply_to)
            return

        learn = Promise.wrap(self.state.learn_search_query,
                             query,
                             user,
                             reset,
                             ptype=PT.MANUAL)
        self.state.bot.queue.put(learn)
        learn.wait()
        offset = learn.value

        if isinstance(offset, Exception):
            self.logger.error(offset)
            return

        try:
            bot.send_chat_action(chat_id, ChatAction.UPLOAD_PHOTO)
        except (Unauthorized, BadRequest) as ex:
            self.logger.warning('send_chat_action: %r', ex)
            try:
                primary_bot.send_message(chat_id,
                                         'add secondary bot to group',
                                         quote=True,
                                         reply_to_message_id=reply_to)
            except TelegramError as ex:
                self.logger.warning('send error message: %r', ex)
            return
        except TelegramError as ex:
            self.logger.error('send_chat_action: %r', ex)

        try:
            res, is_last = self.state.search(query, offset)
        except SearchError as ex:
            primary_bot.send_message(chat_id,
                                     str(ex),
                                     quote=True,
                                     reply_to_message_id=reply_to)
        except Exception as ex:
            primary_bot.send_message(chat_id,
                                     repr(ex),
                                     quote=True,
                                     reply_to_message_id=reply_to)
            return
        else:
            keyboard = [
                InlineKeyboardButton('\U0001f517 %d' % (offset + 1),
                                     url=res.url)
            ]
            if offset >= 1:
                keyboard.append(
                    InlineKeyboardButton('reset', callback_data='picreset'))
            if not is_last:
                keyboard.append(
                    InlineKeyboardButton('next', callback_data='pic'))
            keyboard = InlineKeyboardMarkup([keyboard])

            if self.RE_VIDEO_LINK.match(res.url):
                bot.send_message(chat_id,
                                 '%s\n%s\n\n%s' % (res.title, res.url, query),
                                 reply_markup=keyboard)
                return

            for url in (res.image, res.thumbnail, None):
                try:
                    self.logger.info('%r %r', query, url)
                    if url is None:
                        bot.send_message(
                            chat_id, '(bad request)\n%s\n%s\n\n%s' %
                            (res.image, res.url, query))
                    else:
                        send_image(bot,
                                   chat_id,
                                   url,
                                   caption=query,
                                   reply_markup=keyboard)
                    return
                except TelegramError as ex:
                    self.logger.info('image post failed: %r: %r', res, ex)
Ejemplo n.º 3
0
        def ret(self, bot, update):
            self.logger.info('command %s', method.__name__)

            if update.message is not None:
                if (update.message.text and not match_command_user(
                        update.message.text, self.state.username)):
                    self.logger.info('!match_command_user %s' %
                                     update.message.text)
                    return

                chat = update.message.chat
                if chat.type == chat.PRIVATE:
                    perm = permission_private
                else:
                    perm = permission

                perm, reply = check_permission(self, update.message.from_user,
                                               perm)
                if not perm:
                    if reply:
                        self.logger.warning('permission denied: %s',
                                            update.message)
                        update.message.reply_text('permission denied',
                                                  quote=True)
                    return

            try:
                res = method(self, bot, update)
            except (BotError, dice.DiceBaseException) as ex:
                self.logger.warning(ex)
                update.message.reply_text(str(ex), quote=True)
                return
            except Exception as ex:
                self.logger.error(ex)
                update.message.reply_text(repr(ex), quote=True)
                raise

            on_resolve = lambda msg: reply_text(update, msg, True)
            on_reject = on_resolve

            if type_ == CommandType.NONE:
                return res
            elif type_ == CommandType.REPLY_TEXT:
                pass
            elif type_ == CommandType.REPLY_STICKER:
                on_resolve = lambda msg: reply_sticker(update, msg, True)
            elif type_ == CommandType.GET_OPTIONS:
                on_resolve = lambda res: reply_keyboard(update, res)
            elif type_ == CommandType.SET_OPTION:
                on_resolve = lambda msg: reply_callback_query(update, msg)
                on_reject = on_resolve
            elif type_ == CommandType.REPLY_TEXT_PAGINATED:
                on_resolve = lambda msg: reply_text_paginated(
                    update, msg, True)
            else:
                raise ValueError('invalid command type: %s' % type_)

            if res is None:
                self.logger.info('%s: no command', method.__name__)
                return
            if isinstance(res, Promise):
                promise = res
            elif not callable(res):
                on_resolve(res)
                return
            else:
                promise = Promise.wrap(res, update, ptype=PT.MANUAL)
            self.queue.put(promise)
            promise.then(on_resolve, on_reject).wait()