4242
4343from twitter import (__version__ , _FileCache , json , DirectMessage , List ,
4444 Status , Trend , TwitterError , User , UserStatus )
45+ from twitter .category import Category
4546
4647try :
4748 # python 3
@@ -277,6 +278,7 @@ def ClearCredentials(self):
277278
278279 def GetSearch (self ,
279280 term = None ,
281+ who = None ,
280282 geocode = None ,
281283 since_id = None ,
282284 max_id = None ,
@@ -292,6 +294,8 @@ def GetSearch(self,
292294 Args:
293295 term:
294296 Term to search by. Optional if you include geocode.
297+ who:
298+ Handle of user's tweets you want. Optional.
295299 since_id:
296300 Returns results with an ID greater than (that is, more recent
297301 than) the specified ID. There are limits to the number of
@@ -350,7 +354,7 @@ def GetSearch(self,
350354
351355 if until :
352356 parameters ['until' ] = until
353-
357+
354358 if since :
355359 parameters ['since' ] = since
356360
@@ -360,12 +364,15 @@ def GetSearch(self,
360364 if locale :
361365 parameters ['locale' ] = locale
362366
363- if term is None and geocode is None :
367+ if term is None and geocode is None and who is None :
364368 return []
365369
366370 if term is not None :
367371 parameters ['q' ] = term
368372
373+ if who is not None :
374+ parameters ['q' ] = "from:%s" % (who )
375+
369376 if geocode is not None :
370377 parameters ['geocode' ] = ',' .join (map (str , geocode ))
371378
@@ -479,6 +486,40 @@ def GetTrendsWoeid(self, id, exclude=None):
479486 trends .append (Trend .NewFromJsonDict (trend , timestamp = timestamp ))
480487 return trends
481488
489+ def GetUserSuggestionCategories (self ):
490+ """ Return the list of suggested user categories, this can be used in
491+ GetUserSuggestion function
492+ Returns:
493+ A list of categories
494+ """
495+ url = '%s/users/suggestions.json' % (self .base_url )
496+ json_data = self ._RequestUrl (url , verb = 'GET' )
497+ data = self ._ParseAndCheckTwitter (json_data .content )
498+
499+ categories = []
500+
501+ for category in data :
502+ categories .append (Category .NewFromJsonDict (category ))
503+ return categories
504+
505+ def GetUserSuggestion (self , category ):
506+ """ Returns a list of users in a category
507+ Args:
508+ category:
509+ The Category object to limit the search by
510+ Returns:
511+ A list of users in that category
512+ """
513+ url = '%s/users/suggestions/%s.json' % (self .base_url , category .Slug )
514+
515+ json_data = self ._RequestUrl (url , verb = 'GET' )
516+ data = self ._ParseAndCheckTwitter (json_data .content )
517+
518+ users = []
519+ for user in data ['users' ]:
520+ users .append (User .NewFromJsonDict (user ))
521+ return users
522+
482523 def GetHomeTimeline (self ,
483524 count = None ,
484525 since_id = None ,
@@ -1585,12 +1626,12 @@ def GetFollowerIDsPaged(self,
15851626 if count is not None :
15861627 parameters ['count' ] = count
15871628 result = []
1588-
1629+
15891630 parameters ['cursor' ] = cursor
1590-
1631+
15911632 json = self ._RequestUrl (url , 'GET' , data = parameters )
15921633 data = self ._ParseAndCheckTwitter (json .content )
1593-
1634+
15941635 if 'next_cursor' in data :
15951636 next_cursor = data ['next_cursor' ]
15961637 else :
@@ -1599,7 +1640,7 @@ def GetFollowerIDsPaged(self,
15991640 previous_cursor = data ['previous_cursor' ]
16001641 else :
16011642 previous_cursor = 0
1602-
1643+
16031644 return next_cursor , previous_cursor , data
16041645
16051646 def GetFollowerIDs (self ,
@@ -1638,17 +1679,22 @@ def GetFollowerIDs(self,
16381679 url = '%s/followers/ids.json' % self .base_url
16391680 if not self .__auth :
16401681 raise TwitterError ({'message' : "twitter.Api instance must be authenticated" })
1641-
1682+
16421683 result = []
16431684 if total_count and total_count < count :
16441685 count = total_count
1645-
1686+
16461687 while True :
1688+ < << << << HEAD
16471689 if total_count and total_count < count :
16481690 parameters ['count' ] = total_count
16491691 parameters ['cursor' ] = cursor
16501692 json = self ._RequestUrl (url , 'GET' , data = parameters )
16511693 data = self ._ParseAndCheckTwitter (json .content .decode ('utf-8' ).decode ("utf-8" ))
1694+ == == == =
1695+ next_cursor , previous_cursor , data = self .GetFollowerIDsPaged (user_id , screen_name , cursor , stringify_ids ,
1696+ count )
1697+ >> >> >> > master
16521698 result += [x for x in data ['ids' ]]
16531699 if next_cursor == 0 or next_cursor == previous_cursor :
16541700 break
@@ -1660,7 +1706,7 @@ def GetFollowerIDs(self,
16601706 break
16611707 sec = self .GetSleepTime ('/followers/ids' )
16621708 time .sleep (sec )
1663-
1709+
16641710 return result
16651711
16661712 def GetFollowersPaged (self ,
@@ -2073,7 +2119,7 @@ def CreateFriendship(self, user_id=None, screen_name=None, follow=True):
20732119 A twitter.User instance representing the befriended user.
20742120 """
20752121 return self ._AddOrEditFriendship (user_id = user_id , screen_name = screen_name , follow = follow )
2076-
2122+
20772123 def _AddOrEditFriendship (self , user_id = None , screen_name = None , uri_end = 'create' , follow_key = 'follow' , follow = True ):
20782124 """
20792125 Shared method for Create/Update Friendship.
@@ -2114,7 +2160,8 @@ def UpdateFriendship(self, user_id=None, screen_name=None, follow=True, **kwargs
21142160 A twitter.User instance representing the befriended user.
21152161 """
21162162 follow = kwargs .get ('device' , follow )
2117- return self ._AddOrEditFriendship (user_id = user_id , screen_name = screen_name , follow = follow , follow_key = 'device' , uri_end = 'update' )
2163+ return self ._AddOrEditFriendship (user_id = user_id , screen_name = screen_name , follow = follow , follow_key = 'device' ,
2164+ uri_end = 'update' )
21182165
21192166 def DestroyFriendship (self , user_id = None , screen_name = None ):
21202167 """Discontinues friendship with a user_id or screen_name.
@@ -2893,7 +2940,7 @@ def GetListTimeline(self,
28932940 """
28942941 parameters = {'slug' : slug ,
28952942 'list_id' : list_id ,
2896- }
2943+ }
28972944 url = '%s/lists/statuses.json' % (self .base_url )
28982945 parameters ['slug' ] = slug
28992946 parameters ['list_id' ] = list_id
@@ -2902,7 +2949,7 @@ def GetListTimeline(self,
29022949 raise TwitterError ({'message' : "list_id or slug required" })
29032950 if owner_id is None and not owner_screen_name :
29042951 raise TwitterError ({
2905- 'message' : "if list_id is not given you have to include an owner to help identify the proper list" })
2952+ 'message' : "if list_id is not given you have to include an owner to help identify the proper list" })
29062953 if owner_id :
29072954 parameters ['owner_id' ] = owner_id
29082955 if owner_screen_name :
@@ -2976,7 +3023,7 @@ def GetListMembers(self,
29763023 """
29773024 parameters = {'slug' : slug ,
29783025 'list_id' : list_id ,
2979- }
3026+ }
29803027 url = '%s/lists/members.json' % (self .base_url )
29813028 parameters ['slug' ] = slug
29823029 parameters ['list_id' ] = list_id
@@ -2985,7 +3032,7 @@ def GetListMembers(self,
29853032 raise TwitterError ({'message' : "list_id or slug required" })
29863033 if owner_id is None and not owner_screen_name :
29873034 raise TwitterError ({
2988- 'message' : "if list_id is not given you have to include an owner to help identify the proper list" })
3035+ 'message' : "if list_id is not given you have to include an owner to help identify the proper list" })
29893036 if owner_id :
29903037 parameters ['owner_id' ] = owner_id
29913038 if owner_screen_name :
@@ -3297,22 +3344,22 @@ def UpdateImage(self,
32973344
32983345 url = '%s/account/update_profile_image.json' % (self .base_url )
32993346 with open (image , 'rb' ) as image_file :
3300- encoded_image = base64 .b64encode (image_file .read ())
3347+ encoded_image = base64 .b64encode (image_file .read ())
33013348 data = {
3302- 'image' :encoded_image
3349+ 'image' : encoded_image
33033350 }
33043351 if include_entities :
3305- data ['include_entities' ] = 1
3352+ data ['include_entities' ] = 1
33063353 if skip_status :
3307- data ['skip_status' ] = 1
3354+ data ['skip_status' ] = 1
33083355
33093356 json = self ._RequestUrl (url , 'POST' , data = data )
33103357 if json .status_code in [200 , 201 , 202 ]:
3311- return True
3358+ return True
33123359 if json .status_code == 400 :
3313- raise TwitterError ({'message' : "Image data could not be processed" })
3360+ raise TwitterError ({'message' : "Image data could not be processed" })
33143361 if json .status_code == 422 :
3315- raise TwitterError ({'message' : "The image could not be resized or is too large." })
3362+ raise TwitterError ({'message' : "The image could not be resized or is too large." })
33163363
33173364 def UpdateBanner (self ,
33183365 image ,
@@ -3833,15 +3880,15 @@ def _RequestStream(self, url, verb, data=None):
38333880 return requests .post (url , data = data , stream = True ,
38343881 auth = self .__auth ,
38353882 timeout = self ._timeout
3836- )
3883+ )
38373884 except requests .RequestException as e :
38383885 raise TwitterError (str (e ))
38393886 if verb == 'GET' :
38403887 url = self ._BuildUrl (url , extra_params = data )
38413888 try :
38423889 return requests .get (url , stream = True , auth = self .__auth ,
38433890 timeout = self ._timeout
3844- )
3891+ )
38453892 except requests .RequestException as e :
38463893 raise TwitterError (str (e ))
38473894 return 0 # if not a POST or GET request
0 commit comments