def clear_favourites(): t = Twython(consumer_key, consumer_secret, access_token_key, access_token_secret) # Let's start at page 1 of your favourites because you know, it's a very good place to start count = 1 # Now, let's start an infinite loop and I don't mean the one with Apple's HQ while True: # Get your favourites from Twitter faves = t.get_favorites(page=count) # If there's no favourites left from this page, do the Di Caprio and jump out if len(faves) == 0: break # Programmers have been doing inception for ages before Nolan did. Let's go deeper and get # into another loop now for fav in faves: t.destroy_favorite(id=fav['id']) count += 1 # Now comes the all important part of the code. As my grandmother once told me, it is # important to get good sleep, and we shall precisely do that for 15 minutes because you know # Twitter mama hates rate-limit violators sleep(900)
def get_context_data(self, **kwargs): twitter = Twython(settings.TWITTER_KEY, settings.TWITTER_SECRET, settings.OAUTH_TOKEN, settings.OAUTH_TOKEN_SECRET) context = super(TwitterTimeline, self).get_context_data(**kwargs) context['tweets'] = twitter.get_favorites() return context
class TwitterUnlike: """ Deletes old likes. """ def __init__(self, keys_file: str = "keys.yaml") -> None: self.count = 0 with open(keys_file, "r") as file: keys = yaml.safe_load(file) self.twitter = Twython(*keys.values()) self.twitter.verify_credentials() def pull_ids(self) -> list: """ Pulls latest 20 likes from user """ likes = self.twitter.get_favorites(count=200) like_ids = [i.get("id") for i in likes] return like_ids def delete_likes(self, like_ids: list) -> None: """ Deletes tweets from a list of tweet ids. Parameters: ---------- like_ids: list List of liked tweet ids. """ for like_id in like_ids: try: self.twitter.destroy_favorite(id=like_id) self.count += 1 except TwythonRateLimitError as e: time.sleep(int(e.retry_after) - time.time()) continue
class TwythonEndpointsTestCase(unittest.TestCase): def setUp(self): client_args = { 'headers': { 'User-Agent': '__twython__ Test' }, 'allow_redirects': False } # This is so we can hit coverage that Twython sets # User-Agent for us if none is supplied oauth2_client_args = { 'headers': {} } self.api = Twython(app_key, app_secret, oauth_token, oauth_token_secret, client_args=client_args) self.oauth2_api = Twython(app_key, access_token=access_token, client_args=oauth2_client_args) # Timelines @unittest.skip('skipping non-updated test') def test_get_mentions_timeline(self): """Test returning mentions timeline for authenticated user succeeds""" self.api.get_mentions_timeline() @unittest.skip('skipping non-updated test') def test_get_user_timeline(self): """Test returning timeline for authenticated user and random user succeeds""" self.api.get_user_timeline() # Authenticated User Timeline self.api.get_user_timeline(screen_name='twitter') # Random User Timeline @unittest.skip('skipping non-updated test') def test_get_protected_user_timeline_following(self): """Test returning a protected user timeline who you are following succeeds""" self.api.get_user_timeline(screen_name=protected_twitter_1) @unittest.skip('skipping non-updated test') def test_get_protected_user_timeline_not_following(self): """Test returning a protected user timeline who you are not following fails and raise a TwythonAuthError""" self.assertRaises(TwythonAuthError, self.api.get_user_timeline, screen_name=protected_twitter_2) @unittest.skip('skipping non-updated test') def test_retweeted_of_me(self): """Test that getting recent tweets by authenticated user that have been retweeted by others succeeds""" self.api.retweeted_of_me() @unittest.skip('skipping non-updated test') def test_get_home_timeline(self): """Test returning home timeline for authenticated user succeeds""" self.api.get_home_timeline() # Tweets @unittest.skip('skipping non-updated test') def test_get_retweets(self): """Test getting retweets of a specific tweet succeeds""" self.api.get_retweets(id=test_tweet_id) @unittest.skip('skipping non-updated test') def test_show_status(self): """Test returning a single status details succeeds""" self.api.show_status(id=test_tweet_id) @unittest.skip('skipping non-updated test') def test_update_and_destroy_status(self): """Test updating and deleting a status succeeds""" status = self.api.update_status(status='Test post just to get \ deleted :( %s' % int(time.time())) self.api.destroy_status(id=status['id_str']) @unittest.skip('skipping non-updated test') def test_get_oembed_tweet(self): """Test getting info to embed tweet on Third Party site succeeds""" self.api.get_oembed_tweet(id='99530515043983360') @unittest.skip('skipping non-updated test') def test_get_retweeters_ids(self): """Test getting ids for people who retweeted a tweet succeeds""" self.api.get_retweeters_ids(id='99530515043983360') # Search @unittest.skip('skipping non-updated test') def test_search(self): """Test searching tweets succeeds""" self.api.search(q='twitter') # Direct Messages @unittest.skip('skipping non-updated test') def test_get_direct_messages(self): """Test getting the authenticated users direct messages succeeds""" self.api.get_direct_messages() @unittest.skip('skipping non-updated test') def test_get_sent_messages(self): """Test getting the authenticated users direct messages they've sent succeeds""" self.api.get_sent_messages() @unittest.skip('skipping non-updated test') def test_send_get_and_destroy_direct_message(self): """Test sending, getting, then destory a direct message succeeds""" message = self.api.send_direct_message(screen_name=protected_twitter_1, text='Hey d00d! %s\ ' % int(time.time())) self.api.get_direct_message(id=message['id_str']) self.api.destroy_direct_message(id=message['id_str']) @unittest.skip('skipping non-updated test') def test_send_direct_message_to_non_follower(self): """Test sending a direct message to someone who doesn't follow you fails""" self.assertRaises(TwythonError, self.api.send_direct_message, screen_name=protected_twitter_2, text='Yo, man! \ %s' % int(time.time())) # Friends & Followers @unittest.skip('skipping non-updated test') def test_get_user_ids_of_blocked_retweets(self): """Test that collection of user_ids that the authenticated user does not want to receive retweets from succeeds""" self.api.get_user_ids_of_blocked_retweets(stringify_ids=True) @unittest.skip('skipping non-updated test') def test_get_friends_ids(self): """Test returning ids of users the authenticated user and then a random user is following succeeds""" self.api.get_friends_ids() self.api.get_friends_ids(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_get_followers_ids(self): """Test returning ids of users the authenticated user and then a random user are followed by succeeds""" self.api.get_followers_ids() self.api.get_followers_ids(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_lookup_friendships(self): """Test returning relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided succeeds""" self.api.lookup_friendships(screen_name='twitter,ryanmcgrath') @unittest.skip('skipping non-updated test') def test_get_incoming_friendship_ids(self): """Test returning incoming friendship ids succeeds""" self.api.get_incoming_friendship_ids() @unittest.skip('skipping non-updated test') def test_get_outgoing_friendship_ids(self): """Test returning outgoing friendship ids succeeds""" self.api.get_outgoing_friendship_ids() @unittest.skip('skipping non-updated test') def test_create_friendship(self): """Test creating a friendship succeeds""" self.api.create_friendship(screen_name='justinbieber') @unittest.skip('skipping non-updated test') def test_destroy_friendship(self): """Test destroying a friendship succeeds""" self.api.destroy_friendship(screen_name='justinbieber') @unittest.skip('skipping non-updated test') def test_update_friendship(self): """Test updating friendships succeeds""" self.api.update_friendship(screen_name=protected_twitter_1, retweets='true') self.api.update_friendship(screen_name=protected_twitter_1, retweets=False) @unittest.skip('skipping non-updated test') def test_show_friendships(self): """Test showing specific friendship succeeds""" self.api.show_friendship(target_screen_name=protected_twitter_1) @unittest.skip('skipping non-updated test') def test_get_friends_list(self): """Test getting list of users authenticated user then random user is following succeeds""" self.api.get_friends_list() self.api.get_friends_list(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_get_followers_list(self): """Test getting list of users authenticated user then random user are followed by succeeds""" self.api.get_followers_list() self.api.get_followers_list(screen_name='twitter') # Users @unittest.skip('skipping non-updated test') def test_get_account_settings(self): """Test getting the authenticated user account settings succeeds""" self.api.get_account_settings() @unittest.skip('skipping non-updated test') def test_verify_credentials(self): """Test representation of the authenticated user call succeeds""" self.api.verify_credentials() @unittest.skip('skipping non-updated test') def test_update_account_settings(self): """Test updating a user account settings succeeds""" self.api.update_account_settings(lang='en') @unittest.skip('skipping non-updated test') def test_update_delivery_service(self): """Test updating delivery settings fails because we don't have a mobile number on the account""" self.assertRaises(TwythonError, self.api.update_delivery_service, device='none') @unittest.skip('skipping non-updated test') def test_update_profile(self): """Test updating profile succeeds""" self.api.update_profile(include_entities='true') @unittest.skip('skipping non-updated test') def test_update_profile_colors(self): """Test updating profile colors succeeds""" self.api.update_profile_colors(profile_background_color='3D3D3D') @unittest.skip('skipping non-updated test') def test_list_blocks(self): """Test listing users who are blocked by the authenticated user succeeds""" self.api.list_blocks() @unittest.skip('skipping non-updated test') def test_list_block_ids(self): """Test listing user ids who are blocked by the authenticated user succeeds""" self.api.list_block_ids() @unittest.skip('skipping non-updated test') def test_create_block(self): """Test blocking a user succeeds""" self.api.create_block(screen_name='justinbieber') @unittest.skip('skipping non-updated test') def test_destroy_block(self): """Test unblocking a user succeeds""" self.api.destroy_block(screen_name='justinbieber') @unittest.skip('skipping non-updated test') def test_lookup_user(self): """Test listing a number of user objects succeeds""" self.api.lookup_user(screen_name='twitter,justinbieber') @unittest.skip('skipping non-updated test') def test_show_user(self): """Test showing one user works""" self.api.show_user(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_search_users(self): """Test that searching for users succeeds""" self.api.search_users(q='Twitter API') @unittest.skip('skipping non-updated test') def test_get_contributees(self): """Test returning list of accounts the specified user can contribute to succeeds""" self.api.get_contributees(screen_name='TechCrunch') @unittest.skip('skipping non-updated test') def test_get_contributors(self): """Test returning list of accounts that contribute to the authenticated user fails because we are not a Contributor account""" self.assertRaises(TwythonError, self.api.get_contributors, screen_name=screen_name) @unittest.skip('skipping non-updated test') def test_remove_profile_banner(self): """Test removing profile banner succeeds""" self.api.remove_profile_banner() @unittest.skip('skipping non-updated test') def test_get_profile_banner_sizes(self): """Test getting list of profile banner sizes fails because we have not uploaded a profile banner""" self.assertRaises(TwythonError, self.api.get_profile_banner_sizes) @unittest.skip('skipping non-updated test') def test_list_mutes(self): """Test listing users who are muted by the authenticated user succeeds""" self.api.list_mutes() @unittest.skip('skipping non-updated test') def test_list_mute_ids(self): """Test listing user ids who are muted by the authenticated user succeeds""" self.api.list_mute_ids() @unittest.skip('skipping non-updated test') def test_create_mute(self): """Test muting a user succeeds""" self.api.create_mute(screen_name='justinbieber') @unittest.skip('skipping non-updated test') def test_destroy_mute(self): """Test muting a user succeeds""" self.api.destroy_mute(screen_name='justinbieber') # Suggested Users @unittest.skip('skipping non-updated test') def test_get_user_suggestions_by_slug(self): """Test getting user suggestions by slug succeeds""" self.api.get_user_suggestions_by_slug(slug='twitter') @unittest.skip('skipping non-updated test') def test_get_user_suggestions(self): """Test getting user suggestions succeeds""" self.api.get_user_suggestions() @unittest.skip('skipping non-updated test') def test_get_user_suggestions_statuses_by_slug(self): """Test getting status of suggested users succeeds""" self.api.get_user_suggestions_statuses_by_slug(slug='funny') # Favorites @unittest.skip('skipping non-updated test') def test_get_favorites(self): """Test getting list of favorites for the authenticated user succeeds""" self.api.get_favorites() @unittest.skip('skipping non-updated test') def test_create_and_destroy_favorite(self): """Test creating and destroying a favorite on a tweet succeeds""" self.api.create_favorite(id=test_tweet_id) self.api.destroy_favorite(id=test_tweet_id) # Lists @unittest.skip('skipping non-updated test') def test_show_lists(self): """Test show lists for specified user""" self.api.show_lists(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_get_list_statuses(self): """Test timeline of tweets authored by members of the specified list succeeds""" self.api.get_list_statuses(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_create_update_destroy_list_add_remove_list_members(self): """Test create a list, adding and removing members then deleting the list succeeds""" the_list = self.api.create_list(name='Stuff %s' % int(time.time())) list_id = the_list['id_str'] self.api.update_list(list_id=list_id, name='Stuff Renamed \ %s' % int(time.time())) screen_names = ['johncena', 'xbox'] # Multi add/delete members self.api.create_list_members(list_id=list_id, screen_name=screen_names) self.api.delete_list_members(list_id=list_id, screen_name=screen_names) # Single add/delete member self.api.add_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list(list_id=list_id) @unittest.skip('skipping non-updated test') def test_get_list_memberships(self): """Test list of memberhips the authenticated user succeeds""" self.api.get_list_memberships() @unittest.skip('skipping non-updated test') def test_get_list_subscribers(self): """Test list of subscribers of a specific list succeeds""" self.api.get_list_subscribers(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_subscribe_is_subbed_and_unsubscribe_to_list(self): """Test subscribing, is a list sub and unsubbing to list succeeds""" self.api.subscribe_to_list(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) # Returns 404 if user is not a subscriber self.api.is_list_subscriber(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name, screen_name=screen_name) self.api.unsubscribe_from_list(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_is_list_member(self): """Test returning if specified user is member of a list succeeds""" # Returns 404 if not list member self.api.is_list_member(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name, screen_name='themattharris') @unittest.skip('skipping non-updated test') def test_get_list_members(self): """Test listing members of the specified list succeeds""" self.api.get_list_members(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_get_specific_list(self): """Test getting specific list succeeds""" self.api.get_specific_list(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_get_list_subscriptions(self): """Test collection of the lists the specified user is subscribed to succeeds""" self.api.get_list_subscriptions(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_show_owned_lists(self): """Test collection of lists the specified user owns succeeds""" self.api.show_owned_lists(screen_name='twitter') # Saved Searches @unittest.skip('skipping non-updated test') def test_get_saved_searches(self): """Test getting list of saved searches for authenticated user succeeds""" self.api.get_saved_searches() @unittest.skip('skipping non-updated test') def test_create_get_destroy_saved_search(self): """Test getting list of saved searches for authenticated user succeeds""" saved_search = self.api.create_saved_search(query='#Twitter') saved_search_id = saved_search['id_str'] self.api.show_saved_search(id=saved_search_id) self.api.destroy_saved_search(id=saved_search_id) # Places & Geo @unittest.skip('skipping non-updated test') def test_get_geo_info(self): """Test getting info about a geo location succeeds""" self.api.get_geo_info(place_id='df51dec6f4ee2b2c') @unittest.skip('skipping non-updated test') def test_reverse_geo_code(self): """Test reversing geocode succeeds""" self.api.reverse_geocode(lat='37.76893497', long='-122.42284884') @unittest.skip('skipping non-updated test') def test_search_geo(self): """Test search for places that can be attached to a statuses/update succeeds""" self.api.search_geo(query='Toronto') @unittest.skip('skipping non-updated test') def test_get_similar_places(self): """Test locates places near the given coordinates which are similar in name succeeds""" self.api.get_similar_places(lat='37', long='-122', name='Twitter HQ') # Trends @unittest.skip('skipping non-updated test') def test_get_place_trends(self): """Test getting the top 10 trending topics for a specific WOEID succeeds""" self.api.get_place_trends(id=1) @unittest.skip('skipping non-updated test') def test_get_available_trends(self): """Test returning locations that Twitter has trending topic information for succeeds""" self.api.get_available_trends() @unittest.skip('skipping non-updated test') def test_get_closest_trends(self): """Test getting the locations that Twitter has trending topic information for, closest to a specified location succeeds""" self.api.get_closest_trends(lat='37', long='-122') # Help @unittest.skip('skipping non-updated test') def test_get_twitter_configuration(self): """Test getting Twitter's configuration succeeds""" self.api.get_twitter_configuration() @unittest.skip('skipping non-updated test') def test_get_supported_languages(self): """Test getting languages supported by Twitter succeeds""" self.api.get_supported_languages() @unittest.skip('skipping non-updated test') def test_privacy_policy(self): """Test getting Twitter's Privacy Policy succeeds""" self.api.get_privacy_policy() @unittest.skip('skipping non-updated test') def test_get_tos(self): """Test getting the Twitter Terms of Service succeeds""" self.api.get_tos() @unittest.skip('skipping non-updated test') def test_get_application_rate_limit_status(self): """Test getting application rate limit status succeeds""" self.oauth2_api.get_application_rate_limit_status()
class tweetdelete: def __init__(self, token_file, read_default_file, database): # Initialize Twitter if not os.path.isfile(token_file): print(f'Could not find {token_file}. We need to reauthenticate.') self.authenticate(token_file) self.keys = json.load(open(token_file)) self.twitter = Twython(**self.keys) # Open connection to database self.db = pymysql.connect(read_default_file=read_default_file, database=database) self.c = self.db.cursor() # Check if database is empty, indicating this is a first run # Direct user to initial setup using the Twitter archive if not self.c.execute("""SELECT * FROM tweetdelete"""): self.initialize_from_archive() def authenticate(self, token_file): """ Authenticate with Twitter and save the OAUTH tokens""" keys = {} keys['app_key'] = input('Enter the App Consumer Key: ').strip() keys['app_secret'] = input('Enter the App Consumer Secret: ').strip() twitter = Twython(**keys) auth = twitter.get_authentication_tokens() keys['oauth_token'] = auth['oauth_token'] keys['oauth_token_secret'] = auth['oauth_token_secret'] auth_url = auth['auth_url'] print(f'\nVisit this url to authorize the application: {auth_url}\n') oauth_verifier = input('Enter the PIN code: ') twitter = Twython(**keys) auth = twitter.get_authorized_tokens(oauth_verifier) keys['oauth_token'] = auth['oauth_token'] keys['oauth_token_secret'] = auth['oauth_token_secret'] with open(token_file, 'w') as fp: json.dump(keys, fp) print(f'The authorized user tokens were saved to {token_file}') def run(self, sql, data): """Execute SQL command with data payload""" try: self.c.execute(sql, data) self.db.commit() return True except Exception as e: self.db.rollback() print(f'Error: {e}') return False def flag_error(self, tweet_id): """Flag item as inaccesible via the API in the database""" sql = """UPDATE tweetdelete SET error = error + 1 WHERE id=%s""" if self.run(sql, tweet_id): return ' Flagged in database.' def initialize_from_archive(self): """Use Twitter archive to initialize the database""" msg = "\nThe `tweetdelete` database is currently empty. Because Twitter restricts API access " \ "to older content we need to use the account archive to access the full account history. " \ "Follow the instructions at the following link to download and extract your full archive: " \ "\nhttps://help.twitter.com/en/managing-your-account/how-to-download-your-twitter-archive" path = input(f'{msg}\n\nEnter path to Twitter archive: ').strip() tweet_path = os.path.join(path, 'tweet.js') if not os.path.exists(tweet_path): sys.exit( f'tweet.js not found in {path}. Please try again with valid Twitter archive.' ) like_path = os.path.join(path, 'like.js') if not os.path.exists(like_path): sys.exit( f'like.js not found in {path}. Please try again with valid Twitter archive.' ) # Load the tweets and add to the database print('Parsing tweet.js') with open(tweet_path, 'r') as fp: tweets = fp.read() tweets = tweets.replace('window.YTD.tweet.part0 = ', '') count_tweets = 0 for tweet in json.loads(tweets): tweet_id = int(tweet['id_str']) created_at = parser.parse(tweet['created_at']) sql = """INSERT INTO tweetdelete (id,created_at,kind) VALUES (%s,%s,0)""" data = (tweet_id, created_at) if self.run(sql, data): print(f'{tweet_id} added to database.') count_tweets += 1 # Load the likes and add to the database # Note whether the tweet is actually favorited according to the API print('Parsing like.js') with open(like_path, 'r') as fp: likes = fp.read() likes = likes.replace('window.YTD.like.part0 = ', '') count_likes = 0 for like in json.loads(likes): tweet_id = int(like['like']['tweetId']) try: # likes.js does not contain timestamps, use tweet as proxy tweet = self.twitter.show_status(id=tweet_id) created_at = parser.parse(tweet['created_at']) sql = """INSERT INTO tweetdelete (id,created_at,kind,favorited) VALUES (%s,%s,1,%s)""" data = (tweet_id, created_at, tweet['favorited']) if self.run(sql, data): print(f'{tweet_id} added to database.') count_likes += 1 except Exception as e: print(f'Error retrieving {tweet_id}: {e}') sleep(1) print( f'Added {count_tweets} tweets and {count_likes} likes to the database' ) def add_new_tweets(self): """Iterate through user timeline and add tweets to database.""" # Most recent tweet in database is used to stop iteration ret = self.c.execute( """SELECT id FROM tweetdelete WHERE kind=0 ORDER BY id DESC LIMIT 1""" ) max_id_db = self.c.fetchone()[0] if ret else 0 keep_going = True max_id = None count = 0 while keep_going: print(f'Loading tweets before: {max_id}') timeline = self.twitter.get_user_timeline(count=200, max_id=max_id, include_rts=True, trim_user=True) if len(timeline) == 0: # Reached end of timeline break for tweet in timeline: tweet_id = int(tweet['id_str']) created_at = parser.parse(tweet['created_at']) if tweet_id <= max_id_db: keep_going = False break sql = """INSERT INTO tweetdelete (id,created_at,kind) VALUES (%s,%s,0)""" data = (tweet_id, created_at) if self.run(sql, data): print(f'{tweet_id} added to database.') count += 1 max_id = tweet_id - 1 sleep(1) print(f'Added {count} tweets to the database') def add_new_likes(self): """Iterate through user likes and add tweets to database.""" # Most recent like in database is used to stop iteration ret = self.c.execute( """SELECT id FROM tweetdelete WHERE kind=1 ORDER BY id DESC LIMIT 1""" ) max_id_db = self.c.fetchone()[0] if ret else 0 keep_going = True max_id = None count = 0 while keep_going: print(f'Loading likes before: {max_id}') likes = self.twitter.get_favorites(count=200, max_id=max_id, include_entities=False) if len(likes) == 0: # Reached end of likes break for like in likes: tweet_id = int(like['id_str']) if tweet_id <= max_id_db: keep_going = False break # Since the timestamp of likes is not available, we use the current timestamp created_at = gmtime() sql = """INSERT INTO tweetdelete (id,created_at,kind,favorited) VALUES (%s,%s,1,%s)""" data = (tweet_id, created_at, like['favorited']) if self.run(sql, data): print(f'{tweet_id} added to database.') count += 1 max_id = tweet_id - 1 sleep(1) print(f'Added {count} likes to the database') def cull_tweets(self): """Delete tweets more than 3 months old""" # Get all tweets in database more than 3 months old # Skip tweets with more than 10 errors sql = """ SELECT id FROM tweetdelete WHERE kind = 0 AND error < 10 AND created_at < (NOW() - INTERVAL 3 MONTH) """ self.c.execute(sql) tweets = self.c.fetchall() count = 0 for tweet in tweets: tweet_id = tweet[0] msg = '' # Delete the tweet and remove from database try: self.twitter.destroy_status(id=tweet_id) count += 1 msg += f'Deleted {tweet_id}.' if self.run("""DELETE FROM tweetdelete WHERE id=%s""", tweet_id): msg += ' Removed from database.' except Exception as e: msg += f'Error deleting {tweet_id} ({e}).' msg += self.flag_error(tweet_id) print(msg) sleep(1) print(f'Deleted {count} tweets') def cull_likes(self): """Unlike tweets more than 3 months old""" # Get all likes in database more than 3 months old that are # favorited according to the API. Skip tweets with more than 10 errors sql = """ SELECT id FROM tweetdelete WHERE kind = 1 AND favorited = 1 AND error < 10 AND created_at < (NOW() - INTERVAL 3 MONTH) """ self.c.execute(sql) likes = self.c.fetchall() count = 0 for like in likes: tweet_id = like[0] msg = '' # Unlike the tweet try: self.twitter.destroy_favorite(id=tweet_id) count += 1 msg += f'Unliked {tweet_id}.' if self.run("""DELETE FROM tweetdelete WHERE id=%s""", tweet_id): msg += ' Removed from database.' except Exception as e: msg += f'Error unliking {tweet_id} ({e}).' msg += self.flag_error(tweet_id) print(msg) sleep(1) print(f'Unliked {count} tweets')
class TwitterClient(): def __init__(self, file_name='cred.txt'): with open(file_name) as f: lines = f.readlines() self.APP_KEY = lines[0].strip() self.APP_SECRET = lines[1].strip() if len(lines)>3: self.USER_TOKEN = lines[2].strip() self.USER_SECRET = lines[3].strip() else: self.USER_TOKEN = None self.USER_SECRET = None self.reset() def reset(self): self.twitter = Twython(self.APP_KEY, self.APP_SECRET, self.USER_TOKEN, self.USER_SECRET) def get_timeline(self, screen_name=None, user_id=None): all_tweets = [] results = [] next_max_id = None print('Extracting timeline of: @{}'.format(screen_name or user_id)) while next_max_id==None or (results!=None and len(results) != 0): try: results = self.try_call(lambda: self.twitter.get_user_timeline(screen_name=screen_name, user_id=user_id, count=200, max_id=next_max_id, tweet_mode='extended')) except: #something went wrong: internet or auth break if results: next_max_id = results[-1]['id'] - 1 all_tweets+=results else: break print('Total tweets: {}'.format(len(all_tweets))) timeline_df = pd.DataFrame(all_tweets) if len(timeline_df)>0: timeline_df['created_at']=pd.to_datetime(timeline_df['created_at']) return timeline_df def get_likes(self, screen_name=None, user_id=None): all_tweets = [] results = [] next_max_id = None print('Extracting likes of: @{}'.format(screen_name or user_id)) while next_max_id==None or (results!=None and len(results) != 0): try: results = self.try_call(lambda: self.twitter.get_favorites(screen_name=screen_name, user_id=user_id, count=200, max_id=next_max_id, tweet_mode='extended')) except: #something went wrong: internet or auth break if results: next_max_id = results[-1]['id'] - 1 all_tweets+=results else: break print('Total likes: {}'.format(len(all_tweets))) likes_df = pd.DataFrame(all_tweets) if len(likes_df)>0: likes_df['created_at']=pd.to_datetime(likes_df['created_at']) return likes_df def get_friends_list(self, screen_name=None, user_id=None): all_friends = [] next_cursor = -1 response = None print('Extracting friends of: @{}'.format(screen_name or user_id)) while next_cursor!=0 and (next_cursor==-1 or (response!=None and len(response['users']) != 0)): print(next_cursor, response and len(response['users']), len(all_friends)) time.sleep(5) try: response = self.try_call(lambda: self.twitter.get_friends_list(screen_name=screen_name, user_id=user_id, count=200, cursor=next_cursor)) except: #something went wrong: internet or auth break if response: next_cursor = response['next_cursor'] all_friends+=response['users'] else: break print('Total friends: {}'.format(len(all_friends))) friends_df = pd.DataFrame(all_friends) return friends_df def get_followers_list(self, screen_name=None, user_id=None): all_friends = [] next_cursor = -1 response = None print('Extracting followers of: @{}'.format(screen_name or user_id)) while next_cursor!=0 and (next_cursor==-1 or (response!=None and len(response['users']) != 0)): print(next_cursor, response and len(response['users']), len(all_friends)) time.sleep(5) try: response = self.try_call(lambda: self.twitter.get_followers_list(screen_name=screen_name, user_id=user_id, count=200, cursor=next_cursor)) except: #something went wrong: internet or auth break if response: next_cursor = response['next_cursor'] all_friends+=response['users'] else: break print('Total followers: {}'.format(len(all_friends))) friends_df = pd.DataFrame(all_friends) return friends_df def show_users(self, screen_names): dict_user_details = {} for screen_name in screen_names: dict_user_details[screen_name] = self.try_call(lambda: self.twitter.show_user(screen_name=screen_name, include_entities=False)) return dict_user_details def show_users_ids(self, ids): dict_user_details = {} for id_u in ids: dict_user_details[id_u] = self.try_call(lambda: self.twitter.show_user(user_id=id_u, include_entities=False)) return dict_user_details def try_call(self, call, deep=1, throw_errors = False): try: response = call() return response except TwythonRateLimitError as e: time_to_wait = int(self.twitter.get_lastfunction_header('x-rate-limit-reset')) - int(time.time()) + 10 print('Rate limit exceded. {}th try. Waiting {} seconds: {}'.format(deep, time_to_wait, time.strftime('%X', time.localtime(time.time()+time_to_wait)))) time.sleep(time_to_wait) return self.try_call(call, deep=deep+1) except TwythonAuthError as e: print('Auth error') print(str(e)) if throw_errors: raise return except TwythonError as e: if deep>=6: return print('No internet. Waiting {} seconds'.format(10)) print(str(e)) if throw_errors: raise #time.sleep(10) return #self.try_call(call, deep=deep+1)
class TwythonAPITestCase(unittest.TestCase): def setUp(self): client_args = { 'headers': { 'User-Agent': '__twython__ Test' }, 'allow_redirects': False } oauth2_client_args = { 'headers': {} # This is so we can hit coverage that Twython sets User-Agent for us if none is supplied } self.api = Twython(app_key, app_secret, oauth_token, oauth_token_secret, client_args=client_args) self.oauth2_api = Twython(app_key, access_token=access_token, client_args=oauth2_client_args) def test_construct_api_url(self): """Test constructing a Twitter API url works as we expect""" url = 'https://api.twitter.com/1.1/search/tweets.json' constructed_url = self.api.construct_api_url(url, q='#twitter') self.assertEqual(constructed_url, 'https://api.twitter.com/1.1/search/tweets.json?q=%23twitter') def test_get(self): """Test Twython generic GET request works""" self.api.get('account/verify_credentials') def test_post(self): """Test Twython generic POST request works, with a full url and with just an endpoint""" update_url = 'https://api.twitter.com/1.1/statuses/update.json' status = self.api.post(update_url, params={'status': 'I love Twython!'}) self.api.post('statuses/destroy/%s' % status['id_str']) def test_get_lastfunction_header(self): """Test getting last specific header of the last API call works""" self.api.get('statuses/home_timeline') self.api.get_lastfunction_header('x-rate-limit-remaining') def test_get_lastfunction_header_not_present(self): """Test getting specific header that does not exist from the last call returns None""" self.api.get('statuses/home_timeline') header = self.api.get_lastfunction_header('does-not-exist') self.assertEqual(header, None) def test_get_lastfunction_header_no_last_api_call(self): """Test attempting to get a header when no API call was made raises a TwythonError""" self.assertRaises(TwythonError, self.api.get_lastfunction_header, 'no-api-call-was-made') def test_search_gen(self): """Test looping through the generator results works, at least once that is""" search = self.api.search_gen('twitter', count=1) counter = 0 while counter < 2: counter += 1 result = next(search) new_id_str = int(result['id_str']) if counter == 1: prev_id_str = new_id_str time.sleep(1) # Give time for another tweet to come into search if counter == 2: self.assertTrue(new_id_str > prev_id_str) def test_encode(self): """Test encoding UTF-8 works""" self.api.encode('Twython is awesome!') def test_html_for_tweet(self): """Test HTML for Tweet returns what we want""" tweet_text = self.api.html_for_tweet(test_tweet_object) self.assertEqual(test_tweet_html, tweet_text) def test_html_for_tweet_expanded_url(self): """Test using expanded url in HTML for Tweet displays full urls""" tweet_text = self.api.html_for_tweet(test_tweet_object, use_expanded_url=True) # Make sure full url is in HTML self.assertTrue('http://google.com' in tweet_text) def test_html_for_tweet_short_url(self): """Test using expanded url in HTML for Tweet displays full urls""" tweet_text = self.api.html_for_tweet(test_tweet_object, False) # Make sure HTML doesn't contain the display OR exapanded url self.assertTrue(not 'http://google.com' in tweet_text) self.assertTrue(not 'google.com' in tweet_text) def test_raise_error_on_bad_ssl_cert(self): """Test TwythonError is raised by a RequestException when an actual HTTP happens""" self.assertRaises(TwythonError, self.api.get, 'https://example.com') # Timelines def test_get_mentions_timeline(self): """Test returning mentions timeline for authenticated user succeeds""" self.api.get_mentions_timeline() def test_get_user_timeline(self): """Test returning timeline for authenticated user and random user succeeds""" self.api.get_user_timeline() # Authenticated User Timeline self.api.get_user_timeline(screen_name='twitter') # Random User Timeline def test_get_protected_user_timeline_following(self): """Test returning a protected user timeline who you are following succeeds""" self.api.get_user_timeline(screen_name=protected_twitter_1) def test_get_protected_user_timeline_not_following(self): """Test returning a protected user timeline who you are not following fails and raise a TwythonAuthError""" self.assertRaises(TwythonAuthError, self.api.get_user_timeline, screen_name=protected_twitter_2) def test_retweeted_of_me(self): """Test that getting recent tweets by authenticated user that have been retweeted by others succeeds""" self.api.retweeted_of_me() def test_get_home_timeline(self): """Test returning home timeline for authenticated user succeeds""" self.api.get_home_timeline() # Tweets def test_get_retweets(self): """Test getting retweets of a specific tweet succeeds""" self.api.get_retweets(id=test_tweet_id) def test_show_status(self): """Test returning a single status details succeeds""" self.api.show_status(id=test_tweet_id) def test_update_and_destroy_status(self): """Test updating and deleting a status succeeds""" status = self.api.update_status(status='Test post just to get deleted :(') self.api.destroy_status(id=status['id_str']) def test_get_oembed_tweet(self): """Test getting info to embed tweet on Third Party site succeeds""" self.api.get_oembed_tweet(id='99530515043983360') def test_get_retweeters_ids(self): """Test getting ids for people who retweeted a tweet succeeds""" self.api.get_retweeters_ids(id='99530515043983360') # Search def test_search(self): """Test searching tweets succeeds""" self.api.search(q='twitter') # Direct Messages def test_get_direct_messages(self): """Test getting the authenticated users direct messages succeeds""" self.api.get_direct_messages() def test_get_sent_messages(self): """Test getting the authenticated users direct messages they've sent succeeds""" self.api.get_sent_messages() def test_send_get_and_destroy_direct_message(self): """Test sending, getting, then destory a direct message succeeds""" message = self.api.send_direct_message(screen_name=protected_twitter_1, text='Hey d00d! %s' % int(time.time())) self.api.get_direct_message(id=message['id_str']) self.api.destroy_direct_message(id=message['id_str']) def test_send_direct_message_to_non_follower(self): """Test sending a direct message to someone who doesn't follow you fails""" self.assertRaises(TwythonError, self.api.send_direct_message, screen_name=protected_twitter_2, text='Yo, man!') # Friends & Followers def test_get_user_ids_of_blocked_retweets(self): """Test that collection of user_ids that the authenticated user does not want to receive retweets from succeeds""" self.api.get_user_ids_of_blocked_retweets(stringify_ids=True) def test_get_friends_ids(self): """Test returning ids of users the authenticated user and then a random user is following succeeds""" self.api.get_friends_ids() self.api.get_friends_ids(screen_name='twitter') def test_get_followers_ids(self): """Test returning ids of users the authenticated user and then a random user are followed by succeeds""" self.api.get_followers_ids() self.api.get_followers_ids(screen_name='twitter') def test_lookup_friendships(self): """Test returning relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided succeeds""" self.api.lookup_friendships(screen_name='twitter,ryanmcgrath') def test_get_incoming_friendship_ids(self): """Test returning incoming friendship ids succeeds""" self.api.get_incoming_friendship_ids() def test_get_outgoing_friendship_ids(self): """Test returning outgoing friendship ids succeeds""" self.api.get_outgoing_friendship_ids() def test_create_friendship(self): """Test creating a friendship succeeds""" self.api.create_friendship(screen_name='justinbieber') def test_destroy_friendship(self): """Test destroying a friendship succeeds""" self.api.destroy_friendship(screen_name='justinbieber') def test_update_friendship(self): """Test updating friendships succeeds""" self.api.update_friendship(screen_name=protected_twitter_1, retweets='true') self.api.update_friendship(screen_name=protected_twitter_1, retweets=False) def test_show_friendships(self): """Test showing specific friendship succeeds""" self.api.show_friendship(target_screen_name=protected_twitter_1) def test_get_friends_list(self): """Test getting list of users authenticated user then random user is following succeeds""" self.api.get_friends_list() self.api.get_friends_list(screen_name='twitter') def test_get_followers_list(self): """Test getting list of users authenticated user then random user are followed by succeeds""" self.api.get_followers_list() self.api.get_followers_list(screen_name='twitter') # Users def test_get_account_settings(self): """Test getting the authenticated user account settings succeeds""" self.api.get_account_settings() def test_verify_credentials(self): """Test representation of the authenticated user call succeeds""" self.api.verify_credentials() def test_update_account_settings(self): """Test updating a user account settings succeeds""" self.api.update_account_settings(lang='en') def test_update_delivery_service(self): """Test updating delivery settings fails because we don't have a mobile number on the account""" self.assertRaises(TwythonError, self.api.update_delivery_service, device='none') def test_update_profile(self): """Test updating profile succeeds""" self.api.update_profile(include_entities='true') def test_update_profile_colors(self): """Test updating profile colors succeeds""" self.api.update_profile_colors(profile_background_color='3D3D3D') def test_list_blocks(self): """Test listing users who are blocked by the authenticated user succeeds""" self.api.list_blocks() def test_list_block_ids(self): """Test listing user ids who are blocked by the authenticated user succeeds""" self.api.list_block_ids() def test_create_block(self): """Test blocking a user succeeds""" self.api.create_block(screen_name='justinbieber') def test_destroy_block(self): """Test unblocking a user succeeds""" self.api.destroy_block(screen_name='justinbieber') def test_lookup_user(self): """Test listing a number of user objects succeeds""" self.api.lookup_user(screen_name='twitter,justinbieber') def test_show_user(self): """Test showing one user works""" self.api.show_user(screen_name='twitter') def test_search_users(self): """Test that searching for users succeeds""" self.api.search_users(q='Twitter API') def test_get_contributees(self): """Test returning list of accounts the specified user can contribute to succeeds""" self.api.get_contributees(screen_name='TechCrunch') def test_get_contributors(self): """Test returning list of accounts that contribute to the authenticated user fails because we are not a Contributor account""" self.assertRaises(TwythonError, self.api.get_contributors, screen_name=screen_name) def test_remove_profile_banner(self): """Test removing profile banner succeeds""" self.api.remove_profile_banner() def test_get_profile_banner_sizes(self): """Test getting list of profile banner sizes fails because we have not uploaded a profile banner""" self.assertRaises(TwythonError, self.api.get_profile_banner_sizes) # Suggested Users def test_get_user_suggestions_by_slug(self): """Test getting user suggestions by slug succeeds""" self.api.get_user_suggestions_by_slug(slug='twitter') def test_get_user_suggestions(self): """Test getting user suggestions succeeds""" self.api.get_user_suggestions() def test_get_user_suggestions_statuses_by_slug(self): """Test getting status of suggested users succeeds""" self.api.get_user_suggestions_statuses_by_slug(slug='funny') # Favorites def test_get_favorites(self): """Test getting list of favorites for the authenticated user succeeds""" self.api.get_favorites() def test_create_and_destroy_favorite(self): """Test creating and destroying a favorite on a tweet succeeds""" self.api.create_favorite(id=test_tweet_id) self.api.destroy_favorite(id=test_tweet_id) # Lists def test_show_lists(self): """Test show lists for specified user""" self.api.show_lists(screen_name='twitter') def test_get_list_statuses(self): """Test timeline of tweets authored by members of the specified list succeeds""" self.api.get_list_statuses(list_id=test_list_id) def test_create_update_destroy_list_add_remove_list_members(self): """Test create a list, adding and removing members then deleting the list succeeds""" the_list = self.api.create_list(name='Stuff') list_id = the_list['id_str'] self.api.update_list(list_id=list_id, name='Stuff Renamed') screen_names = ['johncena', 'xbox'] # Multi add/delete members self.api.create_list_members(list_id=list_id, screen_name=screen_names) self.api.delete_list_members(list_id=list_id, screen_name=screen_names) # Single add/delete member self.api.add_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list(list_id=list_id) def test_get_list_subscribers(self): """Test list of subscribers of a specific list succeeds""" self.api.get_list_subscribers(list_id=test_list_id) def test_subscribe_is_subbed_and_unsubscribe_to_list(self): """Test subscribing, is a list sub and unsubbing to list succeeds""" self.api.subscribe_to_list(list_id=test_list_id) # Returns 404 if user is not a subscriber self.api.is_list_subscriber(list_id=test_list_id, screen_name=screen_name) self.api.unsubscribe_from_list(list_id=test_list_id) def test_is_list_member(self): """Test returning if specified user is member of a list succeeds""" # Returns 404 if not list member self.api.is_list_member(list_id=test_list_id, screen_name='jack') def test_get_list_members(self): """Test listing members of the specified list succeeds""" self.api.get_list_members(list_id=test_list_id) def test_get_specific_list(self): """Test getting specific list succeeds""" self.api.get_specific_list(list_id=test_list_id) def test_get_list_subscriptions(self): """Test collection of the lists the specified user is subscribed to succeeds""" self.api.get_list_subscriptions(screen_name='twitter') def test_show_owned_lists(self): """Test collection of lists the specified user owns succeeds""" self.api.show_owned_lists(screen_name='twitter') # Saved Searches def test_get_saved_searches(self): """Test getting list of saved searches for authenticated user succeeds""" self.api.get_saved_searches() def test_create_get_destroy_saved_search(self): """Test getting list of saved searches for authenticated user succeeds""" saved_search = self.api.create_saved_search(query='#Twitter') saved_search_id = saved_search['id_str'] self.api.show_saved_search(id=saved_search_id) self.api.destroy_saved_search(id=saved_search_id) # Places & Geo def test_get_geo_info(self): """Test getting info about a geo location succeeds""" self.api.get_geo_info(place_id='df51dec6f4ee2b2c') def test_reverse_geo_code(self): """Test reversing geocode succeeds""" self.api.reverse_geocode(lat='37.76893497', long='-122.42284884') def test_search_geo(self): """Test search for places that can be attached to a statuses/update succeeds""" self.api.search_geo(query='Toronto') def test_get_similar_places(self): """Test locates places near the given coordinates which are similar in name succeeds""" self.api.get_similar_places(lat='37', long='-122', name='Twitter HQ') # Trends def test_get_place_trends(self): """Test getting the top 10 trending topics for a specific WOEID succeeds""" self.api.get_place_trends(id=1) def test_get_available_trends(self): """Test returning locations that Twitter has trending topic information for succeeds""" self.api.get_available_trends() def test_get_closest_trends(self): """Test getting the locations that Twitter has trending topic information for, closest to a specified location succeeds""" self.api.get_closest_trends(lat='37', long='-122') # Help def test_get_application_rate_limit_status(self): """Test getting application rate limit status succeeds""" self.oauth2_api.get_application_rate_limit_status()
class TwythonEndpointsTestCase(unittest.TestCase): def setUp(self): client_args = { 'headers': { 'User-Agent': '__twython__ Test' }, 'allow_redirects': False } oauth2_client_args = { 'headers': {} # This is so we can hit coverage that Twython sets User-Agent for us if none is supplied } self.api = Twython(app_key, app_secret, oauth_token, oauth_token_secret, client_args=client_args) self.oauth2_api = Twython(app_key, access_token=access_token, client_args=oauth2_client_args) # Timelines @unittest.skip('skipping non-updated test') def test_get_mentions_timeline(self): """Test returning mentions timeline for authenticated user succeeds""" self.api.get_mentions_timeline() @unittest.skip('skipping non-updated test') def test_get_user_timeline(self): """Test returning timeline for authenticated user and random user succeeds""" self.api.get_user_timeline() # Authenticated User Timeline self.api.get_user_timeline(screen_name='twitter') # Random User Timeline @unittest.skip('skipping non-updated test') def test_get_protected_user_timeline_following(self): """Test returning a protected user timeline who you are following succeeds""" self.api.get_user_timeline(screen_name=protected_twitter_1) @unittest.skip('skipping non-updated test') def test_get_protected_user_timeline_not_following(self): """Test returning a protected user timeline who you are not following fails and raise a TwythonAuthError""" self.assertRaises(TwythonAuthError, self.api.get_user_timeline, screen_name=protected_twitter_2) @unittest.skip('skipping non-updated test') def test_retweeted_of_me(self): """Test that getting recent tweets by authenticated user that have been retweeted by others succeeds""" self.api.retweeted_of_me() @unittest.skip('skipping non-updated test') def test_get_home_timeline(self): """Test returning home timeline for authenticated user succeeds""" self.api.get_home_timeline() # Tweets @unittest.skip('skipping non-updated test') def test_get_retweets(self): """Test getting retweets of a specific tweet succeeds""" self.api.get_retweets(id=test_tweet_id) @unittest.skip('skipping non-updated test') def test_show_status(self): """Test returning a single status details succeeds""" self.api.show_status(id=test_tweet_id) @unittest.skip('skipping non-updated test') def test_update_and_destroy_status(self): """Test updating and deleting a status succeeds""" status = self.api.update_status(status='Test post just to get deleted :( %s' % int(time.time())) self.api.destroy_status(id=status['id_str']) @unittest.skip('skipping non-updated test') def test_get_oembed_tweet(self): """Test getting info to embed tweet on Third Party site succeeds""" self.api.get_oembed_tweet(id='99530515043983360') @unittest.skip('skipping non-updated test') def test_get_retweeters_ids(self): """Test getting ids for people who retweeted a tweet succeeds""" self.api.get_retweeters_ids(id='99530515043983360') # Search @unittest.skip('skipping non-updated test') def test_search(self): """Test searching tweets succeeds""" self.api.search(q='twitter') # Direct Messages @unittest.skip('skipping non-updated test') def test_get_direct_messages(self): """Test getting the authenticated users direct messages succeeds""" self.api.get_direct_messages() @unittest.skip('skipping non-updated test') def test_get_sent_messages(self): """Test getting the authenticated users direct messages they've sent succeeds""" self.api.get_sent_messages() @unittest.skip('skipping non-updated test') def test_send_get_and_destroy_direct_message(self): """Test sending, getting, then destory a direct message succeeds""" message = self.api.send_direct_message(screen_name=protected_twitter_1, text='Hey d00d! %s' % int(time.time())) self.api.get_direct_message(id=message['id_str']) self.api.destroy_direct_message(id=message['id_str']) @unittest.skip('skipping non-updated test') def test_send_direct_message_to_non_follower(self): """Test sending a direct message to someone who doesn't follow you fails""" self.assertRaises(TwythonError, self.api.send_direct_message, screen_name=protected_twitter_2, text='Yo, man! %s' % int(time.time())) # Friends & Followers @unittest.skip('skipping non-updated test') def test_get_user_ids_of_blocked_retweets(self): """Test that collection of user_ids that the authenticated user does not want to receive retweets from succeeds""" self.api.get_user_ids_of_blocked_retweets(stringify_ids=True) @unittest.skip('skipping non-updated test') def test_get_friends_ids(self): """Test returning ids of users the authenticated user and then a random user is following succeeds""" self.api.get_friends_ids() self.api.get_friends_ids(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_get_followers_ids(self): """Test returning ids of users the authenticated user and then a random user are followed by succeeds""" self.api.get_followers_ids() self.api.get_followers_ids(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_lookup_friendships(self): """Test returning relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided succeeds""" self.api.lookup_friendships(screen_name='twitter,ryanmcgrath') @unittest.skip('skipping non-updated test') def test_get_incoming_friendship_ids(self): """Test returning incoming friendship ids succeeds""" self.api.get_incoming_friendship_ids() @unittest.skip('skipping non-updated test') def test_get_outgoing_friendship_ids(self): """Test returning outgoing friendship ids succeeds""" self.api.get_outgoing_friendship_ids() @unittest.skip('skipping non-updated test') def test_create_friendship(self): """Test creating a friendship succeeds""" self.api.create_friendship(screen_name='justinbieber') @unittest.skip('skipping non-updated test') def test_destroy_friendship(self): """Test destroying a friendship succeeds""" self.api.destroy_friendship(screen_name='justinbieber') @unittest.skip('skipping non-updated test') def test_update_friendship(self): """Test updating friendships succeeds""" self.api.update_friendship(screen_name=protected_twitter_1, retweets='true') self.api.update_friendship(screen_name=protected_twitter_1, retweets=False) @unittest.skip('skipping non-updated test') def test_show_friendships(self): """Test showing specific friendship succeeds""" self.api.show_friendship(target_screen_name=protected_twitter_1) @unittest.skip('skipping non-updated test') def test_get_friends_list(self): """Test getting list of users authenticated user then random user is following succeeds""" self.api.get_friends_list() self.api.get_friends_list(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_get_followers_list(self): """Test getting list of users authenticated user then random user are followed by succeeds""" self.api.get_followers_list() self.api.get_followers_list(screen_name='twitter') # Users @unittest.skip('skipping non-updated test') def test_get_account_settings(self): """Test getting the authenticated user account settings succeeds""" self.api.get_account_settings() @unittest.skip('skipping non-updated test') def test_verify_credentials(self): """Test representation of the authenticated user call succeeds""" self.api.verify_credentials() @unittest.skip('skipping non-updated test') def test_update_account_settings(self): """Test updating a user account settings succeeds""" self.api.update_account_settings(lang='en') @unittest.skip('skipping non-updated test') def test_update_delivery_service(self): """Test updating delivery settings fails because we don't have a mobile number on the account""" self.assertRaises(TwythonError, self.api.update_delivery_service, device='none') @unittest.skip('skipping non-updated test') def test_update_profile(self): """Test updating profile succeeds""" self.api.update_profile(include_entities='true') @unittest.skip('skipping non-updated test') def test_update_profile_colors(self): """Test updating profile colors succeeds""" self.api.update_profile_colors(profile_background_color='3D3D3D') @unittest.skip('skipping non-updated test') def test_list_blocks(self): """Test listing users who are blocked by the authenticated user succeeds""" self.api.list_blocks() @unittest.skip('skipping non-updated test') def test_list_block_ids(self): """Test listing user ids who are blocked by the authenticated user succeeds""" self.api.list_block_ids() @unittest.skip('skipping non-updated test') def test_create_block(self): """Test blocking a user succeeds""" self.api.create_block(screen_name='justinbieber') @unittest.skip('skipping non-updated test') def test_destroy_block(self): """Test unblocking a user succeeds""" self.api.destroy_block(screen_name='justinbieber') @unittest.skip('skipping non-updated test') def test_lookup_user(self): """Test listing a number of user objects succeeds""" self.api.lookup_user(screen_name='twitter,justinbieber') @unittest.skip('skipping non-updated test') def test_show_user(self): """Test showing one user works""" self.api.show_user(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_search_users(self): """Test that searching for users succeeds""" self.api.search_users(q='Twitter API') @unittest.skip('skipping non-updated test') def test_get_contributees(self): """Test returning list of accounts the specified user can contribute to succeeds""" self.api.get_contributees(screen_name='TechCrunch') @unittest.skip('skipping non-updated test') def test_get_contributors(self): """Test returning list of accounts that contribute to the authenticated user fails because we are not a Contributor account""" self.assertRaises(TwythonError, self.api.get_contributors, screen_name=screen_name) @unittest.skip('skipping non-updated test') def test_remove_profile_banner(self): """Test removing profile banner succeeds""" self.api.remove_profile_banner() @unittest.skip('skipping non-updated test') def test_get_profile_banner_sizes(self): """Test getting list of profile banner sizes fails because we have not uploaded a profile banner""" self.assertRaises(TwythonError, self.api.get_profile_banner_sizes) # Suggested Users @unittest.skip('skipping non-updated test') def test_get_user_suggestions_by_slug(self): """Test getting user suggestions by slug succeeds""" self.api.get_user_suggestions_by_slug(slug='twitter') @unittest.skip('skipping non-updated test') def test_get_user_suggestions(self): """Test getting user suggestions succeeds""" self.api.get_user_suggestions() @unittest.skip('skipping non-updated test') def test_get_user_suggestions_statuses_by_slug(self): """Test getting status of suggested users succeeds""" self.api.get_user_suggestions_statuses_by_slug(slug='funny') # Favorites @unittest.skip('skipping non-updated test') def test_get_favorites(self): """Test getting list of favorites for the authenticated user succeeds""" self.api.get_favorites() @unittest.skip('skipping non-updated test') def test_create_and_destroy_favorite(self): """Test creating and destroying a favorite on a tweet succeeds""" self.api.create_favorite(id=test_tweet_id) self.api.destroy_favorite(id=test_tweet_id) # Lists @unittest.skip('skipping non-updated test') def test_show_lists(self): """Test show lists for specified user""" self.api.show_lists(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_get_list_statuses(self): """Test timeline of tweets authored by members of the specified list succeeds""" self.api.get_list_statuses(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_create_update_destroy_list_add_remove_list_members(self): """Test create a list, adding and removing members then deleting the list succeeds""" the_list = self.api.create_list(name='Stuff %s' % int(time.time())) list_id = the_list['id_str'] self.api.update_list(list_id=list_id, name='Stuff Renamed %s' % int(time.time())) screen_names = ['johncena', 'xbox'] # Multi add/delete members self.api.create_list_members(list_id=list_id, screen_name=screen_names) self.api.delete_list_members(list_id=list_id, screen_name=screen_names) # Single add/delete member self.api.add_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list(list_id=list_id) @unittest.skip('skipping non-updated test') def test_get_list_memberships(self): """Test list of memberhips the authenticated user succeeds""" self.api.get_list_memberships() @unittest.skip('skipping non-updated test') def test_get_list_subscribers(self): """Test list of subscribers of a specific list succeeds""" self.api.get_list_subscribers(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_subscribe_is_subbed_and_unsubscribe_to_list(self): """Test subscribing, is a list sub and unsubbing to list succeeds""" self.api.subscribe_to_list(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) # Returns 404 if user is not a subscriber self.api.is_list_subscriber(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name, screen_name=screen_name) self.api.unsubscribe_from_list(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_is_list_member(self): """Test returning if specified user is member of a list succeeds""" # Returns 404 if not list member self.api.is_list_member(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name, screen_name='themattharris') @unittest.skip('skipping non-updated test') def test_get_list_members(self): """Test listing members of the specified list succeeds""" self.api.get_list_members(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_get_specific_list(self): """Test getting specific list succeeds""" self.api.get_specific_list(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) @unittest.skip('skipping non-updated test') def test_get_list_subscriptions(self): """Test collection of the lists the specified user is subscribed to succeeds""" self.api.get_list_subscriptions(screen_name='twitter') @unittest.skip('skipping non-updated test') def test_show_owned_lists(self): """Test collection of lists the specified user owns succeeds""" self.api.show_owned_lists(screen_name='twitter') # Saved Searches @unittest.skip('skipping non-updated test') def test_get_saved_searches(self): """Test getting list of saved searches for authenticated user succeeds""" self.api.get_saved_searches() @unittest.skip('skipping non-updated test') def test_create_get_destroy_saved_search(self): """Test getting list of saved searches for authenticated user succeeds""" saved_search = self.api.create_saved_search(query='#Twitter') saved_search_id = saved_search['id_str'] self.api.show_saved_search(id=saved_search_id) self.api.destroy_saved_search(id=saved_search_id) # Places & Geo @unittest.skip('skipping non-updated test') def test_get_geo_info(self): """Test getting info about a geo location succeeds""" self.api.get_geo_info(place_id='df51dec6f4ee2b2c') @unittest.skip('skipping non-updated test') def test_reverse_geo_code(self): """Test reversing geocode succeeds""" self.api.reverse_geocode(lat='37.76893497', long='-122.42284884') @unittest.skip('skipping non-updated test') def test_search_geo(self): """Test search for places that can be attached to a statuses/update succeeds""" self.api.search_geo(query='Toronto') @unittest.skip('skipping non-updated test') def test_get_similar_places(self): """Test locates places near the given coordinates which are similar in name succeeds""" self.api.get_similar_places(lat='37', long='-122', name='Twitter HQ') # Trends @unittest.skip('skipping non-updated test') def test_get_place_trends(self): """Test getting the top 10 trending topics for a specific WOEID succeeds""" self.api.get_place_trends(id=1) @unittest.skip('skipping non-updated test') def test_get_available_trends(self): """Test returning locations that Twitter has trending topic information for succeeds""" self.api.get_available_trends() @unittest.skip('skipping non-updated test') def test_get_closest_trends(self): """Test getting the locations that Twitter has trending topic information for, closest to a specified location succeeds""" self.api.get_closest_trends(lat='37', long='-122') # Help @unittest.skip('skipping non-updated test') def test_get_twitter_configuration(self): """Test getting Twitter's configuration succeeds""" self.api.get_twitter_configuration() @unittest.skip('skipping non-updated test') def test_get_supported_languages(self): """Test getting languages supported by Twitter succeeds""" self.api.get_supported_languages() @unittest.skip('skipping non-updated test') def test_privacy_policy(self): """Test getting Twitter's Privacy Policy succeeds""" self.api.get_privacy_policy() @unittest.skip('skipping non-updated test') def test_get_tos(self): """Test getting the Twitter Terms of Service succeeds""" self.api.get_tos() @unittest.skip('skipping non-updated test') def test_get_application_rate_limit_status(self): """Test getting application rate limit status succeeds""" self.oauth2_api.get_application_rate_limit_status()
get_ipython().run_line_magic('matplotlib', 'inline') import seaborn as sns from twython import Twython # Obtain an OAUTH 2 Access Token twitter = Twython(config.API_KEY, config.API_SECRET_KEY, oauth_version=2) ACCESS_TOKEN = twitter.obtain_access_token() #%% # Prepare to use Access Token twitter = Twython(config.API_KEY, access_token=ACCESS_TOKEN) #%% # Get users Tweets, Rts, Replies and Favs from timeline Tweets = twitter.get_user_timeline(screen_name=config.USER, count=200) Favs = twitter.get_favorites(screen_name=config.USER) # for fav in Favs: # print(f"User: {fav['quoted_status']['user']['screen_name']} -> {fav['text']}") #%% # Select the columns we want to use in our DataFrame cols = [ "screen_name", "created_at", "text", "in_reply_to_status_id_str", "type" ] #%% # Find the type of each Tweet object and add another key called "type" for tweet in Tweets: tweet["created_at"] = pd.to_datetime( tweet["created_at"], infer_datetime_format=True).normalize().date()
class ServiceTwitter(ServicesMgr): """ Service Twitter """ def __init__(self, token=None, **kwargs): """ :param token: :param kwargs: """ super(ServiceTwitter, self).__init__(token, **kwargs) self.consumer_key = settings.TH_TWITTER_KEY['consumer_key'] self.consumer_secret = settings.TH_TWITTER_KEY['consumer_secret'] self.token = token self.oauth = 'oauth1' self.service = 'ServiceTwitter' if self.token is not None: token_key, token_secret = self.token.split('#TH#') try: self.twitter_api = Twython(self.consumer_key, self.consumer_secret, token_key, token_secret) except (TwythonAuthError, TwythonRateLimitError) as e: us = UserService.objects.get(token=token) logger.error(e.msg, e.error_code) update_result(us.trigger_id, msg=e.msg, status=False) def read_data(self, **kwargs): """ get the data from the service :param kwargs: contain keyword args : trigger_id at least :type kwargs: dict :rtype: list """ twitter_status_url = 'https://www.twitter.com/{}/status/{}' twitter_fav_url = 'https://www.twitter.com/{}/status/{}' now = arrow.utcnow().to(settings.TIME_ZONE) my_tweets = [] search = {} since_id = None trigger_id = kwargs['trigger_id'] date_triggered = arrow.get(kwargs['date_triggered']) def _get_tweets(twitter_obj, search): """ get the tweets from twitter and return the filters to use : search and count :param twitter_obj: from Twitter model :param search: filter used for twython.search() or twython.get_user_timeline()) :type twitter_obj: Object :type search: dict :return: count that limit the quantity of tweet to retrieve, the filter named search, the tweets :rtype: list """ """ explanations about statuses : when we want to track the tweet of a screen statuses contain all of them when we want to track all the tweet matching a tag statuses contain statuses + metadata array this is why we need to do statuses = statuses['statuses'] to be able to handle the result as for screen_name """ # get the tweets for a given tag # https://dev.twitter.com/docs/api/1.1/get/search/tweets statuses = '' count = 100 if twitter_obj.tag: count = 100 search['count'] = count search['q'] = twitter_obj.tag search['result_type'] = 'recent' # do a search statuses = self.twitter_api.search(**search) # just return the content of te statuses array statuses = statuses['statuses'] # get the tweets from a given user # https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline elif twitter_obj.screen: count = 200 search['count'] = count search['screen_name'] = twitter_obj.screen # call the user timeline and get his tweet try: if twitter_obj.fav: count = 20 search['count'] = 20 # get the favorites https://dev.twitter.com/rest/ # reference/get/favorites/list statuses = self.twitter_api.get_favorites(**search) else: statuses = self.twitter_api.get_user_timeline(**search) except TwythonAuthError as e: logger.error(e.msg, e.error_code) update_result(trigger_id, msg=e.msg, status=False) return count, search, statuses if self.token is not None: kw = { 'app_label': 'th_twitter', 'model_name': 'Twitter', 'trigger_id': trigger_id } twitter_obj = super(ServiceTwitter, self).read_data(**kw) # https://dev.twitter.com/rest/public/timelines if twitter_obj.since_id is not None and twitter_obj.since_id > 0: since_id = twitter_obj.since_id search = {'since_id': twitter_obj.since_id} # first request to Twitter count, search, statuses = _get_tweets(twitter_obj, search) if len(statuses) > 0: newest = None for status in statuses: if newest is None: newest = True # first query ; get the max id search['max_id'] = max_id = status['id'] since_id = search['since_id'] = statuses[-1]['id'] - 1 count, search, statuses = _get_tweets(twitter_obj, search) newest = None if len(statuses) > 0: my_tweets = [] for s in statuses: if newest is None: newest = True max_id = s['id'] - 1 screen_name = s['user']['screen_name'] # get the text of the tweet + url to this one if twitter_obj.fav: url = twitter_fav_url.format( screen_name, s['id_str']) title = _('Tweet Fav from @{}'.format(screen_name)) else: url = twitter_status_url.format( screen_name, s['id_str']) title = _('Tweet from @{}'.format(screen_name)) # Wed Aug 29 17:12:58 +0000 2012 my_date = arrow.get(s['created_at'], 'ddd MMM DD HH:mm:ss Z YYYY') published = arrow.get(my_date).to(settings.TIME_ZONE) if date_triggered is not None and \ published is not None and \ now >= published >= date_triggered: if s.get('extended_entities'): # get a media extended_entities = s['extended_entities'] if extended_entities.get('media'): medias = extended_entities.get('media') for media in medias: text = s['text'] + ' ' + \ media.get('media_url_https') else: text = s['text'] my_tweets.append({ 'title': title, 'content': text, 'link': url, 'my_date': my_date }) # digester self.send_digest_event(trigger_id, title, url) cache.set('th_twitter_' + str(trigger_id), my_tweets) Twitter.objects.filter(trigger_id=trigger_id).update( since_id=since_id, max_id=max_id, count=count) return my_tweets def save_data(self, trigger_id, **data): """ let's save the data :param trigger_id: trigger ID from which to save data :param data: the data to check to be used and save :type trigger_id: int :type data: dict :return: the status of the save statement :rtype: boolean """ status = False # set the title and content of the data title, content = super(ServiceTwitter, self).save_data(trigger_id, **data) if data.get('link') and len(data.get('link')) > 0: # remove html tag if any content = html.strip_tags(content) if self.title_or_content(title): content = str("{title} {link}").format(title=title, link=data.get('link')) content += self.get_tags(trigger_id) else: content = self.set_twitter_content(content) try: self.twitter_api.update_status(status=content) status = True except Exception as inst: logger.critical("Twitter ERR {}".format(inst)) update_result(trigger_id, msg=inst, status=False) status = False return status def get_tags(self, trigger_id): """ get the tags if any :param trigger_id: the id of the related trigger :return: tags string """ # get the Twitter data of this trigger trigger = Twitter.objects.get(trigger_id=trigger_id) tags = '' if len(trigger.tag) > 0: # is there several tag ? tags = ["#" + tag.strip() for tag in trigger.tag.split(',') ] if ',' in trigger.tag else "#" + trigger.tag tags = str(','.join(tags)) if isinstance(tags, list) else tags tags = ' ' + tags return tags def auth(self, request): """ build the request to access to the Twitter website with all its required parms :param request: makes the url to call Twitter + the callback url :return: go to the Twitter website to ask to the user to allow the access of TriggerHappy """ callback_url = self.callback_url(request) twitter = Twython(self.consumer_key, self.consumer_secret) req_token = twitter.get_authentication_tokens( callback_url=callback_url) request.session['oauth_token'] = req_token['oauth_token'] request.session['oauth_token_secret'] = req_token['oauth_token_secret'] return req_token['auth_url'] def callback(self, request, **kwargs): """ Called from the Service when the user accept to activate it """ return super(ServiceTwitter, self).callback(request, **kwargs) def get_access_token(self, oauth_token, oauth_token_secret, oauth_verifier): """ :param oauth_token: oauth_token retrieve by the API Twython get_authentication_tokens() :param oauth_token_secret: oauth_token_secret retrieve by the API Twython get_authentication_tokens() :param oauth_verifier: oauth_verifier retrieve from Twitter :type oauth_token: string :type oauth_token_secret: string :type oauth_verifier: string :return: access_token :rtype: dict """ twitter = Twython(self.consumer_key, self.consumer_secret, oauth_token, oauth_token_secret) access_token = twitter.get_authorized_tokens(oauth_verifier) return access_token def title_or_content(self, title): """ If the title always contains 'New status from' drop the title and get 'the content' instead :param title: :return: """ return "Toot from" not in title def set_twitter_content(self, content): """ cleaning content by removing any existing html tag :param content: :return: """ content = html.strip_tags(content) if len(content) > 140: return content[:140] return content
# Post post = raw_input("Write your tweet: ") twitter.update_status(status=post) # Get timelines print twitter.get_user_timeline(screen_name = "name") print twitter.get_home_timeline(count = 5) # Search print twitter.search(q="linux", result_type="popular") # Follow twitter.create_friendship(screen_name = "LinuxUserMag") # Retweet twitter.retweet(id = "12345") # Favouriting twitter.create_favorite(id = "12345") print twitter.get_favorites() # Mentions print twitter.get_mentions_timeline(count="5") # Trending print twitter.get_place_trends(id="1") # Retrieve lists print twitter.get_list_statuses(id = "12345")
# https://miguelmalvarez.com/2015/03/03/download-the-pictures-from-a-twitter-feed-using-python/ (uses tweepy) from twython import Twython import psycopg2 import urllib3 import twitter_secret import json twitter_credentials = twitter_secret.twitter_credentials twitter = Twython(twitter_credentials['consumer_api_key'], twitter_credentials['consumer_secret_key'], twitter_credentials['access_token'], twitter_credentials['token_secret']) faves = twitter.get_favorites() #gets 20 by default. <class 'list'> print(type(faves)) # it is a <class 'list'> print(faves) print("Writing results to file...") with open('faves.json', 'w') as outfile: outfile.write(json.dumps( faves, indent=4)) #dump as string because we are opening file as 'w' not 'wb' print("Now starting for loop...") i = 0 print("Number of posts found: ", len(faves))
import sys from twython import Twython # Twitter Login creds = json.load(open('creds.json')) twitter = Twython(creds['APP_KEY'], creds['APP_SECRET'], oauth_version=2) ACCESS_TOKEN = twitter.obtain_access_token() twitter = Twython(creds['APP_KEY'], access_token=ACCESS_TOKEN) # Lets grabe favs from this year user = '******' keep_going = 1 min = 0 while keep_going: # https://dev.twitter.com/rest/reference/get/favorites/list if min: favs = twitter.get_favorites(screen_name=user, count=200, max_id=min) else: favs = twitter.get_favorites(screen_name=user, count=200) # Write out file max = favs[0]['id'] min = favs[-1]['id'] with open('favs.%s.%s.json' % (max, min), 'w') as outfile: json.dump(favs, outfile) # Stop after 2014 if favs[-1]['created_at'][-4:] != '2014': keep_going = 0
def favourites_xls(opt): t = Twython(consumer_key, consumer_secret, access_token_key, access_token_secret) # Let's create an empty xls Workbook and define formatting wb = Workbook() ws = wb.add_sheet('0') # Column widths ws.col(0).width = 256 * 30 ws.col(1).width = 256 * 30 ws.col(2).width = 256 * 60 ws.col(3).width = 256 * 30 ws.col(4).width = 256 * 30 # Stylez style_link = easyxf('font: underline single, name Arial, height 280, colour_index blue') style_heading = easyxf('font: bold 1, name Arial, height 280; pattern: pattern solid, pattern_fore_colour yellow, pattern_back_colour yellow') style_wrap = easyxf('align: wrap 1; font: height 280') # Headings in proper MBA spreadsheet style - Bold with yellow background ws.write(0,0,'Author',style_heading) ws.write(0,1,'Twitter Handle',style_heading) ws.write(0,2,'Text',style_heading) ws.write(0,3,'Embedded Links',style_heading) # Let's start at page 1 of your favourites because you know, it's a very good place to start count = 1 pagenum = 1 # Now, let's start an infinite loop and I don't mean the one with Apple's HQ while True: # Get your favourites from Twitter faves = t.get_favorites(page=pagenum) # If there's no favourites left from this page OR we've reached the page number specified by our user, do the Di Caprio and jump out if len(faves) == 0 or (opt != 'all' and pagenum > int(opt)): break # Programmers have been doing inception for ages before Nolan did. Let's go deeper and get # into another loop now for fav in faves: ws.write(count, 0, fav['user']['name'],style_wrap) ws.write(count, 1, fav['user']['screen_name'],style_wrap) ws.write(count, 2, fav['text'],style_wrap) links = fav['entities']['urls'] i = 0 for link in links: formatted_link = 'HYPERLINK("%s";"%s")' % (link['url'],"link") ws.write(count, 3+i, Formula(formatted_link), style_link) i += 1 count += 1 pagenum += 1 # Now comes the all important part of the code. As my grandmother once told me, it is # important to get good sleep, and we shall precisely do that for 15 minutes because you know # Twitter mama hates rate-limit violators. We will use 12 requests for every 15 minutes just to be # on the safe side if (pagenum % 12 == 0): time.sleep(900) # Now for the step that has caused untold misery and suffering to people who forget to do it at work wb.save('twitter_favourites.xls')
class Tweets(): """ Manages Tweet class instances. """ def __init__(self): # arrays of tweets classes self.tweets = [] # Boolean that tracks if the calls # to the server were successful. self.successful_connection = False # arrays of tids represented # in this object self.tids = [] # twitter connection self.api = Twython( settings.NEWS_TWITTER_CONSUMER_KEY, settings.NEWS_TWITTER_CONSUMER_SECRET, settings.NEWS_TWITTER_ACCESS_TOKEN, settings.NEWS_TWITTER_ACCESS_TOKEN_SECRET) # raw twitter response self.raw = self.get_tweets() # add all posts to this manager for tweet in self.raw: self.add(Tweet(tweet)) def get_tweets(self): """ will get all of the toots to deal with """ tweets = [] timeline, favorites = None, None try: timeline = self.api.get_user_timeline( screen_name=settings.NEWS_TWITTER_ACCOUNT, count=200, include_rts=True, exclude_replies=True) # sleep for 10 seconds # between calls. time.sleep(10) favorites = self.api.get_favorites( screen_name=settings.NEWS_TWITTER_ACCOUNT, count=200) if len(timeline) > 0 and len(favorites) > 0: tweets = timeline + favorites self.successful_connection = True else: self.successful_connection = False except: self.successful_connection = False logging.info("Problems getting tweets from Twitter API.") logging.info("Favorites:") logging.info(favorites) logging.info("Timeline:") logging.info(timeline) return tweets def add(self, tweet): """ add a Tweet instance to be tracked for updates, to to be created """ self.tids.append(tweet.tid) self.tweets.append(tweet) return self def compare(self, steam_model): """ steam_model is a Tweet model instance if update needs to occur, do so from the steam_model instance return self """ tweet = None # set `tweet` to the Tweet class # of data that twitter sent us # to compare against steam_model for t in self.tweets: if steam_model.tid == t.tid: tweet = t break # compare the twitter data to steam data if tweet: # we now have evidence that this # thing exists in some form in the # database, and does not need to # be created. tweet.exists_in_database = True need_to_save = False if steam_model.user != tweet.user: need_to_save = True steam_model.user = tweet.user if steam_model.screen_name != tweet.screen_name: need_to_save = True steam_model.screen_name = tweet.screen_name if steam_model.text != tweet.text: need_to_save = True steam_model.text = tweet.text if steam_model.html != tweet.html: need_to_save = True steam_model.html = tweet.html if steam_model.epoch_timestamp != tweet.epoch_timestamp: need_to_save = True steam_model.epoch_timestamp = tweet.epoch_timestamp if steam_model.timestamp != tweet.timestamp: need_to_save = True steam_model.timestamp = tweet.timestamp if steam_model.url != tweet.url: need_to_save = True steam_model.url = tweet.url # save it out if anything changed if need_to_save: steam_model.save() return self def to_create(self): """ looks for Tweet objects that have a False ['exists_in_database'] value returns a list of tweets that need to be created in the database. """ tweets_to_create = [] for tweet in self.tweets: if not tweet.exists_in_database: tweets_to_create.append(tweet) return tweets_to_create
class RecolectorFavoritosUser(Recolector): def __init__(self, escritor): super(RecolectorFavoritosUser, self).__init__(escritor) self.authorizator = GetAuthorizations(14) self.twitter = None self.apoyo = ApoyoTwitter() self.tipo_id = 6 self.inicializa() def inicializa(self): self.authorizator.load_twitter_token(self.tipo_id) api_key, access_token = self.authorizator.get_twython_token() self.twitter = Twython(api_key, access_token=access_token) def recolecta(self, query=None, id_user=-1, complete=False): #TODO recolectar todos los favoritos si flag activa if query is None and id_user == -1: raise Exception('Al menos debe haber un parametro usable') if query is not None: if query[0] == '@': query = query[1:] id_user = self.apoyo.getUserIDByScreenName(query) if id_user == None: raise Exception('El usuario debe estar en la base de datos') #print id_user maximo = 0 while True: tweets = self.privateRealizaConsulta(id_user, maximo=maximo) if tweets == []: break relaciones = [] for tweet in tweets: #el usuario1 -[:FAV]-> el tweet X relaciones.append((id_user, tweet["id"])) self.guarda(tweets, relaciones) if complete == False: break maximo = self.getMinIDtweets(tweets) maximo -= 1 print maximo def guarda(self, arrayDatos, relaciones): #mal diseño sorry for escritor in self.escritores: if "EscritorTweets" in escritor.__class__.__name__: escritor.escribe(arrayDatos) else: escritor.escribe(relaciones) def getMinIDtweets(self, tweets): minimo = long(10**20) for tweet in tweets: if minimo > tweet["id"]: minimo = tweet["id"] if minimo == long(10**20): return 0 return minimo def privateRealizaConsulta(self, identificador, maximo=0): count = 200 if self.authorizator.is_limit_api(self.tipo_id): raise Exception('LIMITE') try: if maximo == 0: retorno = self.twitter.get_favorites(user_id=identificador, count=count) else: retorno = self.twitter.get_favorites(user_id=identificador, count=count, max_id=maximo) self.authorizator.add_query_to_key(self.tipo_id) return retorno except Exception, e: print e self.authorizator.add_query_to_key(self.tipo_id) if "429" in str(e): raise Exception('LIMITE') return []
class TwythonAPITestCase(unittest.TestCase): def setUp(self): client_args = { 'headers': { 'User-Agent': '__twython__ Test' }, 'allow_redirects': False } oauth2_client_args = { 'headers': { } # This is so we can hit coverage that Twython sets User-Agent for us if none is supplied } self.api = Twython(app_key, app_secret, oauth_token, oauth_token_secret, client_args=client_args) self.oauth2_api = Twython(app_key, access_token=access_token, client_args=oauth2_client_args) def test_construct_api_url(self): """Test constructing a Twitter API url works as we expect""" url = 'https://api.twitter.com/1.1/search/tweets.json' constructed_url = self.api.construct_api_url(url, q='#twitter') self.assertEqual( constructed_url, 'https://api.twitter.com/1.1/search/tweets.json?q=%23twitter') def test_get(self): """Test Twython generic GET request works""" self.api.get('account/verify_credentials') def test_post(self): """Test Twython generic POST request works, with a full url and with just an endpoint""" update_url = 'https://api.twitter.com/1.1/statuses/update.json' status = self.api.post( update_url, params={'status': 'I love Twython! %s' % int(time.time())}) self.api.post('statuses/destroy/%s' % status['id_str']) def test_get_lastfunction_header(self): """Test getting last specific header of the last API call works""" self.api.get('statuses/home_timeline') self.api.get_lastfunction_header('x-rate-limit-remaining') def test_get_lastfunction_header_not_present(self): """Test getting specific header that does not exist from the last call returns None""" self.api.get('statuses/home_timeline') header = self.api.get_lastfunction_header('does-not-exist') self.assertEqual(header, None) def test_get_lastfunction_header_no_last_api_call(self): """Test attempting to get a header when no API call was made raises a TwythonError""" self.assertRaises(TwythonError, self.api.get_lastfunction_header, 'no-api-call-was-made') def test_cursor(self): """Test looping through the generator results works, at least once that is""" search = self.api.cursor(self.api.search, q='twitter', count=1) counter = 0 while counter < 2: counter += 1 result = next(search) new_id_str = int(result['id_str']) if counter == 1: prev_id_str = new_id_str time.sleep( 1) # Give time for another tweet to come into search if counter == 2: self.assertTrue(new_id_str > prev_id_str) def test_encode(self): """Test encoding UTF-8 works""" self.api.encode('Twython is awesome!') def test_html_for_tweet(self): """Test HTML for Tweet returns what we want""" tweet_text = self.api.html_for_tweet(test_tweet_object) self.assertEqual(test_tweet_html, tweet_text) def test_html_for_tweet_expanded_url(self): """Test using expanded url in HTML for Tweet displays full urls""" tweet_text = self.api.html_for_tweet(test_tweet_object, use_expanded_url=True) # Make sure full url is in HTML self.assertTrue('http://google.com' in tweet_text) def test_html_for_tweet_short_url(self): """Test using expanded url in HTML for Tweet displays full urls""" tweet_text = self.api.html_for_tweet(test_tweet_object, False) # Make sure HTML doesn't contain the display OR exapanded url self.assertTrue(not 'http://google.com' in tweet_text) self.assertTrue(not 'google.com' in tweet_text) def test_raise_error_on_bad_ssl_cert(self): """Test TwythonError is raised by a RequestException when an actual HTTP happens""" self.assertRaises(TwythonError, self.api.get, 'https://example.com') # Timelines def test_get_mentions_timeline(self): """Test returning mentions timeline for authenticated user succeeds""" self.api.get_mentions_timeline() def test_get_user_timeline(self): """Test returning timeline for authenticated user and random user succeeds""" self.api.get_user_timeline() # Authenticated User Timeline self.api.get_user_timeline( screen_name='twitter') # Random User Timeline def test_get_protected_user_timeline_following(self): """Test returning a protected user timeline who you are following succeeds""" self.api.get_user_timeline(screen_name=protected_twitter_1) def test_get_protected_user_timeline_not_following(self): """Test returning a protected user timeline who you are not following fails and raise a TwythonAuthError""" self.assertRaises(TwythonAuthError, self.api.get_user_timeline, screen_name=protected_twitter_2) def test_retweeted_of_me(self): """Test that getting recent tweets by authenticated user that have been retweeted by others succeeds""" self.api.retweeted_of_me() def test_get_home_timeline(self): """Test returning home timeline for authenticated user succeeds""" self.api.get_home_timeline() # Tweets def test_get_retweets(self): """Test getting retweets of a specific tweet succeeds""" self.api.get_retweets(id=test_tweet_id) def test_show_status(self): """Test returning a single status details succeeds""" self.api.show_status(id=test_tweet_id) def test_update_and_destroy_status(self): """Test updating and deleting a status succeeds""" status = self.api.update_status( status='Test post just to get deleted :( %s' % int(time.time())) self.api.destroy_status(id=status['id_str']) def test_get_oembed_tweet(self): """Test getting info to embed tweet on Third Party site succeeds""" self.api.get_oembed_tweet(id='99530515043983360') def test_get_retweeters_ids(self): """Test getting ids for people who retweeted a tweet succeeds""" self.api.get_retweeters_ids(id='99530515043983360') # Search def test_search(self): """Test searching tweets succeeds""" self.api.search(q='twitter') # Direct Messages def test_get_direct_messages(self): """Test getting the authenticated users direct messages succeeds""" self.api.get_direct_messages() def test_get_sent_messages(self): """Test getting the authenticated users direct messages they've sent succeeds""" self.api.get_sent_messages() def test_send_get_and_destroy_direct_message(self): """Test sending, getting, then destory a direct message succeeds""" message = self.api.send_direct_message(screen_name=protected_twitter_1, text='Hey d00d! %s' % int(time.time())) self.api.get_direct_message(id=message['id_str']) self.api.destroy_direct_message(id=message['id_str']) def test_send_direct_message_to_non_follower(self): """Test sending a direct message to someone who doesn't follow you fails""" self.assertRaises(TwythonError, self.api.send_direct_message, screen_name=protected_twitter_2, text='Yo, man! %s' % int(time.time())) # Friends & Followers def test_get_user_ids_of_blocked_retweets(self): """Test that collection of user_ids that the authenticated user does not want to receive retweets from succeeds""" self.api.get_user_ids_of_blocked_retweets(stringify_ids=True) def test_get_friends_ids(self): """Test returning ids of users the authenticated user and then a random user is following succeeds""" self.api.get_friends_ids() self.api.get_friends_ids(screen_name='twitter') def test_get_followers_ids(self): """Test returning ids of users the authenticated user and then a random user are followed by succeeds""" self.api.get_followers_ids() self.api.get_followers_ids(screen_name='twitter') def test_lookup_friendships(self): """Test returning relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided succeeds""" self.api.lookup_friendships(screen_name='twitter,ryanmcgrath') def test_get_incoming_friendship_ids(self): """Test returning incoming friendship ids succeeds""" self.api.get_incoming_friendship_ids() def test_get_outgoing_friendship_ids(self): """Test returning outgoing friendship ids succeeds""" self.api.get_outgoing_friendship_ids() def test_create_friendship(self): """Test creating a friendship succeeds""" self.api.create_friendship(screen_name='justinbieber') def test_destroy_friendship(self): """Test destroying a friendship succeeds""" self.api.destroy_friendship(screen_name='justinbieber') def test_update_friendship(self): """Test updating friendships succeeds""" self.api.update_friendship(screen_name=protected_twitter_1, retweets='true') self.api.update_friendship(screen_name=protected_twitter_1, retweets=False) def test_show_friendships(self): """Test showing specific friendship succeeds""" self.api.show_friendship(target_screen_name=protected_twitter_1) def test_get_friends_list(self): """Test getting list of users authenticated user then random user is following succeeds""" self.api.get_friends_list() self.api.get_friends_list(screen_name='twitter') def test_get_followers_list(self): """Test getting list of users authenticated user then random user are followed by succeeds""" self.api.get_followers_list() self.api.get_followers_list(screen_name='twitter') # Users def test_get_account_settings(self): """Test getting the authenticated user account settings succeeds""" self.api.get_account_settings() def test_verify_credentials(self): """Test representation of the authenticated user call succeeds""" self.api.verify_credentials() def test_update_account_settings(self): """Test updating a user account settings succeeds""" self.api.update_account_settings(lang='en') def test_update_delivery_service(self): """Test updating delivery settings fails because we don't have a mobile number on the account""" self.assertRaises(TwythonError, self.api.update_delivery_service, device='none') def test_update_profile(self): """Test updating profile succeeds""" self.api.update_profile(include_entities='true') def test_update_profile_colors(self): """Test updating profile colors succeeds""" self.api.update_profile_colors(profile_background_color='3D3D3D') def test_list_blocks(self): """Test listing users who are blocked by the authenticated user succeeds""" self.api.list_blocks() def test_list_block_ids(self): """Test listing user ids who are blocked by the authenticated user succeeds""" self.api.list_block_ids() def test_create_block(self): """Test blocking a user succeeds""" self.api.create_block(screen_name='justinbieber') def test_destroy_block(self): """Test unblocking a user succeeds""" self.api.destroy_block(screen_name='justinbieber') def test_lookup_user(self): """Test listing a number of user objects succeeds""" self.api.lookup_user(screen_name='twitter,justinbieber') def test_show_user(self): """Test showing one user works""" self.api.show_user(screen_name='twitter') def test_search_users(self): """Test that searching for users succeeds""" self.api.search_users(q='Twitter API') def test_get_contributees(self): """Test returning list of accounts the specified user can contribute to succeeds""" self.api.get_contributees(screen_name='TechCrunch') def test_get_contributors(self): """Test returning list of accounts that contribute to the authenticated user fails because we are not a Contributor account""" self.assertRaises(TwythonError, self.api.get_contributors, screen_name=screen_name) def test_remove_profile_banner(self): """Test removing profile banner succeeds""" self.api.remove_profile_banner() def test_get_profile_banner_sizes(self): """Test getting list of profile banner sizes fails because we have not uploaded a profile banner""" self.assertRaises(TwythonError, self.api.get_profile_banner_sizes) # Suggested Users def test_get_user_suggestions_by_slug(self): """Test getting user suggestions by slug succeeds""" self.api.get_user_suggestions_by_slug(slug='twitter') def test_get_user_suggestions(self): """Test getting user suggestions succeeds""" self.api.get_user_suggestions() def test_get_user_suggestions_statuses_by_slug(self): """Test getting status of suggested users succeeds""" self.api.get_user_suggestions_statuses_by_slug(slug='funny') # Favorites def test_get_favorites(self): """Test getting list of favorites for the authenticated user succeeds""" self.api.get_favorites() def test_create_and_destroy_favorite(self): """Test creating and destroying a favorite on a tweet succeeds""" self.api.create_favorite(id=test_tweet_id) self.api.destroy_favorite(id=test_tweet_id) # Lists def test_show_lists(self): """Test show lists for specified user""" self.api.show_lists(screen_name='twitter') def test_get_list_statuses(self): """Test timeline of tweets authored by members of the specified list succeeds""" self.api.get_list_statuses( slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) def test_create_update_destroy_list_add_remove_list_members(self): """Test create a list, adding and removing members then deleting the list succeeds""" the_list = self.api.create_list(name='Stuff %s' % int(time.time())) list_id = the_list['id_str'] self.api.update_list(list_id=list_id, name='Stuff Renamed %s' % int(time.time())) screen_names = ['johncena', 'xbox'] # Multi add/delete members self.api.create_list_members(list_id=list_id, screen_name=screen_names) self.api.delete_list_members(list_id=list_id, screen_name=screen_names) # Single add/delete member self.api.add_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list(list_id=list_id) def test_get_list_memberships(self): """Test list of memberhips the authenticated user succeeds""" self.api.get_list_memberships() def test_get_list_subscribers(self): """Test list of subscribers of a specific list succeeds""" self.api.get_list_subscribers( slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) def test_subscribe_is_subbed_and_unsubscribe_to_list(self): """Test subscribing, is a list sub and unsubbing to list succeeds""" self.api.subscribe_to_list( slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) # Returns 404 if user is not a subscriber self.api.is_list_subscriber( slug=test_list_slug, owner_screen_name=test_list_owner_screen_name, screen_name=screen_name) self.api.unsubscribe_from_list( slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) def test_is_list_member(self): """Test returning if specified user is member of a list succeeds""" # Returns 404 if not list member self.api.is_list_member(slug=test_list_slug, owner_screen_name=test_list_owner_screen_name, screen_name='themattharris') def test_get_list_members(self): """Test listing members of the specified list succeeds""" self.api.get_list_members( slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) def test_get_specific_list(self): """Test getting specific list succeeds""" self.api.get_specific_list( slug=test_list_slug, owner_screen_name=test_list_owner_screen_name) def test_get_list_subscriptions(self): """Test collection of the lists the specified user is subscribed to succeeds""" self.api.get_list_subscriptions(screen_name='twitter') def test_show_owned_lists(self): """Test collection of lists the specified user owns succeeds""" self.api.show_owned_lists(screen_name='twitter') # Saved Searches def test_get_saved_searches(self): """Test getting list of saved searches for authenticated user succeeds""" self.api.get_saved_searches() def test_create_get_destroy_saved_search(self): """Test getting list of saved searches for authenticated user succeeds""" saved_search = self.api.create_saved_search(query='#Twitter') saved_search_id = saved_search['id_str'] self.api.show_saved_search(id=saved_search_id) self.api.destroy_saved_search(id=saved_search_id) # Places & Geo def test_get_geo_info(self): """Test getting info about a geo location succeeds""" self.api.get_geo_info(place_id='df51dec6f4ee2b2c') def test_reverse_geo_code(self): """Test reversing geocode succeeds""" self.api.reverse_geocode(lat='37.76893497', long='-122.42284884') def test_search_geo(self): """Test search for places that can be attached to a statuses/update succeeds""" self.api.search_geo(query='Toronto') def test_get_similar_places(self): """Test locates places near the given coordinates which are similar in name succeeds""" self.api.get_similar_places(lat='37', long='-122', name='Twitter HQ') # Trends def test_get_place_trends(self): """Test getting the top 10 trending topics for a specific WOEID succeeds""" self.api.get_place_trends(id=1) def test_get_available_trends(self): """Test returning locations that Twitter has trending topic information for succeeds""" self.api.get_available_trends() def test_get_closest_trends(self): """Test getting the locations that Twitter has trending topic information for, closest to a specified location succeeds""" self.api.get_closest_trends(lat='37', long='-122') # Help def test_get_twitter_configuration(self): """Test getting Twitter's configuration succeeds""" self.api.get_twitter_configuration() def test_get_supported_languages(self): """Test getting languages supported by Twitter succeeds""" self.api.get_supported_languages() def test_privacy_policy(self): """Test getting Twitter's Privacy Policy succeeds""" self.api.get_privacy_policy() def test_get_tos(self): """Test getting the Twitter Terms of Service succeeds""" self.api.get_tos() def test_get_application_rate_limit_status(self): """Test getting application rate limit status succeeds""" self.oauth2_api.get_application_rate_limit_status()
class TwythonAPITestCase(unittest.TestCase): def setUp(self): self.api = Twython(app_key, app_secret, oauth_token, oauth_token_secret) # Timelines def test_get_mentions_timeline(self): '''Test returning mentions timeline for authenticated user succeeds''' self.api.get_mentions_timeline() def test_get_user_timeline(self): '''Test returning timeline for authenticated user and random user succeeds''' self.api.get_user_timeline() # Authenticated User Timeline self.api.get_user_timeline(screen_name='twitter') # Random User Timeline def test_get_protected_user_timeline_following(self): '''Test returning a protected user timeline who you are following succeeds''' self.api.get_user_timeline(screen_name=protected_twitter_1) def test_get_protected_user_timeline_not_following(self): '''Test returning a protected user timeline who you are not following fails and raise a TwythonAuthError''' self.assertRaises(TwythonAuthError, self.api.get_user_timeline, screen_name=protected_twitter_2) def test_get_home_timeline(self): '''Test returning home timeline for authenticated user succeeds''' self.api.get_home_timeline() # Tweets def test_get_retweets(self): '''Test getting retweets of a specific tweet succeeds''' self.api.get_retweets(id=test_tweet_id) def test_show_status(self): '''Test returning a single status details succeeds''' self.api.show_status(id=test_tweet_id) def test_update_and_destroy_status(self): '''Test updating and deleting a status succeeds''' status = self.api.update_status(status='Test post just to get deleted :(') self.api.destroy_status(id=status['id_str']) def test_retweet(self): '''Test retweeting a status succeeds''' retweet = self.api.retweet(id='99530515043983360') self.api.destroy_status(id=retweet['id_str']) def test_retweet_twice(self): '''Test that trying to retweet a tweet twice raises a TwythonError''' retweet = self.api.retweet(id='99530515043983360') self.assertRaises(TwythonError, self.api.retweet, id='99530515043983360') # Then clean up self.api.destroy_status(id=retweet['id_str']) def test_get_oembed_tweet(self): '''Test getting info to embed tweet on Third Party site succeeds''' self.api.get_oembed_tweet(id='99530515043983360') def test_get_retweeters_ids(self): '''Test getting ids for people who retweeted a tweet succeeds''' self.api.get_retweeters_ids(id='99530515043983360') # Search def test_search(self): '''Test searching tweets succeeds''' self.api.search(q='twitter') # Direct Messages def test_get_direct_messages(self): '''Test getting the authenticated users direct messages succeeds''' self.api.get_direct_messages() def test_get_sent_messages(self): '''Test getting the authenticated users direct messages they've sent succeeds''' self.api.get_sent_messages() def test_send_get_and_destroy_direct_message(self): '''Test sending, getting, then destory a direct message succeeds''' message = self.api.send_direct_message(screen_name=protected_twitter_1, text='Hey d00d!') self.api.get_direct_message(id=message['id_str']) self.api.destroy_direct_message(id=message['id_str']) def test_send_direct_message_to_non_follower(self): '''Test sending a direct message to someone who doesn't follow you fails''' self.assertRaises(TwythonError, self.api.send_direct_message, screen_name=protected_twitter_2, text='Yo, man!') # Friends & Followers def test_get_user_ids_of_blocked_retweets(self): '''Test that collection of user_ids that the authenticated user does not want to receive retweets from succeeds''' self.api.get_user_ids_of_blocked_retweets(stringify_ids='true') def test_get_friends_ids(self): '''Test returning ids of users the authenticated user and then a random user is following succeeds''' self.api.get_friends_ids() self.api.get_friends_ids(screen_name='twitter') def test_get_followers_ids(self): '''Test returning ids of users the authenticated user and then a random user are followed by succeeds''' self.api.get_followers_ids() self.api.get_followers_ids(screen_name='twitter') def test_lookup_friendships(self): '''Test returning relationships of the authenticating user to the comma-separated list of up to 100 screen_names or user_ids provided succeeds''' self.api.lookup_friendships(screen_name='twitter,ryanmcgrath') def test_get_incoming_friendship_ids(self): '''Test returning incoming friendship ids succeeds''' self.api.get_incoming_friendship_ids() def test_get_outgoing_friendship_ids(self): '''Test returning outgoing friendship ids succeeds''' self.api.get_outgoing_friendship_ids() def test_create_friendship(self): '''Test creating a friendship succeeds''' self.api.create_friendship(screen_name='justinbieber') def test_destroy_friendship(self): '''Test destroying a friendship succeeds''' self.api.destroy_friendship(screen_name='justinbieber') def test_update_friendship(self): '''Test updating friendships succeeds''' self.api.update_friendship(screen_name=protected_twitter_1, retweets='true') self.api.update_friendship(screen_name=protected_twitter_1, retweets='false') def test_show_friendships(self): '''Test showing specific friendship succeeds''' self.api.show_friendship(target_screen_name=protected_twitter_1) def test_get_friends_list(self): '''Test getting list of users authenticated user then random user is following succeeds''' self.api.get_friends_list() self.api.get_friends_list(screen_name='twitter') def test_get_followers_list(self): '''Test getting list of users authenticated user then random user are followed by succeeds''' self.api.get_followers_list() self.api.get_followers_list(screen_name='twitter') # Users def test_get_account_settings(self): '''Test getting the authenticated user account settings succeeds''' self.api.get_account_settings() def test_verify_credentials(self): '''Test representation of the authenticated user call succeeds''' self.api.verify_credentials() def test_update_account_settings(self): '''Test updating a user account settings succeeds''' self.api.update_account_settings(lang='en') def test_update_delivery_service(self): '''Test updating delivery settings fails because we don't have a mobile number on the account''' self.assertRaises(TwythonError, self.api.update_delivery_service, device='none') def test_update_profile(self): '''Test updating profile succeeds''' self.api.update_profile(include_entities='true') def test_update_profile_colors(self): '''Test updating profile colors succeeds''' self.api.update_profile_colors(profile_background_color='3D3D3D') def test_list_blocks(self): '''Test listing users who are blocked by the authenticated user succeeds''' self.api.list_blocks() def test_list_block_ids(self): '''Test listing user ids who are blocked by the authenticated user succeeds''' self.api.list_block_ids() def test_create_block(self): '''Test blocking a user succeeds''' self.api.create_block(screen_name='justinbieber') def test_destroy_block(self): '''Test unblocking a user succeeds''' self.api.destroy_block(screen_name='justinbieber') def test_lookup_user(self): '''Test listing a number of user objects succeeds''' self.api.lookup_user(screen_name='twitter,justinbieber') def test_show_user(self): '''Test showing one user works''' self.api.show_user(screen_name='twitter') def test_search_users(self): '''Test that searching for users succeeds''' self.api.search_users(q='Twitter API') def test_get_contributees(self): '''Test returning list of accounts the specified user can contribute to succeeds''' self.api.get_contributees(screen_name='TechCrunch') def test_get_contributors(self): '''Test returning list of accounts that contribute to the authenticated user fails because we are not a Contributor account''' self.assertRaises(TwythonError, self.api.get_contributors, screen_name=screen_name) def test_remove_profile_banner(self): '''Test removing profile banner succeeds''' self.api.remove_profile_banner() def test_get_profile_banner_sizes(self): '''Test getting list of profile banner sizes fails because we have not uploaded a profile banner''' self.assertRaises(TwythonError, self.api.get_profile_banner_sizes) # Suggested Users def test_get_user_suggestions_by_slug(self): '''Test getting user suggestions by slug succeeds''' self.api.get_user_suggestions_by_slug(slug='twitter') def test_get_user_suggestions(self): '''Test getting user suggestions succeeds''' self.api.get_user_suggestions() def test_get_user_suggestions_statuses_by_slug(self): '''Test getting status of suggested users succeeds''' self.api.get_user_suggestions_statuses_by_slug(slug='funny') # Favorites def test_get_favorites(self): '''Test getting list of favorites for the authenticated user succeeds''' self.api.get_favorites() def test_create_and_destroy_favorite(self): '''Test creating and destroying a favorite on a tweet succeeds''' self.api.create_favorite(id=test_tweet_id) self.api.destroy_favorite(id=test_tweet_id) # Lists def test_show_lists(self): '''Test show lists for specified user''' self.api.show_lists(screen_name='twitter') def test_get_list_statuses(self): '''Test timeline of tweets authored by members of the specified list succeeds''' self.api.get_list_statuses(list_id=test_list_id) def test_create_update_destroy_list_add_remove_list_members(self): '''Test create a list, adding and removing members then deleting the list succeeds''' the_list = self.api.create_list(name='Stuff') list_id = the_list['id_str'] self.api.update_list(list_id=list_id, name='Stuff Renamed') # Multi add/delete members self.api.create_list_members(list_id=list_id, screen_name='johncena,xbox') self.api.delete_list_members(list_id=list_id, screen_name='johncena,xbox') # Single add/delete member self.api.add_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list_member(list_id=list_id, screen_name='justinbieber') self.api.delete_list(list_id=list_id) def test_get_list_memberships(self): '''Test list of lists the authenticated user is a member of succeeds''' self.api.get_list_memberships() def test_get_list_subscribers(self): '''Test list of subscribers of a specific list succeeds''' self.api.get_list_subscribers(list_id=test_list_id) def test_subscribe_is_subbed_and_unsubscribe_to_list(self): '''Test subscribing, is a list sub and unsubbing to list succeeds''' self.api.subscribe_to_list(list_id=test_list_id) # Returns 404 if user is not a subscriber self.api.is_list_subscriber(list_id=test_list_id, screen_name=screen_name) self.api.unsubscribe_from_list(list_id=test_list_id) def test_is_list_member(self): '''Test returning if specified user is member of a list succeeds''' # Returns 404 if not list member self.api.is_list_member(list_id=test_list_id, screen_name='jack') def test_get_list_members(self): '''Test listing members of the specified list succeeds''' self.api.get_list_members(list_id=test_list_id) def test_get_specific_list(self): '''Test getting specific list succeeds''' self.api.get_specific_list(list_id=test_list_id) def test_get_list_subscriptions(self): '''Test collection of the lists the specified user is subscribed to succeeds''' self.api.get_list_subscriptions(screen_name='twitter') def test_show_owned_lists(self): '''Test collection of lists the specified user owns succeeds''' self.api.show_owned_lists(screen_name='twitter') # Saved Searches def test_get_saved_searches(self): '''Test getting list of saved searches for authenticated user succeeds''' self.api.get_saved_searches() def test_create_get_destroy_saved_search(self): '''Test getting list of saved searches for authenticated user succeeds''' saved_search = self.api.create_saved_search(query='#Twitter') saved_search_id = saved_search['id_str'] self.api.show_saved_search(id=saved_search_id) self.api.destroy_saved_search(id=saved_search_id) # Places & Geo def test_get_geo_info(self): '''Test getting info about a geo location succeeds''' self.api.get_geo_info(place_id='df51dec6f4ee2b2c') def test_reverse_geo_code(self): '''Test reversing geocode succeeds''' self.api.reverse_geocode(lat='37.76893497', long='-122.42284884') def test_search_geo(self): '''Test search for places that can be attached to a statuses/update succeeds''' self.api.search_geo(query='Toronto') def test_get_similar_places(self): '''Test locates places near the given coordinates which are similar in name succeeds''' self.api.get_similar_places(lat='37', long='-122', name='Twitter HQ') # Trends def test_get_place_trends(self): '''Test getting the top 10 trending topics for a specific WOEID succeeds''' self.api.get_place_trends(id=1) def test_get_available_trends(self): '''Test returning locations that Twitter has trending topic information for succeeds''' self.api.get_available_trends() def test_get_closest_trends(self): '''Test getting the locations that Twitter has trending topic information for, closest to a specified location succeeds''' self.api.get_closest_trends(lat='37', long='-122')
class ServiceTwitter(ServicesMgr): """ Service Twitter """ def __init__(self, token=None, **kwargs): """ :param token: :param kwargs: """ super(ServiceTwitter, self).__init__(token, **kwargs) self.consumer_key = settings.TH_TWITTER_KEY['consumer_key'] self.consumer_secret = settings.TH_TWITTER_KEY['consumer_secret'] self.token = token self.oauth = 'oauth1' self.service = 'ServiceTwitter' if self.token is not None: token_key, token_secret = self.token.split('#TH#') try: self.twitter_api = Twython(self.consumer_key, self.consumer_secret, token_key, token_secret) except (TwythonAuthError, TwythonRateLimitError) as e: us = UserService.objects.get(token=token) logger.error(e.msg, e.error_code) update_result(us.trigger_id, msg=e.msg, status=False) def read_data(self, **kwargs): """ get the data from the service :param kwargs: contain keyword args : trigger_id at least :type kwargs: dict :rtype: list """ twitter_status_url = 'https://www.twitter.com/{}/status/{}' twitter_fav_url = 'https://www.twitter.com/{}/status/{}' now = arrow.utcnow().to(settings.TIME_ZONE) my_tweets = [] search = {} since_id = None trigger_id = kwargs['trigger_id'] date_triggered = arrow.get(kwargs['date_triggered']) def _get_tweets(twitter_obj, search): """ get the tweets from twitter and return the filters to use : search and count :param twitter_obj: from Twitter model :param search: filter used for twython.search() or twython.get_user_timeline()) :type twitter_obj: Object :type search: dict :return: count that limit the quantity of tweet to retrieve, the filter named search, the tweets :rtype: list """ """ explanations about statuses : when we want to track the tweet of a screen 'statuses' contain all of them when we want to track all the tweet matching a tag 'statuses' contain statuses + metadata array this is why we need to do statuses = statuses['statuses'] to be able to handle the result as for screen_name """ # get the tweets for a given tag # https://dev.twitter.com/docs/api/1.1/get/search/tweets statuses = '' count = 100 if twitter_obj.tag: count = 100 search['count'] = count search['q'] = twitter_obj.tag search['result_type'] = 'recent' # do a search statuses = self.twitter_api.search(**search) # just return the content of te statuses array statuses = statuses['statuses'] # get the tweets from a given user # https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline elif twitter_obj.screen: count = 200 search['count'] = count search['screen_name'] = twitter_obj.screen # call the user timeline and get his tweet try: if twitter_obj.fav: count = 20 search['count'] = 20 # get the favorites https://dev.twitter.com/rest/ # reference/get/favorites/list statuses = self.twitter_api.get_favorites(**search) else: statuses = self.twitter_api.get_user_timeline(**search) except TwythonAuthError as e: logger.error(e.msg, e.error_code) update_result(trigger_id, msg=e.msg, status=False) return count, search, statuses if self.token is not None: kw = {'app_label': 'th_twitter', 'model_name': 'Twitter', 'trigger_id': trigger_id} twitter_obj = super(ServiceTwitter, self).read_data(**kw) # https://dev.twitter.com/rest/public/timelines if twitter_obj.since_id is not None and twitter_obj.since_id > 0: since_id = twitter_obj.since_id search = {'since_id': twitter_obj.since_id} # first request to Twitter count, search, statuses = _get_tweets(twitter_obj, search) if len(statuses) > 0: newest = None for status in statuses: if newest is None: newest = True # first query ; get the max id search['max_id'] = max_id = status['id'] since_id = search['since_id'] = statuses[-1]['id'] - 1 count, search, statuses = _get_tweets(twitter_obj, search) newest = None if len(statuses) > 0: my_tweets = [] for s in statuses: if newest is None: newest = True max_id = s['id'] - 1 screen_name = s['user']['screen_name'] # get the text of the tweet + url to this one if twitter_obj.fav: url = twitter_fav_url.format(screen_name, s['id_str']) title = _('Tweet Fav from @{}'.format(screen_name)) else: url = twitter_status_url.format(screen_name, s['id_str']) title = _('Tweet from @{}'.format(screen_name)) # Wed Aug 29 17:12:58 +0000 2012 my_date = arrow.get(s['created_at'], 'ddd MMM DD HH:mm:ss Z YYYY') published = arrow.get(my_date).to(settings.TIME_ZONE) if date_triggered is not None and published is not None and now >= published >= date_triggered: if s.get('extended_entities'): # get a media extended_entities = s['extended_entities'] if extended_entities.get('media'): medias = extended_entities.get('media') for media in medias: text = s['text'] + ' ' + media.get('media_url_https') else: text = s['text'] my_tweets.append({'title': title, 'content': text, 'link': url, 'my_date': my_date}) # digester self.send_digest_event(trigger_id, title, url) cache.set('th_twitter_' + str(trigger_id), my_tweets) Twitter.objects.filter(trigger_id=trigger_id).update( since_id=since_id, max_id=max_id, count=count) return my_tweets def save_data(self, trigger_id, **data): """ let's save the data :param trigger_id: trigger ID from which to save data :param data: the data to check to be used and save :type trigger_id: int :type data: dict :return: the status of the save statement :rtype: boolean """ status = False # set the title and content of the data title, content = super(ServiceTwitter, self).save_data(trigger_id, **data) if data.get('link') and len(data.get('link')) > 0: # remove html tag if any content = html.strip_tags(content) if self.title_or_content(title): content = str("{title} {link}").format(title=title, link=data.get('link')) content += get_tags(Twitter, trigger_id) else: content = self.set_twitter_content(content) try: self.twitter_api.update_status(status=content) status = True except Exception as inst: logger.critical("Twitter ERR {}".format(inst)) update_result(trigger_id, msg=inst, status=False) status = False return status def auth(self, request): """ build the request to access to the Twitter website with all its required parms :param request: makes the url to call Twitter + the callback url :return: go to the Twitter website to ask to the user to allow the access of TriggerHappy """ callback_url = self.callback_url(request) twitter = Twython(self.consumer_key, self.consumer_secret) req_token = twitter.get_authentication_tokens( callback_url=callback_url) request.session['oauth_token'] = req_token['oauth_token'] request.session['oauth_token_secret'] = req_token['oauth_token_secret'] return req_token['auth_url'] def callback(self, request, **kwargs): """ Called from the Service when the user accept to activate it """ return super(ServiceTwitter, self).callback(request, **kwargs) def get_access_token( self, oauth_token, oauth_token_secret, oauth_verifier ): """ :param oauth_token: oauth_token retrieve by the API Twython get_authentication_tokens() :param oauth_token_secret: oauth_token_secret retrieve by the API Twython get_authentication_tokens() :param oauth_verifier: oauth_verifier retrieve from Twitter :type oauth_token: string :type oauth_token_secret: string :type oauth_verifier: string :return: access_token :rtype: dict """ twitter = Twython(self.consumer_key, self.consumer_secret, oauth_token, oauth_token_secret) access_token = twitter.get_authorized_tokens(oauth_verifier) return access_token def title_or_content(self, title): """ If the title always contains 'New status from' drop the title and get 'the content' instead :param title: :return: """ return "Toot from" not in title def set_twitter_content(self, content): """ cleaning content by removing any existing html tag :param content: :return: """ return limit_content(content, 280)
fo = open(user + ".txt", "wb") fo.write("File of favorites from " + user + ":\n\n"); fo.close() #file of tweet links for stuff fl = open(user+ "_links" + ".txt", "wb") fl.write("File of links from " + user + ":\n\n"); fl.close() howlong = 0 for i in range(0, endrange): ## iterate through all tweets at 200 per round ## tweet extract method with the last list item as the max_id if starting_tweet_id == 0: try: user_faves = twitter.get_favorites(screen_name=user, count=count) except: print "You are not authorized to view this user, they probably have a private profile. The jerks..." break else: try: if howlong == endrange: user_faves = twitter.get_favorites(screen_name=user, count=count, max_id = starting_tweet_id) else: user_faves = twitter.get_favorites(screen_name=user, count=lastround, max_id = starting_tweet_id) except: print "You are not authorized to view this user, they probably have a private profile. The jerks..." break ## pretty printing used for troublshooting and finding further parts of a tweet to use #pprint.pprint(user_faves)
# --------------------------------------------------------- twitter = Twython(settings.APP_KEY, settings.APP_SECRET, oauth_version=2) ACCESS_TOKEN = twitter.obtain_access_token() twitter = Twython(settings.APP_KEY, access_token=ACCESS_TOKEN) conn = psycopg2.connect('dbname={}'.format(settings.DATABASE)) cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) screen_name = 'josefrousek' # The main twitter account # --------------------------------------------------------- # Get tweets user has liked # --------------------------------------------------------- favorites = twitter.get_favorites(screen_name=screen_name, count=200) liked_users_ids = [tweet['user']['id'] for tweet in favorites] # we want only unique records liked_users_ids = list(set(liked_users_ids)) # add the main twitter account so we can compare distances me = twitter.show_user(screen_name=screen_name) liked_users_ids.append(me['id']) # --------------------------------------------------------- # Get 200 tweets per user # (200 is the maximum number of tweets imposed by twitter) # ---------------------------------------------------------