2014-11-12 20:41:29 -06:00
# -*- coding: utf-8 -*-
2018-08-17 17:42:41 -05:00
""" This is the main session needed to access all Twitter Features. """
2018-11-22 13:35:19 -06:00
from __future__ import absolute_import
2019-06-06 11:52:23 -05:00
from __future__ import unicode_literals
from builtins import range
2018-08-17 17:42:41 -05:00
import os
import time
import logging
2018-08-18 23:09:08 -05:00
import webbrowser
2017-07-30 04:05:32 -05:00
import wx
2016-08-06 14:47:42 -05:00
import config
2014-11-12 20:41:29 -06:00
import output
2015-05-02 03:41:28 -04:00
import application
2015-02-01 21:13:18 -06:00
from pubsub import pub
2020-07-20 13:11:37 -05:00
from twython import Twython
import tweepy
2018-08-17 17:42:41 -05:00
from mysc . thread_utils import call_threaded
from keys import keyring
from sessions import base
2018-08-18 23:09:08 -05:00
from sessions . twitter import utils , compose
2018-08-16 17:26:19 -05:00
from sessions . twitter . long_tweets import tweets , twishort
2018-11-22 13:35:19 -06:00
from . wxUI import authorisationDialog
2018-08-17 17:42:41 -05:00
log = logging . getLogger ( " sessions.twitterSession " )
2014-11-12 20:41:29 -06:00
2018-08-17 05:12:49 -05:00
class Session ( base . baseSession ) :
2014-11-12 20:41:29 -06:00
""" A session object where we will save configuration, the twitter object and a local storage for saving the items retrieved through the Twitter API methods """
2017-05-07 10:45:35 +04:00
def order_buffer ( self , name , data , ignore_older = True ) :
2018-08-17 17:42:41 -05:00
""" Put new items in the local database.
2014-11-12 20:41:29 -06:00
name str : The name for the buffer stored in the dictionary .
data list : A list with tweets .
2018-08-17 17:42:41 -05:00
ignore_older bool : if set to True , items older than the first element on the list will be ignored .
2015-04-12 19:43:19 -04:00
returns the number of items that have been added in this execution """
2014-11-12 20:41:29 -06:00
num = 0
2017-05-07 10:45:35 +04:00
last_id = None
2018-11-22 13:35:19 -06:00
if ( name in self . db ) == False :
2014-11-12 20:41:29 -06:00
self . db [ name ] = [ ]
2018-11-22 13:35:19 -06:00
if ( " users " in self . db ) == False :
2018-07-17 09:27:13 -05:00
self . db [ " users " ] = { }
2017-05-07 10:45:35 +04:00
if ignore_older and len ( self . db [ name ] ) > 0 :
if self . settings [ " general " ] [ " reverse_timelines " ] == False :
2020-12-22 17:29:33 -06:00
last_id = self . db [ name ] [ 0 ] . id
2017-05-07 10:45:35 +04:00
else :
2020-12-22 17:29:33 -06:00
last_id = self . db [ name ] [ - 1 ] . id
2014-11-12 20:41:29 -06:00
for i in data :
2017-05-07 10:45:35 +04:00
if ignore_older and last_id != None :
2020-12-22 17:29:33 -06:00
if i . id < last_id :
log . error ( " Ignoring an older tweet... Last id: {0} , tweet id: {1} " . format ( last_id , i . id ) )
2017-05-07 10:45:35 +04:00
continue
2020-12-22 17:29:33 -06:00
if utils . find_item ( i . id , self . db [ name ] ) == None and utils . is_allowed ( i , self . settings , name ) == True :
2017-11-29 10:55:42 -06:00
i = self . check_quoted_status ( i )
2016-04-28 13:54:06 -05:00
i = self . check_long_tweet ( i )
2017-01-29 17:20:37 -06:00
if i == False : continue
2014-11-12 20:41:29 -06:00
if self . settings [ " general " ] [ " reverse_timelines " ] == False : self . db [ name ] . append ( i )
else : self . db [ name ] . insert ( 0 , i )
num = num + 1
2020-12-22 17:29:33 -06:00
if hasattr ( i , " user " ) :
if ( i . user . id in self . db [ " users " ] ) == False :
self . db [ " users " ] [ i . user . id ] = i . user
2014-11-12 20:41:29 -06:00
return num
def order_cursored_buffer ( self , name , data ) :
2018-08-17 17:42:41 -05:00
""" Put new items on the local database. Useful for cursored buffers (followers, friends, users of a list and searches)
2014-11-12 20:41:29 -06:00
name str : The name for the buffer stored in the dictionary .
data list : A list with items and some information about cursors .
2015-04-12 19:43:19 -04:00
returns the number of items that have been added in this execution """
2018-08-17 17:42:41 -05:00
# Direct messages should be added to db in other function.
# Because they will be populating two buffers with one endpoint.
2018-08-13 11:26:55 -05:00
if name == " direct_messages " :
return self . order_direct_messages ( data )
2014-11-12 20:41:29 -06:00
num = 0
2018-11-22 13:35:19 -06:00
if ( name in self . db ) == False :
2014-11-12 20:41:29 -06:00
self . db [ name ] = { }
self . db [ name ] [ " items " ] = [ ]
for i in data :
2020-12-22 17:29:33 -06:00
if utils . find_item ( i . id , self . db [ name ] [ " items " ] ) == None :
2014-11-12 20:41:29 -06:00
if self . settings [ " general " ] [ " reverse_timelines " ] == False : self . db [ name ] [ " items " ] . append ( i )
else : self . db [ name ] [ " items " ] . insert ( 0 , i )
num = num + 1
return num
2018-08-13 11:26:55 -05:00
def order_direct_messages ( self , data ) :
2018-08-17 17:42:41 -05:00
""" Add incoming and sent direct messages to their corresponding database items.
data list : A list of direct messages to add .
returns the number of incoming messages processed in this execution , and sends an event with data regarding amount of sent direct messages added . """
2018-08-13 11:26:55 -05:00
incoming = 0
sent = 0
2018-11-22 13:35:19 -06:00
if ( " direct_messages " in self . db ) == False :
2018-08-13 11:26:55 -05:00
self . db [ " direct_messages " ] = { }
self . db [ " direct_messages " ] [ " items " ] = [ ]
for i in data :
2020-12-22 17:29:33 -06:00
if i . message_create . sender_id == self . db [ " user_id " ] :
if " sent_direct_messages " in self . db and utils . find_item ( i . id , self . db [ " sent_direct_messages " ] [ " items " ] ) == None :
2018-08-13 11:26:55 -05:00
if self . settings [ " general " ] [ " reverse_timelines " ] == False : self . db [ " sent_direct_messages " ] [ " items " ] . append ( i )
else : self . db [ " sent_direct_messages " ] [ " items " ] . insert ( 0 , i )
sent = sent + 1
else :
2020-12-22 17:29:33 -06:00
if utils . find_item ( i . id , self . db [ " direct_messages " ] [ " items " ] ) == None :
2018-08-13 11:26:55 -05:00
if self . settings [ " general " ] [ " reverse_timelines " ] == False : self . db [ " direct_messages " ] [ " items " ] . append ( i )
else : self . db [ " direct_messages " ] [ " items " ] . insert ( 0 , i )
incoming = incoming + 1
pub . sendMessage ( " sent-dms-updated " , total = sent , account = self . db [ " user_name " ] )
return incoming
2018-08-17 05:12:49 -05:00
def __init__ ( self , * args , * * kwargs ) :
super ( Session , self ) . __init__ ( * args , * * kwargs )
2015-01-13 12:31:37 -06:00
self . reconnection_function_active = False
2015-03-07 20:23:41 -06:00
self . counter = 0
2015-04-27 16:08:02 -05:00
self . lists = [ ]
2014-11-12 20:41:29 -06:00
2018-08-17 05:12:49 -05:00
# @_require_configuration
2015-03-08 00:36:41 -06:00
def login ( self , verify_credentials = True ) :
2015-04-12 19:43:19 -04:00
""" Log into twitter using credentials from settings.
2014-11-12 20:41:29 -06:00
if the user account isn ' t authorised, it needs to call self.authorise() before login. " " "
if self . settings [ " twitter " ] [ " user_key " ] != None and self . settings [ " twitter " ] [ " user_secret " ] != None :
2017-02-13 13:35:32 +01:00
try :
log . debug ( " Logging in to twitter... " )
2020-07-20 13:11:37 -05:00
self . auth = tweepy . OAuthHandler ( keyring . get ( " api_key " ) , keyring . get ( " api_secret " ) )
self . auth . set_access_token ( self . settings [ " twitter " ] [ " user_key " ] , self . settings [ " twitter " ] [ " user_secret " ] )
self . twitter = tweepy . API ( self . auth )
2018-08-18 23:09:08 -05:00
if verify_credentials == True :
self . credentials = self . twitter . verify_credentials ( )
2017-02-13 13:35:32 +01:00
self . logged = True
log . debug ( " Logged. " )
self . counter = 0
2018-08-18 23:09:08 -05:00
except IOError :
2017-02-13 13:35:32 +01:00
log . error ( " The login attempt failed. " )
self . logged = False
2014-11-12 20:41:29 -06:00
else :
self . logged = False
raise Exceptions . RequireCredentialsSessionError
2018-08-17 05:12:49 -05:00
# @_require_configuration
2014-11-12 20:41:29 -06:00
def authorise ( self ) :
2015-04-12 19:43:19 -04:00
""" Authorises a Twitter account. This function needs to be called for each new session, after self.get_configuration() and before self.login() """
2014-11-12 20:41:29 -06:00
if self . logged == True :
raise Exceptions . AlreadyAuthorisedError ( " The authorisation process is not needed at this time. " )
else :
2020-07-20 13:11:37 -05:00
self . auth = tweepy . OAuthHandler ( keyring . get ( " api_key " ) , keyring . get ( " api_secret " ) )
redirect_url = self . auth . get_authorization_url ( )
webbrowser . open_new_tab ( redirect_url )
2017-07-30 04:05:32 -05:00
self . authorisation_dialog = authorisationDialog ( )
self . authorisation_dialog . cancel . Bind ( wx . EVT_BUTTON , self . authorisation_cancelled )
2018-06-06 09:11:37 -05:00
self . authorisation_dialog . ok . Bind ( wx . EVT_BUTTON , self . authorisation_accepted )
2017-07-30 04:05:32 -05:00
self . authorisation_dialog . ShowModal ( )
2018-08-18 23:09:08 -05:00
def verify_authorisation ( self , pincode ) :
2020-07-20 13:11:37 -05:00
self . auth . get_access_token ( pincode )
self . settings [ " twitter " ] [ " user_key " ] = self . auth . access_token
self . settings [ " twitter " ] [ " user_secret " ] = self . auth . access_token_secret
2018-08-18 23:09:08 -05:00
self . settings . write ( )
del self . auth
2017-07-30 04:05:32 -05:00
def authorisation_cancelled ( self , * args , * * kwargs ) :
2018-08-17 17:42:41 -05:00
""" Destroy the authorization dialog. """
2017-07-30 04:05:32 -05:00
self . authorisation_dialog . Destroy ( )
del self . authorisation_dialog
2018-06-06 09:11:37 -05:00
def authorisation_accepted ( self , * args , * * kwargs ) :
2018-08-17 17:42:41 -05:00
""" Gets the PIN code entered by user and validate it through Twitter. """
2018-06-06 09:11:37 -05:00
pincode = self . authorisation_dialog . text . GetValue ( )
2018-08-18 23:09:08 -05:00
self . verify_authorisation ( pincode )
2017-07-30 04:05:32 -05:00
self . authorisation_dialog . Destroy ( )
2014-11-12 20:41:29 -06:00
2018-07-19 12:27:01 -05:00
def get_more_items ( self , update_function , users = False , dm = False , name = None , * args , * * kwargs ) :
2018-08-17 17:42:41 -05:00
""" Get more items for twitter objects.
update_function str : function to call for getting more items . Must be member of self . twitter .
users , dm bool : If any of these is set to True , the function will treat items as users or dm ( they need different handling ) .
name str : name of the database item to put new element in . """
2015-02-03 09:59:18 -06:00
results = [ ]
2018-11-22 13:35:19 -06:00
if " cursor " in kwargs and kwargs [ " cursor " ] == 0 :
2018-09-18 09:09:25 -05:00
output . speak ( _ ( u " There are no more items to retrieve in this buffer. " ) )
return
2018-08-18 23:09:08 -05:00
data = getattr ( self . twitter , update_function ) ( * args , * * kwargs )
2015-02-03 09:59:18 -06:00
if users == True :
2018-11-22 13:35:19 -06:00
if type ( data ) == dict and " next_cursor " in data :
if " next_cursor " in data : # There are more objects to retrieve.
2018-09-18 09:09:25 -05:00
self . db [ name ] [ " cursor " ] = data [ " next_cursor " ]
else : # Set cursor to 0, wich means no more items available.
self . db [ name ] [ " cursor " ] = 0
2017-06-15 09:57:45 -05:00
for i in data [ " users " ] : results . append ( i )
elif type ( data ) == list :
results . extend ( data [ 1 : ] )
2018-07-19 12:27:01 -05:00
elif dm == True :
2018-11-22 13:35:19 -06:00
if " next_cursor " in data : # There are more objects to retrieve.
2018-09-18 09:09:25 -05:00
self . db [ name ] [ " cursor " ] = data [ " next_cursor " ]
else : # Set cursor to 0, wich means no more items available.
self . db [ name ] [ " cursor " ] = 0
2018-07-19 12:27:01 -05:00
for i in data [ " events " ] : results . append ( i )
2015-02-03 09:59:18 -06:00
else :
results . extend ( data [ 1 : ] )
return results
2014-11-12 20:41:29 -06:00
def api_call ( self , call_name , action = " " , _sound = None , report_success = False , report_failure = True , preexec_message = " " , * args , * * kwargs ) :
2015-04-12 19:43:19 -04:00
""" Make a call to the Twitter API. If there is a connectionError or another exception not related to Twitter, It will call the method again at least 25 times, waiting a while between calls. Useful for post methods.
If twitter returns an error , it will not call the method anymore .
2014-11-12 20:41:29 -06:00
call_name str : The method to call
2015-04-12 19:43:19 -04:00
action str : What you are doing on twitter , it will be reported to the user if report_success is set to True .
2014-11-12 20:41:29 -06:00
for example " following @tw_blue2 " will be reported as " following @tw_blue2 succeeded " .
_sound str : a sound to play if the call is executed properly .
2015-04-12 19:43:19 -04:00
report_success and report_failure bool : These are self explanatory . True or False .
preexec_message str : A message to speak to the user while the method is running , example : " trying to follow x user " . """
2014-11-12 20:41:29 -06:00
finished = False
tries = 0
if preexec_message :
output . speak ( preexec_message , True )
while finished == False and tries < 25 :
try :
2018-08-18 23:09:08 -05:00
val = getattr ( self . twitter , call_name ) ( * args , * * kwargs )
2014-11-12 20:41:29 -06:00
finished = True
2021-01-13 08:47:13 -06:00
except TweepError as e :
output . speak ( e . reason )
2018-08-26 08:09:55 -05:00
val = None
2015-03-01 20:41:02 -06:00
if e . error_code != 403 and e . error_code != 404 :
tries = tries + 1
time . sleep ( 5 )
2021-01-13 08:47:13 -06:00
elif report_failure and hasattr ( e , ' reason ' ) :
output . speak ( _ ( " %s failed. Reason: %s " ) % ( action , e . reason ) )
2014-11-12 20:41:29 -06:00
finished = True
2016-12-19 11:43:32 -06:00
# except:
# tries = tries + 1
# time.sleep(5)
2014-11-12 20:41:29 -06:00
if report_success :
output . speak ( _ ( " %s succeeded. " ) % action )
2015-01-22 08:54:41 -06:00
if _sound != None : self . sound . play ( _sound )
2015-12-26 09:02:08 -06:00
return val
2014-11-12 20:41:29 -06:00
2018-08-17 21:01:58 -05:00
def search ( self , name , * args , * * kwargs ) :
2018-08-17 17:42:41 -05:00
""" Search in twitter, passing args and kwargs as arguments to the Twython function. """
2018-08-18 23:09:08 -05:00
tl = self . twitter . search ( * args , * * kwargs )
2020-12-22 17:29:33 -06:00
tl . reverse ( )
return tl
2015-03-24 17:07:14 -06:00
2018-08-17 05:12:49 -05:00
# @_require_login
2014-11-12 20:41:29 -06:00
def get_favourites_timeline ( self , name , * args , * * kwargs ) :
2015-04-12 19:43:19 -04:00
""" Gets favourites for the authenticated user or a friend or follower.
2018-08-17 21:01:58 -05:00
name str : Name for storage in the database .
args and kwargs are passed directly to the Twython function . """
2020-12-22 17:29:33 -06:00
tl = self . call_paged ( " favorites " , * args , * * kwargs )
2014-11-12 20:41:29 -06:00
return self . order_buffer ( name , tl )
def call_paged ( self , update_function , * args , * * kwargs ) :
""" Makes a call to the Twitter API methods several times. Useful for get methods.
this function is needed for retrieving more than 200 items .
2018-08-18 23:09:08 -05:00
update_function str : The function to call . This function must be child of self . twitter
2018-08-17 21:01:58 -05:00
args and kwargs are passed to update_function .
2015-04-12 19:43:19 -04:00
returns a list with all items retrieved . """
2018-08-16 10:42:14 -05:00
max = 0
2014-11-12 20:41:29 -06:00
results = [ ]
2018-08-18 23:09:08 -05:00
data = getattr ( self . twitter , update_function ) ( count = self . settings [ " general " ] [ " max_tweets_per_call " ] , * args , * * kwargs )
2014-11-12 20:41:29 -06:00
results . extend ( data )
for i in range ( 0 , max ) :
2020-12-22 17:29:33 -06:00
if i == 0 : max_id = results [ - 1 ] . id
else : max_id = results [ 0 ] . id
2018-08-18 23:09:08 -05:00
data = getattr ( self . twitter , update_function ) ( max_id = max_id , count = self . settings [ " general " ] [ " max_tweets_per_call " ] , * args , * * kwargs )
2014-11-12 20:41:29 -06:00
results . extend ( data )
results . reverse ( )
return results
2018-08-17 05:12:49 -05:00
# @_require_login
2014-11-12 20:41:29 -06:00
def get_user_info ( self ) :
""" Retrieves some information required by TWBlue for setup. """
2020-07-20 13:26:22 -05:00
f = self . twitter . get_settings ( )
2014-11-12 20:41:29 -06:00
sn = f [ " screen_name " ]
2015-03-03 13:48:57 -06:00
self . settings [ " twitter " ] [ " user_name " ] = sn
2014-11-12 20:41:29 -06:00
self . db [ " user_name " ] = sn
2020-07-20 13:26:22 -05:00
self . db [ " user_id " ] = self . twitter . get_user ( screen_name = sn ) . id
2014-11-12 20:41:29 -06:00
try :
self . db [ " utc_offset " ] = f [ " time_zone " ] [ " utc_offset " ]
except KeyError :
self . db [ " utc_offset " ] = - time . timezone
2017-11-12 23:39:45 -06:00
# Get twitter's supported languages and save them in a global variable
#so we won't call to this method once per session.
if len ( application . supported_languages ) == 0 :
2021-01-04 12:23:04 -06:00
application . supported_languages = self . twitter . supported_languages ( )
2014-11-12 20:41:29 -06:00
self . get_lists ( )
self . get_muted_users ( )
self . settings . write ( )
2018-08-17 05:12:49 -05:00
# @_require_login
2014-11-12 20:41:29 -06:00
def get_lists ( self ) :
2015-04-12 19:43:19 -04:00
""" Gets the lists that the user is subscribed to and stores them in the database. Returns None. """
2020-07-20 13:26:22 -05:00
self . db [ " lists " ] = self . twitter . lists_all ( reverse = True )
2014-11-12 20:41:29 -06:00
2018-08-17 05:12:49 -05:00
# @_require_login
2014-11-12 20:41:29 -06:00
def get_muted_users ( self ) :
""" Gets muted users (oh really?). """
2020-07-20 13:26:22 -05:00
self . db [ " muted_users " ] = self . twitter . mutes_ids
2015-05-26 20:23:02 -05:00
2018-08-17 05:12:49 -05:00
# @_require_login
2014-11-12 20:41:29 -06:00
def get_stream ( self , name , function , * args , * * kwargs ) :
""" Retrieves the items for a regular stream.
2015-04-12 19:43:19 -04:00
name str : Name to save items to the database .
2014-11-12 20:41:29 -06:00
function str : A function to get the items . """
last_id = - 1
2018-11-22 13:35:19 -06:00
if name in self . db :
2014-11-12 20:41:29 -06:00
try :
if self . db [ name ] [ 0 ] [ " id " ] > self . db [ name ] [ - 1 ] [ " id " ] :
last_id = self . db [ name ] [ 0 ] [ " id " ]
else :
last_id = self . db [ name ] [ - 1 ] [ " id " ]
except IndexError :
pass
tl = self . call_paged ( function , sinze_id = last_id , * args , * * kwargs )
self . order_buffer ( name , tl )
2015-12-26 23:28:46 -06:00
def get_cursored_stream ( self , name , function , items = " users " , get_previous = False , * args , * * kwargs ) :
2015-04-12 19:43:19 -04:00
""" Gets items for API calls that require using cursors to paginate the results.
2014-11-12 20:41:29 -06:00
name str : Name to save it in the database .
function str : Function that provides the items .
2018-08-17 17:42:41 -05:00
items : When the function returns the list with results , items will tell how the order function should be look . for example get_followers_list returns a list and users are under list [ " users " ] , here the items should point to " users " .
get_previous bool : wether this function will be used to get previous items in a buffer or load the buffer from scratch .
returns number of items retrieved . """
2014-11-12 20:41:29 -06:00
items_ = [ ]
try :
2018-11-22 13:35:19 -06:00
if " cursor " in self . db [ name ] and get_previous :
2015-02-03 09:59:18 -06:00
cursor = self . db [ name ] [ " cursor " ]
2014-11-12 20:41:29 -06:00
else :
2015-02-03 09:59:18 -06:00
cursor = - 1
2014-11-12 20:41:29 -06:00
except KeyError :
2015-02-03 09:59:18 -06:00
cursor = - 1
2018-07-18 09:27:02 -05:00
if cursor != - 1 :
2018-08-18 23:09:08 -05:00
tl = getattr ( self . twitter , function ) ( cursor = cursor , count = self . settings [ " general " ] [ " max_tweets_per_call " ] , * args , * * kwargs )
2018-07-18 09:27:02 -05:00
else :
2018-08-18 23:09:08 -05:00
tl = getattr ( self . twitter , function ) ( count = self . settings [ " general " ] [ " max_tweets_per_call " ] , * args , * * kwargs )
2014-11-12 20:41:29 -06:00
tl [ items ] . reverse ( )
num = self . order_cursored_buffer ( name , tl [ items ] )
2018-07-18 09:27:02 -05:00
# Recently, Twitter's new endpoints have cursor if there are more results.
2018-11-22 13:35:19 -06:00
if " next_cursor " in tl :
2018-07-18 09:27:02 -05:00
self . db [ name ] [ " cursor " ] = tl [ " next_cursor " ]
2018-09-18 09:09:25 -05:00
else :
self . db [ name ] [ " cursor " ] = 0
2014-11-12 20:41:29 -06:00
return num
2015-01-13 12:31:37 -06:00
def check_connection ( self ) :
2018-08-17 21:01:58 -05:00
""" Restart the Twitter object every 5 executions. It is useful for dealing with requests timeout and other oddities. """
2018-06-17 19:38:29 -05:00
log . debug ( " Executing check connection... " )
2015-03-07 20:23:41 -06:00
self . counter + = 1
if self . counter > = 4 :
2018-06-17 19:38:29 -05:00
log . debug ( " Restarting connection after 5 minutes. " )
2015-03-07 20:23:41 -06:00
del self . twitter
self . logged = False
2015-03-08 00:36:41 -06:00
self . login ( False )
2018-06-17 19:38:29 -05:00
self . counter = 0
2015-05-01 01:48:42 -04:00
2015-09-29 08:38:05 -05:00
def check_quoted_status ( self , tweet ) :
2018-08-17 21:01:58 -05:00
""" Helper for get_quoted_tweet. Get a quoted status inside a tweet and create a special tweet with all info available.
tweet dict : A tweet dictionary .
Returns a quoted tweet or the original tweet if is not a quote """
2015-09-29 08:38:05 -05:00
status = tweets . is_long ( tweet )
2016-08-06 14:47:42 -05:00
if status != False and config . app [ " app-settings " ] [ " handle_longtweets " ] :
2017-11-29 10:55:42 -06:00
quoted_tweet = self . get_quoted_tweet ( tweet )
return quoted_tweet
2015-09-29 08:38:05 -05:00
return tweet
def get_quoted_tweet ( self , tweet ) :
2018-08-17 21:01:58 -05:00
""" Process a tweet and extract all information related to the quote. """
2016-04-28 13:54:06 -05:00
quoted_tweet = tweet
2020-12-22 17:29:33 -06:00
if hasattr ( tweet , " full_text " ) :
2016-10-03 22:54:54 -05:00
value = " full_text "
else :
value = " text "
2021-01-04 11:16:56 -06:00
setattr ( quoted_tweet , value , utils . expand_urls ( getattr ( quoted_tweet , value ) , quoted_tweet . entities ) )
2020-12-22 17:29:33 -06:00
if hasattr ( quoted_tweet , " quoted_status " ) :
original_tweet = quoted_tweet . quoted_status
elif hasattr ( quoted_tweet , " retweeted_status " ) and hasattr ( quoted_tweet . retweeted_status , " quoted_status " ) :
original_tweet = quoted_tweet . retweeted_status . quoted_status
2017-11-29 10:55:42 -06:00
else :
return quoted_tweet
2016-07-27 11:56:38 -05:00
original_tweet = self . check_long_tweet ( original_tweet )
2020-12-22 17:29:33 -06:00
if hasattr ( original_tweet , " full_text " ) :
2017-12-05 08:43:26 -06:00
value = " full_text "
2020-12-22 17:29:33 -06:00
elif hasattr ( original_tweet , " message " ) :
2018-03-14 11:34:49 -06:00
value = " message "
2017-12-05 08:43:26 -06:00
else :
value = " text "
2021-01-04 11:16:56 -06:00
setattr ( original_tweet , value , utils . expand_urls ( getattr ( original_tweet , value ) , original_tweet . entities ) )
2015-09-29 08:38:05 -05:00
return compose . compose_quoted_tweet ( quoted_tweet , original_tweet )
2016-04-28 13:54:06 -05:00
def check_long_tweet ( self , tweet ) :
2018-08-17 21:01:58 -05:00
""" Process a tweet and add extra info if it ' s a long tweet made with Twyshort.
tweet dict : a tweet object .
returns a tweet with a new argument message , or original tweet if it ' s not a long tweet. " " "
2016-04-28 13:54:06 -05:00
long = twishort . is_long ( tweet )
2016-08-06 14:47:42 -05:00
if long != False and config . app [ " app-settings " ] [ " handle_longtweets " ] :
2018-03-14 11:34:49 -06:00
message = twishort . get_full_text ( long )
2020-12-22 17:29:33 -06:00
if hasattr ( tweet , " quoted_status " ) :
tweet . quoted_status . message = message
if tweet . quoted_status . message == False : return False
tweet . quoted_status . twishort = True
2021-01-04 12:23:04 -06:00
for i in tweet . quoted_status . entities [ " user_mentions " ] :
if " @ %s " % ( i [ " screen_name " ] ) not in tweet . quoted_status . message and i [ " screen_name " ] != tweet . user . screen_name :
if hasattr ( tweet [ " quoted_status " ] , " retweeted_status " ) and tweet . retweeted_status . user . screen_name == i [ " screen_name " ] :
2018-03-14 11:34:49 -06:00
continue
2021-01-04 12:23:04 -06:00
tweet . quoted_status . message = u " @ %s %s " % ( i [ " screen_name " ] , tweet . message )
2018-03-14 11:34:49 -06:00
else :
2020-12-22 17:29:33 -06:00
tweet . message = message
if tweet . message == False : return False
tweet . twishort = True
2021-01-04 12:23:04 -06:00
for i in tweet . entities [ " user_mentions " ] :
if " @ %s " % ( i [ " screen_name " ] ) not in tweet . message and i [ " screen_name " ] != tweet . user . screen_name :
if hasattr ( tweet , " retweeted_status " ) and tweet . retweeted_status . user . screen_name == i [ " screen_name " ] :
2018-03-14 11:34:49 -06:00
continue
2018-07-17 10:58:09 -05:00
return tweet
def get_user ( self , id ) :
2018-08-17 21:01:58 -05:00
""" Returns an user object associated with an ID.
id str : User identifier , provided by Twitter .
returns an user dict . """
2018-11-22 13:35:19 -06:00
if ( " users " in self . db ) == False or ( id in self . db [ " users " ] ) == False :
2019-02-15 09:04:52 -06:00
try :
user = self . twitter . show_user ( id = id )
except TwythonError :
user = dict ( screen_name = " deleted_account " , name = " Deleted account " )
return user
2018-07-18 09:27:02 -05:00
self . db [ " users " ] [ user [ " id_str " ] ] = user
2018-07-17 10:58:09 -05:00
return user
else :
2018-07-25 11:22:57 -05:00
return self . db [ " users " ] [ id ]
def get_user_by_screen_name ( self , screen_name ) :
2018-08-17 21:01:58 -05:00
""" Returns an user identifier associated with a screen_name.
screen_name str : User name , such as tw_blue2 , provided by Twitter .
returns an user ID . """
2018-11-22 13:35:19 -06:00
if ( " users " in self . db ) == False :
2018-08-18 23:09:08 -05:00
user = utils . if_user_exists ( self . twitter , screen_name )
2018-07-25 11:22:57 -05:00
self . db [ " users " ] [ user [ " id_str " ] ] = user
return user [ " id_str " ]
else :
2019-06-06 11:52:23 -05:00
for i in list ( self . db [ " users " ] . keys ( ) ) :
2018-07-25 11:22:57 -05:00
if self . db [ " users " ] [ i ] [ " screen_name " ] == screen_name :
return self . db [ " users " ] [ i ] [ " id_str " ]
2018-08-18 23:09:08 -05:00
user = utils . if_user_exists ( self . twitter , screen_name )
2018-07-25 11:22:57 -05:00
self . db [ " users " ] [ user [ " id_str " ] ] = user
return user [ " id_str " ]