Skip to content

Commit

Permalink
Improved the Twitter plugin (fixes rmmh#11)
Browse files Browse the repository at this point in the history
Display the full retweeted status in case of a native retweet.
Also, time.strptime() is now done in a much more locale-independent manner. Before that, a system without an english locale available was not able to parse the dates provided by the Twitter API.
  • Loading branch information
stoneLeaf committed Apr 15, 2012
1 parent 8e8e94e commit c94b02b
Showing 1 changed file with 34 additions and 16 deletions.
50 changes: 34 additions & 16 deletions plugins/twitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,19 @@
from util import hook, http


def unescape_xml(string):
# unescape the 5 chars that might be escaped in xml
# Conversion table to prevent locale issues
abbreviated_month_name = {"Jan": "01", "Feb": "02", "Mar": "03", "Apr": "04",
"May": "05", "Jun": "06", "Jul": "07", "Aug": "08",
"Sep": "09", "Oct": "10", "Nov": "11", "Dec": "12"}


# gratuitously functional
def unescape_xml(string):
"""Unescape the 5 chars that might be escaped in xml"""
# Gratuitously functional
# return reduce(lambda x, y: x.replace(*y), (string,
# zip('&gt; &lt; &apos; &quote; &amp'.split(), '> < \' " &'.split()))

# boring, normal
# Boring, normal
return string.replace('&gt;', '>').replace('&lt;', '<').replace('&apos;',
"'").replace('&quote;', '"').replace('&amp;', '&')

Expand Down Expand Up @@ -47,13 +52,15 @@ def find_reply(reply_name):
return 'error: no replies to %s found' % inp
inp = reply_inp

url = 'http://twitter.com'
url = 'http://api.twitter.com'
getting_nth = False
getting_id = False
searching_hashtag = False

time = 'status/created_at'
text = 'status/text'
retweeted_text = 'status/retweeted_status/text'
retweeted_screen_name = 'status/retweeted_status/user/screen_name'
reply_name = 'status/in_reply_to_screen_name'
reply_id = 'status/in_reply_to_status_id'
reply_user = 'status/in_reply_to_user_id'
Expand All @@ -67,15 +74,17 @@ def find_reply(reply_name):
reply_name = 'in_reply_to_screen_name'
reply_id = 'in_reply_to_status_id'
reply_user = 'in_reply_to_user_id'
elif re.match(r'^\w{1,15}$', inp):
url += '/users/show/%s.xml' % inp
screen_name = 'screen_name'
elif re.match(r'^\w{1,15}\s+\d+$', inp):
elif re.match(r'^\w{1,15}$', inp) or re.match(r'^\w{1,15}\s+\d+$', inp):
getting_nth = True
name, num = inp.split()
if inp.find(' ') == -1:
name = inp
num = 1
else:
name, num = inp.split()
if int(num) > 3200:
return 'error: only supports up to the 3200th tweet'
url += '/statuses/user_timeline/%s.xml?count=1&page=%s' % (name, num)
url += ('/1/statuses/user_timeline.xml?include_rts=true&'
'screen_name=%s&count=1&page=%s' % (name, num))
screen_name = 'status/user/screen_name'
elif re.match(r'^#\w+$', inp):
url = 'http://search.twitter.com/search.atom?q=%23' + inp[1:]
Expand All @@ -98,7 +107,7 @@ def find_reply(reply_name):
if e.code in errors:
return 'error: ' + errors[e.code]
return 'error: unknown %s' % e.code
except http.URLerror, e:
except http.URLError, e:
return 'error: timeout'

if searching_hashtag:
Expand All @@ -122,13 +131,22 @@ def find_reply(reply_name):
reply_id = tweet.find(reply_id).text
reply_user = tweet.find(reply_user).text
if reply_name is not None and (reply_id is not None or
reply_user is not None):
reply_user is not None):
add_reply(reply_name, reply_id or -1)

# Retrieving the full tweet in case of a native retweet
if tweet.find(retweeted_text) is not None:
text = 'RT @' + tweet.find(retweeted_screen_name).text + ': '
text += unescape_xml(tweet.find(retweeted_text).text.replace('\n', ''))
else:
text = unescape_xml(tweet.find(text).text.replace('\n', ''))

# Using a conversion table to do a locale-independent date parsing
time_parts = time.text.split(' ', 2)
time = abbreviated_month_name[time_parts[1]] + ' ' + time_parts[2]
time = strftime('%Y-%m-%d %H:%M:%S',
strptime(time.text,
'%a %b %d %H:%M:%S +0000 %Y'))
text = unescape_xml(tweet.find(text).text.replace('\n', ''))
strptime(time, '%m %d %H:%M:%S +0000 %Y'))

screen_name = tweet.find(screen_name).text

return "%s %s: %s" % (time, screen_name, text)

0 comments on commit c94b02b

Please sign in to comment.