Skip to content

Commit

Permalink
twitter: support fetching the current user's likes
Browse files Browse the repository at this point in the history
  • Loading branch information
snarfed committed Feb 10, 2015
1 parent 72b8298 commit bd15523
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 12 deletions.
17 changes: 14 additions & 3 deletions twitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
'https://api.twitter.com/1.1/account/verify_credentials.json'
API_SEARCH_URL = \
'https://api.twitter.com/1.1/search/tweets.json?q=%s&include_entities=true&result_type=recent&count=100'
API_FAVORITES_URL = 'https://api.twitter.com/1.1/favorites/list.json?screen_name=%s&include_entities=true'
API_POST_TWEET_URL = 'https://api.twitter.com/1.1/statuses/update.json'
API_POST_RETWEET_URL = 'https://api.twitter.com/1.1/statuses/retweet/%s.json'
API_POST_FAVORITE_URL = 'https://api.twitter.com/1.1/favorites/create.json'
Expand Down Expand Up @@ -188,6 +189,7 @@ def get_activities_response(self, user_id=None, group_id=None, app_id=None,
fetch tweets from the list @exampleuser/example-list you would call
get_activities(user_id='exampleuser', group_id='example-list').
"""
activities = []
if activity_id:
tweets = [self.urlopen(API_STATUS_URL % activity_id)]
total_count = len(tweets)
Expand All @@ -200,6 +202,14 @@ def get_activities_response(self, user_id=None, group_id=None, app_id=None,
'count': count + start_index,
'screen_name': user_id,
}

if fetch_likes:
liked = self.urlopen(API_FAVORITES_URL % (user_id or ''))
if liked:
user = self.urlopen(API_USER_URL % user_id if user_id
else API_CURRENT_USER_URL)
activities += [self._make_like(tweet, user) for tweet in liked]

elif group_id in (None, source.FRIENDS, source.ALL):
url = API_TIMELINE_URL % (count + start_index)
else:
Expand Down Expand Up @@ -260,13 +270,13 @@ def get_activities_response(self, user_id=None, group_id=None, app_id=None,
retweet_calls += 1
cache_updates['ATR ' + id] = count

activities = [self.tweet_to_activity(t) for t in tweets]
tweet_activities = [self.tweet_to_activity(t) for t in tweets]

if fetch_replies:
self.fetch_replies(activities, min_id=min_id)
self.fetch_replies(tweet_activities, min_id=min_id)

if fetch_likes:
for tweet, activity in zip(tweets, activities):
for tweet, activity in zip(tweets, tweet_activities):
id = tweet['id_str']
count = tweet.get('favorite_count')
if count and count != cached.get('ATF ' + id):
Expand All @@ -282,6 +292,7 @@ def get_activities_response(self, user_id=None, group_id=None, app_id=None,
activity['object'].setdefault('tags', []).extend(likes)
cache_updates['ATF ' + id] = count

activities += tweet_activities
response = self._make_activities_base_response(activities)
response.update({'total_count': total_count, 'etag': etag})
if cache_updates and cache is not None:
Expand Down
32 changes: 23 additions & 9 deletions twitter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ def tag_uri(name):
'in_reply_to_screen_name': 'other_user',
'in_reply_to_status_id': 789,
}
TWEET_2 = copy.deepcopy(TWEET)
TWEET_2['user']['name'] = 'foo'
OBJECT = { # ActivityStreams
'objectType': 'note',
'author': ACTOR,
Expand Down Expand Up @@ -203,6 +205,8 @@ def tag_uri(name):
}]
},
}
ACTIVITY_2 = copy.deepcopy(ACTIVITY)
ACTIVITY_2['actor']['displayName'] = 'foo'

# This is the original tweet and reply chain:
# 100 (snarfed_org) -- 200 (alice) -- 400 (snarfed_org) -- 500 (alice)
Expand Down Expand Up @@ -377,7 +381,7 @@ def tag_uri(name):
'target': USER,
'target_object' : TWEET,
}
LIKE_FROM_EVENT = { # ActivityStreams
LIKE_OBJ = { # ActivityStreams
'id': tag_uri('100_favorited_by_789'),
'url': 'https://twitter.com/snarfed_org/status/100',
'objectType': 'activity',
Expand Down Expand Up @@ -600,18 +604,13 @@ def test_get_activities(self):
self.assert_equals([ACTIVITY, ACTIVITY], self.twitter.get_activities())

def test_get_activities_start_index_count(self):
tweet2 = copy.deepcopy(TWEET)
tweet2['user']['name'] = 'foo'
activity2 = copy.deepcopy(ACTIVITY)
activity2['actor']['displayName'] = 'foo'

self.expect_urlopen(
'https://api.twitter.com/1.1/statuses/home_timeline.json?'
'include_entities=true&count=2',
json.dumps([TWEET, tweet2]))
json.dumps([TWEET, TWEET_2]))
self.mox.ReplayAll()

self.assert_equals([activity2],
self.assert_equals([ACTIVITY_2],
self.twitter.get_activities(start_index=1, count=1))

def test_get_activities_activity_id(self):
Expand All @@ -633,6 +632,21 @@ def test_get_activities_self(self):

self.assert_equals([], self.twitter.get_activities(group_id=source.SELF))

def test_get_activities_self_fetch_likes(self):
self.expect_urlopen('https://api.twitter.com/1.1/favorites/list.json?'
'screen_name=&include_entities=true',
json.dumps([TWEET_2]))
self.expect_urlopen('https://api.twitter.com/1.1/account/verify_credentials.json',
json.dumps(FAVORITE_EVENT['source']))
self.expect_urlopen('https://api.twitter.com/1.1/statuses/user_timeline.json?'
'include_entities=true&count=0',
json.dumps([TWEET]))
self.mox.ReplayAll()

got = self.twitter.get_activities(group_id=source.SELF, fetch_likes=True)
like_obj = copy.copy(LIKE_OBJ)
del like_obj['published']
self.assert_equals([like_obj, ACTIVITY], got)

def test_get_activities_for_screen_name(self):
self.expect_urlopen('https://api.twitter.com/1.1/statuses/user_timeline.json?'
Expand Down Expand Up @@ -963,7 +977,7 @@ def test_retweet_to_object(self):
self.assertEquals(None, self.twitter.retweet_to_object(TWEET))

def test_streaming_event_to_object(self):
self.assert_equals(LIKE_FROM_EVENT,
self.assert_equals(LIKE_OBJ,
self.twitter.streaming_event_to_object(FAVORITE_EVENT))

# not a favorite event
Expand Down

0 comments on commit bd15523

Please sign in to comment.