Beispiel #1
0
def etymology(word):
    # @@ <nsh> sbp, would it be possible to have a flag for .ety to get 2nd/etc
    # entries? - http://swhack.com/logs/2006-07-19#T15-05-29

    if len(word) > 25:
        raise ValueError("Word too long: %s[…]" % word[:10])

    ety = get(ETYURI % web.quote(word))
    if ety.status_code != 200:
        return None

    # Let's find it
    start = ety.text.find("word__defination")
    start = ety.text.find("<p>", start)
    stop = ety.text.find("</p>", start)
    sentence = ety.text[start + 3:stop]
    # Clean up
    sentence = unescape(sentence)
    sentence = sub('<[^<]+?>', '', sentence)

    maxlength = 275
    if len(sentence) > maxlength:
        sentence = sentence[:maxlength]
        words = sentence[:-5].split(' ')
        words.pop()
        sentence = ' '.join(words) + ' […]'

    sentence = '"' + sentence.replace('"', "'") + '"'
    return sentence + ' - ' + (ETYURI % web.quote(word))
Beispiel #2
0
def mw_snippet(server, query, bot):
    """
    Retrives a snippet of the specified length from the given page on the given
    server.
    """
    if bot.config.lang == 'fr':
        snippet_url = ('https://fr.wikipedia.org/w/api.php?format=json'
                       '&action=query&prop=extracts&exintro&explaintext'
                       '&exchars=300&redirects&titles=')
    elif bot.config.lang == 'es':
        snippet_url = ('https://es.wikipedia.org/w/api.php?format=json'
                       '&action=query&prop=extracts&exintro&explaintext'
                       '&exchars=300&redirects&titles=')
    else:
        snippet_url = ('https://en.wikipedia.org/w/api.php?format=json'
                       '&action=query&prop=extracts&exintro&explaintext'
                       '&exchars=300&redirects&titles=')
    if bot.config.lang == 'fr' or bot.config.lang == 'es':
        snippet_url += web.quote(query.encode('utf-8'))
    else:
        snippet_url += web.quote(query.encode('cp1252'))
    snippet = json.loads(web.get(snippet_url))
    snippet = snippet['query']['pages']

    # For some reason, the API gives the page *number* as the key, so we just
    # grab the first page number in the results.
    snippet = snippet[snippet.keys()[0]]

    return snippet['extract']
Beispiel #3
0
def etymology(word):
    # @@ <nsh> sbp, would it be possible to have a flag for .ety to get 2nd/etc
    # entries? - http://swhack.com/logs/2006-07-19#T15-05-29

    if len(word) > 25:
        raise ValueError("Word too long: %s[…]" % word[:10])

    ety = get(ETYURI % web.quote(word))
    if ety.status_code != 200:
        return None

    # Let's find it
    start = ety.text.find("word__defination")
    start = ety.text.find("<p>", start)
    stop = ety.text.find("</p>", start)
    sentence = ety.text[start + 3:stop]
    # Clean up
    sentence = unescape(sentence)
    sentence = sub('<[^<]+?>', '', sentence)

    maxlength = 275
    if len(sentence) > maxlength:
        sentence = sentence[:maxlength]
        words = sentence[:-5].split(' ')
        words.pop()
        sentence = ' '.join(words) + ' […]'

    sentence = '"' + sentence.replace('"', "'") + '"'
    return sentence + ' - ' + (ETYURI % web.quote(word))
Beispiel #4
0
def urbansearch(bot, searchterm):
    """Search Urban Dictionary."""
    try:
        data = web.get("http://api.urbandictionary.com/v0/define?term={0}".format(web.quote(searchterm)))
        data = json.loads(data)
    except:
        return osd(bot, trigger.sender, 'say', "Error connecting to urban dictionary")
    if data['result_type'] == 'no_results':
        return "No results found for {0}".format(searchterm)
    result = data['list'][0]
    url = 'http://www.urbandictionary.com/define.php?term={0}'.format(web.quote(searchterm))
    response = "{0} - {1}".format(result['definition'].strip()[:256], url)
    return response
Beispiel #5
0
def mw_search(server, query, num, bot):
    """
    Searches the specified MediaWiki server for the given query, and returns
    the specified number of results.
    """
    search_url = ('http://%s/w/api.php?format=json&action=query'
                  '&list=search&srlimit=%d&srprop=timestamp&srwhat=text'
                  '&srsearch=') % (server, num)
    if bot.config.lang == 'fr' or bot.config.lang == 'es':
        search_url += web.quote(query.encode('utf-8'))
    else:
        search_url += web.quote(query.encode('cp1252'))
    query = json.loads(web.get(search_url))
    query = query['query']['search']
    return [r['title'] for r in query]
Beispiel #6
0
def bing_search(query, lang='en-GB'):
    query = web.quote(query)
    base = 'http://www.bing.com/search?mkt=%s&q=' % lang
    bytes = web.get(base + query)
    m = r_bing.search(bytes)
    if m:
        return m.group(1)
Beispiel #7
0
def googleit(bot, trigger):
    """Let me just... google that for you."""
    # No input
    if not trigger.group(2):
        return bot.say('https://www.google.com/')
    bot.say('https://lmgtfy.com/?q=' +
            quote(trigger.group(2).replace(' ', '+'), '+'))
Beispiel #8
0
def wikt(word):
    bytes = web.get(uri % web.quote(word))
    bytes = r_ul.sub('', bytes)

    mode = None
    etymology = None
    definitions = {}
    for line in bytes.splitlines():
        if 'id="Etymology"' in line:
            mode = 'etymology'
        elif 'id="Noun"' in line:
            mode = 'noun'
        elif 'id="Verb"' in line:
            mode = 'verb'
        elif 'id="Adjective"' in line:
            mode = 'adjective'
        elif 'id="Adverb"' in line:
            mode = 'adverb'
        elif 'id="Interjection"' in line:
            mode = 'interjection'
        elif 'id="Particle"' in line:
            mode = 'particle'
        elif 'id="Preposition"' in line:
            mode = 'preposition'
        elif 'id="' in line:
            mode = None

        elif (mode == 'etmyology') and ('<p>' in line):
            etymology = text(line)
        elif (mode is not None) and ('<li>' in line):
            definitions.setdefault(mode, []).append(text(line))

        if '<hr' in line:
            break
    return etymology, definitions
Beispiel #9
0
def endmeeting(bot, trigger):
    """
    End a meeting.\
    See [meetbot module usage]({% link _usage/meetbot-module.md %})
    """
    if not is_meeting_running(trigger.sender):
        bot.say("There is no active meeting")
        return
    if not is_chair(trigger.nick, trigger.sender):
        bot.say("Only meeting head or chairs can do that")
        return
    meeting_length = time.time() - meetings_dict[trigger.sender]["start"]
    bot.say(
        formatting.bold("Meeting ended!") +
        " Total meeting length %d minutes" % (meeting_length // 60)
    )
    log_html_end(trigger.sender)
    htmllog_url = meeting_log_baseurl + web.quote(
        trigger.sender + "/" + figure_logfile_name(trigger.sender) + ".html"
    )
    log_plain(
        "Meeting ended by %s. Total meeting length: %d minutes"
        % (trigger.nick, meeting_length // 60),
        trigger.sender,
    )
    bot.say("Meeting minutes: " + htmllog_url)
    meetings_dict[trigger.sender] = tools.Ddict(dict)
    del meeting_actions[trigger.sender]
Beispiel #10
0
def wikt(word):
    bytes = requests.get(uri % web.quote(word)).text
    bytes = r_ul.sub('', bytes)

    mode = None
    etymology = None
    definitions = {}
    for line in bytes.splitlines():
        if 'id="Etymology"' in line:
            mode = 'etymology'
        elif 'id="Noun"' in line:
            mode = 'noun'
        elif 'id="Verb"' in line:
            mode = 'verb'
        elif 'id="Adjective"' in line:
            mode = 'adjective'
        elif 'id="Adverb"' in line:
            mode = 'adverb'
        elif 'id="Interjection"' in line:
            mode = 'interjection'
        elif 'id="Particle"' in line:
            mode = 'particle'
        elif 'id="Preposition"' in line:
            mode = 'preposition'
        elif 'id="' in line:
            mode = None

        elif (mode == 'etmyology') and ('<p>' in line):
            etymology = text(line)
        elif (mode is not None) and ('<li>' in line):
            definitions.setdefault(mode, []).append(text(line))

        if '<hr' in line:
            break
    return etymology, definitions
Beispiel #11
0
def endmeeting(bot, trigger):
    """
    End a meeting.\
    See [meetbot module usage]({% link _usage/meetbot-module.md %})
    """
    if not ismeetingrunning(trigger.sender):
        bot.say('Can\'t do that, start meeting first')
        return
    if not ischair(trigger.nick, trigger.sender):
        bot.say('Only meeting head or chairs can do that')
        return
    meeting_length = time.time() - meetings_dict[trigger.sender]['start']
    # TODO: Humanize time output
    bot.say(
        bold("Meeting ended!") +
        " total meeting length %d seconds" % meeting_length)
    logHTML_end(trigger.sender)
    htmllog_url = meeting_log_baseurl + quote(
        trigger.sender + '/' + figure_logfile_name(trigger.sender) + '.html')
    logplain(
        'Meeting ended by %s, total meeting length %d seconds' %
        (trigger.nick, meeting_length), trigger.sender)
    bot.say('Meeting minutes: ' + htmllog_url)
    meetings_dict[trigger.sender] = Ddict(dict)
    del meeting_actions[trigger.sender]
Beispiel #12
0
def wikt(word):
    bytes = requests.get(uri % web.quote(word)).text
    bytes = r_ul.sub('', bytes)

    mode = None
    etymology = None
    definitions = {}
    for line in bytes.splitlines():
        is_new_mode = False
        if 'id="Etymology' in line:
            mode = 'etymology'
            is_new_mode = True
        else:
            for pos in PARTS_OF_SPEECH:
                if 'id="{}"'.format(pos.replace(' ', '_')) in line:
                    mode = pos.lower()
                    is_new_mode = True
                    break

        if not is_new_mode:
            # 'id="' can occur in definition lines <li> when <sup> tag is used for references;
            # make sure those are not excluded (see e.g., abecedarian).
            if ('id="' in line) and ('<li>' not in line):
                mode = None
            elif (mode == 'etmyology') and ('<p>' in line):
                etymology = text(line)
            elif (mode is not None) and ('<li>' in line):
                definitions.setdefault(mode, []).append(text(line))

        if '<hr' in line:
            break
    return etymology, definitions
Beispiel #13
0
def get_np_info(username):
    username = web.quote(username)
    api_key = "782c02b1c96ae181d83850f050509103"
    recent_tracks = web.get("http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&format=json&user=%s&api_key=%s" % (username, api_key))

    #now playing track, or most recently scrobbled track
    now_playing = json.loads(recent_tracks)

    # if the user does not exist
    if 'recenttracks' not in now_playing:
        return None

    now_playing = now_playing['recenttracks']['track'][0]

    track = now_playing['name']
    album = now_playing['album']['#text']
    artist = now_playing['artist']['#text']

    # why the f**k doesnt this work with web.get() ???
    track_page = urllib.request.urlopen("http://ws.audioscrobbler.com/2.0/?method=track.getInfo&format=json&artist=%s&track=%s&username=%s&api_key=%s" % (web.quote(artist), web.quote(track), username, api_key))
    track_info = json.loads(track_page.read().decode())['track']
    user_playcount = "0"
    if 'userplaycount' in track_info:
        user_playcount = track_info['userplaycount']
    user_loved = False
    if int(track_info['userloved']) > 0:
        user_loved = True

    return {"track": track, "album": album, "artist": artist, "user_playcount": user_playcount, "user_loved": user_loved}
Beispiel #14
0
def get_np_info(username):
    username = web.quote(username)
    api_key = "API_KEY"
    recent_tracks = web.get("http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&format=json&user=%s&api_key=%s" % (username, api_key))

    #now playing track, or most recently scrobbled track
    now_playing = json.loads(recent_tracks)

    # if the user does not exist
    if 'recenttracks' not in now_playing:
        return None

    now_playing = now_playing['recenttracks']['track'][0]

    track = now_playing['name']
    album = now_playing['album']['#text']
    artist = now_playing['artist']['#text']

    import sys

    reload(sys)
    sys.setdefaultencoding('utf8')
    # why the f**k doesnt this work with web.get() ???
    track_page = urllib.urlopen("http://ws.audioscrobbler.com/2.0/?method=track.getInfo&format=json&artist=%s&track=%s&username=%s&api_key=%s" % (web.quote(artist), web.quote(track), username, api_key))
    track_info = json.loads(track_page.read().decode(), encoding='utf-8')['track']
    user_playcount = "0"
    if 'userplaycount' in track_info:
        user_playcount = track_info['userplaycount']
    user_loved = False
    if int(track_info['userloved']) > 0:
        user_loved = True

    return {"track": track, "album": album, "artist": artist, "user_playcount": user_playcount, "user_loved": user_loved}
Beispiel #15
0
def shorten_url(url):
    try:
        res, headers = web.post('http://git.io',
                                'url=' + web.quote(url),
                                return_headers=True)
        return headers['location']
    except:
        return url
Beispiel #16
0
def logHTML_end(channel):
    logfile = codecs.open(meeting_log_path + channel + '/' + figure_logfile_name(channel) + '.html', 'a', encoding='utf-8')
    current_time = time.strftime('%H:%M:%S', time.gmtime())
    logfile.write('</ul>\n<h4>Meeting ended at %s UTC</h4>\n' % current_time)
    plainlog_url = meeting_log_baseurl + quote(channel + '/' + figure_logfile_name(channel) + '.log')
    logfile.write('<a href="%s">Full log</a>' % plainlog_url)
    logfile.write('\n</body>\n</html>')
    logfile.close()
Beispiel #17
0
def logHTML_end(channel):
    logfile = codecs.open(meeting_log_path + channel + '/' + figure_logfile_name(channel) + '.html', 'a', encoding='utf-8')
    current_time = time.strftime('%H:%M:%S', time.gmtime())
    logfile.write('</ul>\n<h4>Meeting ended at %s UTC</h4>\n' % current_time)
    plainlog_url = meeting_log_baseurl + quote(channel + '/' + figure_logfile_name(channel) + '.log')
    logfile.write('<a href="%s">Full log</a>' % plainlog_url)
    logfile.write('\n</body>\n</html>')
    logfile.close()
Beispiel #18
0
def duck_search(query):
    query = query.replace('!', '')
    query = web.quote(query)
    uri = 'http://duckduckgo.com/html/?q=%s&kl=uk-en' % query
    bytes = web.get(uri)
    m = r_duck.search(bytes)
    if m:
        return web.decode(m.group(1))
Beispiel #19
0
def logHTML_end(channel):
    logfile = codecs.open(
        meeting_log_path + channel + "/" + figure_logfile_name(channel) + ".html", "a", encoding="utf-8"
    )
    current_time = time.strftime("%H:%M:%S", time.gmtime())
    logfile.write("</ul>\n<h4>Meeting ended at %s UTC</h4>\n" % current_time)
    plainlog_url = meeting_log_baseurl + quote(channel + "/" + figure_logfile_name(channel) + ".log")
    logfile.write('<a href="%s">Full log</a>' % plainlog_url)
    logfile.write("\n</body>\n</html>")
    logfile.close()
Beispiel #20
0
def duck_api(query):
    if '!bang' in query.lower():
        return 'https://duckduckgo.com/bang.html'

    uri = web.quote(query)
    uri = 'http://api.duckduckgo.com/?q=%s&format=json&no_html=1&no_redirect=1' % query
    results = json.loads(web.get(uri))
    print results
    if results['Redirect']:
        return results['Redirect']
    else:
        return None
Beispiel #21
0
def py(bot, trigger):
    """Evaluate a Python expression."""
    if not trigger.group(2):
        return bot.say("Need an expression to evaluate")

    query = trigger.group(2)
    uri = BASE_TUMBOLIA_URI + 'py/'
    answer = web.get(uri + web.quote(query))
    if answer:
        #bot.say can potentially lead to 3rd party commands triggering.
        bot.reply(answer)
    else:
        bot.reply('Sorry, no result.')
Beispiel #22
0
def py(bot, trigger):
    """Evaluate a Python expression."""
    if not trigger.group(2):
        return bot.say("Need an expression to evaluate")

    query = trigger.group(2)
    uri = BASE_TUMBOLIA_URI + 'py/'
    answer = web.get(uri + web.quote(query))
    if answer:
        #bot.say can potentially lead to 3rd party commands triggering.
        bot.reply(answer)
    else:
        bot.reply('Sorry, no result.')
Beispiel #23
0
def log_html_end(channel):
    logfile_filename = os.path.join(
        meeting_log_path + channel, figure_logfile_name(channel) + ".html"
    )
    logfile = codecs.open(logfile_filename, "a", encoding="utf-8")
    current_time = time.strftime("%H:%M:%S", time.gmtime())
    logfile.write("</ul>\n<h4>Meeting ended at %s UTC</h4>\n" % current_time)
    plainlog_url = meeting_log_baseurl + web.quote(
        channel + "/" + figure_logfile_name(channel) + ".log"
    )
    logfile.write('<a href="%s">Full log</a>' % plainlog_url)
    logfile.write("\n</body>\n</html>\n")
    logfile.close()
Beispiel #24
0
def f_etymology(bot, trigger):
    """Look up the etymology of a word"""
    word = trigger.group(2)

    try:
        result = etymology(word)
    except IOError:
        msg = "Can't connect to etymonline.com (%s)" % (ETYURI % web.quote(word))
        bot.msg(trigger.sender, msg)
        return NOLIMIT
    except (AttributeError, TypeError):
        result = None
    except ValueError as ve:
        result = str(ve)

    if result is not None:
        bot.msg(trigger.sender, result)
    else:
        uri = ETYSEARCH % web.quote(word)
        msg = 'Can\'t find the etymology for "%s". Try %s' % (word, uri)
        bot.msg(trigger.sender, msg)
        return NOLIMIT
def fucking_weather(bot, trigger):
    text = trigger.group(2)
    if not text:
        bot.reply("DOES THAT LOCATION EVEN F*****G EXIST?!. TRY ENTERING A GORRAM F*****G ZIP CODE, OR A F*****G CITY-STATE PAIR..SHEESH.")
        return
    text = web.quote(text)
    page = web.get("http://thefuckingweather.com/Where/%s" % (text))
    re_mark = re.compile('<p class="remark jsRemark">(.*?)</p>')
    results = re_mark.findall(page)
    if results:
        bot.reply(results[0])
    else:
        bot.reply("I CAN'T GET THE F*****G WEATHER.")
        return bot.NOLIMIT
Beispiel #26
0
def fucking_weather(bot, trigger):
    text = trigger.group(2)
    if not text:
        bot.reply("INVALID F*****G PLACE. PLEASE ENTER A F*****G ZIP CODE, OR A F*****G CITY-STATE PAIR.")
        return
    text = web.quote(text)
    page = web.get("http://thefuckingweather.com/Where/%s" % (text))
    re_mark = re.compile('<p class="remark jsRemark">(.*?)</p>')
    results = re_mark.findall(page)
    if results:
        bot.reply(results[0])
    else:
        bot.reply("I CAN'T GET THE F*****G WEATHER.")
        return bot.NOLIMIT
Beispiel #27
0
def urbandict(bot, trigger):
    """.urb <word> - Search Urban Dictionary for a definition."""

    word = trigger.group(2)
    if not word:
        return bot.say(urbandict.__doc__.strip())

    try:
        data = web.get(
            "http://api.urbandictionary.com/v0/define?term={0}".format(
                web.quote(word)))
        data = json.loads(data)
    except:
        return bot.say("Error connecting to urban dictionary")

    if data['result_type'] == 'no_results':
        return bot.say("No results found for {0}".format(word))

    result = data['list'][0]
    url = 'http://www.urbandictionary.com/define.php?term={0}'.format(
        web.quote(word))

    response = "{0} - {1}".format(result['definition'].strip()[:256], url)
    bot.say(response)
Beispiel #28
0
def lastfm(willie, trigger):
    user = ''
    if trigger.group(2):
        user = trigger.group(2).replace("@", trigger.nick)
    if not (user and user != ''):
        user = willie.db.get_nick_value(trigger.nick, 'lastfm_user')
        if not user:
            willie.reply("Invalid username given or no username set. Use .fmset to set a username.")
            return
    #username variable prepared for insertion into REST string
    user = user.lower()
    quoted_user = web.quote(user)
    #json formatted output for recent track
    try:
        recent_page = web.get("http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=%s&api_key=782c02b1c96ae181d83850f050509103&format=json" % (quoted_user))
    except Exception, e:
        willie.say("last.fm is currently having technical difficulties. See .fmstatus for more information.")
        return
Beispiel #29
0
def nowplaying(bot, trigger):
    """displays the most recent track played by a given IRC nick."""
    output = ""
    notme = False
    if trigger.group(2):
        nick = re.match(r"^\S+", trigger.group(2)).group()
        notme = True
    else:
        nick = trigger.nick
    # check if nick is in room, if not, just use as lastfm username directly
    fmuser = bot.db.get_nick_value(nick, "lastfm_user")
    if not fmuser:
        bot.say("Use .fmset to associate a last.fm username with your IRC nick.")
        fmuser = nick
    try:
        recent_tracks = query_lastfm(bot, method="user.getrecenttracks", user=web.quote(fmuser))
    except Exception, e:
        bot.say("Couldn't contact last.fm :(")
        return
Beispiel #30
0
def endmeeting(bot, trigger):
    """
    End a meeting.
    https://github.com/sopel-irc/sopel/wiki/Using-the-meetbot-module
    """
    if not ismeetingrunning(trigger.sender):
        bot.say('Can\'t do that, start meeting first')
        return
    if not ischair(trigger.nick, trigger.sender):
        bot.say('Only meeting head or chairs can do that')
        return
    meeting_length = time.time() - meetings_dict[trigger.sender]['start']
    #TODO: Humanize time output
    bot.say("Meeting ended! total meeting length %d seconds" % meeting_length)
    logHTML_end(trigger.sender)
    htmllog_url = meeting_log_baseurl + quote(trigger.sender + '/' + figure_logfile_name(trigger.sender) + '.html')
    logplain('Meeting ended by %s, total meeting length %d seconds' % (trigger.nick, meeting_length), trigger.sender)
    bot.say('Meeting minutes: ' + htmllog_url)
    meetings_dict[trigger.sender] = Ddict(dict)
    del meeting_actions[trigger.sender]
Beispiel #31
0
def endmeeting(bot, trigger):
    """
    End a meeting.\
    See [meetbot module usage]({% link _usage/meetbot-module.md %})
    """
    if not ismeetingrunning(trigger.sender):
        bot.say('Can\'t do that, start meeting first')
        return
    if not ischair(trigger.nick, trigger.sender):
        bot.say('Only meeting head or chairs can do that')
        return
    meeting_length = time.time() - meetings_dict[trigger.sender]['start']
    # TODO: Humanize time output
    bot.say(bold("Meeting ended!") + " total meeting length %d seconds" % meeting_length)
    logHTML_end(trigger.sender)
    htmllog_url = meeting_log_baseurl + quote(trigger.sender + '/' + figure_logfile_name(trigger.sender) + '.html')
    logplain('Meeting ended by %s, total meeting length %d seconds' % (trigger.nick, meeting_length), trigger.sender)
    bot.say('Meeting minutes: ' + htmllog_url)
    meetings_dict[trigger.sender] = Ddict(dict)
    del meeting_actions[trigger.sender]
Beispiel #32
0
def endmeeting(bot, trigger):
    """
    End a meeting.
    https://github.com/embolalia/sopel/wiki/Using-the-meetbot-module
    """
    if not ismeetingrunning(trigger.sender):
        bot.say("Can't do that, start meeting first")
        return
    if not ischair(trigger.nick, trigger.sender):
        bot.say("Only meeting head or chairs can do that")
        return
    meeting_length = time.time() - meetings_dict[trigger.sender]["start"]
    # TODO: Humanize time output
    bot.say("Meeting ended! total meeting length %d seconds" % meeting_length)
    logHTML_end(trigger.sender)
    htmllog_url = meeting_log_baseurl + quote(trigger.sender + "/" + figure_logfile_name(trigger.sender) + ".html")
    logplain("Meeting ended by %s, total meeting length %d seconds" % (trigger.nick, meeting_length), trigger.sender)
    bot.say("Meeting minutes: " + htmllog_url)
    meetings_dict[trigger.sender] = Ddict(dict)
    del meeting_actions[trigger.sender]
Beispiel #33
0
def wikt(word):
    bytes = requests.get(uri % web.quote(word)).text
    bytes = r_ul.sub('', bytes)

    mode = None
    etymology = None
    definitions = {}
    for line in bytes.splitlines():
        if 'id="Etymology"' in line:
            mode = 'etymology'
        elif 'id="Noun"' in line:
            mode = 'noun'
        elif 'id="Verb"' in line:
            mode = 'verb'
        elif 'id="Adjective"' in line:
            mode = 'adjective'
        elif 'id="Adverb"' in line:
            mode = 'adverb'
        elif 'id="Interjection"' in line:
            mode = 'interjection'
        elif 'id="Particle"' in line:
            mode = 'particle'
        elif 'id="Preposition"' in line:
            mode = 'preposition'
        elif 'id="Prefix"' in line:
            mode = 'prefix'
        elif 'id="Suffix"' in line:
            mode = 'suffix'
        # 'id="' can occur in definition lines <li> when <sup> tag is used for references;
        # make sure those are not excluded (see e.g., abecedarian).
        elif ('id="' in line) and ('<li>' not in line):
            mode = None

        elif (mode == 'etmyology') and ('<p>' in line):
            etymology = text(line)
        elif (mode is not None) and ('<li>' in line):
            definitions.setdefault(mode, []).append(text(line))

        if '<hr' in line:
            break
    return etymology, definitions
Beispiel #34
0
def wikt(word):
    bytes = requests.get(uri % web.quote(word)).text
    bytes = r_ul.sub('', bytes)

    mode = None
    etymology = None
    definitions = {}
    for line in bytes.splitlines():
        if 'id="Etymology"' in line:
            mode = 'etymology'
        elif 'id="Noun"' in line:
            mode = 'noun'
        elif 'id="Verb"' in line:
            mode = 'verb'
        elif 'id="Adjective"' in line:
            mode = 'adjective'
        elif 'id="Adverb"' in line:
            mode = 'adverb'
        elif 'id="Interjection"' in line:
            mode = 'interjection'
        elif 'id="Particle"' in line:
            mode = 'particle'
        elif 'id="Preposition"' in line:
            mode = 'preposition'
        elif 'id="Prefix"' in line:
            mode = 'prefix'
        elif 'id="Suffix"' in line:
            mode = 'suffix'
        # 'id="' can occur in definition lines <li> when <sup> tag is used for references;
        # make sure those are not excluded (see e.g., abecedarian).
        elif ('id="' in line) and ('<li>' not in line):
            mode = None

        elif (mode == 'etmyology') and ('<p>' in line):
            etymology = text(line)
        elif (mode is not None) and ('<li>' in line):
            definitions.setdefault(mode, []).append(text(line))

        if '<hr' in line:
            break
    return etymology, definitions
Beispiel #35
0
def suggest(bot, trigger):
    if not trigger.group(2):
	if bot.config.lang == 'fr':
            bot.reply("Erreur de syntaxe.")
	elif bot.config.lang == 'es':
            bot.reply("Error de sintaxis.")
	else:
            bot.reply("Syntax error.")
	return
    query = trigger.group(2)
    uri = 'http://websitedev.de/temp-bin/suggest.pl?q='
    answer = web.get(uri + web.quote(query).replace('+', '%2B'))
    if answer:
    	bot.say(answer)
    else:
    	if bot.config.lang == 'fr':
    	    bot.reply("N'aucun résultat.")
    	elif bot.config.lang == 'es':
            bot.reply("No hay resultados")
    	else:
            bot.reply('Sorry, no result.')
Beispiel #36
0
def wa(bot, trigger):
    """Wolfram Alpha calculator"""
    if not trigger.group(2):
        return bot.reply("No search term.")
    query = trigger.group(2)
    uri = BASE_TUMBOLIA_URI + 'wa/'
    try:
        answer = web.get(uri + web.quote(query.replace('+', 'plus')),
                         45,
                         dont_decode=True)
    except timeout as e:
        return bot.say('[WOLFRAM ERROR] Request timed out')
    if answer:
        answer = answer.decode('unicode_escape')
        answer = HTMLParser.HTMLParser().unescape(answer)
        # This might not work if there are more than one instance of escaped
        # unicode chars But so far I haven't seen any examples of such output
        # examples from Wolfram Alpha
        match = re.search('\\\:([0-9A-Fa-f]{4})', answer)
        if match is not None:
            char_code = match.group(1)
            char = unichr(int(char_code, 16))
            answer = answer.replace('\:' + char_code, char)
        waOutputArray = answer.split(";")
        if (len(waOutputArray) < 2):
            if (answer.strip(
            ) == "Couldn't grab results from json stringified precioussss."):
                # Answer isn't given in an IRC-able format, just link to it.
                bot.say(
                    '[WOLFRAM]Couldn\'t display answer, try http://www.wolframalpha.com/input/?i='
                    + query.replace(' ', '+'))
            else:
                bot.say('[WOLFRAM ERROR]' + answer)
        else:

            bot.say('[WOLFRAM] ' + waOutputArray[0] + " = " + waOutputArray[1])
        waOutputArray = []
    else:
        bot.reply('Sorry, no result.')
Beispiel #37
0
def nowplaying(bot, trigger):
    """displays the most recent track played by a given IRC nick."""
    output = '' 
    notme = False
    if trigger.group(2):
        nick = re.match(r'^\S+', trigger.group(2)).group()
        notme = True
    else:
        nick = trigger.nick
    #check if nick is in room, if not, just use as lastfm username directly
    fmuser = bot.db.get_nick_value(nick, 'lastfm_user')
    if not fmuser:
        bot.say("Use .fmset to associate a last.fm username with your IRC nick.")
        fmuser = nick
    try:
        recent_tracks = query_lastfm(
            bot, 
            method = 'user.getrecenttracks', 
            user=web.quote(fmuser)
        )
    except Exception, e:
        bot.say("Couldn't contact last.fm :(")
        return
Beispiel #38
0
def wa_query(bot, trigger):
    if not trigger.group(2):
        return bot.say('[W|A] You must provide a query')
    elif not bot.config.wolfram.app_id:
        return bot.say('[W|A] Wolfram|Alpha API app ID not configured.')
    client = wolframalpha.Client(bot.config.wolfram.app_id)

    try:
        result = client.query(trigger.group(2))
    except Exception as e:
        return bot.say('[W|A] An error occurred ({})'.format(e.message))

    for pod in result.pods:
        if pod.id not in output_ids:
            continue
        return bot.say('[W|A] {}: {}'.format(pod.title, pod.text))

    if len(result.pods) > 0:
        return bot.say(
            '[W|A] No text-representable result found, see http://wolframalpha.com/input/?i={}'
            .format(web.quote(trigger.group(2))))

    return bot.say('[W|A] No results found.')
Beispiel #39
0
def wa(bot, trigger):
    """Wolfram Alpha calculator"""
    if not trigger.group(2):
        return bot.reply("No search term.")
    query = trigger.group(2)
    uri = BASE_TUMBOLIA_URI + "wa/"
    try:
        answer = web.get(uri + web.quote(query.replace("+", "plus")), 45, dont_decode=True)
    except timeout as e:
        return bot.say("[WOLFRAM ERROR] Request timed out")
    if answer:
        answer = answer.decode("unicode_escape")
        answer = HTMLParser.HTMLParser().unescape(answer)
        # This might not work if there are more than one instance of escaped
        # unicode chars But so far I haven't seen any examples of such output
        # examples from Wolfram Alpha
        match = re.search("\\\:([0-9A-Fa-f]{4})", answer)
        if match is not None:
            char_code = match.group(1)
            char = unichr(int(char_code, 16))
            answer = answer.replace("\:" + char_code, char)
        waOutputArray = answer.split(";")
        if len(waOutputArray) < 2:
            if answer.strip() == "Couldn't grab results from json stringified precioussss.":
                # Answer isn't given in an IRC-able format, just link to it.
                bot.say(
                    "[WOLFRAM]Couldn't display answer, try http://www.wolframalpha.com/input/?i="
                    + query.replace(" ", "+")
                )
            else:
                bot.say("[WOLFRAM ERROR]" + answer)
        else:

            bot.say("[WOLFRAM] " + waOutputArray[0] + " = " + waOutputArray[1])
        waOutputArray = []
    else:
        bot.reply("Sorry, no result.")
Beispiel #40
0
Datei: calc.py Projekt: mvk/sopel
def wa(bot, trigger):
    """Wolfram Alpha calculator"""
    if not trigger.group(2):
        return bot.reply("No search term.")
    query = trigger.group(2)
    uri = 'http://tumbolia-hrd.appspot.com/wa/'
    try:
        answer = web.get(uri + web.quote(query.replace('+', 'plus')), 45,
                         dont_decode=True)
    except timeout as e:
        return bot.say('[WOLFRAM ERROR] Request timed out')
    if answer:
        answer = answer.decode('unicode_escape')
        answer = HTMLParser.HTMLParser().unescape(answer)
        # This might not work if there are more than one instance of escaped
        # unicode chars But so far I haven't seen any examples of such output
        # examples from Wolfram Alpha
        match = re.search('\\\:([0-9A-Fa-f]{4})', answer)
        if match is not None:
            char_code = match.group(1)
            char = unichr(int(char_code, 16))
            answer = answer.replace('\:' + char_code, char)
        waOutputArray = answer.split(";")
        if(len(waOutputArray) < 2):
            if(answer.strip() == "Couldn't grab results from json stringified precioussss."):
                # Answer isn't given in an IRC-able format, just link to it.
                bot.say('[WOLFRAM]Couldn\'t display answer, try http://www.wolframalpha.com/input/?i=' + query.replace(' ', '+'))
            else:
                bot.say('[WOLFRAM ERROR]' + answer)
        else:

            bot.say('[WOLFRAM] ' + waOutputArray[0] + " = "
                    + waOutputArray[1])
        waOutputArray = []
    else:
        bot.reply('Sorry, no result.')
Beispiel #41
0
def say_fact(bot, trigger):
    """Response, if needed"""
    query = trigger.group(0)
    was = bucket_runtime_data.what_was_that
    db = None
    cur = None
    results = None

    if query.startswith('\001ACTION'):
        query = query[len('\001ACTION '):]

    # Check if our nick was mentioned
    addressed = query.lower().startswith(bot.nick.lower())
    addressed |= query.lower().endswith(bot.nick.lower())
    search_term = query.lower().strip()

    # Remove our nickname from the search term
    if search_term.startswith(bot.nick.lower()):
        search_term = search_term[(len(bot.nick) + 1):].strip()
    elif search_term.endswith(bot.nick.lower()):
        search_term = search_term[:-len(bot.nick)].strip()
    search_term = remove_punctuation(search_term).strip()

    fact_length = bot.config.bucket.fact_length or 6
    if len(query) < int(fact_length) and not addressed:
        return  # Ignore factoids shorter than configured or default 6 chars when not addresed
    if addressed and len(search_term) is 0:
        return  # Ignore 0 length queries when addressed
    if search_term == 'don\'t know' and not addressed:
        return  # Ignore "don't know" when not addressed
    if not addressed and trigger.sender in bucket_runtime_data.shut_up:
        return  # Don't say anything if not addressed and shutting up
    if search_term == 'shut up' and addressed:
        bot.reply('Okay...')
        bucket_runtime_data.shut_up.append(trigger.sender)
        _friend_decrease(bot, trigger)
        return
    elif search_term in [
            'come back', 'unshutup', 'get your sorry ass back here'
    ] and addressed:
        if trigger.sender in bucket_runtime_data.shut_up:
            bucket_runtime_data.shut_up.remove(trigger.sender)
            bot.reply('I\'m back!')
        else:
            bot.reply('Uhm, what? I was here all the time!')
        return
    literal = False
    inhibit = bucket_runtime_data.inhibit_reply
    if search_term.startswith('literal '):
        literal = True
        search_term = search_term[len('literal '):]
    elif search_term == 'what was that' and addressed:
        try:
            factoid_id = was[trigger.sender][0]
            factoid_fact = was[trigger.sender][1]
            factoid_tidbit = was[trigger.sender][2]
            factoid_verb = was[trigger.sender][3]
            bot.say('That was #%s - %s %s %s' %
                    (factoid_id, factoid_fact, factoid_verb, factoid_tidbit))
        except KeyError:
            bot.say('I have no idea')
        return
    elif search_term.startswith('reload') or search_term.startswith(
            'update') or inhibit == trigger:
        # ignore commands such as reload or update, don't show 'Don't Know'
        # responses for these
        return

    db = connect_db(bot)
    cur = db.cursor()
    factoid_search = None
    if addressed:
        factoid_search = bucket_runtime_data.factoid_search_re.search(
            search_term)
        _friend_increase(bot, trigger)
    try:
        if search_term == 'random quote':
            cur.execute(
                'SELECT * FROM bucket_facts WHERE fact LIKE "% quotes" ORDER BY id ASC'
            )
        elif factoid_search is not None:
            cur.execute(
                'SELECT * FROM bucket_facts WHERE fact = %s AND tidbit LIKE %s ORDER BY id ASC',
                (factoid_search.group(1), '%' + factoid_search.group(2) + '%'))
        else:
            cur.execute(
                'SELECT * FROM bucket_facts WHERE fact = %s ORDER BY id ASC',
                [search_term])
        results = cur.fetchall()
    except UnicodeEncodeError as e:
        bot.debug('bucket', 'Warning, database encoding error', 'warning')
        bot.debug('bucket', e, 'warning')
    finally:
        db.close()
    if results is None:
        return
    result = pick_result(results, bot)
    if addressed and result is None and factoid_search is None:
        was[trigger.sender] = dont_know(bot, trigger)
        return
    elif factoid_search is not None and result is None:
        bot.reply('Sorry, I could\'t find anything matching your query')
        return
    elif result is None:
        return

    fact, tidbit, verb = parse_factoid(result)
    tidbit = tidbit_vars(tidbit, trigger)

    if literal:
        if len(results) == 1:
            result = results[0]
            number = int(result[0])
            fact, tidbit, verb = parse_factoid(result)
            bot.say("#%d - %s %s %s" % (number, fact, verb, tidbit))
        else:
            bot.reply('just a second, I\'ll make the list!')
            bucket_literal_path = bot.config.bucket.literal_path
            bucket_literal_baseurl = bot.config.bucket.literal_baseurl
            if not bucket_literal_baseurl.endswith('/'):
                bucket_literal_baseurl = bucket_literal_baseurl + '/'
            if not os.path.isdir(bucket_literal_path):
                try:
                    os.makedirs(bucket_literal_path)
                except Exception as e:
                    bot.say("Can't create directory to store literal, sorry!")
                    bot.say(e)
                    return
            if search_term == 'random quote':
                filename = 'quotes'
            else:
                filename = fact.lower()
            f = open(os.path.join(bucket_literal_path, filename + '.txt'), 'w')
            for result in results:
                number = int(result[0])
                fact, tidbit, verb = parse_factoid(result)
                literal_line = "#%d - %s %s %s" % (number, fact, verb, tidbit)
                f.write(literal_line.encode('utf8') + '\n')
            f.close()
            link = bucket_literal_baseurl + web.quote(filename + '.txt')
            bot.reply('Here you go! %s (%d factoids)' % (link, len(results)))
        result = 'Me giving you a literal link'
    else:
        say_factoid(bot, fact, verb, tidbit, addressed)
    was[trigger.sender] = result
Beispiel #42
0
def wa_query(app_id, query, units='metric'):
    if not app_id:
        return 'Wolfram|Alpha API app ID not provided.'
    client = wolframalpha.Client(app_id)
    query = query.encode('utf-8').strip()
    params = (
        ('format', 'plaintext'),
        ('units', units),
    )

    try:  # Remove this mess for the next bump after 0.4
        try:  # wolframalpha 3.x supports extra stuff
            result = client.query(
                input=query,
                params=params)  # This is the only necessary line post-0.4
        except TypeError:  # fall back to query-only for 2.x
            try:
                result = client.query(query)
            except:
                raise  # send any exceptions to the outer level
        except:
            raise  # ditto; the 0.4 mess ends here
    except AssertionError:
        return 'Temporary API issue. Try again in a moment.'
    except Exception as e:
        return 'Query failed: {} ({})'.format(
            type(e).__name__, e.message or 'Unknown error, try again!')

    num_results = 0
    try:  # try wolframalpha 3.x way
        num_results = int(result['@numpods'])
    except TypeError:  # fall back to wolframalpha 2.x way
        num_results = len(result.pods)
    finally:
        if num_results == 0:
            return 'No results found.'

    texts = []
    try:
        for pod in result.pods:
            try:
                texts.append(pod.text)
            except AttributeError:
                pass  # pod with no text; skip it
            except Exception:
                raise  # raise unexpected exceptions to outer try for bug reports
            if len(texts) >= 2:
                break  # len() is O(1); this cheaply avoids copying more strings than needed
    except Exception as e:
        return 'Unhandled {}; please report this query ("{}") at https://dgw.me/wabug'.format(
            type(e).__name__, query)

    try:
        input, output = texts[0], texts[1]
    except IndexError:
        return 'No text-representable result found; see http://wolframalpha.com/input/?i={}'.format(
            web.quote(query))

    if not output:
        return input
    return '{} = {}'.format(input, output)
Beispiel #43
0
def wa_query(app_id, query, units='metric'):
    if not app_id:
        return 'Wolfram|Alpha API app ID not provided.'
    client = wolframalpha.Client(app_id)
    query = query.encode('utf-8').strip()
    params = (
        ('format', 'plaintext'),
        ('units', units),
    )

    try:  # Remove this mess for the next bump after 0.4
        try:  # wolframalpha 3.x supports extra stuff
            result = client.query(input=query, params=params)  # This is the only necessary line post-0.4
        except TypeError:  # fall back to query-only for 2.x
            try:
                result = client.query(query)
            except:
                raise  # send any exceptions to the outer level
        except:
            raise  # ditto; the 0.4 mess ends here
    except AssertionError:
        return 'Temporary API issue. Try again in a moment.'
    except Exception as e:
        return 'Query failed: {} ({})'.format(type(e).__name__, e.message or 'Unknown error, try again!')

    num_results = 0
    try:  # try wolframalpha 3.x way
        num_results = int(result['@numpods'])
    except TypeError:  # fall back to wolframalpha 2.x way
        num_results = len(result.pods)
    finally:
        if num_results == 0:
            return 'No results found.'

    texts = []
    try:
        for pod in result.pods:
            try:
                texts.append(pod.text)
            except AttributeError:
                pass  # pod with no text; skip it
            except Exception:
                raise  # raise unexpected exceptions to outer try for bug reports
            if len(texts) >= 2:
                break  # len() is O(1); this cheaply avoids copying more strings than needed
    except Exception as e:
        return 'Unhandled {}; please report this query ("{}") at https://dgw.me/wabug'.format(type(e).__name__, query)

    try:
        input, output = texts[0], texts[1]
    except IndexError:
        return 'No text-representable result found; see http://wolframalpha.com/input/?i={}'.format(web.quote(query))

    if not output:
        return input
    return '{} = {}'.format(input, output)
Beispiel #44
0
def wa_query(bot, trigger):
    if not trigger.group(2):
        return bot.say('[W|A] You must provide a query')
    elif not bot.config.wolfram.app_id:
        return bot.say('[W|A] Wolfram|Alpha API app ID not configured.')
    client = wolframalpha.Client(bot.config.wolfram.app_id)

    try:
        result = client.query(trigger.group(2))
    except Exception as e:
        return bot.say('[W|A] An error occurred ({})'.format(e.message))

    for pod in result.pods:
        if pod.id not in output_ids:
            continue
        return bot.say('[W|A] {}: {}'.format(pod.title, pod.text))

    if len(result.pods) > 0:
        return bot.say('[W|A] No text-representable result found, see http://wolframalpha.com/input/?i={}'.format(web.quote(trigger.group(2))))

    return bot.say('[W|A] No results found.')
Beispiel #45
0
def googleit(bot, trigger):
    """Let me just... google that for you."""
    # No input
    if not trigger.group(2):
        return bot.say('https://www.google.com/')
    bot.say('https://lmgtfy.com/?q=' + quote(trigger.group(2).replace(' ', '+'), '+'))
def shorten_url(url):
    try:
        res, headers = web.post('http://git.io', 'url=' + web.quote(url), return_headers=True)
        return headers['location']
    except:
        return url
Beispiel #47
0
def wa_query(app_id, query):
    if not app_id:
        return 'Wolfram|Alpha API app ID not provided.'
    client = wolframalpha.Client(app_id)

    try:
        result = client.query(query)
    except Exception as e:
        return 'An error occurred: {}'.format(e.message or 'Unknown error, try again!')

    if len(result.pods) >= 2:
        try:
            input = result.pods[0].text
            output = result.pods[1].text
        except (IndexError, KeyError):
            pass
        else:
            return '{} = {}'.format(input, output)

    if len(result.pods) > 0:
        return 'No text-representable result found, see http://wolframalpha.com/input/?i={}'.format(web.quote(query))

    return 'No results found.'
Beispiel #48
0
    user = user.lower()
    quoted_user = web.quote(user)
    #json formatted output for recent track
    try:
        recent_page = web.get("http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=%s&api_key=782c02b1c96ae181d83850f050509103&format=json" % (quoted_user))
    except Exception, e:
        willie.say("last.fm is currently having technical difficulties. See .fmstatus for more information.")
        return

    try:
        recent_track = json.loads(recent_page)['recenttracks']['track'][0]
    except KeyError:
        willie.say("Couldn't find user")
        sys.exit(0)
    #artist and track name pulled from recent_track
    quoted_artist = web.quote(recent_track['artist']['#text'])
    quoted_track = web.quote(recent_track['name'])
    #json formatted track info
    trackinfo_page = urllib.urlopen("http://ws.audioscrobbler.com/2.0/?method=track.getInfo&artist=%s&track=%s&username=%s&api_key=782c02b1c96ae181d83850f050509103&format=json" % (quoted_artist, quoted_track, quoted_user))
    #track playcount and loved stats
    loved = 0
    try:
      trackinfo = json.loads(trackinfo_page.read())['track']
      playcount = trackinfo['userplaycount']
      loved = int(trackinfo['userloved'])
    except KeyError:
        playcount = "unknown"
    album = '(' + recent_track['album']['#text'] + ') '
    if len(recent_track['album']['#text']) == 0:
        album = ''
Beispiel #49
0
def wa(bot, trigger):
    if not trigger.group(2):
        if bot.config.lang == 'fr':
            return bot.reply(
                "Rien à trouver. Syntaxe: .wa <mot|phrase|opération|...>.")
        elif bot.config.lang == 'es':
            return bot.reply(
                "Nada para buscar. Sintaxis: .wa <palabra|frase|operación|...>."
            )
        else:
            return bot.reply(
                "Nothing to search. Syntax: .wa <word|sentence|operation|...>."
            )
    query = trigger.group(2)
    uri = 'http://tumbolia.appspot.com/wa/'
    try:
        answer = web.get(uri + web.quote(query.replace('+', '%2B')), 45)
    except timeout as e:
        if bot.config.lang == 'fr':
            return bot.say('[WOLFRAM ERROR] Délai d\'expiration dépassée.')
        elif bot.config.lang == 'es':
            return bot.say('[WOLFRAM ERROR] Tiempo de espera excedido.')
        else:
            return bot.say('[WOLFRAM ERROR] Request timed out')
    if answer:
        answer = answer.decode('string_escape')
        answer = HTMLParser.HTMLParser().unescape(answer)
        # This might not work if there are more than one instance of escaped
        # unicode chars But so far I haven't seen any examples of such output
        # examples from Wolfram Alpha
        match = re.search('\\\:([0-9A-Fa-f]{4})', answer)
        if match is not None:
            char_code = match.group(1)
            char = unichr(int(char_code, 16))
            answer = answer.replace('\:' + char_code, char)
        waOutputArray = string.split(answer, ";")
        if (len(waOutputArray) < 2):
            if (answer.strip(
            ) == "Couldn't grab results from json stringified precioussss."):
                # Answer isn't given in an IRC-able format, just link to it.
                if bot.config.lang == 'fr':
                    bot.say(
                        '[WOLFRAM] Il n\'y a pas n\'aucune réposte disponible. Tenter amb http://www.wolframalpha.com/input/?i='
                        + query.replace(' ', '+'))
                elif bot.config.lang == 'es':
                    bot.say(
                        '[WOLFRAM] No hay ninguna respusta disponible. Prueba con http://www.wolframalpha.com/input/?i='
                        + query.replace(' ', '+'))
                else:
                    bot.say(
                        '[WOLFRAM] Couldn\'t display any answer. Please try http://www.wolframalpha.com/input/?i='
                        + query.replace(' ', '+'))
            else:
                bot.say('[WOLFRAM ERROR]' + answer)
        else:

            bot.say('[WOLFRAM] ' + waOutputArray[0] + " = " + waOutputArray[1])
        waOutputArray = []
    else:
        if bot.config.lang == 'fr':
            bot.reply(u"Sans résultats.")
        elif bot.config.lang == 'es':
            bot.repy(u"Sin resultados.")
        else:
            bot.reply('No results.')