2017-03-23 19:23:31 +00:00
import ast , dbtools , html , io , logging , moviepy . editor , os , PIL . Image , random , re , setuptools , string , bottools . strings , sys , telegram . ext , telegram , time , twitools , twitools . streaming , urllib . request , tweepy
2017-03-22 00:53:51 +00:00
def getTwo ( message ) :
try :
return twitools . twoBotHelper ( message . chat_id )
except ValueError :
message . reply_text ( bottools . strings . noauth )
except tweepy . error . TweepError as e :
raise
def twoExceptions ( e , message ) :
text = {
32 : bottools . strings . badToken ,
36 : bottools . strings . selfSpam ,
64 : bottools . strings . accountSuspended ,
88 : bottools . strings . rateLimit ,
89 : bottools . strings . badToken ,
99 : bottools . strings . badToken ,
130 : bottools . strings . overload ,
131 : bottools . strings . twitterError ,
161 : bottools . strings . followLimit ,
185 : bottools . strings . tweetLimit ,
186 : bottools . strings . longTweet ,
187 : bottools . strings . dupTweet ,
205 : bottools . strings . rateLimit ,
226 : bottools . strings . automatedTweet ,
271 : bottools . strings . selfMute ,
272 : bottools . strings . notMuted ,
323 : bottools . strings . multipleGIFs ,
326 : bottools . strings . accountLocked ,
354 : bottools . strings . longTweet
} . get ( e . api_code )
message . reply_text ( text or bottools . strings . twoFail )
# Actual methods:
# ---------------
def start ( bot , update ) :
2017-03-22 11:18:07 +00:00
update . message . reply_text ( bottools . strings . start % { " name " : setuptools . botname ( ) } )
2017-03-22 00:53:51 +00:00
def fish ( bot , update ) :
dbtools . dbHelper ( ) . addFish ( update . message . chat_id )
update . message . reply_text ( bottools . strings . fishThanks )
def getTweetID ( tlid , cid ) :
try :
db = dbtools . dbHelper ( )
db . executeQuery ( " SELECT tid FROM timelines WHERE nr = %i AND cid = %i ; " % ( int ( tlid ) , int ( cid ) ) )
return db . getNext ( ) [ 0 ]
except Exception :
raise ValueError ( " No such tweet in timeline " )
def toggleTweet ( bot , update ) :
try :
update . message . reply_text ( bottools . strings . toggleTweet % ( bottools . strings . toggleTweetOn if dbtools . dbHelper ( ) . toggleTweet ( update . message . chat_id ) else bottools . strings . toggleTweetOff ) )
except tweepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
def unknown ( bot , update ) :
update . message . reply_text ( bottools . strings . unknownCommand )
2017-03-23 21:39:54 +00:00
def makeMenu ( buttons , columns ) :
return [ buttons [ i : i + columns ] for i in range ( 0 , len ( buttons ) , columns ) ]
2017-03-22 00:53:51 +00:00
# Authentication process
def auth ( bot , update ) :
db = dbtools . dbHelper ( )
cid = update . message . chat_id
if not ( db . ato ( cid ) or db . ase ( cid ) ) :
auth = tweepy . OAuthHandler ( setuptools . cke ( ) , setuptools . cse ( ) )
update . message . reply_text ( bottools . strings . auth % auth . get_authorization_url ( ) )
dbtools . dbHelper ( ) . storeToken ( cid , auth . request_token )
else :
update . message . reply_text ( bottools . strings . authimp )
def verify ( bot , update , args ) :
db = dbtools . dbHelper ( )
cid = update . message . chat_id
if db . ato ( cid ) and not db . ase ( cid ) :
auth = tweepy . OAuthHandler ( setuptools . cke ( ) , setuptools . cse ( ) )
auth . request_token = ast . literal_eval ( db . ato ( cid ) )
try :
auth . get_access_token ( args [ 0 ] )
dbtools . dbHelper ( ) . storeUser ( cid , auth . access_token , auth . access_token_secret )
update . message . reply_text ( bottools . strings . verify )
except Exception as e :
dbtools . dbHelper ( ) . deleteUser ( update . message . chat_id )
update . message . reply_text ( bottools . strings . verifyfail )
else :
update . message . reply_text ( bottools . strings . verifyimp )
def unauth ( bot , update ) :
dbtools . dbHelper ( ) . deleteUser ( update . message . chat_id )
update . message . reply_text ( bottools . strings . unauth % setuptools . url ( ) )
# User methods
def follow ( bot , update , args ) :
try :
two = bottools . methods . getTwo ( update . message )
for user in args :
two . api . create_friendship ( screen_name = user )
except tweepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
def unfollow ( bot , update , args ) :
try :
two = bottools . methods . getTwo ( update . message )
for user in args :
two . api . destroy_friendship ( screen_name = user )
except tweepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
# Tweet methods
def explicitTweet ( bot , update , args , reply = None ) :
try :
two = bottools . methods . getTwo ( update . message )
if update . message . photo or update . message . document or update . message . video or update . message . sticker :
fid = update . message . document . file_id if update . message . document else update . message . sticker . file_id if update . message . sticker else update . message . video . file_id if update . message . video else update . message . photo [ - 1 ] . file_id
path = bot . getFile ( fid ) . file_path
media = urllib . request . urlopen ( path )
mobj = io . BytesIO ( media . read ( ) )
filename = path . split ( " / " ) [ - 1 ]
if filename . split ( " . " ) [ - 1 ] . lower ( ) == " webp " :
out = io . BytesIO ( )
PIL . Image . open ( mobj ) . convert ( ' RGB ' ) . save ( out , format = " JPEG " )
filename = " %s .jpg " % filename . split ( " . " ) [ 0 ]
if update . message . document and filename . split ( " . " ) [ - 1 ] . lower ( ) == " mp4 " :
temp = ' ' . join ( random . choice ( string . ascii_letters + string . digits ) for i in range ( 32 ) )
with open ( " tmp/ %s . %s " % ( temp , filename . split ( " . " ) [ - 1 ] ) , " wb " ) as f :
f . write ( mobj . getvalue ( ) )
moviepy . editor . VideoFileClip ( " tmp/ %s . %s " % ( temp , filename . split ( " . " ) [ - 1 ] ) ) . resize ( 0.3 ) . write_gif ( " tmp/ %s .gif " % temp )
filename = " %s .gif " % temp
out = open ( " tmp/ %s .gif " % temp , " rb " )
else :
out = mobj
two . api . update_with_media ( filename , update . message . caption , reply , file = out )
out . close ( )
else :
two . tweet ( ' ' . join ( args ) , reply )
except tweepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
def reply ( bot , update , args ) :
try :
reply = bottools . methods . getTweetID ( args [ 0 ] , update . message . chat_id )
2017-03-23 19:23:31 +00:00
two = bottools . methods . getTwo ( update . message )
otweet = twitools . getTweet ( reply )
sender = otweet . user . screen_name
if not ( " @ %s " % sender . strip ( " @ " ) ) in [ ( " @ %s " % a . strip ( " @ " ) ) for a in args ] :
mentions = [ ]
for m in re . split ( ' [^ \ w@]+ ' , otweet . text ) :
try :
if m [ 0 ] == " @ " :
mentions + = [ m ]
except :
pass
for m in mentions :
2017-03-23 21:39:54 +00:00
if m in args or m == " @ %s " % two . whoami ( ) . strip ( " @ " ) or m == " @ %s " % sender . strip ( " @ " ) :
2017-03-23 19:23:31 +00:00
mentions . remove ( m )
else :
mentions = [ ]
if " @ %s " % sender . strip ( " @ " ) != " @ %s " % two . whoami ( ) . strip ( " @ " ) :
first = [ " @ %s " % sender . strip ( " @ " ) ]
else :
2017-03-23 21:39:54 +00:00
try :
first = [ mentions [ 0 ] ]
mentions . remove ( mentions [ 0 ] )
except :
first = [ " " ]
2017-03-23 19:23:31 +00:00
pargs = first + args [ 1 : ] + mentions
2017-03-22 00:53:51 +00:00
except :
update . message . reply_text ( bottools . strings . cantfind % args [ 0 ] )
2017-03-23 19:23:31 +00:00
raise
2017-03-22 00:53:51 +00:00
2017-03-23 19:23:31 +00:00
bottools . methods . explicitTweet ( bot , update , pargs , reply )
2017-03-22 00:53:51 +00:00
def retweet ( bot , update , args ) :
for tweet in args :
try :
tid = bottools . methods . getTweetID ( tweet , update . message . chat_id )
bottools . methods . getTwo ( update . message ) . api . retweet ( tid )
except ValueError :
update . message . reply_text ( bottools . strings . cantfind % tweet )
except tweepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
def like ( bot , update , args ) :
for tweet in args :
try :
tid = bottools . methods . getTweetID ( tweet , update . message . chat_id )
bottools . methods . getTwo ( update . message ) . api . create_favorite ( tid )
except ValueError :
update . message . reply_text ( bottools . strings . cantfind % tweet )
except tweepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
def tweet ( bot , update ) :
try :
if dbtools . dbHelper ( ) . getTStatus ( update . message . chat_id ) :
bottools . methods . explicitTweet ( bot , update , [ update . message . text ] )
except twepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
# Timelines
def timeline ( bot , update , args = [ 10 ] ) :
try :
count = int ( args [ 0 ] )
except :
count = 10
db = dbtools . dbHelper ( )
db . executeQuery ( " DELETE FROM timelines WHERE cid = %i ; " % int ( update . message . chat_id ) )
try :
i = 1
two = bottools . methods . getTwo ( update . message )
for status in two . api . home_timeline ( count = count ) :
db . executeQuery ( " INSERT INTO timelines VALUES( %i , %i , %i ); " % ( update . message . chat_id , i , status . id ) )
update . message . reply_text ( " Tweet %i : \n %s (@ %s ) at %s : \n %s " % ( i , status . author . name , status . author . screen_name , status . created_at , html . unescape ( status . text ) ) )
i + = 1
except tweepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
db . commit ( )
2017-03-23 13:18:52 +00:00
# Streaming
2017-03-23 16:32:06 +00:00
2017-03-23 13:18:52 +00:00
mentionstreams = { }
2017-03-23 16:01:05 +00:00
def makeStream ( bot , cid ) :
two = twitools . twoBotHelper ( cid )
stream = tweepy . Stream ( auth = two . auth , listener = twitools . streaming . BotStreamListener ( bot , cid ) )
stream . filter ( track = [ two . whoami ( ) ] , async = True )
return stream
try :
for u in dbtools . dbHelper ( ) . mentionsOn ( ) :
mentionstreams [ u ] = makeStream ( telegram . Bot ( token = setuptools . token ( ) ) , u )
except Exception as e :
print ( e )
2017-03-23 13:18:52 +00:00
def mentionstream ( bot , update ) :
global mentionstreams
2017-03-23 16:01:05 +00:00
try :
dbtools . dbHelper ( ) . toggleMentions ( update . message . chat_id )
if update . message . chat_id in mentionstreams :
mentionstreams . pop ( update . message . chat_id ) . disconnect ( )
update . message . reply_text ( bottools . strings . toggleMentions % bottools . strings . toggleTweetOff )
else :
mentionstreams [ update . message . chat_id ] = makeStream ( bot , update . message . chat_id )
update . message . reply_text ( bottools . strings . toggleMentions % bottools . strings . toggleTweetOn )
except tweepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
2017-03-23 13:18:52 +00:00
2017-03-23 17:14:22 +00:00
# Admin interaction
def togglebroadcasts ( bot , update ) :
try :
update . message . reply_text ( bottools . strings . toggleBroadcasts % ( bottools . strings . toggleTweetOn if dbtools . dbHelper ( ) . toggleBroadcasts ( update . message . chat_id ) else bottools . strings . toggleTweetOff ) )
except tweepy . error . TweepError as e :
bottools . methods . twoExceptions ( e , update . message )
2017-03-23 12:05:48 +00:00
# Administrator
def isadmin ( message ) :
two = bottools . methods . getTwo ( message )
if two . whoami ( ) . strip ( " @ " ) == setuptools . admin ( ) . strip ( " @ " ) :
return True
return False
def restart ( bot , update ) :
if bottools . methods . isadmin ( update . message ) :
update . message . reply_text ( bottools . strings . restart )
time . sleep ( 0.5 )
os . execl ( sys . executable , sys . executable , * sys . argv )
2017-03-23 12:06:58 +00:00
else :
bottools . methods . unknown ( bot , update )
2017-03-23 16:01:05 +00:00
2017-03-23 16:32:06 +00:00
def broadcast ( bot , update , args ) :
2017-03-23 17:14:22 +00:00
if bottools . methods . isadmin ( update . message ) :
for u in dbtools . dbHelper ( ) . broadcastUsers ( ) :
2017-03-23 19:23:31 +00:00
try :
bot . sendMessage ( chat_id = u , text = ' ' . join ( args ) )
except :
logging . exception ( " Could not send broadcast. " )
2017-03-23 17:14:22 +00:00
else :
bottools . methods . unknown ( bot , update )
def emergency ( bot , update , args ) :
2017-03-23 16:32:06 +00:00
if bottools . methods . isadmin ( update . message ) :
for u in dbtools . dbHelper ( ) . allUsers ( ) :
2017-03-23 19:23:31 +00:00
try :
bot . sendMessage ( chat_id = u , text = ' ' . join ( args ) )
except :
logging . exception ( " Could not send emergency broadcast. " )
2017-03-23 16:32:06 +00:00
else :
bottools . methods . unknown ( bot , update )