Ejemplo n.º 1
1
def webhook():
    bot = Bot(TOKEN)
    if request.method == 'POST':
        print(request.get_json())
        updates = bot.get_update(request.get_json())
        bot.send_message(updates)
        return 'OK'
Ejemplo n.º 2
1
 def test_unicode(self):
     settings = Settings()
     bot = Bot(settings, None, irc_wrapper=FakeWrapper, logger=nullLogger,
               wrap_irc=False)
     bot.command_managers["#tmp"] = FakeCommandManager()
     # This shouldn't crash
     bot.irc_command("#tmp", "test", "ヽ༼ຈل͜ຈ༽ノ", ["AMENO", "ヽ༼ຈل͜ຈ༽ノ"], 1)
Ejemplo n.º 3
0
    def test_get_random_quote(self):
        dbPath = os.path.join(testPath, '__test_bot_get_random_quote.sqlite')
        self._delete(dbPath)

        settings = Settings()
        settings.DATABASE_PATH = dbPath

        bot = Bot(settings, None, FakeWrapper, logger=nullLogger,
                  wrap_irc=False)
        bot._initialize_models()
        quote_id, quote = bot._get_model("#tmp", "quotes").get_random_quote()

        assert quote_id is None
        assert quote is None
Ejemplo n.º 4
0
    def __init__(self, config):
        """
        Class constructor

        :param config: Dictionary with the configuration variables
        (token,host,database,user,password)
        """
        self.avaible_languages = {
            'Catalan': 'ca', 'English': 'en', 'Spanish': 'es', 'Swedish': 'sv',
            'Asturian': 'ast', 'Galician': 'gl', 'French': 'fr',
            'Italian': 'it',
            'Basque': 'eu', 'Polish': 'pl', 'German': 'de', 'Dutch': 'nl',
            'Czech': 'cs', 'Persian': 'fa', 'Japanese': 'ja', 'Ukrainian': 'uk',
            'Chinese (Taiwan)': 'zh_TW', 'Vietnamese': 'vi', 'Russian': 'ru',
            'Slovak': 'sk', 'Chinese (Hong Kong)': 'zh_HK', 'Hungarian': 'hu'
        }
        self.rtl_languages = ['fa']
        token = config.get('token', '')
        if config:
            self.user = u.User(
                config.get('host', ''), config.get('database', ''),
                config.get('user', ''), config.get('password', ''))

        self.jinja_env = Environment(extensions=['jinja2.ext.i18n'])
        self.jinja_env.filters['url_escape'] = url_escape
        self.language = None
        if token:
            self.bot = Bot(token)
            self.telegram_api = telegram.Bot(token)
Ejemplo n.º 5
0
    def test__del_quote(self):
        dbPath = os.path.join(testPath, '__test_bot_del_quote.sqlite')
        self._delete(dbPath)

        settings = Settings()
        settings.DATABASE_PATH = dbPath

        bot = Bot(settings, None, FakeWrapper, logger=nullLogger,
                  wrap_irc=False)
        bot._initialize_models()
        bot._add_quote("#tmp", "foobar", ["test"])
        bot._add_quote("#tmp", "foobar", ["test2"])
        bot._del_quote("#tmp", "foobar", [1])

        quote_id, quote = bot._get_model("#tmp", "quotes").get_random_quote()

        assert str(quote) == "test2"
Ejemplo n.º 6
0
    def test_blacklist_commands(self):
        dbPath = os.path.join(testPath, '__test_bot_blacklist_commands.sqlite')
        self._delete(dbPath)

        settings = Settings()
        settings.DATABASE_PATH = dbPath

        bot = Bot(settings, None, FakeWrapper, logger=nullLogger,
                  wrap_irc=False)
        bot._initialize_models()
        bot._initialize_blacklists()

        lines = [
            "!blacklist foobar",
            "!blacklist --banTime=15m foobar2",
            "!unblacklist 1",
            "!unblacklist 2",
            "!whitelist foobar",
            "!unwhitelist 1"
        ]

        for line in lines:
            parts = line.split(" ")
            bot.irc_command("#tmp", "mod_user", parts[0][1:], parts[1:], 1)

        assert len(bot.blacklist_managers["#tmp"].blacklist) == 0
        assert len(bot.blacklist_managers["#tmp"].whitelist) == 0
Ejemplo n.º 7
0
def main(br):
    print(time.asctime())
    soul = Bot(br)

    if soul.multiplevillages():
        soul.multiplevillages_handler()
    else:
        soul.botloop()

    #print_cstring( '\nRank: ' + soul.var_game_settings[ 'player' ][ 'rank' ], 'blue' )

    igm = int(soul.var_game_settings['player']['new_igm'])
    if igm:
        print_cstring('You got new ingame messages!'.format(**locals()), 'magenta')
        soul.igm_reader()

    print_cstring('#'*100+'\n', 'yellow')
Ejemplo n.º 8
0
    def test_validate_full_turn(self):
        bot = Bot(username='******', password='******')
        self._init_battle(bot)
        bc = bot.battleclient
        self.assertEqual(bc.name, 'BingsF')
        self._turn_0(bot)
        bot.received_message('>battle-randombattle-245152194\n'
                             '|request|{"forceSwitch":[true],"side":{"name":"BingsF","id":"p2","pokemon":[{"ident":"p2: Haxorus","details":"Haxorus, L77, M","condition":"0 fnt","active":true,"stats":{"atk":271,"def":183,"spa":137,"spd":152,"spe":194},"moves":["earthquake","poisonjab","outrage","substitute"],"baseAbility":"moldbreaker","item":"leftovers","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Grumpig","details":"Grumpig, L83, F","condition":"268/268","active":false,"stats":{"atk":79,"def":156,"spa":197,"spd":230,"spe":180},"moves":["toxic","healbell","lightscreen","psychic"],"baseAbility":"thickfat","item":"lightclay","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Doublade","details":"Doublade, L77, F","condition":"217/217","active":false,"stats":{"atk":214,"def":276,"spa":114,"spd":120,"spe":98},"moves":["shadowclaw","ironhead","swordsdance","sacredsword"],"baseAbility":"noguard","item":"eviolite","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Togekiss","details":"Togekiss, L76, M","condition":"254/254","active":false,"stats":{"atk":81,"def":188,"spa":226,"spd":219,"spe":166},"moves":["airslash","nastyplot","batonpass","healbell"],"baseAbility":"serenegrace","item":"leftovers","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Ninjask","details":"Ninjask, L83, M","condition":"237/237","active":false,"stats":{"atk":197,"def":122,"spa":131,"spd":131,"spe":313},"moves":["substitute","batonpass","protect","xscissor"],"baseAbility":"speedboost","item":"leftovers","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Spiritomb","details":"Spiritomb, L79, F","condition":"209/209","active":false,"stats":{"atk":191,"def":216,"spa":191,"spd":216,"spe":101},"moves":["pursuit","darkpulse","willowisp","shadowsneak"],"baseAbility":"infiltrator","item":"lifeorb","pokeball":"pokeball","canMegaEvo":false}]},"rqid":2,"noCancel":true}')

        bot.received_message('>battle-randombattle-245152194\n'
                             '|move|p2a: Haxorus|Outrage|p1a: Beautifly\n'
                             '|-damage|p1a: Beautifly|11/100\n'
                             '|move|p1a: Beautifly|Bug Buzz|p2a: Haxorus\n'
                             '|-crit|p2a: Haxorus\n'
                             '|-damage|p2a: Haxorus|0 fnt\n'
                             '|-damage|p1a: Beautifly|1/100|[from] item: Life Orb\n'
                             '|faint|p2a: Haxorus')
        self.assertEqual(bc.foe_side.active_pokemon.name, 'beautifly')
        beautifly = bc.foe_side.active_pokemon
        self.assertEqual(beautifly.hp, 1)
        self.assertListEqual(beautifly.moves.keys(), [movedex['bugbuzz']])
        self.assertEqual(beautifly.pp[movedex['bugbuzz']], movedex['bugbuzz'].max_pp - 1)
        haxorus = bc.my_side.active_pokemon
        self.assertEqual(haxorus.hp, 0)
        self.assertEqual(haxorus.status, Status.FNT)
        self.assertTrue(haxorus.is_active)

        bot.received_message('>battle-randombattle-245152194\n'
                             '|request|{"active":[{"moves":[{"move":"Substitute","id":"substitute","pp":16,"maxpp":16,"target":"self","disabled":false},{"move":"Baton Pass","id":"batonpass","pp":64,"maxpp":64,"target":"self","disabled":false},{"move":"Protect","id":"protect","pp":16,"maxpp":16,"target":"self","disabled":false},{"move":"X-Scissor","id":"xscissor","pp":24,"maxpp":24,"target":"normal","disabled":false}]}],"side":{"name":"BingsF","id":"p2","pokemon":[{"ident":"p2: Ninjask","details":"Ninjask, L83, M","condition":"237/237","active":true,"stats":{"atk":197,"def":122,"spa":131,"spd":131,"spe":313},"moves":["substitute","batonpass","protect","xscissor"],"baseAbility":"speedboost","item":"leftovers","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Grumpig","details":"Grumpig, L83, F","condition":"268/268","active":false,"stats":{"atk":79,"def":156,"spa":197,"spd":230,"spe":180},"moves":["toxic","healbell","lightscreen","psychic"],"baseAbility":"thickfat","item":"lightclay","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Doublade","details":"Doublade, L77, F","condition":"217/217","active":false,"stats":{"atk":214,"def":276,"spa":114,"spd":120,"spe":98},"moves":["shadowclaw","ironhead","swordsdance","sacredsword"],"baseAbility":"noguard","item":"eviolite","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Togekiss","details":"Togekiss, L76, M","condition":"254/254","active":false,"stats":{"atk":81,"def":188,"spa":226,"spd":219,"spe":166},"moves":["airslash","nastyplot","batonpass","healbell"],"baseAbility":"serenegrace","item":"leftovers","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Haxorus","details":"Haxorus, L77, M","condition":"0 fnt","active":false,"stats":{"atk":271,"def":183,"spa":137,"spd":152,"spe":194},"moves":["earthquake","poisonjab","outrage","substitute"],"baseAbility":"moldbreaker","item":"leftovers","pokeball":"pokeball","canMegaEvo":false},{"ident":"p2: Spiritomb","details":"Spiritomb, L79, F","condition":"209/209","active":false,"stats":{"atk":191,"def":216,"spa":191,"spd":216,"spe":101},"moves":["pursuit","darkpulse","willowisp","shadowsneak"],"baseAbility":"infiltrator","item":"lifeorb","pokeball":"pokeball","canMegaEvo":false}]},"rqid":3}')
        bot.received_message('>battle-randombattle-245152194\n'
                             '|switch|p2a: Ninjask|Ninjask, L83, M|237/237\n'
                             '|turn|2')
        self.assertEqual(bc.battlefield.turns, 2)
        ninjask = bc.my_side.active_pokemon
        self.assertEqual(ninjask.name, 'ninjask')
        self.assertTrue(ninjask.is_active)
        self.assertFalse(haxorus.is_active)
Ejemplo n.º 9
0
    def test_update_global_value(self):
        dbPath = os.path.join(testPath,
                              '__test_bot_update_global_value.sqlite')
        self._delete(dbPath)

        settings = Settings()
        settings.DATABASE_PATH = dbPath

        bot = Bot(settings, None, FakeWrapper, logger=nullLogger,
                  wrap_irc=False)
        bot._initialize_models()
        bot.update_global_value("#tmp", "test", {"key1": "value1"})

        data = bot._load_channel_data("#tmp")

        assert data["test"]["key1"] == "value1"
Ejemplo n.º 10
0
    def test_quote_suffix(self):
        dbPath = os.path.join(testPath, '__test_bot_quote_suffix.sqlite')
        self._delete(dbPath)

        settings = Settings()
        settings.QUOTE_AUTO_SUFFIX = True

        now = datetime.now()
        expected_suffix = " - {streamer} @ {year}-{month:02}-{day:02}".format(
            streamer=settings.CHANNEL_LIST["#tmp"],
            year=int(now.strftime("%Y")),
            month=int(now.strftime("%m")),
            day=int(now.strftime("%d"))
        )

        bot = Bot(settings, None, FakeWrapper, logger=nullLogger,
                  wrap_irc=False)
        bot._initialize_models()
        bot._add_quote("#tmp", "foobar", ["test"], timestamp=now)
        quote_id, quote = bot._get_model("#tmp", "quotes").get_random_quote()

        expected = "test" + expected_suffix

        assert quote == expected
Ejemplo n.º 11
0
def setup(bot: Bot) -> None:
    """Load the Superstarify cog."""
    bot.add_cog(Superstarify(bot))
Ejemplo n.º 12
0
class OsmBot(object):
    """
        Class that represents the OsmBot
    """
    def __init__(self, config):
        """
        Class constructor

        :param config: Dictionary with the configuration variables
        (token,host,database,user,password)
        """
        self.avaible_languages = {
            'Catalan': 'ca', 'English': 'en', 'Spanish': 'es', 'Swedish': 'sv',
            'Asturian': 'ast', 'Galician': 'gl', 'French': 'fr',
            'Italian': 'it',
            'Basque': 'eu', 'Polish': 'pl', 'German': 'de', 'Dutch': 'nl',
            'Czech': 'cs', 'Persian': 'fa', 'Japanese': 'ja', 'Ukrainian': 'uk',
            'Chinese (Taiwan)': 'zh_TW', 'Vietnamese': 'vi', 'Russian': 'ru',
            'Slovak': 'sk', 'Chinese (Hong Kong)': 'zh_HK', 'Hungarian': 'hu'
        }
        self.rtl_languages = ['fa']
        token = config.get('token', '')
        if config:
            self.user = u.User(
                config.get('host', ''), config.get('database', ''),
                config.get('user', ''), config.get('password', ''))

        self.jinja_env = Environment(extensions=['jinja2.ext.i18n'])
        self.jinja_env.filters['url_escape'] = url_escape
        self.language = None
        if token:
            self.bot = Bot(token)
            self.telegram_api = telegram.Bot(token)

    def load_language(self, language):
        """
        Function to load the language of the answer

        :param language: code of the language
        :return: None
        """
        self.language = language
        lang = gettext.translation('messages', localedir='./bot/locales/', languages=[language, 'en'])
        lang.install()
        self.jinja_env.install_gettext_translations(gettext.translation('messages', localedir='./bot/locales/',languages=[language, 'en']))

    def get_is_rtl(self):
        """
        Returns if the actual language is RTL

        :return: Boolean to indicate if the language is RTL
        """
        return  self.language in self.rtl_languages

    def get_language(self):
        """
        Retunrs the actual language code

        :return: str Language code
        """
        return self.language

    def get_languages(self):
        """
        Returns the avaible languages

        :return: Dict with the name of the language as a key and code as a value
        """
        return self.avaible_languages

    def get_rtl_languages(self):
        """
        Returns the list of RTL langauges

        :return: list of the code of RTL languages
        """
        return self.rtl_languages

    def _get_template(self, template_name):
        """
        Returns the text of a template

        :param template_name: The template name as a str
        :return: str with the text of the template
        """
        url = os.path.join('bot/templates', template_name)
        with open(url) as f:
            template_text = f.read()
        return self.jinja_env.from_string(template_text)

    def set_only_mention(self, message, user_id, chat_id, user, group):
        """
        Manages the set only mention requests

        :param message: Str with the message (Yes or No)
        :param user_id: User id
        :param chat_id: Chat ud
        :param user: Dict with user configuration
        :param group: Boolean to indicate if is a group
        :return: None
        """
        onlymentions = message == 'Yes'
        if group:
            user.set_field(chat_id, 'onlymentions', onlymentions, group=group)
            user.set_field(chat_id, 'mode', 'normal', group=group)
        else:
            user.set_field(user_id, 'onlymentions', onlymentions, group=group)
            user.set_field(user_id, 'mode', 'normal', group=group)
        if not onlymentions:
            text = self._get_template('only_mention.md').render()
            m = Message(chat_id, text)
            self.bot.sendMessage(m)
        else:
            text = self._get_template('answer_always.md').render(is_rtl=self.get_is_rtl())
            m = Message(chat_id, text)
            self.bot.sendMessage(m)
        return []

    def set_language_command(self, message, user_id, chat_id, u, group=False):
        """
        Answers the language command

        :param message: Message
        :param user_id: User identifier
        :param chat_id: Chat identifier
        :param u: User object
        :param group: Boolean to indicate if its a group
        :return: None
        """
        if message in self.get_languages():
            if group:
                u.set_field(chat_id, 'lang', self.get_languages()[message], group=group)
                u.set_field(chat_id, 'mode', 'normal', group=group)
            else:
                u.set_field(user_id, 'lang', self.get_languages()[message], group=group)
                u.set_field(user_id, 'mode', 'normal', group=group)
            self.load_language(self.get_languages()[message])
            text = self._get_template('new_language.md').render(is_rtl=self.get_is_rtl())
            m = Message(chat_id, text)
            self.bot.sendMessage(m)
            return []
        else:
            if group:
                u.set_field(chat_id, 'mode', 'normal', group=True)
            else:
                u.set_field(user_id, 'mode', 'normal')
            temp = self._get_template('cant_talk_message.md')
            text = temp.render()
            message = Message(chat_id, text)
            self.bot.sendMessage(message)
            return []

    def answer_command(self, chat_id, user):
        """
        Answers the only answer command

        :param message: User message
        :param user_id: User identifier
        :param chat_id: Chat id
        :param user: User object
        :return:
        """
        k = ReplyKeyboardMarkup(['Yes', 'No'], one_time_keyboard=True)
        text = self._get_template('question_mention.md').render()
        m = Message(chat_id, text, reply_markup=k)
        self.bot.sendMessage(m)
        user.set_field(chat_id, 'mode', 'setonlymention', group=True)

    def language_command(self, message, user_id, chat_id, user, group=False):
        """
        Handles the Language command and sends the lis of languages

        :param message: the message sent by the user
        :param user_id: User id
        :param chat_id: Chat id
        :param user: Dict with user configuration
        :param group: Indicates if the message comes from a group
        :return: None
        """
        k = ReplyKeyboardMarkup(
            sorted(self.get_languages().keys()),
            one_time_keyboard=True)
        text = self._get_template('language_answer.md').render()
        m = Message(chat_id, text, reply_markup=k)
        self.bot.sendMessage(m)
        if group:
            user.set_field(chat_id, 'mode', 'setlanguage', group=group)
        else:
            user.set_field(user_id, 'mode', 'setlanguage', group=group)

    def settings_command(self, message, user_id, chat_id, u, group=False):
        """
        Answers the settings command

        :param message: User message
        :param user_id: User identifier
        :param chat_id: Chat id
        :param u: Uers object
        :param group: Boolen to indicate if it's on a group
        :return: None
        """
        k = ReplyKeyboardMarkup(['Language'], one_time_keyboard=True)
        if group:
            text = self._get_template('question_only_mention.md').render()
            k.addButton(text)
        text = self._get_template('configure_question.md').render()
        m = Message(chat_id, text, reply_markup=k)
        self.bot.sendMessage(m)
        if group:
            identifier = chat_id
        else:
            identifier = user_id
        u.set_field(identifier, 'mode', 'settings', group=group)

    def legend_command(self, message, chat_id):
        """
        Answers the legend commands

        :param message: Legend filter message
        :param chat_id: Chat identifier
        :return: None
        """
        filt = message[8:]
        selected_keys = []
        for key in typeemoji.keys():
            if filt in key:
                selected_keys.append(key)
        selected_keys = sorted(selected_keys)
        temp = self._get_template('legend_command.md')
        template_params = {
            'typeemoji': typeemoji,
            'keys': selected_keys,
            'is_rtl': self.get_is_rtl()
        }
        text = temp.render(**template_params)
        m = Message(chat_id, text)
        self.bot.sendMessage(m)
        if len(selected_keys) > 50:
            text = self._get_template('easter_egg.md').render()
            m = Message(chat_id, text)
            self.bot.sendMessage(m)
        elif len(selected_keys) == 0:
            text = self._get_template('no_emoji.md').render()
            m = Message(chat_id, text)
            self.bot.sendMessage(m)

    def search_command(self, message, user_config, chat_id):
        """
        Answers the search commands

        :param message: User message
        :param user_config: User configuration as a dict
        :param chat_id: Identifier of the chat
        :return: None
        """
        import pynominatim
        t = ''
        search = message[8:].replace('\n', '').replace('\r', '')
        nom = pynominatim.Nominatim()
        results = nom.query(search, acceptlanguage=user_config['lang'], addressdetails=True)
        if not results:
            template = self._get_template('not_found_message.md')
            text = template.render(search=search)
            m = Message(chat_id, text, parse_mode='Markdown')
            self.bot.sendMessage(m)
            return None
        else:
            t = _('Results for') + ' "{0}":\n\n'.format(search)
            for result in results[:10]:
                if 'osm_id' in result:
                    if result['osm_type'] == 'relation':
                        element_type = 'rel'
                    elif result['osm_type'] == 'way':
                        element_type = 'way'
                    elif result['osm_type'] == 'node':
                        element_type = 'nod'
                    try:
                        if result['osm_type'] == 'relation':
                            osm_data = getData(result['osm_id'], element_type)
                        else:
                            osm_data = getData(result['osm_id'])
                    except Exception:
                        osm_data = None
                else:
                    osm_data = None
                type = result['class'] + ':' + result['type']
                if 'address' in result:
                    country = result['address'].get('country_code', '').upper()
                if type in typeemoji and country in emojiflag:
                    t += emojiflag[country][0] + typeemoji[result['class'] + ':' + result['type']] + " " + result['display_name'] + '\n'
                elif country in emojiflag:
                    t += emojiflag[country][0] + '\xE2\x96\xB6 ' + result['display_name'] + '\n'
                elif type in typeemoji:
                    t += typeemoji[result['class'] + ':' + result['type']] + " " + result['display_name'] + '\n'
                else:
                    t += '\xE2\x96\xB6 ' + result['display_name']+'\n'
                t += '\xF0\x9F\x93\x8D [' + _('Map') + '](http://www.openstreetmap.org/?minlat={0}&maxlat={1}&minlon={2}&maxlon={3}&mlat={4}&mlon={5})\n'.format(result['boundingbox'][0],result['boundingbox'][1],result['boundingbox'][2],result['boundingbox'][3],result['lat'],result['lon'])
                if osm_data is not None and ('phone' in osm_data['tag'] or 'contact:phone' in osm_data['tag']):
                    if 'osm_type' in result and result['osm_type'] == 'node':
                        t += _('More info') + ' /detailsnod{0}\n'.format(result['osm_id'])
                    elif 'osm_type' in result and result['osm_type'] == 'way':
                        t += _('More info')+' /detailsway{0}\n'.format(result['osm_id'])
                    elif 'osm_type' in result and result['osm_type'] == 'relation':
                        t += _('More info') + ' /detailsrel{0}\n'.format(result['osm_id'])
                    else:
                        t += '\n' + _('More info') + ' /details{0}'.format(result['osm_id'])
                    t += _("Phone") + " /phone{0}{1}".format(element_type, result['osm_id']) + "\n\n"
                else:
                    if 'osm_id' in result:
                        if 'osm_type' in result and result['osm_type'] == 'node':
                            t += _('More info') + ' /detailsnod{0}\n\n'.format(result['osm_id'])
                        elif 'osm_type' in result and result['osm_type'] == 'way':
                            t += _('More info')+' /detailsway{0}\n\n'.format(result['osm_id'])
                        elif 'osm_type' in result and result['osm_type'] =="relation":
                            t += _('More info') + ' /detailsrel{0}\n\n'.format(result['osm_id'])
                        else:
                            t += _('More info') + ' /details{0}\n\n'.format(result['osm_id'])

            t += '\xC2\xA9' + _('OpenStreetMap contributors') + '\n'
        m = Message(chat_id, t, parse_mode='Markdown',
                    disable_web_page_preview=True)
        self.bot.sendMessage(m)

    def pretty_tags(self, data, identificador, type, user_config, chat_id, lat=None, lon=None, link=False):
        """
        Function that generates a pretty answer from a osm data

        :param data: OSM data
        :param identificador: User identifier
        :param type: Type of element
        :param user_config: Dict of the user configuration
        :param chat_id: Chat identifier
        :param lat:
        :param lon:
        :param link:
        :return: String with the answer
        """
        preview = False
        tags = {}
        if 'tag' in data:
            tags = data['tag']
        elif 'elements' in data:
            tags = data['elements']
            min_dist = None
            nearest = None
            for element in tags:
                if 'lat' in element and 'lon' in element:
                    element_lat = element['lat']
                    element_lon = element['lon']

                    dist = math.sqrt((element_lat - lat)**2 + (element_lon - lon)**2)
                elif 'center' in element:
                    element_lat = element['center']['lat']
                    element_lon = element['center']['lon']
                    dist = math.sqrt((element_lat - lat)**2 + (element_lon - lon)**2)
                if min_dist is None:
                    identificador = element['id']
                    if element['type'] == 'node':
                        type = 'nod'
                    elif element['type'] == 'way':
                        type = 'way'
                    else:
                        type = 'rel'
                    nearest = element
                    min_dist = dist
                elif dist < min_dist:
                    nearest = element
                    min_dist = dist
                    identificador = element['id']
                    if element['type'] == 'node':
                        type = 'nod'
                    elif element['type'] == 'way':
                        type = 'way'
                    else:
                        type = 'rel'
            if nearest:
                tags = nearest['tags']
            else:
                text = self._get_template('not_found_overpass_message.md')
                m = Message(
                    chat_id,
                    text,
                    disable_web_page_preview=True
                )
                self.bot.sendMessage(m)
        t = ''

        if 'name' in tags:
            if not user_config['lang_set']:
                t += ' ' + _('Tags for') + ' ' + str(tags['name']) + '\n\n'
            else:
                if 'name:' + self.get_language() in tags:
                    t += ' ' + _('Tags for') + ' ' + str(tags['name:'+ self.get_language()]) + '\n\n'
                else:
                    t += _('Tags for') + ' ' + str(tags['name']) + '\n\n'
        if tags.get('admin_level') == '2' and "Europe" in tags.get("is_in:continent", ''):
            t += '\xF0\x9F\x8C\x8D ' + _('European country') + "\n"
        elif tags.get('admin_level') == '2' and "Europa" in tags.get('is_in:continent', ''):
            t += "\xF0\x9F\x8C\x8D " + _("European country") + "\n"
        elif tags.get('admin_level') == '2' and "Africa" in tags.get('is_in:continent', ''):
            t += "\xF0\x9F\x8C\x8D " + _("African country") + "\n"
        elif tags.get('admin_level') == '2' and "South America" in tags.get('is_in:continent', ''):
            t += "\xF0\x9F\x8C\x8E " + _("South american country") + "\n"
        elif tags.get('admin_level') == '2' and "Latin America" in tags.get('is_in:continent', ''):
            t += "\xF0\x9F\x8C\x8E " + _("South american country") + "\n"
        elif tags.get('admin_level') == '2' and "America del Sur" in tags.get('is_in:continent', ''):
            t += "\xF0\x9F\x8C\x8E " + _("South american country") + "\n"
        elif tags.get('admin_level') == '2' and "North America" in tags.get('is_in:continent', ''):
            t += "\xF0\x9F\x8C\x8E " + _("North american country") + "\n"
        elif tags.get('admin_level') == '2' and "Amérique du Nord" in tags.get('is_in:continent', ''):
            t += "\xF0\x9F\x8C\x8E " + _("North american country") + "\n"
        elif tags.get('admin_level') == '2' and "Central America" in tags.get('is_in:continent', ''):
            t += "\xF0\x9F\x8C\x8E " + _("Central american country") + "\n"
        elif tags.get('admin_level') == '2' and "América" in tags.get("is_in:continent", ''):
            t += "\xF0\x9F\x8C\x8E " + _("American country") + "\n"
        elif tags.get('admin_level') == '2' and "America" in tags.get("is_in:continent", ''):
            t += "\xF0\x9F\x8C\x8E " + _("American country") + "\n"
        elif tags.get('admin_level') == '2' and "Asia" in tags.get("is_in:continent", ''):
            t += "\xF0\x9F\x8C\x8F " + _("Asian country") + "\n"
        elif tags.get('admin_level') == '2' and "Oceania" in tags.get("is_in:continent", ''):
            t += "\xF0\x9F\x8C\x8F " + _("Oceanian country") + "\n"
        elif tags.get('admin_level') == '2' and "Australia" in tags.get("is_in:continent", ''):
            t += "\xF0\x9F\x8C\x8F " + _("Oceanian country") + "\n"
        elif tags.get('admin_level') == '2' and "Eurasia" in tags.get("is_in:continent", ''):
            t += "\xF0\x9F\x8C\x8D \xF0\x9F\x8C\x8F " + _("Eurasian country") + "\n"
        elif tags.get('admin_level') == '2' and "Europe; Asia" in tags.get("is_in:continent", ''):
            t += "\xF0\x9F\x8C\x8D \xF0\x9F\x8C\x8F " + _("Eurasian country") + "\n"
        if 'flag' in tags:
            t += '\xF0\x9F\x9A\xA9 {}\n'.format(tags.get('flag'))
        if 'currency' in tags:
            t += "\xF0\x9F\x92\xB5 " + str(tags['currency']) + "\n"
        if 'timezone' in tags:
            t += "\xF0\x9F\x95\x92\xF0\x9F\x8C\x90 " + str(tags['timezone']) + "\n"
        if 'addr:housenumber' and 'addr:street' in tags:
            t += '\xF0\x9F\x93\xAE ' + tags['addr:street'] + ', ' + tags['addr:housenumber'] + '\n'
        else:
            if 'addr:housenumber' in tags:
                t += '\xF0\x9F\x93\xAE ' + tags['addr:housenumber'] + '\n'
            if 'addr:street' in tags:
                t += '\xF0\x9F\x93\xAE ' + tags['addr:street'] + '\n'
        if 'addr:city' in tags:
            t += tags['addr:city'] + '\n'
        if 'addr:country' in tags:
            t += tags['addr:country'] + '\n'
        if 'phone' in tags:
            t += '\xF0\x9F\x93\x9E ' + str(tags['phone']) + '\n'
        if 'contact:phone' in tags:
            t += '\xF0\x9F\x93\x9E ' + str(tags['contact:phone']) + '\n'
        if 'fax' in tags:
            t += "\xF0\x9F\x93\xA0 " + str(tags['fax']) + "\n"
        if 'email' in tags:
            t += "\xE2\x9C\x89 " + str(tags['email']) + "\n"
        if 'website' in tags:
            preview = True
            t += "\xF0\x9F\x8C\x8D " + str(tags['website']) + "\n"
        if 'opening_hours' in tags:
            t += "\xF0\x9F\x95\x9E " + str(tags['opening_hours']) + "\n"
        if 'internet_access' in tags:
            t += "\xF0\x9F\x93\xB6 " + str(tags['internet_access']) + "\n"
        if 'wheelchair' in tags:
            t += "\xE2\x99\xBF " + str(tags['wheelchair']) + "\n"
        if 'population' in tags:
            if 'population:date' in tags:
                t += "\xF0\x9F\x91\xAA " + '{:,}'.format(int(tags['population'])) + " " + _("inhabitants") + ' ' + _('at') + ' '+ tags['population:date'] + "\n"
            else:
                t += "\xF0\x9F\x91\xAA " + '{:,}'.format(int(tags['population'])) + " " + _("inhabitants") + "\n"

        if 'ele' in tags:
            t += "\xF0\x9F\x93\x8F " + str(tags['ele']) + " " + _("meters") + "\n"
        if 'wikidata' in tags:
            preview = True
            t += "\xF0\x9F\x93\x97 https://www.wikidata.org/wiki/{0}".format(urllib.quote(tags["wikidata"])) + "\n"
        if 'wikipedia' in tags:
            preview = True
            if ":" in tags["wikipedia"]:
                lang = str(tags['wikipedia'].split(":")[0])
                term = str(tags['wikipedia'].split(":")[1])
                t += "\xF0\x9F\x93\x92 http://{0}.wikipedia.org/wiki/{1}".format(lang, urllib.quote(term)) + "\n"
            else:
                t += "\xF0\x9F\x93\x92 http://wikipedia.org/wiki/{0}".format(urllib.quote(tags["wikipedia"])) + "\n"

        t += '\n' +_('Raw data:') + ' /raw' + str(type) + str(identificador) + '\n'
        if link:
            if type == 'nod':
                t += 'http://osm.org/node/{0}\n'.format(str(identificador))
            elif type == 'way':
                t += 'http://osm.org/way/{0}\n'.format(str(identificador))
            else:
                t += 'http://osm.org/relation/{0}\n'.format(str(identificador))
        t += '\n\xC2\xA9 ' + _('OpenStreetMap contributors') + '\n'

        m = Message(chat_id, t, disable_web_page_preview=(not preview))
        self.bot.sendMessage(m)

    def map_command(self, message, chat_id, user_id, user, zoom=None, imgformat='png', lat=None, lon=None):
        """
        Answers the map command

        :param message:  Map command with parameters
        :param chat_id: Chat identifier
        :param user_id: User identifier
        :param user: User object
        :param zoom: Zoom level for the map
        :param imgformat: Image format
        :param lat: latitude of the center of the map
        :param lon: longitude of the center of the map
        :return:
        """
        zoom_halfside = {
            1: 2000,
            2: 95,
            3: 70,
            4: 55,
            5: 50,
            6: 35,
            7: 25,
            8: 18,
            9: 14,
            10: 8,
            11: 6,
            12: 4,
            13: 2,
            14: 1,
            15: 0.5,
            16: 0.25,
            17: 0.15,
            18: 0.07,
            19: 0.04
        }
        nom = pynominatim.Nominatim()
        response = []
        message = message[4:]
        if lat is not None and lon is not None:
            if zoom:
                halfside = zoom_halfside[zoom]
            else:
                halfside = 0.1
            bbox = genBBOX(lat, lon, halfside)
            try:
                data = download(bbox, _, imageformat=imgformat, zoom=zoom)
            except ValueError as v:
                response.append(Message(chat_id, v.message))
            else:
                signature = '©' + _('OSM contributors')
                if imgformat == 'pdf':
                    self.bot.sendDocument(chat_id, data, 'map.pdf')
                elif imgformat == 'jpeg':
                    self.bot.sendPhoto(chat_id, data, 'map.jpg', signature)
                elif imgformat == 'png':
                    self.bot.sendPhoto(chat_id, data, 'map.png', signature)
            user.set_field(user_id, 'mode', 'normal')
        else:
            if re.match(" ?(png|jpg|pdf)? ?(\d?\d)?$", message):
                m = re.match(" ?(?P<imgformat>png|jpg|pdf)? ?(?P<zoom>\d{0,2})$", message)
                zoom = m.groupdict()["zoom"]
                imgformat = m.groupdict()["imgformat"]
                m = Message(
                    chat_id,
                    _('Please send me your location') + " \xF0\x9F\x93\x8D " +
                    _("to receive the map") + '.\n' +
                    _("You can do it with the Telegram paperclip button") +
                    " \xF0\x9F\x93\x8E."
                            )
                response.append(m)
                if imgformat is None:
                    imgformat = 'png'
                if zoom == '':
                    zoom = 19
                user.set_field(user_id, 'format', imgformat)
                user.set_field(user_id, 'zoom', zoom)
                user.set_field(user_id, 'mode', 'map')

            elif re.match(" -?\d+(\.\d*)?,-?\d+(\.\d*)? (png|jpg|pdf)? ?(\d?\d)?", message):
                m = re.match(" (?P<lat>-?\d+(\.\d*)?),(?P<lon>-?\d+(\.\d*)?) ?(?P<imgformat>png|jpeg|pdf)? ?(?P<zoom>\d{0,2})",message)
                lat = float(m.groupdict()['lat'])
                lon = float(m.groupdict()['lon'])
                imgformat = m.groupdict()['imgformat']
                zoom = m.groupdict()['zoom']
                bbox = genBBOX(lat, lon, 0.1)
                if imgformat is None:
                    imgformat = 'png'
                if zoom == '':
                    zoom = 19
                try:
                    user_config = user.get_user(user_id, group=False)
                    lang = gettext.translation('messages', localedir='./bot/locales/', languages=[user_config['lang'], 'en'])
                    data = download(bbox, lang.gettext, imageformat=imgformat, zoom=zoom)
                except ValueError as v:
                    response.append(v.message)
                else:
                    if imgformat == 'pdf':
                        self.bot.sendDocument(chat_id, data, 'map.pdf')
                    elif imgformat == 'jpeg':
                        self.bot.sendPhoto(
                            chat_id, data, 'map.jpg', '©' + _('OSM contributors'))
                    elif imgformat == 'png':
                        self.bot.sendPhoto(
                            chat_id, data, 'map.png', '©' + _('OSM contributors'))
            elif re.match(" -?\d+(\.\d*)?,-?\d+(\.\d*)?,-?\d+(\.\d*)?,-?\d+(\.\d*)? ?(png|jpeg|pdf)? ?\d{0,2}",message):
                m = re.match(" (?P<bb1>-?\d+(\.\d*)?),(?P<bb2>-?\d+(\.\d*)?),(?P<bb3>-?\d+(\.\d*)?),(?P<bb4>-?\d+(\.\d*)?) ?(?P<format>png|jpg|pdf)? ?(?P<zoom>\d{0,2})",message)
                if m is not None:
                    bbox1 = m.groupdict()['bb1']
                    bbox2 = m.groupdict()['bb2']
                    bbox3 = m.groupdict()['bb3']
                    bbox4 = m.groupdict()['bb4']
                    imgformat = m.groupdict()['format']
                    zoom = m.groupdict()['zoom']
                    if imgformat is None:
                        imgformat = 'png'
                    if zoom == '':
                        zoom = 19
                    try:
                        data = download(
                            [bbox1, bbox2, bbox3, bbox4], _,
                            imgformat, zoom=zoom)
                    except ValueError as v:
                        response.append(v.message)
                    else:
                        signature = '©' + _('OSM contributors')
                        if imgformat == 'pdf':
                            self.bot.sendDocument(chat_id, data, 'map.pdf')
                        elif imgformat == 'jpeg':
                            self.bot.sendPhoto(
                                chat_id, data, 'map.jpg', signature)
                        elif imgformat == 'png':
                            self.bot.sendPhoto(
                                chat_id, data, 'map.png',signature)
                else:
                    template = self._get_template('cant_understand_message.md')
                    text = template.render()
                    response.append(text)
            else:
                res = nom.query(message)
                if res:
                    bbox = res[0]['boundingbox']
                    auto_scale = getScale([bbox[0], bbox[2], bbox[1], bbox[3]])
                    try:
                        data = download([bbox[2], bbox[0], bbox[3], bbox[1]], _, scale=auto_scale)
                    except ValueError as v:
                        m = Message(chat_id, v.message)
                        response.append(m)
                    else:
                        signature = '©' + _('OSM contributors')
                        self.bot.sendPhoto(chat_id, data, 'map.png', signature)
                else:
                    temp = self._get_template('cant_understand_message.md')
                    text = temp.render()
                    m = Message(chat_id, text)
                    response.append(m)
        self.bot.sendMessage(response)

    def phone_command(self, message, chat_id):
        id = message[9:]
        element_type = message[6: 9]
        osm_data = getData(id, element_type)
        if 'phone' in osm_data['tag']:
            template = self._get_template('phone_message.md')
            text = template.render(phone=osm_data['tag']['phone'], is_rtl=self.get_is_rtl())
            m = Message(chat_id, text)
            self.bot.sendMessage(m)
        if 'contact:phone' in osm_data['tag'] and tags.get('phone') != tags.get('contact:phone'):
            template = self._get_template('phone_message.md')
            text = template.render(phone=osm_data['tag']['contact:phone'], is_rtl=self.get_is_rtl())
            m = Message(chat_id, text)
            self.bot.sendMessage(m)

    @staticmethod
    def clean_message(message):
        """
        Function that cleans a message removing de @osmbot mention and \r,\n

        :param message: Message as string
        :return: Cleaned message as string
        """
        if message.startswith('@osmbot'):
            message = message[8:]
        message = message.replace('\n', '').replace('\r', '')
        return message

    def details_command(self, message, user_config, chat_id):
        """
        Answers the details command

        :param message: Message with de details command as str
        :param user_config: User config as a dict
        :param chat_id: Chat id
        :return: None
        """
        preview = False
        result = re.match('/details\s*(?P<type>nod|way|rel)\s*(?P<id>\d*)', message)
        if not result:
            text = self._get_template('not_found_id_message.md').render()
            m = Message(
                chat_id,
                text,
                disable_web_page_preview=(not preview)
            )
            self.bot.sendMessage(m)
            return None
        params = result.groupdict()
        element_type = params['type']
        identifier = params['id']
        if element_type in ['nod', 'way', 'rel']:
            osm_data = getData(identifier, geom_type=element_type)
        else:
            osm_data = getData(identifier)
        if osm_data is None:
            text = self._get_template('not_found_id_message.md').render()
            m = Message(
                chat_id,
                text,
                disable_web_page_preview=(not preview)
            )
            self.bot.sendMessage(m)
        else:
            if osm_data['tag'] == {}:
                text = self._get_template('not_recognized_message.md').render()
                m = Message(chat_id, text)
                self.bot.sendMessage(m)
            else:
                preview = False
                if 'website' in osm_data['tag'] or 'wikidata' in osm_data['tag'] or 'wikipedia' in osm_data['tag']:
                    preview = True
                text = self._get_template('details_message.md').render(data=osm_data, type=element_type, identifier=identifier, user_config=user_config,is_rtl=self.get_is_rtl())
                m = Message(chat_id, text, disable_web_page_preview=(not preview), parse_mode='Markdown')
                self.bot.sendMessage(m)

    def nearest_command(self, message, chat_id, user_id, user, config=None, lat=None, lon=None, type=None, distance=None):
        """
        Answers nearest command if lat & lon are none asks for position

        :param message: User mesage
        :param chat_id: Chat id
        :param user_id: User id
        :param user: User object
        :param config: User configuration
        :param lat: User latitude
        :param lon: User longitude
        :param type: Element type
        :param distance: Range of distance to search
        :return: None
        """
        if lat is not None and lon is not None:
            api = overpass.API()
            query = type_query[type.encode('unicode_escape')]['query']
            bbox = 'around:{0},{1},{2}'.format(distance, lat, lon)
            query = query.format(bbox)
            query = '({});out body center;'.format(query)
            data = api.Get(query.format(bbox))

            user.set_field(user_id, 'mode', 'normal')
            self.pretty_tags(data, chat_id, type, config, chat_id, lat=lat, lon=lon, link=True)
            return None
        else:
            t = message.replace('/nearest', '').strip().split(' ')[0]
            if t.encode('unicode_escape') not in type_query:
                text = self._get_template('not_implemented_message.md').render()
                m = Message(chat_id, text)
                self.bot.sendMessage(m)
                return None
            
            if len(message) == 3:
                if message[2].lower()[-2:] == 'km':
                    distance = int(message[:-1]) * 1000
                elif message[2].lower()[-1:] == 'm':
                    distance = int(message[:-1])
                else:
                    distance = int(message)
            else:
                distance = type_query[t.encode('unicode_escape')]['distance']
                user.set_field(user_id, 'type', unicode(t))
                user.set_field(user_id, 'distance', str(distance))
                user.set_field(user_id, 'mode', 'nearest')
            text = self._get_template('send_location_message.md').render()
            m = Message(chat_id, text)
            self.bot.sendMessage(m)
            return None

    def raw_command(self, message, chat_id):
        """
        Answers the raw command

        :param message: User message
        :param chat_id: Chat id
        :return: None
        """

        type = message[4:7]
        if type in ['nod', 'way', 'rel']:
            identificador = message[7:]
            osm_data = getData(identificador, geom_type=type)
        else:
            identificador = message[7:].strip()
            osm_data = getData(identificador)
        if osm_data is None:
            text = self._get_template('not_found_id_message.md').render()
            m = Message(chat_id, text)
            self.bot.sendMessage(m)
        else:
            if osm_data['tag'] == {}:
                m = Message(
                    chat_id,
                    _("Sorry, but now I can't recognize tags for this element, perhaps with my new features I will do it") +
                    ' \xF0\x9F\x98\x8B'
                )
                self.bot.sendMessage(m)
            else:
                parts = 1
                max_parts = 1+len(osm_data['tag'])/20
                if 'name' in osm_data['tag']:
                    t = '\xE2\x9C\x8F '+_('Raw data for')+' {0} ({1}/{2})\n\n'.format(osm_data['tag']['name'], parts, max_parts)
                else:
                    t = '\xE2\x9C\x8F '+_('Raw data') + '({0}/{1})\n\n'.format(parts, max_parts)
                i = 0
                response = []
                for tag in sorted(osm_data['tag'].keys()):
                    t += "{0} = {1}\n".format(tag, osm_data['tag'][tag])
                    i += 1
                    if i >= 20:
                        t += "\n\xC2\xA9 " + _("OpenStreetMap contributors")
                        m = Message(chat_id, t)
                        response.append(m)
                        i = 0
                        parts += 1
                        if 'name' in osm_data['tag']:
                            t = '\xE2\x9C\x8F '+_('Raw data for')+' {0} ({1}/{2})\n\n'.format(osm_data['tag']['name'], parts, max_parts)
                        else:
                            t = '\xE2\x9C\x8F '+_('Raw data') + '({0}/{1})\n\n'.format(parts, max_parts)
                t += '\n\xC2\xA9 ' + _('OpenStreetMap contributors')
                m = Message(chat_id, t)
                response.append(m)
                self.bot.sendMessage(response)

    def answer_inline(self, message, query, user_config):
        """
        Answers the inline queryes

        :param message: User inline search
        :param query: Dict with the full query as a dict
        :param user_config: User configuration as a dict
        :return: None
        """

        nom = pynominatim.Nominatim()
        is_rtl = user_config['lang'] in self.get_rtl_languages()
        search_results = nom.query(message, acceptlanguage=user_config['lang'])
        temp = self._get_template('inline_article.md')
        inline_query_id = query['inline_query']['id']
        results = []
        if search_results:
            for index, r in enumerate(search_results[:7]):
                element_type = ''
                if r.get('osm_type', '') == 'node':
                    element_type = 'nod'
                elif r.get('osm_type', '') == 'way':
                    element_type = 'way'
                elif r.get('osm_type', '') == 'relation':
                    element_type = 'rel'
                osm_data = getData(r['osm_id'], geom_type=element_type)
                params = {
                    'data': osm_data, 'type': element_type,
                    'identifier': r['osm_id'], 'user_config': user_config,
                    'is_rtl': is_rtl, 'nominatim_data': r
                }
                if osm_data:
                    text = temp.render(**params)
                name_lang = 'name:{}'.format(user_config['lang'])
                if name_lang in osm_data['tag']:
                    results.append(InlineQueryResultArticle(
                        id=uuid4(),
                        title=osm_data['tag'][name_lang],
                        description=r['display_name'],
                        input_message_content=InputTextMessageContent(
                            text,
                            parse_mode=ParseMode.MARKDOWN)))
                else:
                    results.append(InlineQueryResultArticle(
                        id=uuid4(),
                        title=osm_data['tag']['name'],
                        description=r['display_name'],
                        input_message_content=InputTextMessageContent(
                            text,
                            parse_mode=ParseMode.MARKDOWN)))

        self.telegram_api.answerInlineQuery(inline_query_id, results, is_personal=True,cache_time=86400)
        #self.bot.answerInlineQuery(inline_query_id, results, is_personal=True, cache_time=86400)

    def answer_message(self, message, query, chat_id, user_id, user_config, is_group, user, message_type):
        """
        Function that handles messages and sends to the concrete functions

        :param message: User message
        :param query: Dict with the full query
        :param chat_id: Chat id
        :param user_id: User id
        :param user_config: Dict with the user config
        :param is_group: Boolean that indicates if the message comes from
        a group
        :param user: User object
        :param message_type: Type of message
        :return: None
        """
        if message_type == 'inline':
            self.answer_inline(message, query, user_config)
        else:
            preview = False
            response = []
            if message.lower() == '/start':
                user.set_field(chat_id, 'mode', 'normal')
                text = self._get_template('start_answer.md').render()
                m = Message(
                    chat_id, text,
                    disable_web_page_preview=(not preview),
                    parse_mode='Markdown')
                self.bot.sendMessage(m)
            elif 'location' in query['message']:
                if user_config is not None and user_config.get('mode','') == 'map':
                    self.map_command(
                        message, chat_id, user_id, user, zoom=user_config["zoom"],
                        imgformat=user_config['format'],
                        lat=float(query['message']['location']['latitude']),
                        lon=float(query['message']['location']['longitude']))
                elif user_config.get('mode', '') == 'nearest':
                    self.nearest_command(
                        message, chat_id, user_id, user,
                        lat=float(query['message']['location']['latitude']),
                        lon=float(query['message']['location']['longitude']),
                        distance=user_config['distance'],
                        type=user_config['type'],
                        config=user_config
                    )
            elif user_config['mode'] == 'settings':
                if message == 'Language':
                    self.language_command(
                        message, user_id, chat_id, user, is_group)
                elif message == 'Answer only when mention?':
                    self.answer_command(chat_id, user)
                else:
                    template_name = 'seting_not_recognized_message.md'
                    temp = self._get_template(template_name)
                    text = temp.render()
                    m = Message(
                        chat_id, text, disable_web_page_preview=(not preview),
                        parse_mode='Markdown'
                    )
                    self.bot.sendMessage(m)
                    user.set_field(chat_id, 'mode', 'normal', group=is_group)
            elif user_config['mode'] == 'setlanguage':
                self.set_language_command(
                    message, user_id, chat_id, user, is_group)
            elif user_config['mode'] == 'setonlymention':
                response += self.set_only_mention(message, user_id, chat_id, user, is_group)
            elif 'text' in query['message']:
                if re.match(".*geo:-?\d+(\.\d*)?,-?\d+(\.\d*)?", message) is not None and user_config.get('mode', '') == 'map':
                    m = re.match(
                        ".*geo:(?P<lat>-?\d+(\.\d*)?),(?P<lon>-?\d+(\.\d*)?).*",
                        message)
                    lat = m.groupdict()['lat']
                    lon = m.groupdict()['lon']
                    response += self.map_command(
                        message, chat_id, user_id, user,
                        zoom=user_config['zoom'],
                        imgformat=user_config['format'],
                        lat=float(lat), lon=float(lon))
                elif message == 'Language':
                    response += self.language_command(message, user_id, chat_id, user,
                                                      is_group)
                elif message == 'Answer only when mention?':
                    response += self.answer_command(message, user_id, chat_id, user)
                elif message.lower().startswith('/settings'):
                    self.settings_command(message, user_id, chat_id, user, is_group)
                elif message.lower().startswith('/nearest'):
                    self.nearest_command(message, chat_id, user_id, user)
                elif message.lower().startswith('/map'):
                    self.map_command(message, chat_id, user_id, user)
                elif re.match('/phone.*', message.lower()):
                    self.phone_command(message, chat_id)
                elif re.match('/details.*', message.lower()):
                    try:
                        self.details_command(message, user_config, chat_id)
                    except Exception as e:
                        print(e.message)
                elif re.match("/raw.*", message.lower()):
                    try:
                        self.raw_command(message, chat_id)
                    except Exception as e:
                        print(e.message)
                        import traceback
                        print(traceback.format_exc())
                        pass
                elif message.lower().startswith('/legend'):
                    self.legend_command(message, chat_id)
                elif message.lower().startswith('/about'):
                    is_rtl = self.get_is_rtl()
                    template = self._get_template('about_answer.md')
                    text = template.render(is_rtl=is_rtl)
                    m = Message(
                        chat_id, text,
                        disable_web_page_preview=(not preview),
                        parse_mode='Markdown')
                    self.bot.sendMessage(m)
                elif message.lower().startswith('/help'):
                    template = self._get_template('help_message.md')
                    text = template.render(is_rtl=self.get_is_rtl())
                    response = [text]
                    response[-1] = response[-1].replace('_', '\_')
                elif re.match('/search.*', message.lower()) is not None and message[8:] != '':
                    self.search_command(message, user_config, chat_id)
                elif re.match('/search', message.lower()) is not None:
                    m = Message(
                        chat_id,
                        _('Please indicate what are you searching with command /search <search_term>')
                    )
                    self.bot.sendMessage(m)
                else:
                    m = Message(
                        chat_id,
                        _('Use /search <search_term> command to indicate what you are searching')
                    )
                    self.bot.sendMessage(m)
            if response:
                m = Message(
                    chat_id, response, disable_web_page_preview=(not preview),
                    parse_mode='Markdown'
                )
                self.bot.sendMessage(m)
Ejemplo n.º 13
0
def setup(bot: Bot) -> None:
    """Loads the cog into the bot."""
    bot.add_cog(OwnerCog(bot))
Ejemplo n.º 14
0
file_handler = NonBlockingFileHandler("log.txt", encoding="utf-8")
file_handler.setFormatter(formatter)
root_logger.addHandler(file_handler)

console_logger = logging.getLogger("console")
console = logging.StreamHandler(stdout)
console.setFormatter(formatter)
console_logger.addHandler(console)

banned_extensions = ("captcha_verification", "test")
root_logger.info(f"Banned extension: {banned_extensions}")


load_dotenv()
bot = Bot(prefix="t.")

for extension_path in Path("bot/cogs").glob("*.py"):
    extension_name = extension_path.stem

    if extension_name in banned_extensions:
        continue

    dotted_path = f"bot.cogs.{extension_name}"

    try:
        bot.load_extension(dotted_path)
        console_logger.info(f"loaded {dotted_path}")
    except Exception as e:
        traceback_msg = traceback.format_exception(etype=type(e), value=e, tb=e.__traceback__)
        console_logger.info(f"Failed to load cog {dotted_path} - traceback:{traceback_msg}")
Ejemplo n.º 15
0
def setup(bot: Bot) -> None:
    """Load the Doc cog."""
    from ._cog import DocCog
    bot.add_cog(DocCog(bot))
Ejemplo n.º 16
0
def setup(bot: Bot) -> None:
    """Load the ConfigVerifier cog."""
    bot.add_cog(ConfigVerifier(bot))
Ejemplo n.º 17
0
def setup(bot: Bot) -> None:
    """Load the Spooky Eight Ball Cog."""
    bot.add_cog(SpookyEightBall())
Ejemplo n.º 18
0
def setup(bot: Bot) -> None:
    """Loads the cog into the bot."""
    bot.add_cog(AntiMalwareCog())
Ejemplo n.º 19
0
def setup(bot: Bot) -> None:
    """Adding the help cog."""
    bot.add_cog(Help(bot))
Ejemplo n.º 20
0
def setup(bot: Bot) -> None:
    """Validate the AntiSpam configs and load the AntiSpam cog."""
    validation_errors = validate_config()
    bot.add_cog(AntiSpam(bot, validation_errors))
Ejemplo n.º 21
0
def setup(bot: Bot) -> None:
    """Load the Tags cog."""
    bot.add_cog(Tags(bot))
Ejemplo n.º 22
0
def setup(bot: Bot) -> None:
    bot.add_cog(VerificationCog(bot))
Ejemplo n.º 23
0
def setup(bot: Bot) -> None:
    """Load the Clean cog."""
    bot.add_cog(Clean(bot))
Ejemplo n.º 24
0
#!/usr/bin/env python
import getpass
import logging
import os

from bot.bot import Bot

logging.basicConfig(level=logging.DEBUG,
                    format=u'%(asctime)s - %(name)s - %(levelname)s - %(message)s')

PASSWORD_ENV_NAME = u'HCBOT_HIPCHAT_PASSWORD'


if __name__ == '__main__':
    # init config
    config_file = u'config.ini'

    # get password if available
    password = os.getenv(PASSWORD_ENV_NAME, u'').strip().decode('utf-8')

    # get password if it's not passed through the environment variable
    if not password:
        print u"Please input your Hipchat password:"
        password = getpass.getpass().decode('utf-8')

    bot = Bot(config_file, password)
    bot.initialize()
    bot.start()
Ejemplo n.º 25
0
def setup(bot: Bot) -> None:
    """Load the Reminders cog."""
    bot.add_cog(Reminders(bot))
Ejemplo n.º 26
0
    def test__is_allowed_to_run_command(self):
        bot = Bot()

        bot._get_user_level = Mock(return_value="user")
        assert bot._is_allowed_to_run_command("#a", "a", "addquote") is False
        assert bot._is_allowed_to_run_command("#a", "a", "delquote") is False
        assert bot._is_allowed_to_run_command("#a", "a", "quote") is False
        assert bot._is_allowed_to_run_command("#a", "a", "reg") is False
        assert bot._is_allowed_to_run_command("#a", "a", "def") is False

        bot._get_user_level = Mock(return_value="reg")
        assert bot._is_allowed_to_run_command("#a", "a", "addquote") is True
        assert bot._is_allowed_to_run_command("#a", "a", "delquote") is True
        assert bot._is_allowed_to_run_command("#a", "a", "quote") is True
        assert bot._is_allowed_to_run_command("#a", "a", "reg") is False
        assert bot._is_allowed_to_run_command("#a", "a", "def") is False

        bot._get_user_level = Mock(return_value="mod")
        assert bot._is_allowed_to_run_command("#a", "a", "addquote") is True
        assert bot._is_allowed_to_run_command("#a", "a", "delquote") is True
        assert bot._is_allowed_to_run_command("#a", "a", "quote") is True
        assert bot._is_allowed_to_run_command("#a", "a", "reg") is True
        assert bot._is_allowed_to_run_command("#a", "a", "def") is True

        bot._get_user_level = Mock(return_value="owner")
        assert bot._is_allowed_to_run_command("#a", "a", "addquote") is True
        assert bot._is_allowed_to_run_command("#a", "a", "delquote") is True
        assert bot._is_allowed_to_run_command("#a", "a", "quote") is True
        assert bot._is_allowed_to_run_command("#a", "a", "reg") is True
        assert bot._is_allowed_to_run_command("#a", "a", "def") is True
Ejemplo n.º 27
0
from voice import Voice
import logging
from bot.bot import Bot
from bot.exceptions import DialogFailed

driver = Voice()
bot = Bot()

while 1:
    try:
        text = input("Type a text: ")
        response = bot.send_text(text)
        response_text = bot.get_text_response(response)
        driver.say(response_text)
    except DialogFailed:
        driver.say("Disculpa, no te entendí")
        continue
Ejemplo n.º 28
0
def setup(bot: Bot) -> None:
    """Load the AntiMalware cog."""
    bot.add_cog(AntiMalware(bot))
Ejemplo n.º 29
0
def setup(bot: Bot) -> None:
    """Load the Filtering cog."""
    bot.add_cog(Filtering(bot))
Ejemplo n.º 30
0
        if 'mention' not in kwargs:
            self.mention = f"@{self.name}"


class MockAPIClient(CustomMockMixin, unittest.mock.MagicMock):
    """
    A MagicMock subclass to mock APIClient objects.

    Instances of this class will follow the specifications of `bot.api.APIClient` instances.
    For more information, see the `MockGuild` docstring.
    """
    spec_set = APIClient


# Create a Bot instance to get a realistic MagicMock of `discord.ext.commands.Bot`
bot_instance = Bot(command_prefix=unittest.mock.MagicMock())
bot_instance.http_session = None
bot_instance.api_client = None


class MockBot(CustomMockMixin, unittest.mock.MagicMock):
    """
    A MagicMock subclass to mock Bot objects.

    Instances of this class will follow the specifications of `discord.ext.commands.Bot` instances.
    For more information, see the `MockGuild` docstring.
    """
    spec_set = bot_instance
    additional_spec_asyncs = ("wait_for", )

    def __init__(self, **kwargs) -> None:
Ejemplo n.º 31
0
def main():
    # Creating a new bot instance.
    bot = Bot(token=TOKEN, name=NAME, version=VERSION, api_url_base=API_URL)

    # Registering handlers #
    # -------------------- #
    # Handler for start command
    bot.dispatcher.add_handler(StartCommandHandler(callback=start_cb))

    # Handler for help command
    bot.dispatcher.add_handler(HelpCommandHandler(callback=help_cb))

    # Any other user command handler
    bot.dispatcher.add_handler(CommandHandler(command="test",
                                              callback=test_cb))

    # Handler for feedback command
    bot.dispatcher.add_handler(FeedbackCommandHandler(target=OWNER))

    # Handler for unknown commands
    bot.dispatcher.add_handler(
        UnknownCommandHandler(callback=unknown_command_cb))

    # Handler for private command with filter by user
    bot.dispatcher.add_handler(
        CommandHandler(command="restart",
                       filters=Filter.sender(user_id=OWNER),
                       callback=private_command_cb))

    # Handler for add user to chat
    bot.dispatcher.add_handler(
        NewChatMembersHandler(callback=new_chat_members_cb))

    # Handler for left user from chat
    bot.dispatcher.add_handler(
        LeftChatMembersHandler(callback=left_chat_members_cb))

    # Handler for pinned message
    bot.dispatcher.add_handler(
        PinnedMessageHandler(callback=pinned_message_cb))

    # Handler for unpinned message
    bot.dispatcher.add_handler(
        UnPinnedMessageHandler(callback=unpinned_message_cb))

    # Handler for edited message
    bot.dispatcher.add_handler(
        EditedMessageHandler(callback=edited_message_cb))

    # Handler for deleted message
    bot.dispatcher.add_handler(
        DeletedMessageHandler(callback=deleted_message_cb))

    # Handler for message with bot mention
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.message
                       & Filter.mention(user_id=bot.uin),
                       callback=message_with_bot_mention_cb))

    # Handler for mention something else
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.mention()
                       & ~Filter.mention(user_id=bot.uin),
                       callback=mention_cb))

    # Handler for simple text message without media content
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.text, callback=message_cb))

    # Handler with regexp filter
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.regexp("^\d*$"),
                       callback=regexp_only_dig_cb))

    # Handler for no media file. For example, text file
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.data, callback=file_cb))

    # Handlers for other file types
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.image, callback=image_cb))
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.video, callback=video_cb))
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.audio, callback=audio_cb))

    # Handler for sticker
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.sticker, callback=sticker_cb))

    # Handler for url
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.url & ~Filter.sticker, callback=url_cb))

    # Handlers for forward and reply getting
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.forward, callback=forward_cb))
    bot.dispatcher.add_handler(
        MessageHandler(filters=Filter.reply, callback=reply_cb))

    # Send command like this:
    # /pin 6752793278973351456
    # 6752793278973351456 - msgId
    # Handler for pin command
    bot.dispatcher.add_handler(CommandHandler(command="pin", callback=pin_cb))

    # Send command like this:
    # /unpin 6752793278973351456
    # 6752793278973351456 - msgId
    # Handler for unpin command
    bot.dispatcher.add_handler(
        CommandHandler(command="unpin", callback=unpin_cb))

    # Starting a polling thread watching for new events from server. This is a non-blocking call
    # ---------------------------------------------------------------------------------------- #
    bot.start_polling()

    # Call bot methods
    # -------------- #
    # Get info about bot
    bot.self_get()

    # Send message
    response = bot.send_text(chat_id=OWNER, text="Hello")
    msg_id = response.json()['msgId']

    # Reply
    bot.send_text(chat_id=OWNER, text="Reply to 'Hello'", reply_msg_id=msg_id)

    # Forward
    bot.send_text(chat_id=OWNER,
                  text="Forward 'Hello'",
                  forward_msg_id=msg_id,
                  forward_chat_id=OWNER)

    # Send binary file
    with io.StringIO() as file:
        file.write(u'x' * 100)
        file.name = "file.txt"
        file.seek(0)
        response = bot.send_file(chat_id=OWNER,
                                 file=file.read(),
                                 caption="binary file caption")
        file_id = response.json()['fileId']

    # Get file info
    bot.get_file_info(file_id=file_id)

    # Send file by file_id
    bot.send_file(chat_id=OWNER,
                  file_id=file_id,
                  caption="file_id file caption")

    # Send file by file_id as reply to message
    bot.send_file(chat_id=OWNER,
                  file_id=file_id,
                  caption="file_id file caption",
                  reply_msg_id=msg_id)

    # Forward file by file_id
    bot.send_file(chat_id=OWNER,
                  file_id=file_id,
                  caption="file_id file caption",
                  forward_msg_id=msg_id,
                  forward_chat_id=OWNER)

    # Send voice file
    if sys.version_info[0] == 3:
        with io.BytesIO() as file:
            gTTS('Hello everybody!').write_to_fp(file)
            file.name = "hello_voice.mp3"
            file.seek(0)
            response = bot.send_voice(chat_id=OWNER, file=file.read())
            hello_voice_file_id = response.json()['fileId']

        # Send voice by file_id
        bot.send_voice(chat_id=OWNER, file_id=hello_voice_file_id)

    # Edit text
    msg_id = bot.send_text(chat_id=OWNER,
                           text="Message to be edited").json()['msgId']
    bot.edit_text(chat_id=OWNER, msg_id=msg_id, text="edited text")

    # Delete message
    msg_id = bot.send_text(chat_id=OWNER,
                           text="Message to be deleted").json()['msgId']
    bot.delete_messages(chat_id=OWNER, msg_id=msg_id)

    # Send typing action
    bot.send_actions(chat_id=OWNER, actions=["typing"])
    sleep(1)
    # Stop typing
    bot.send_actions(chat_id=OWNER, actions=[])

    # Get info about chat
    bot.get_chat_info(chat_id=TEST_CHAT)

    # Get chat admins
    bot.get_chat_admins(chat_id=TEST_CHAT)
    # Get chat members
    bot.get_chat_members(chat_id=TEST_CHAT)
    # Get chat blocked users
    bot.get_chat_blocked_users(chat_id=TEST_CHAT)
    # Get chat pending users
    bot.get_chat_pending_users(chat_id=TEST_CHAT)

    # Block user in chat
    bot.chat_block_user(chat_id=TEST_CHAT,
                        user_id=TEST_USER,
                        del_last_messages=True)
    # Unlock user in chat
    bot.chat_unblock_user(chat_id=TEST_CHAT, user_id=TEST_USER)

    # Chat resolve pending user or everyone
    bot.chat_resolve_pending(chat_id=TEST_CHAT,
                             approve=True,
                             user_id=TEST_USER,
                             everyone=False)

    # Set chat title
    bot.set_chat_title(chat_id=TEST_CHAT, title="TEST TITLE")
    # Set chat about
    bot.set_chat_about(chat_id=TEST_CHAT, about="TEST ABOUT")
    # Set chat title
    bot.set_chat_rules(chat_id=TEST_CHAT, rules="TEST RULES")

    # Send bot buttons
    bot.send_text(chat_id=OWNER,
                  text="Hello with buttons.",
                  inline_keyboard_markup="[{}]".format(
                      json.dumps([{
                          "text": "Action 1",
                          "url": "http://mail.ru"
                      }, {
                          "text": "Action 2",
                          "callbackData": "call_back_id_2"
                      }, {
                          "text": "Action 3",
                          "callbackData": "call_back_id_3"
                      }])))

    # Handler for bot buttons reply.
    bot.dispatcher.add_handler(
        BotButtonCommandHandler(callback=buttons_answer_cb))

    bot.idle()
Ejemplo n.º 32
0
def setup(bot: Bot) -> None:
    """Load the ErrorHandler cog."""
    bot.add_cog(ErrorHandler(bot))
Ejemplo n.º 33
0
def setup(bot: Bot) -> None:
    """Load the Bot cog."""
    bot.add_cog(BotCog(bot))
Ejemplo n.º 34
0
def setup(bot: Bot) -> None:
    """Load the Defcon cog."""
    bot.add_cog(Defcon(bot))
Ejemplo n.º 35
0
def setup(bot: Bot):
    bot.add_cog(General(bot))
Ejemplo n.º 36
0
def setup(bot: Bot) -> None:
    """Load the ModManagement cog."""
    bot.add_cog(ModManagement(bot))
Ejemplo n.º 37
0
def setup(bot: Bot) -> None:
    """Load the Hangman cog."""
    bot.add_cog(Hangman(bot))
Ejemplo n.º 38
0
def setup(bot: Bot) -> None:
    """Load the stats cog."""
    bot.add_cog(Stats(bot))
Ejemplo n.º 39
0
import os
import logging
from sys import stdout

from dotenv import load_dotenv

from bot.bot import Bot
from bot.non_blocking_file_handler import NonBlockingFileHandler

root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO)

formatter = logging.Formatter("%(asctime)s - %(name)s - %(message)s")

file_handler = NonBlockingFileHandler("log.txt", encoding="utf-8")
file_handler.setFormatter(formatter)
root_logger.addHandler(file_handler)

console_logger = logging.getLogger("console")
console = logging.StreamHandler(stdout)
console.setFormatter(formatter)
console_logger.addHandler(console)

load_dotenv()
Bot().run(os.getenv("BOT_TOKEN"))
Ejemplo n.º 40
0
from bot.bot import Bot

bot = Bot()
bot.start_update_loop()
Ejemplo n.º 41
0
def setup(bot: Bot) -> None:
    """Load the Who is Valentine Cog."""
    bot.add_cog(ValentineFacts())
Ejemplo n.º 42
0
import logging
from bot.bot import Bot

from flask import Flask, request, current_app
from bot import Osmbot
from configobj import ConfigObj
import os
from raven.contrib.flask import Sentry

application = Flask(__name__)
application.debug = True
Osmbot(application, '')

config = ConfigObj('bot.conf')
token = config['token']
bot = Bot(token)

if 'sentry_dsn' in config:
    application.config['sentry_dsn'] = config['sentry_dsn']
    sentry = Sentry(application, dsn=config['sentry_dsn'])
    sentry.captureMessage('OSMBot started', level=logging.INFO)
    application.sentry = sentry

f = open('nginx.crt', 'r')
cert_data = f.read()
f.close()
webhook = os.path.join(config['webhook'], config['token'])
application.logger.debug('webhook:%s', config['webhook'])
response = bot.setWebhook(webhook, cert_data)
application.logger.debug('response:%s', response)
Ejemplo n.º 43
0
def setup(bot: Bot) -> None:
    """Load the Easter Egg facts Cog."""
    bot.add_cog(EasterFacts(bot))
Ejemplo n.º 44
0
def setup(bot: Bot) -> None:
    bot.add_cog(UserbotsCog(bot))
Ejemplo n.º 45
0
def setup(bot: Bot) -> None:
    """Load the Hacktober Stats Cog."""
    bot.add_cog(HacktoberStats(bot))