From ff1832c47155d3a415528e701f5e19132760ca5b Mon Sep 17 00:00:00 2001 From: stoneLeaf Date: Thu, 12 Apr 2012 01:52:32 +0200 Subject: [PATCH 1/6] Fixed a locale issue in the youtube plugin locale.format() can throw a UnicodeDecodeError in some cases. The use of str.decode() prevents its occurrence. See http://stackoverflow.com/questions/4082645/using-python-2-xs-locale-module-to-format-numbers-and-currency --- plugins/youtube.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/youtube.py b/plugins/youtube.py index 747a1b2..651fa4d 100644 --- a/plugins/youtube.py +++ b/plugins/youtube.py @@ -41,9 +41,11 @@ def get_video_description(vid_id): out += ' - rated \x02%.2f/5.0\x02 (%d)' % (j['rating'], j['ratingCount']) + # The use of str.decode() prevents UnicodeDecodeError with some locales + # See http://stackoverflow.com/questions/4082645/ if 'viewCount' in j: out += ' - \x02%s\x02 views' % locale.format('%d', - j['viewCount'], 1) + j['viewCount'], 1).decode(locale.getlocale()[1]) upload_time = time.strptime(j['uploaded'], "%Y-%m-%dT%H:%M:%S.000Z") out += ' - \x02%s\x02 on \x02%s\x02' % (j['uploader'], From b279f96af094edff711271cb21f7de2f66223e70 Mon Sep 17 00:00:00 2001 From: stoneLeaf Date: Thu, 12 Apr 2012 02:11:33 +0200 Subject: [PATCH 2/6] Updated Encyclopedia Dramatica's url On March 21, 2012, the website moved to a Swedish domain name: http://encyclopediadramatica.se --- plugins/drama.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/drama.py b/plugins/drama.py index 1a84fda..7715da7 100644 --- a/plugins/drama.py +++ b/plugins/drama.py @@ -3,8 +3,8 @@ article''' from util import hook, http -api_url = "http://encyclopediadramatica.ch/api.php?action=opensearch" -ed_url = "http://encyclopediadramatica.ch/" +api_url = "http://encyclopediadramatica.se/api.php?action=opensearch" +ed_url = "http://encyclopediadramatica.se/" @hook.command('ed') From 3c9e6a6736a003aa44fe8f14ab9eae2d0638a752 Mon Sep 17 00:00:00 2001 From: stoneLeaf Date: Thu, 12 Apr 2012 03:02:46 +0200 Subject: [PATCH 3/6] Added a check to the oblique plugin Checks if lines can be split. --- plugins/oblique.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/oblique.py b/plugins/oblique.py index a39b91f..9f0cd37 100644 --- a/plugins/oblique.py +++ b/plugins/oblique.py @@ -19,6 +19,9 @@ def update_commands(force=False): if not line.strip(): continue + if line.strip().find(" ") == -1: + continue + name, url = line.strip().split(None, 1) commands[name] = url From 25116e20f99d4fd68f0fd431710c8327ea3470d0 Mon Sep 17 00:00:00 2001 From: stoneLeaf Date: Thu, 12 Apr 2012 03:41:35 +0200 Subject: [PATCH 4/6] Fixed the suggest plugin The API get request needed to be tweaked. --- plugins/suggest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/suggest.py b/plugins/suggest.py index f3e69bc..3d30195 100644 --- a/plugins/suggest.py +++ b/plugins/suggest.py @@ -19,7 +19,7 @@ def suggest(inp, inp_unstripped=''): else: num = 0 - page = http.get('http://google.com/complete/search', q=inp) + page = http.get('http://google.com/complete/search', output='json', client='hp', q=inp) page_json = page.split('(', 1)[1][:-1] suggestions = json.loads(page_json)[1] if not suggestions: @@ -30,4 +30,4 @@ def suggest(inp, inp_unstripped=''): out = suggestions[num - 1] else: out = random.choice(suggestions) - return '#%d: %s' % (int(out[2][0]) + 1, out[0]) + return '#%d: %s' % (int(out[2][0]) + 1, out[0].replace('', '').replace('', '')) From b939a94be7b02da9abf7a978f2b4587abdca8b8c Mon Sep 17 00:00:00 2001 From: stoneLeaf Date: Thu, 12 Apr 2012 14:02:36 +0200 Subject: [PATCH 5/6] Improved the Last.fm plugin The API key is now retrieved from the bot config file and the API response is more thoroughly analyzed. --- plugins/lastfm.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/plugins/lastfm.py b/plugins/lastfm.py index 89f590d..4e77f65 100644 --- a/plugins/lastfm.py +++ b/plugins/lastfm.py @@ -1,13 +1,19 @@ +''' +The Last.fm API key is retrieved from the bot config file. +''' + from util import hook, http -api_key = "" - api_url = "http://ws.audioscrobbler.com/2.0/?format=json" @hook.command -def lastfm(inp, nick='', say=None): +def lastfm(inp, nick='', say=None, bot=None): + api_key = bot.config.get("api_keys", {}).get("lastfm", None) + if not api_key: + return None + if inp: user = inp else: @@ -20,13 +26,13 @@ def lastfm(inp, nick='', say=None): if inp: # specified a user name return "error: %s" % response["message"] else: - return "your nick is not a LastFM account. try '.lastfm username'." + return "your nick is not a Last.fm account. try '.lastfm username'." + + if not "track" in response["recenttracks"] or len(response["recenttracks"]["track"]) == 0: + return "no recent tracks for user \x02%s\x0F found" % user tracks = response["recenttracks"]["track"] - if len(tracks) == 0: - return "no recent tracks for user %r found" % user - if type(tracks) == list: # if the user is listening to something, the tracks entry is a list # the first item is the current track From 4770c8c2271b795b8434e0827fb7af19c364d2be Mon Sep 17 00:00:00 2001 From: stoneLeaf Date: Thu, 12 Apr 2012 16:11:52 +0200 Subject: [PATCH 6/6] Updated the Google Translate plugin The Google Translate API v1 has been stopped since December 1, 2011. From now on, the API is a paid service only. The plugin has been updated to support v2 and grab the (mandatory) API key from the bot config file. --- plugins/translate.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/plugins/translate.py b/plugins/translate.py index ec4fd42..efdb54e 100644 --- a/plugins/translate.py +++ b/plugins/translate.py @@ -1,8 +1,15 @@ +''' +A Google API key is required and retrieved from the bot config file. +Since December 1, 2011, the Google Translate API is a paid service only. +''' + import htmlentitydefs import re from util import hook, http +api_key = "" + ########### from http://effbot.org/zone/re-sub.htm#unescape-html ############# @@ -32,15 +39,15 @@ def unescape(text): def goog_trans(text, slang, tlang): - url = 'http://ajax.googleapis.com/ajax/services/language/translate?v=1.0' - parsed = http.get_json(url, q=text, langpair=(slang + '|' + tlang)) + url = 'https://www.googleapis.com/language/translate/v2' + parsed = http.get_json(url, key=api_key, q=text, source=slang, target=tlang) if not 200 <= parsed['responseStatus'] < 300: raise IOError('error with the translation server: %d: %s' % ( parsed['responseStatus'], parsed['responseDetails'])) if not slang: return unescape('(%(detectedSourceLanguage)s) %(translatedText)s' % - (parsed['responseData'])) - return unescape(parsed['responseData']['translatedText']) + (parsed['responseData']['data']['translations'][0])) + return unescape('%(translatedText)s' % parsed['responseData']['data']['translations'][0]) def match_language(fragment): @@ -57,11 +64,14 @@ def match_language(fragment): @hook.command -def translate(inp): +def translate(inp, bot=None): '.translate [source language [target language]] -- translates' \ ' from source language (default autodetect) to target' \ ' language (default English) using Google Translate' + if not hasapikey(bot): + return None + args = inp.split(' ', 2) try: @@ -69,6 +79,8 @@ def translate(inp): sl = match_language(args[0]) if not sl: return goog_trans(inp, '', 'en') + if len(args) == 2: + return goog_trans(args[1], sl, 'en') if len(args) >= 3: tl = match_language(args[1]) if not tl: @@ -94,9 +106,12 @@ def babel_gen(inp): @hook.command -def babel(inp): +def babel(inp, bot=None): ".babel -- translates through multiple languages" + if not hasapikey(bot): + return None + try: return list(babel_gen(inp))[-1][2] except IOError, e: @@ -104,9 +119,12 @@ def babel(inp): @hook.command -def babelext(inp): +def babelext(inp, bot=None): ".babelext -- like .babel, but with more detailed output" + if not hasapikey(bot): + return None + try: babels = list(babel_gen(inp)) except IOError, e: @@ -123,6 +141,9 @@ def babelext(inp): return out +def hasapikey(bot): + api_key = bot.config.get("api_keys", {}).get("googletranslate", None) + return api_key lang_pairs = [ ("no", "Norwegian"),