Ejemplo n.º 1
0
    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
        """
        if not message:
            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[:10]):
                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'].get('name',r['display_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)
Ejemplo n.º 2
0
import bot.user as u
from bot.osmbot import OsmBot
from telegram import Bot as TBot

application = Flask(__name__)
application.debug = True
config = ConfigObj('bot.conf')

if config:
    user = u.User(config.get('host', ''), config.get('database', ''),
                  config.get('user', ''), config.get('password', ''))
    osmbot = OsmBot(config)
    telegram_api = TBot(config['token'])

api = OsmApi()
nom = pynominatim.Nominatim()

osmbot_blueprint = Blueprint('osmbot',
                             __name__,
                             template_folder='templates',
                             static_folder='static')


@osmbot_blueprint.route('/osmbot/hook/<string:token>', methods=['POST'])
def attend_webhook(token):
    user = u.User(config['host'], config['database'], config['user'],
                  config['password'])
    current_app.logger.debug('token:%s', token)
    osmbot.set_group(False)
    if token == config['token']:
        try:
Ejemplo n.º 3
0
    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()
        message = message[4:]
        signature = self._get_template('signature.md').render()
        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)
                f = BytesIO(data)
            except ValueError as v:
                self.telegram_api.sendMessage(chat_id, v.message)
            else:

                if imgformat == 'pdf':
                    self.telegram_api.sendDocument(chat_id, f, 'map.pdf')
                elif imgformat == 'jpeg':
                    self.telegram_api.sendPhoto(chat_id, f, signature)
                elif imgformat == 'png':
                    self.telegram_api.sendPhoto(chat_id, f, 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"]
                text = _('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."
                self.telegram_api.sendMessage(chat_id, text, 'Markdown')
                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)
                    f = BytesIO(data)
                except ValueError as v:
                    self.telegram_api.sendMessage(chat_id, v.message)
                else:
                    if imgformat == 'pdf':
                        self.telegram_api.sendDocument(chat_id, f, 'map.pdf')
                    elif imgformat == 'jpeg':
                        self.telegram_api.sendPhoto(chat_id, f, signature)
                    elif imgformat == 'png':
                        self.telegram_api.sendPhoto(chat_id, f, signature)
            elif re.match(self.re_map, 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)
                        f = BytesIO(data)
                    except ValueError as v:
                        self.telegram_api.sendMessage(chat_id, v.message)
                    else:
                        if imgformat == 'pdf':
                            self.telegram_api.sendDocument(chat_id, f, 'map.pdf')
                        elif imgformat == 'jpeg':
                            self.telegram_api.sendPhoto(
                                chat_id, f, signature)
                        elif imgformat == 'png':
                            self.telegram_api.sendPhoto(
                                chat_id, f, signature)
                else:
                    template = self._get_template('cant_understand_message.md')
                    text = template.render()
                    self.telegram_api.sendMessage(chat_id, text, 'Markdown')
            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)
                        f = BytesIO(data)
                    except ValueError as v:
                        self.telegram_api.sendMessage(chat_id, v.message)
                    else:
                        self.telegram_api.sendPhoto(chat_id, f, signature)
                else:
                    temp = self._get_template('cant_understand_message.md')
                    text = temp.render()
                    self.telegram_api.sendMessage(chat_id, text, 'Markdown')
Ejemplo n.º 4
0
    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
        """
        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)
            self.telegram_api.sendMessage(chat_id, text, parse_mode='Markdown')
            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 result.get('osm_type', '') == 'node':
                        t += _('More info') + ' /detailsnod{0}\n'.format(result['osm_id'])
                    elif result.get('osm_type', '') == 'way':
                        t += _('More info')+' /detailsway{0}\n'.format(result['osm_id'])
                    elif result.get('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 result.get('osm_type', '') == 'node':
                            t += _('More info') + ' /detailsnod{0}\n\n'.format(result['osm_id'])
                        elif result.get('osm_type', '') == 'way':
                            t += _('More info')+' /detailsway{0}\n\n'.format(result['osm_id'])
                        elif result.get('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'
        self.telegram_api.sendMessage(
            chat_id,
            t,
            parse_mode='Markdown',
            disable_web_page_preview=True)