X Tutup
Skip to content

Commit 83167b4

Browse files
committed
Adding the ability to get the suggested user categories
1 parent dfa3efa commit 83167b4

File tree

4 files changed

+105
-26
lines changed

4 files changed

+105
-26
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def read(*paths):
2929

3030
setup(
3131
name='python-twitter',
32-
version='2.3',
32+
version='2.3.1',
3333
author='The Python-Twitter Developers',
3434
author_email='python-twitter@googlegroups.com',
3535
license='Apache License 2.0',

twitter/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"""A library that provides a Python interface to the Twitter API"""
2020

2121
__author__ = 'python-twitter@googlegroups.com'
22-
__version__ = '2.3'
22+
__version__ = '2.3.1'
2323

2424
import json
2525

@@ -37,5 +37,6 @@
3737
from .url import Url
3838
from .status import Status
3939
from .user import User, UserStatus
40+
from .category import Category
4041
from .list import List
4142
from .api import Api

twitter/api.py

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
from twitter import (__version__, _FileCache, json, DirectMessage, List,
3838
Status, Trend, TwitterError, User, UserStatus)
39+
from twitter.category import Category
3940

4041
CHARACTER_LIMIT = 140
4142

@@ -341,7 +342,7 @@ def GetSearch(self,
341342

342343
if until:
343344
parameters['until'] = until
344-
345+
345346
if since:
346347
parameters['since'] = since
347348

@@ -474,6 +475,22 @@ def GetTrendsWoeid(self, id, exclude=None):
474475
trends.append(Trend.NewFromJsonDict(trend, timestamp=timestamp))
475476
return trends
476477

478+
def GetUserSuggestionCategories(self):
479+
""" Return the list of suggested user categories, this can be used in
480+
GetUserSuggestion function
481+
Returns:
482+
A list of categories
483+
"""
484+
url = '%s/users/suggestions.json' % (self.base_url)
485+
json_data = self._RequestUrl(url, verb='GET')
486+
data = self._ParseAndCheckTwitter(json_data.content)
487+
488+
categories = []
489+
490+
for category in data:
491+
categories.append(Category.NewFromJsonDict(category))
492+
return categories
493+
477494
def GetHomeTimeline(self,
478495
count=None,
479496
since_id=None,
@@ -1579,12 +1596,12 @@ def GetFollowerIDsPaged(self,
15791596
if count is not None:
15801597
parameters['count'] = count
15811598
result = []
1582-
1599+
15831600
parameters['cursor'] = cursor
1584-
1601+
15851602
json = self._RequestUrl(url, 'GET', data=parameters)
15861603
data = self._ParseAndCheckTwitter(json.content)
1587-
1604+
15881605
if 'next_cursor' in data:
15891606
next_cursor = data['next_cursor']
15901607
else:
@@ -1593,7 +1610,7 @@ def GetFollowerIDsPaged(self,
15931610
previous_cursor = data['previous_cursor']
15941611
else:
15951612
previous_cursor = 0
1596-
1613+
15971614
return next_cursor, previous_cursor, data
15981615

15991616
def GetFollowerIDs(self,
@@ -1632,13 +1649,14 @@ def GetFollowerIDs(self,
16321649
url = '%s/followers/ids.json' % self.base_url
16331650
if not self.__auth:
16341651
raise TwitterError({'message': "twitter.Api instance must be authenticated"})
1635-
1652+
16361653
result = []
16371654
if total_count and total_count < count:
16381655
count = total_count
1639-
1656+
16401657
while True:
1641-
next_cursor, previous_cursor, data = self.GetFollowerIDsPaged(user_id, screen_name, cursor, stringify_ids, count)
1658+
next_cursor, previous_cursor, data = self.GetFollowerIDsPaged(user_id, screen_name, cursor, stringify_ids,
1659+
count)
16421660
result += [x for x in data['ids']]
16431661
if next_cursor == 0 or next_cursor == previous_cursor:
16441662
break
@@ -1650,7 +1668,7 @@ def GetFollowerIDs(self,
16501668
break
16511669
sec = self.GetSleepTime('/followers/ids')
16521670
time.sleep(sec)
1653-
1671+
16541672
return result
16551673

16561674
def GetFollowersPaged(self,
@@ -2063,7 +2081,7 @@ def CreateFriendship(self, user_id=None, screen_name=None, follow=True):
20632081
A twitter.User instance representing the befriended user.
20642082
"""
20652083
return self._AddOrEditFriendship(user_id=user_id, screen_name=screen_name, follow=follow)
2066-
2084+
20672085
def _AddOrEditFriendship(self, user_id=None, screen_name=None, uri_end='create', follow_key='follow', follow=True):
20682086
"""
20692087
Shared method for Create/Update Friendship.
@@ -2104,7 +2122,8 @@ def UpdateFriendship(self, user_id=None, screen_name=None, follow=True, **kwargs
21042122
A twitter.User instance representing the befriended user.
21052123
"""
21062124
follow = kwargs.get('device', follow)
2107-
return self._AddOrEditFriendship(user_id=user_id, screen_name=screen_name, follow=follow, follow_key='device', uri_end='update')
2125+
return self._AddOrEditFriendship(user_id=user_id, screen_name=screen_name, follow=follow, follow_key='device',
2126+
uri_end='update')
21082127

21092128
def DestroyFriendship(self, user_id=None, screen_name=None):
21102129
"""Discontinues friendship with a user_id or screen_name.
@@ -2883,7 +2902,7 @@ def GetListTimeline(self,
28832902
"""
28842903
parameters = {'slug': slug,
28852904
'list_id': list_id,
2886-
}
2905+
}
28872906
url = '%s/lists/statuses.json' % (self.base_url)
28882907
parameters['slug'] = slug
28892908
parameters['list_id'] = list_id
@@ -2892,7 +2911,7 @@ def GetListTimeline(self,
28922911
raise TwitterError({'message': "list_id or slug required"})
28932912
if owner_id is None and not owner_screen_name:
28942913
raise TwitterError({
2895-
'message': "if list_id is not given you have to include an owner to help identify the proper list"})
2914+
'message': "if list_id is not given you have to include an owner to help identify the proper list"})
28962915
if owner_id:
28972916
parameters['owner_id'] = owner_id
28982917
if owner_screen_name:
@@ -2966,7 +2985,7 @@ def GetListMembers(self,
29662985
"""
29672986
parameters = {'slug': slug,
29682987
'list_id': list_id,
2969-
}
2988+
}
29702989
url = '%s/lists/members.json' % (self.base_url)
29712990
parameters['slug'] = slug
29722991
parameters['list_id'] = list_id
@@ -2975,7 +2994,7 @@ def GetListMembers(self,
29752994
raise TwitterError({'message': "list_id or slug required"})
29762995
if owner_id is None and not owner_screen_name:
29772996
raise TwitterError({
2978-
'message': "if list_id is not given you have to include an owner to help identify the proper list"})
2997+
'message': "if list_id is not given you have to include an owner to help identify the proper list"})
29792998
if owner_id:
29802999
parameters['owner_id'] = owner_id
29813000
if owner_screen_name:
@@ -3287,22 +3306,22 @@ def UpdateImage(self,
32873306

32883307
url = '%s/account/update_profile_image.json' % (self.base_url)
32893308
with open(image, 'rb') as image_file:
3290-
encoded_image = base64.b64encode(image_file.read())
3309+
encoded_image = base64.b64encode(image_file.read())
32913310
data = {
3292-
'image':encoded_image
3311+
'image': encoded_image
32933312
}
32943313
if include_entities:
3295-
data['include_entities'] = 1
3314+
data['include_entities'] = 1
32963315
if skip_status:
3297-
data['skip_status'] = 1
3316+
data['skip_status'] = 1
32983317

32993318
json = self._RequestUrl(url, 'POST', data=data)
33003319
if json.status_code in [200, 201, 202]:
3301-
return True
3320+
return True
33023321
if json.status_code == 400:
3303-
raise TwitterError({'message': "Image data could not be processed"})
3322+
raise TwitterError({'message': "Image data could not be processed"})
33043323
if json.status_code == 422:
3305-
raise TwitterError({'message': "The image could not be resized or is too large."})
3324+
raise TwitterError({'message': "The image could not be resized or is too large."})
33063325

33073326
def UpdateBanner(self,
33083327
image,
@@ -3832,15 +3851,15 @@ def _RequestStream(self, url, verb, data=None):
38323851
return requests.post(url, data=data, stream=True,
38333852
auth=self.__auth,
38343853
timeout=self._timeout
3835-
)
3854+
)
38363855
except requests.RequestException as e:
38373856
raise TwitterError(str(e))
38383857
if verb == 'GET':
38393858
url = self._BuildUrl(url, extra_params=data)
38403859
try:
38413860
return requests.get(url, stream=True, auth=self.__auth,
38423861
timeout=self._timeout
3843-
)
3862+
)
38443863
except requests.RequestException as e:
38453864
raise TwitterError(str(e))
38463865
return 0 # if not a POST or GET request

twitter/category.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/env python
2+
3+
4+
class Category(object):
5+
"""A class representing the suggested user category structure used by the twitter API.
6+
7+
The UserStatus structure exposes the following properties:
8+
9+
category.name
10+
category.slug
11+
category.size
12+
"""
13+
14+
def __init__(self, **kwargs):
15+
"""An object to hold a Twitter suggested user category .
16+
This class is normally instantiated by the twitter.Api class and
17+
returned in a sequence.
18+
19+
Args:
20+
name:
21+
name of the category
22+
slug:
23+
24+
size:
25+
"""
26+
param_defaults = {
27+
'name': None,
28+
'slug': None,
29+
'size': None,
30+
}
31+
32+
for (param, default) in param_defaults.iteritems():
33+
setattr(self, param, kwargs.get(param, default))
34+
35+
@property
36+
def Name(self):
37+
return self.name or False
38+
39+
@property
40+
def Slug(self):
41+
return self.slug or False
42+
43+
@property
44+
def Size(self):
45+
return self.size or False
46+
47+
@staticmethod
48+
def NewFromJsonDict(data):
49+
"""Create a new instance based on a JSON dict.
50+
51+
Args:
52+
data: A JSON dict, as converted from the JSON in the twitter API
53+
Returns:
54+
A twitter.Category instance
55+
"""
56+
57+
return Category(name=data.get('name', None),
58+
slug=data.get('slug', None),
59+
size=data.get('size', None))

0 commit comments

Comments
 (0)
X Tutup