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))
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']
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
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]
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)
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 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
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]
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
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]
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
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}
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}
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
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()
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))
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()
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
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.')
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()
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
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
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)
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
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
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]
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]
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]
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
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.')
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.')
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
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.')
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.")
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.')
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
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)
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)
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.')
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.'
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 = ''
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.')