2010-12-15 23:08:08 -06:00
"""
Twitter - access to Twitter through bot commands
Copyright ( C ) 2010 Brian S . Stephan
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : / / www . gnu . org / licenses / > .
"""
import urlparse
import oauth2 as oauth
from extlib import irclib
from extlib import twitter
from Module import Module
class Twitter ( Module ) :
"""
Access Twitter via the bot as an authenticated client .
"""
def __init__ ( self , config , server , modlist ) :
"""
Prompt the user for oauth stuff when starting up .
TODO : make this optional , and have API calls log if they need auth .
"""
Module . __init__ ( self , config , server , modlist )
# begin oauth magic
2010-12-16 20:15:49 -06:00
self . consumer_key = ' N2aSGxBP8t3cCgWyF1B2Aw '
self . consumer_secret = ' 0aQPEV4K3MMpicfi2lDtCP5pvjsKaqIpfuWtsPzx8 '
2010-12-15 23:08:08 -06:00
2010-12-16 20:15:49 -06:00
self . request_token_url = ' https://api.twitter.com/oauth/request_token '
self . access_token_url = ' https://api.twitter.com/oauth/access_token '
self . authorize_url = ' https://api.twitter.com/oauth/authorize '
2010-12-15 23:08:08 -06:00
2010-12-16 20:15:49 -06:00
self . consumer = oauth . Consumer ( self . consumer_key , self . consumer_secret )
self . client = oauth . Client ( self . consumer )
2010-12-15 23:08:08 -06:00
2010-12-16 20:15:49 -06:00
# create a default twitter API account, in case we never auth
self . twit = twitter . Api ( )
2010-12-24 13:19:11 -06:00
self . authed = False
2010-12-15 23:08:08 -06:00
def do ( self , connection , event , nick , userhost , replypath , what , admin_unlocked ) :
"""
Attempt to do twitter things .
"""
whats = what . split ( ' ' )
if whats [ 0 ] == ' twitter ' and len ( whats ) > = 2 :
if whats [ 1 ] == ' status ' and len ( whats ) == 3 :
try :
tweet = self . twit . GetStatus ( whats [ 2 ] )
2010-12-16 15:22:34 -06:00
return self . reply ( connection , replypath , self . tweet_or_retweet_text ( tweet = tweet , print_source = True ) )
2010-12-15 23:08:08 -06:00
except twitter . TwitterError as e :
return self . reply ( connection , replypath , ' Couldn \' t obtain status: ' + str ( e ) )
2010-12-16 15:23:35 -06:00
elif whats [ 1 ] == ' user ' and len ( whats ) > = 3 :
if len ( whats ) > = 4 :
index = int ( whats [ 3 ] )
2010-12-16 15:44:51 -06:00
if index > 0 :
2010-12-16 15:23:35 -06:00
index = 0
else :
index = 0
count = ( - 1 * index ) + 1
2010-12-15 23:31:26 -06:00
try :
2010-12-16 15:23:35 -06:00
tweets = self . twit . GetUserTimeline ( screen_name = whats [ 2 ] , count = count , include_rts = True )
2010-12-15 23:52:59 -06:00
if tweets :
2010-12-16 15:23:35 -06:00
tweet = tweets [ - 1 * index ]
2010-12-16 15:22:34 -06:00
return self . reply ( connection , replypath , self . tweet_or_retweet_text ( tweet = tweet ) )
2010-12-15 23:31:26 -06:00
except twitter . TwitterError as e :
return self . reply ( connection , replypath , ' Couldn \' t obtain status: ' + str ( e ) )
2010-12-24 13:19:50 -06:00
elif whats [ 1 ] == ' tweet ' and len ( whats ) > = 3 :
if self . authed is False :
return self . reply ( connection , replypath , ' You must be authenticated to tweet. ' )
if admin_unlocked is False :
return self . reply ( connection , replypath , ' Only admins can tweet. ' )
try :
if self . twit . PostUpdates ( ' ' . join ( whats [ 2 : ] ) , continuation = u ' \u2026 ' ) is not None :
return self . reply ( connection , replypath , ' Tweet(s) sent. ' )
else :
return self . reply ( connection , replypath , ' Unknown error sending tweet(s). ' )
except twitter . TwitterError as e :
return self . reply ( connection , replypath , ' Couldn \' t tweet: ' + str ( e ) )
2010-12-16 20:15:49 -06:00
elif whats [ 1 ] == ' gettoken ' :
# get request token
resp , content = self . client . request ( self . request_token_url , " GET " )
if resp [ ' status ' ] != ' 200 ' :
raise Exception ( " Invalid response %s . " % resp [ ' status ' ] )
self . request_token = dict ( urlparse . parse_qsl ( content ) )
# have the user auth
return self . reply ( connection , replypath , ' Go to the following link in your browser: %s ?oauth_token= %s and then send me the pin. ' % ( self . authorize_url , self . request_token [ ' oauth_token ' ] ) )
elif whats [ 1 ] == ' auth ' and len ( whats ) > = 3 :
oauth_verifier = whats [ 2 ]
# request access token
token = oauth . Token ( self . request_token [ ' oauth_token ' ] , self . request_token [ ' oauth_token_secret ' ] )
token . set_verifier ( oauth_verifier )
client = oauth . Client ( self . consumer , token )
resp , content = client . request ( self . access_token_url , " POST " )
self . access_token = dict ( urlparse . parse_qsl ( content ) )
# finally, create the twitter API object
self . twit = twitter . Api ( self . consumer_key , self . consumer_secret , self . access_token [ ' oauth_token ' ] , self . access_token [ ' oauth_token_secret ' ] )
2010-12-24 13:19:11 -06:00
self . authed = True
2010-12-16 20:15:49 -06:00
return self . reply ( connection , replypath , ' The bot is now logged in. ' )
2010-12-15 23:08:08 -06:00
2010-12-16 15:22:34 -06:00
def tweet_or_retweet_text ( self , tweet , print_source = False ) :
2010-12-16 13:04:58 -06:00
"""
Return a string of the author and text body of a status ,
accounting for whether or not the fetched status is a
retweet .
"""
if tweet . retweeted_status :
retweet = tweet . retweeted_status
2010-12-16 15:22:34 -06:00
if print_source :
return ' %s (RT %s ): %s ' % ( tweet . user . name . encode ( ' utf-8 ' , ' ignore ' ) , retweet . user . name . encode ( ' utf-8 ' , ' ignore ' ) , retweet . text . encode ( ' utf-8 ' , ' ignore ' ) )
else :
return ' (RT %s ): %s ' % ( retweet . user . name . encode ( ' utf-8 ' , ' ignore ' ) , retweet . text . encode ( ' utf-8 ' , ' ignore ' ) )
2010-12-16 13:04:58 -06:00
else :
2010-12-16 15:22:34 -06:00
if print_source :
return ' %s : %s ' % ( tweet . user . name . encode ( ' utf-8 ' , ' ignore ' ) , tweet . text . encode ( ' utf-8 ' , ' ignore ' ) )
else :
return ' %s ' % ( tweet . text . encode ( ' utf-8 ' , ' ignore ' ) )
2010-12-16 13:04:58 -06:00
2010-12-15 23:08:08 -06:00
# vi:tabstop=4:expandtab:autoindent
# kate: indent-mode python;indent-width 4;replace-tabs on;