xitiomet is sharing code with you
Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.
Don't show this againpython-twitter / twitter.py
- commit
- 82aae45f64f2
- parent
- a58f4a7ad991
- branch
- default
Added GetMentions to twitter.py
1 |
fc159c49c080
|
#!/usr/bin/python2.4 |
2 |
4805aee792f0
|
# |
3 |
4805aee792f0
|
# Copyright 2007 Google Inc. All Rights Reserved. |
4 |
fceb5d2374d2
|
# |
5 |
fceb5d2374d2
|
# Licensed under the Apache License, Version 2.0 (the "License"); |
6 |
fceb5d2374d2
|
# you may not use this file except in compliance with the License. |
7 |
fceb5d2374d2
|
# You may obtain a copy of the License at |
8 |
fceb5d2374d2
|
# |
9 |
fceb5d2374d2
|
# http://www.apache.org/licenses/LICENSE-2.0 |
10 |
fceb5d2374d2
|
# |
11 |
fceb5d2374d2
|
# Unless required by applicable law or agreed to in writing, software |
12 |
fceb5d2374d2
|
# distributed under the License is distributed on an "AS IS" BASIS, |
13 |
fceb5d2374d2
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 |
fceb5d2374d2
|
# See the License for the specific language governing permissions and |
15 |
fceb5d2374d2
|
# limitations under the License. |
16 |
4805aee792f0
|
|
17 |
4805aee792f0
|
'''A library that provides a python interface to the Twitter API''' |
18 |
4805aee792f0
|
|
19 |
4805aee792f0
|
__author__ = 'dewitt@google.com' |
20 |
8aaa14d8c799
|
__version__ = '0.6-devel' |
21 |
4805aee792f0
|
|
22 |
4805aee792f0
|
|
23 |
f73c99cf9b51
|
import base64 |
24 |
3a4752d10bb7
|
import calendar |
25 |
4805aee792f0
|
import os |
26 |
3a4752d10bb7
|
import rfc822 |
27 |
4805aee792f0
|
import simplejson |
28 |
4dfd36cb761d
|
import sys |
29 |
4805aee792f0
|
import tempfile |
30 |
81cef10d2991
|
import textwrap |
31 |
4805aee792f0
|
import time |
32 |
4805aee792f0
|
import urllib |
33 |
4805aee792f0
|
import urllib2 |
34 |
4805aee792f0
|
import urlparse |
35 |
0ef37898cd2b
|
|
36 |
a58f4a7ad991
|
try: |
37 |
a58f4a7ad991
|
from hashlib import md5 |
38 |
a58f4a7ad991
|
except ImportError: |
39 |
a58f4a7ad991
|
from md5 import md5 |
40 |
a58f4a7ad991
|
|
41 |
4805aee792f0
|
|
42 |
81cef10d2991
|
CHARACTER_LIMIT = 140 |
43 |
81cef10d2991
|
|
44 |
81cef10d2991
|
|
45 |
4805aee792f0
|
class TwitterError(Exception): |
46 |
4805aee792f0
|
'''Base class for Twitter errors''' |
47 |
2367f0c7822c
|
|
48 |
2367f0c7822c
|
@property |
49 |
2367f0c7822c
|
def message(self): |
50 |
2367f0c7822c
|
'''Returns the first argument used to construct this error.''' |
51 |
2367f0c7822c
|
return self.args[0] |
52 |
4805aee792f0
|
|
53 |
4805aee792f0
|
|
54 |
4805aee792f0
|
class Status(object): |
55 |
4805aee792f0
|
'''A class representing the Status structure used by the twitter API. |
56 |
4805aee792f0
|
|
57 |
4805aee792f0
|
The Status structure exposes the following properties: |
58 |
4805aee792f0
|
|
59 |
4805aee792f0
|
status.created_at |
60 |
17f566981b41
|
status.created_at_in_seconds # read only |
61 |
a1e65b8c9435
|
status.favorited |
62 |
1139636b672f
|
status.in_reply_to_screen_name |
63 |
1139636b672f
|
status.in_reply_to_user_id |
64 |
1139636b672f
|
status.in_reply_to_status_id |
65 |
1139636b672f
|
status.truncated |
66 |
1139636b672f
|
status.source |
67 |
4805aee792f0
|
status.id |
68 |
4805aee792f0
|
status.text |
69 |
17f566981b41
|
status.relative_created_at # read only |
70 |
4805aee792f0
|
status.user |
71 |
4805aee792f0
|
''' |
72 |
4805aee792f0
|
def __init__(self, |
73 |
4805aee792f0
|
created_at=None, |
74 |
a1e65b8c9435
|
favorited=None, |
75 |
4805aee792f0
|
id=None, |
76 |
4805aee792f0
|
text=None, |
77 |
17f566981b41
|
user=None, |
78 |
1139636b672f
|
in_reply_to_screen_name=None, |
79 |
1139636b672f
|
in_reply_to_user_id=None, |
80 |
1139636b672f
|
in_reply_to_status_id=None, |
81 |
1139636b672f
|
truncated=None, |
82 |
1139636b672f
|
source=None, |
83 |
17f566981b41
|
now=None): |
84 |
4805aee792f0
|
'''An object to hold a Twitter status message. |
85 |
4805aee792f0
|
|
86 |
4805aee792f0
|
This class is normally instantiated by the twitter.Api class and |
87 |
4805aee792f0
|
returned in a sequence. |
88 |
4805aee792f0
|
|
89 |
4805aee792f0
|
Note: Dates are posted in the form "Sat Jan 27 04:17:38 +0000 2007" |
90 |
17f566981b41
|
|
91 |
4805aee792f0
|
Args: |
92 |
4805aee792f0
|
created_at: The time this status message was posted |
93 |
a1e65b8c9435
|
favorited: Whether this is a favorite of the authenticated user |
94 |
4805aee792f0
|
id: The unique id of this status message |
95 |
4805aee792f0
|
text: The text of this status message |
96 |
4805aee792f0
|
relative_created_at: |
97 |
4805aee792f0
|
A human readable string representing the posting time |
98 |
4805aee792f0
|
user: |
99 |
4805aee792f0
|
A twitter.User instance representing the person posting the message |
100 |
17f566981b41
|
now: |
101 |
17f566981b41
|
The current time, if the client choses to set it. Defaults to the |
102 |
17f566981b41
|
wall clock time. |
103 |
4805aee792f0
|
''' |
104 |
17f566981b41
|
self.created_at = created_at |
105 |
a1e65b8c9435
|
self.favorited = favorited |
106 |
4805aee792f0
|
self.id = id |
107 |
4805aee792f0
|
self.text = text |
108 |
4805aee792f0
|
self.user = user |
109 |
e565d3a31699
|
self.now = now |
110 |
1139636b672f
|
self.in_reply_to_screen_name = in_reply_to_screen_name |
111 |
1139636b672f
|
self.in_reply_to_user_id = in_reply_to_user_id |
112 |
1139636b672f
|
self.in_reply_to_status_id = in_reply_to_status_id |
113 |
1139636b672f
|
self.truncated = truncated |
114 |
1139636b672f
|
self.source = source |
115 |
4805aee792f0
|
|
116 |
4805aee792f0
|
def GetCreatedAt(self): |
117 |
4805aee792f0
|
'''Get the time this status message was posted. |
118 |
4805aee792f0
|
|
119 |
4805aee792f0
|
Returns: |
120 |
4805aee792f0
|
The time this status message was posted |
121 |
4805aee792f0
|
''' |
122 |
4805aee792f0
|
return self._created_at |
123 |
4805aee792f0
|
|
124 |
4805aee792f0
|
def SetCreatedAt(self, created_at): |
125 |
4805aee792f0
|
'''Set the time this status message was posted. |
126 |
4805aee792f0
|
|
127 |
4805aee792f0
|
Args: |
128 |
4805aee792f0
|
created_at: The time this status message was created |
129 |
4805aee792f0
|
''' |
130 |
4805aee792f0
|
self._created_at = created_at |
131 |
4805aee792f0
|
|
132 |
4805aee792f0
|
created_at = property(GetCreatedAt, SetCreatedAt, |
133 |
4805aee792f0
|
doc='The time this status message was posted.') |
134 |
4805aee792f0
|
|
135 |
17f566981b41
|
def GetCreatedAtInSeconds(self): |
136 |
17f566981b41
|
'''Get the time this status message was posted, in seconds since the epoch. |
137 |
17f566981b41
|
|
138 |
17f566981b41
|
Returns: |
139 |
17f566981b41
|
The time this status message was posted, in seconds since the epoch. |
140 |
17f566981b41
|
''' |
141 |
3a4752d10bb7
|
return calendar.timegm(rfc822.parsedate(self.created_at)) |
142 |
17f566981b41
|
|
143 |
17f566981b41
|
created_at_in_seconds = property(GetCreatedAtInSeconds, |
144 |
17f566981b41
|
doc="The time this status message was " |
145 |
17f566981b41
|
"posted, in seconds since the epoch") |
146 |
17f566981b41
|
|
147 |
a1e65b8c9435
|
def GetFavorited(self): |
148 |
a1e65b8c9435
|
'''Get the favorited setting of this status message. |
149 |
a1e65b8c9435
|
|
150 |
a1e65b8c9435
|
Returns: |
151 |
a1e65b8c9435
|
True if this status message is favorited; False otherwise |
152 |
a1e65b8c9435
|
''' |
153 |
a1e65b8c9435
|
return self._favorited |
154 |
a1e65b8c9435
|
|
155 |
a1e65b8c9435
|
def SetFavorited(self, favorited): |
156 |
a1e65b8c9435
|
'''Set the favorited state of this status message. |
157 |
a1e65b8c9435
|
|
158 |
a1e65b8c9435
|
Args: |
159 |
a1e65b8c9435
|
favorited: boolean True/False favorited state of this status message |
160 |
a1e65b8c9435
|
''' |
161 |
a1e65b8c9435
|
self._favorited = favorited |
162 |
a1e65b8c9435
|
|
163 |
a1e65b8c9435
|
favorited = property(GetFavorited, SetFavorited, |
164 |
a1e65b8c9435
|
doc='The favorited state of this status message.') |
165 |
a1e65b8c9435
|
|
166 |
4805aee792f0
|
def GetId(self): |
167 |
4805aee792f0
|
'''Get the unique id of this status message. |
168 |
4805aee792f0
|
|
169 |
4805aee792f0
|
Returns: |
170 |
4805aee792f0
|
The unique id of this status message |
171 |
4805aee792f0
|
''' |
172 |
4805aee792f0
|
return self._id |
173 |
4805aee792f0
|
|
174 |
4805aee792f0
|
def SetId(self, id): |
175 |
4805aee792f0
|
'''Set the unique id of this status message. |
176 |
4805aee792f0
|
|
177 |
4805aee792f0
|
Args: |
178 |
4805aee792f0
|
id: The unique id of this status message |
179 |
4805aee792f0
|
''' |
180 |
4805aee792f0
|
self._id = id |
181 |
4805aee792f0
|
|
182 |
4805aee792f0
|
id = property(GetId, SetId, |
183 |
4805aee792f0
|
doc='The unique id of this status message.') |
184 |
4805aee792f0
|
|
185 |
1139636b672f
|
def GetInReplyToScreenName(self): |
186 |
1139636b672f
|
return self._in_reply_to_screen_name |
187 |
1139636b672f
|
|
188 |
1139636b672f
|
def SetInReplyToScreenName(self, in_reply_to_screen_name): |
189 |
1139636b672f
|
self._in_reply_to_screen_name = in_reply_to_screen_name |
190 |
1139636b672f
|
|
191 |
1139636b672f
|
in_reply_to_screen_name = property(GetInReplyToScreenName, SetInReplyToScreenName, |
192 |
1139636b672f
|
doc='') |
193 |
1139636b672f
|
|
194 |
1139636b672f
|
def GetInReplyToUserId(self): |
195 |
1139636b672f
|
return self._in_reply_to_user_id |
196 |
1139636b672f
|
|
197 |
1139636b672f
|
def SetInReplyToUserId(self, in_reply_to_user_id): |
198 |
1139636b672f
|
self._in_reply_to_user_id = in_reply_to_user_id |
199 |
1139636b672f
|
|
200 |
1139636b672f
|
in_reply_to_user_id = property(GetInReplyToUserId, SetInReplyToUserId, |
201 |
1139636b672f
|
doc='') |
202 |
1139636b672f
|
|
203 |
1139636b672f
|
def GetInReplyToStatusId(self): |
204 |
1139636b672f
|
return self._in_reply_to_status_id |
205 |
1139636b672f
|
|
206 |
1139636b672f
|
def SetInReplyToStatusId(self, in_reply_to_status_id): |
207 |
1139636b672f
|
self._in_reply_to_status_id = in_reply_to_status_id |
208 |
1139636b672f
|
|
209 |
1139636b672f
|
in_reply_to_status_id = property(GetInReplyToStatusId, SetInReplyToStatusId, |
210 |
1139636b672f
|
doc='') |
211 |
1139636b672f
|
|
212 |
1139636b672f
|
def GetTruncated(self): |
213 |
1139636b672f
|
return self._truncated |
214 |
1139636b672f
|
|
215 |
1139636b672f
|
def SetTruncated(self, truncated): |
216 |
1139636b672f
|
self._truncated = truncated |
217 |
1139636b672f
|
|
218 |
1139636b672f
|
truncated = property(GetTruncated, SetTruncated, |
219 |
1139636b672f
|
doc='') |
220 |
1139636b672f
|
|
221 |
1139636b672f
|
def GetSource(self): |
222 |
1139636b672f
|
return self._source |
223 |
1139636b672f
|
|
224 |
1139636b672f
|
def SetSource(self, source): |
225 |
1139636b672f
|
self._source = source |
226 |
1139636b672f
|
|
227 |
1139636b672f
|
source = property(GetSource, SetSource, |
228 |
1139636b672f
|
doc='') |
229 |
1139636b672f
|
|
230 |
4805aee792f0
|
def GetText(self): |
231 |
4805aee792f0
|
'''Get the text of this status message. |
232 |
4805aee792f0
|
|
233 |
4805aee792f0
|
Returns: |
234 |
4805aee792f0
|
The text of this status message. |
235 |
4805aee792f0
|
''' |
236 |
4805aee792f0
|
return self._text |
237 |
4805aee792f0
|
|
238 |
4805aee792f0
|
def SetText(self, text): |
239 |
4805aee792f0
|
'''Set the text of this status message. |
240 |
4805aee792f0
|
|
241 |
4805aee792f0
|
Args: |
242 |
4805aee792f0
|
text: The text of this status message |
243 |
4805aee792f0
|
''' |
244 |
4805aee792f0
|
self._text = text |
245 |
4805aee792f0
|
|
246 |
4805aee792f0
|
text = property(GetText, SetText, |
247 |
4805aee792f0
|
doc='The text of this status message') |
248 |
4805aee792f0
|
|
249 |
4805aee792f0
|
def GetRelativeCreatedAt(self): |
250 |
4805aee792f0
|
'''Get a human redable string representing the posting time |
251 |
4805aee792f0
|
|
252 |
4805aee792f0
|
Returns: |
253 |
4805aee792f0
|
A human readable string representing the posting time |
254 |
4805aee792f0
|
''' |
255 |
3c401eb136ea
|
fudge = 1.25 |
256 |
e565d3a31699
|
delta = int(self.now) - int(self.created_at_in_seconds) |
257 |
4805aee792f0
|
|
258 |
3c401eb136ea
|
if delta < (1 * fudge): |
259 |
3c401eb136ea
|
return 'about a second ago' |
260 |
3c401eb136ea
|
elif delta < (60 * (1/fudge)): |
261 |
3c401eb136ea
|
return 'about %d seconds ago' % (delta) |
262 |
3c401eb136ea
|
elif delta < (60 * fudge): |
263 |
17f566981b41
|
return 'about a minute ago' |
264 |
3c401eb136ea
|
elif delta < (60 * 60 * (1/fudge)): |
265 |
3c401eb136ea
|
return 'about %d minutes ago' % (delta / 60) |
266 |
3c401eb136ea
|
elif delta < (60 * 60 * fudge): |
267 |
17f566981b41
|
return 'about an hour ago' |
268 |
3c401eb136ea
|
elif delta < (60 * 60 * 24 * (1/fudge)): |
269 |
3c401eb136ea
|
return 'about %d hours ago' % (delta / (60 * 60)) |
270 |
3c401eb136ea
|
elif delta < (60 * 60 * 24 * fudge): |
271 |
3c401eb136ea
|
return 'about a day ago' |
272 |
17f566981b41
|
else: |
273 |
3c401eb136ea
|
return 'about %d days ago' % (delta / (60 * 60 * 24)) |
274 |
4805aee792f0
|
|
275 |
3c401eb136ea
|
relative_created_at = property(GetRelativeCreatedAt, |
276 |
3c401eb136ea
|
doc='Get a human readable string representing' |
277 |
3c401eb136ea
|
'the posting time') |
278 |
dbe3b23bfd08
|
|
279 |
4805aee792f0
|
def GetUser(self): |
280 |
4805aee792f0
|
'''Get a twitter.User reprenting the entity posting this status message. |
281 |
4805aee792f0
|
|
282 |
4805aee792f0
|
Returns: |
283 |
4805aee792f0
|
A twitter.User reprenting the entity posting this status message |
284 |
4805aee792f0
|
''' |
285 |
4805aee792f0
|
return self._user |
286 |
4805aee792f0
|
|
287 |
4805aee792f0
|
def SetUser(self, user): |
288 |
4805aee792f0
|
'''Set a twitter.User reprenting the entity posting this status message. |
289 |
4805aee792f0
|
|
290 |
4805aee792f0
|
Args: |
291 |
4805aee792f0
|
user: A twitter.User reprenting the entity posting this status message |
292 |
4805aee792f0
|
''' |
293 |
4805aee792f0
|
self._user = user |
294 |
4805aee792f0
|
|
295 |
4805aee792f0
|
user = property(GetUser, SetUser, |
296 |
4805aee792f0
|
doc='A twitter.User reprenting the entity posting this ' |
297 |
4805aee792f0
|
'status message') |
298 |
4805aee792f0
|
|
299 |
3c401eb136ea
|
def GetNow(self): |
300 |
3c401eb136ea
|
'''Get the wallclock time for this status message. |
301 |
3c401eb136ea
|
|
302 |
3c401eb136ea
|
Used to calculate relative_created_at. Defaults to the time |
303 |
3c401eb136ea
|
the object was instantiated. |
304 |
dbe3b23bfd08
|
|
305 |
3c401eb136ea
|
Returns: |
306 |
3c401eb136ea
|
Whatever the status instance believes the current time to be, |
307 |
3c401eb136ea
|
in seconds since the epoch. |
308 |
3c401eb136ea
|
''' |
309 |
8218c3572da9
|
if self._now is None: |
310 |
c68ef9d563c3
|
self._now = time.time() |
311 |
3c401eb136ea
|
return self._now |
312 |
3c401eb136ea
|
|
313 |
3c401eb136ea
|
def SetNow(self, now): |
314 |
3c401eb136ea
|
'''Set the wallclock time for this status message. |
315 |
3c401eb136ea
|
|
316 |
3c401eb136ea
|
Used to calculate relative_created_at. Defaults to the time |
317 |
3c401eb136ea
|
the object was instantiated. |
318 |
3c401eb136ea
|
|
319 |
3c401eb136ea
|
Args: |
320 |
3c401eb136ea
|
now: The wallclock time for this instance. |
321 |
3c401eb136ea
|
''' |
322 |
3c401eb136ea
|
self._now = now |
323 |
3c401eb136ea
|
|
324 |
3c401eb136ea
|
now = property(GetNow, SetNow, |
325 |
3c401eb136ea
|
doc='The wallclock time for this status instance.') |
326 |
3c401eb136ea
|
|
327 |
dbe3b23bfd08
|
|
328 |
4805aee792f0
|
def __ne__(self, other): |
329 |
4805aee792f0
|
return not self.__eq__(other) |
330 |
4805aee792f0
|
|
331 |
4805aee792f0
|
def __eq__(self, other): |
332 |
4805aee792f0
|
try: |
333 |
4805aee792f0
|
return other and \ |
334 |
4805aee792f0
|
self.created_at == other.created_at and \ |
335 |
4805aee792f0
|
self.id == other.id and \ |
336 |
4805aee792f0
|
self.text == other.text and \ |
337 |
1139636b672f
|
self.user == other.user and \ |
338 |
1139636b672f
|
self.in_reply_to_screen_name == other.in_reply_to_screen_name and \ |
339 |
1139636b672f
|
self.in_reply_to_user_id == other.in_reply_to_user_id and \ |
340 |
1139636b672f
|
self.in_reply_to_status_id == other.in_reply_to_status_id and \ |
341 |
1139636b672f
|
self.truncated == other.truncated and \ |
342 |
1139636b672f
|
self.favorited == other.favorited and \ |
343 |
1139636b672f
|
self.source == other.source |
344 |
4805aee792f0
|
except AttributeError: |
345 |
4805aee792f0
|
return False |
346 |
17f566981b41
|
|
347 |
4805aee792f0
|
def __str__(self): |
348 |
4805aee792f0
|
'''A string representation of this twitter.Status instance. |
349 |
4805aee792f0
|
|
350 |
4805aee792f0
|
The return value is the same as the JSON string representation. |
351 |
4805aee792f0
|
|
352 |
4805aee792f0
|
Returns: |
353 |
17f566981b41
|
A string representation of this twitter.Status instance. |
354 |
4805aee792f0
|
''' |
355 |
4805aee792f0
|
return self.AsJsonString() |
356 |
4805aee792f0
|
|
357 |
4805aee792f0
|
def AsJsonString(self): |
358 |
4805aee792f0
|
'''A JSON string representation of this twitter.Status instance. |
359 |
4805aee792f0
|
|
360 |
4805aee792f0
|
Returns: |
361 |
4805aee792f0
|
A JSON string representation of this twitter.Status instance |
362 |
17f566981b41
|
''' |
363 |
4805aee792f0
|
return simplejson.dumps(self.AsDict(), sort_keys=True) |
364 |
17f566981b41
|
|
365 |
4805aee792f0
|
def AsDict(self): |
366 |
4805aee792f0
|
'''A dict representation of this twitter.Status instance. |
367 |
4805aee792f0
|
|
368 |
4805aee792f0
|
The return value uses the same key names as the JSON representation. |
369 |
4805aee792f0
|
|
370 |
4805aee792f0
|
Return: |
371 |
4805aee792f0
|
A dict representing this twitter.Status instance |
372 |
4805aee792f0
|
''' |
373 |
4805aee792f0
|
data = {} |
374 |
4805aee792f0
|
if self.created_at: |
375 |
4805aee792f0
|
data['created_at'] = self.created_at |
376 |
a1e65b8c9435
|
if self.favorited: |
377 |
a1e65b8c9435
|
data['favorited'] = self.favorited |
378 |
4805aee792f0
|
if self.id: |
379 |
4805aee792f0
|
data['id'] = self.id |
380 |
4805aee792f0
|
if self.text: |
381 |
4805aee792f0
|
data['text'] = self.text |
382 |
4805aee792f0
|
if self.user: |
383 |
4805aee792f0
|
data['user'] = self.user.AsDict() |
384 |
1139636b672f
|
if self.in_reply_to_screen_name: |
385 |
1139636b672f
|
data['in_reply_to_screen_name'] = self.in_reply_to_screen_name |
386 |
1139636b672f
|
if self.in_reply_to_user_id: |
387 |
1139636b672f
|
data['in_reply_to_user_id'] = self.in_reply_to_user_id |
388 |
1139636b672f
|
if self.in_reply_to_status_id: |
389 |
1139636b672f
|
data['in_reply_to_status_id'] = self.in_reply_to_status_id |
390 |
1139636b672f
|
if self.truncated is not None: |
391 |
1139636b672f
|
data['truncated'] = self.truncated |
392 |
1139636b672f
|
if self.favorited is not None: |
393 |
1139636b672f
|
data['favorited'] = self.favorited |
394 |
1139636b672f
|
if self.source: |
395 |
1139636b672f
|
data['source'] = self.source |
396 |
4805aee792f0
|
return data |
397 |
4805aee792f0
|
|
398 |
4805aee792f0
|
@staticmethod |
399 |
4805aee792f0
|
def NewFromJsonDict(data): |
400 |
4805aee792f0
|
'''Create a new instance based on a JSON dict. |
401 |
4805aee792f0
|
|
402 |
4805aee792f0
|
Args: |
403 |
4805aee792f0
|
data: A JSON dict, as converted from the JSON in the twitter API |
404 |
4805aee792f0
|
Returns: |
405 |
4805aee792f0
|
A twitter.Status instance |
406 |
4805aee792f0
|
''' |
407 |
4805aee792f0
|
if 'user' in data: |
408 |
4805aee792f0
|
user = User.NewFromJsonDict(data['user']) |
409 |
4805aee792f0
|
else: |
410 |
4805aee792f0
|
user = None |
411 |
4805aee792f0
|
return Status(created_at=data.get('created_at', None), |
412 |
a1e65b8c9435
|
favorited=data.get('favorited', None), |
413 |
4805aee792f0
|
id=data.get('id', None), |
414 |
4805aee792f0
|
text=data.get('text', None), |
415 |
1139636b672f
|
in_reply_to_screen_name=data.get('in_reply_to_screen_name', None), |
416 |
1139636b672f
|
in_reply_to_user_id=data.get('in_reply_to_user_id', None), |
417 |
1139636b672f
|
in_reply_to_status_id=data.get('in_reply_to_status_id', None), |
418 |
1139636b672f
|
truncated=data.get('truncated', None), |
419 |
1139636b672f
|
source=data.get('source', None), |
420 |
4805aee792f0
|
user=user) |
421 |
4805aee792f0
|
|
422 |
4805aee792f0
|
|
423 |
4805aee792f0
|
class User(object): |
424 |
4805aee792f0
|
'''A class representing the User structure used by the twitter API. |
425 |
4805aee792f0
|
|
426 |
4805aee792f0
|
The User structure exposes the following properties: |
427 |
4805aee792f0
|
|
428 |
4805aee792f0
|
user.id |
429 |
4805aee792f0
|
user.name |
430 |
4805aee792f0
|
user.screen_name |
431 |
4805aee792f0
|
user.location |
432 |
4805aee792f0
|
user.description |
433 |
4805aee792f0
|
user.profile_image_url |
434 |
1139636b672f
|
user.profile_background_tile |
435 |
1139636b672f
|
user.profile_background_image_url |
436 |
1139636b672f
|
user.profile_sidebar_fill_color |
437 |
1139636b672f
|
user.profile_background_color |
438 |
1139636b672f
|
user.profile_link_color |
439 |
1139636b672f
|
user.profile_text_color |
440 |
1139636b672f
|
user.protected |
441 |
1139636b672f
|
user.utc_offset |
442 |
1139636b672f
|
user.time_zone |
443 |
4805aee792f0
|
user.url |
444 |
4805aee792f0
|
user.status |
445 |
1139636b672f
|
user.statuses_count |
446 |
1139636b672f
|
user.followers_count |
447 |
1139636b672f
|
user.friends_count |
448 |
1139636b672f
|
user.favourites_count |
449 |
4805aee792f0
|
''' |
450 |
4805aee792f0
|
def __init__(self, |
451 |
4805aee792f0
|
id=None, |
452 |
4805aee792f0
|
name=None, |
453 |
4805aee792f0
|
screen_name=None, |
454 |
4805aee792f0
|
location=None, |
455 |
4805aee792f0
|
description=None, |
456 |
4805aee792f0
|
profile_image_url=None, |
457 |
1139636b672f
|
profile_background_tile=None, |
458 |
1139636b672f
|
profile_background_image_url=None, |
459 |
1139636b672f
|
profile_sidebar_fill_color=None, |
460 |
1139636b672f
|
profile_background_color=None, |
461 |
1139636b672f
|
profile_link_color=None, |
462 |
1139636b672f
|
profile_text_color=None, |
463 |
1139636b672f
|
protected=None, |
464 |
1139636b672f
|
utc_offset=None, |
465 |
1139636b672f
|
time_zone=None, |
466 |
1139636b672f
|
followers_count=None, |
467 |
1139636b672f
|
friends_count=None, |
468 |
1139636b672f
|
statuses_count=None, |
469 |
1139636b672f
|
favourites_count=None, |
470 |
4805aee792f0
|
url=None, |
471 |
4805aee792f0
|
status=None): |
472 |
4805aee792f0
|
self.id = id |
473 |
4805aee792f0
|
self.name = name |
474 |
4805aee792f0
|
self.screen_name = screen_name |
475 |
4805aee792f0
|
self.location = location |
476 |
4805aee792f0
|
self.description = description |
477 |
4805aee792f0
|
self.profile_image_url = profile_image_url |
478 |
1139636b672f
|
self.profile_background_tile = profile_background_tile |
479 |
1139636b672f
|
self.profile_background_image_url = profile_background_image_url |
480 |
1139636b672f
|
self.profile_sidebar_fill_color = profile_sidebar_fill_color |
481 |
1139636b672f
|
self.profile_background_color = profile_background_color |
482 |
1139636b672f
|
self.profile_link_color = profile_link_color |
483 |
1139636b672f
|
self.profile_text_color = profile_text_color |
484 |
1139636b672f
|
self.protected = protected |
485 |
1139636b672f
|
self.utc_offset = utc_offset |
486 |
1139636b672f
|
self.time_zone = time_zone |
487 |
1139636b672f
|
self.followers_count = followers_count |
488 |
1139636b672f
|
self.friends_count = friends_count |
489 |
1139636b672f
|
self.statuses_count = statuses_count |
490 |
1139636b672f
|
self.favourites_count = favourites_count |
491 |
4805aee792f0
|
self.url = url |
492 |
4805aee792f0
|
self.status = status |
493 |
4805aee792f0
|
|
494 |
4805aee792f0
|
|
495 |
4805aee792f0
|
def GetId(self): |
496 |
4805aee792f0
|
'''Get the unique id of this user. |
497 |
4805aee792f0
|
|
498 |
4805aee792f0
|
Returns: |
499 |
4805aee792f0
|
The unique id of this user |
500 |
4805aee792f0
|
''' |
501 |
4805aee792f0
|
return self._id |
502 |
4805aee792f0
|
|
503 |
4805aee792f0
|
def SetId(self, id): |
504 |
4805aee792f0
|
'''Set the unique id of this user. |
505 |
4805aee792f0
|
|
506 |
4805aee792f0
|
Args: |
507 |
4805aee792f0
|
id: The unique id of this user. |
508 |
4805aee792f0
|
''' |
509 |
4805aee792f0
|
self._id = id |
510 |
4805aee792f0
|
|
511 |
4805aee792f0
|
id = property(GetId, SetId, |
512 |
4805aee792f0
|
doc='The unique id of this user.') |
513 |
4805aee792f0
|
|
514 |
4805aee792f0
|
def GetName(self): |
515 |
4805aee792f0
|
'''Get the real name of this user. |
516 |
4805aee792f0
|
|
517 |
4805aee792f0
|
Returns: |
518 |
4805aee792f0
|
The real name of this user |
519 |
4805aee792f0
|
''' |
520 |
4805aee792f0
|
return self._name |
521 |
4805aee792f0
|
|
522 |
4805aee792f0
|
def SetName(self, name): |
523 |
4805aee792f0
|
'''Set the real name of this user. |
524 |
4805aee792f0
|
|
525 |
4805aee792f0
|
Args: |
526 |
4805aee792f0
|
name: The real name of this user |
527 |
4805aee792f0
|
''' |
528 |
4805aee792f0
|
self._name = name |
529 |
4805aee792f0
|
|
530 |
4805aee792f0
|
name = property(GetName, SetName, |
531 |
4805aee792f0
|
doc='The real name of this user.') |
532 |
4805aee792f0
|
|
533 |
4805aee792f0
|
def GetScreenName(self): |
534 |
4805aee792f0
|
'''Get the short username of this user. |
535 |
4805aee792f0
|
|
536 |
4805aee792f0
|
Returns: |
537 |
4805aee792f0
|
The short username of this user |
538 |
4805aee792f0
|
''' |
539 |
4805aee792f0
|
return self._screen_name |
540 |
4805aee792f0
|
|
541 |
4805aee792f0
|
def SetScreenName(self, screen_name): |
542 |
4805aee792f0
|
'''Set the short username of this user. |
543 |
4805aee792f0
|
|
544 |
4805aee792f0
|
Args: |
545 |
4805aee792f0
|
screen_name: the short username of this user |
546 |
4805aee792f0
|
''' |
547 |
4805aee792f0
|
self._screen_name = screen_name |
548 |
4805aee792f0
|
|
549 |
4805aee792f0
|
screen_name = property(GetScreenName, SetScreenName, |
550 |
4805aee792f0
|
doc='The short username of this user.') |
551 |
4805aee792f0
|
|
552 |
4805aee792f0
|
def GetLocation(self): |
553 |
4805aee792f0
|
'''Get the geographic location of this user. |
554 |
4805aee792f0
|
|
555 |
4805aee792f0
|
Returns: |
556 |
4805aee792f0
|
The geographic location of this user |
557 |
4805aee792f0
|
''' |
558 |
4805aee792f0
|
return self._location |
559 |
4805aee792f0
|
|
560 |
4805aee792f0
|
def SetLocation(self, location): |
561 |
4805aee792f0
|
'''Set the geographic location of this user. |
562 |
4805aee792f0
|
|
563 |
4805aee792f0
|
Args: |
564 |
4805aee792f0
|
location: The geographic location of this user |
565 |
4805aee792f0
|
''' |
566 |
4805aee792f0
|
self._location = location |
567 |
4805aee792f0
|
|
568 |
4805aee792f0
|
location = property(GetLocation, SetLocation, |
569 |
4805aee792f0
|
doc='The geographic location of this user.') |
570 |
17f566981b41
|
|
571 |
4805aee792f0
|
def GetDescription(self): |
572 |
4805aee792f0
|
'''Get the short text description of this user. |
573 |
4805aee792f0
|
|
574 |
4805aee792f0
|
Returns: |
575 |
4805aee792f0
|
The short text description of this user |
576 |
4805aee792f0
|
''' |
577 |
4805aee792f0
|
return self._description |
578 |
4805aee792f0
|
|
579 |
4805aee792f0
|
def SetDescription(self, description): |
580 |
4805aee792f0
|
'''Set the short text description of this user. |
581 |
4805aee792f0
|
|
582 |
4805aee792f0
|
Args: |
583 |
4805aee792f0
|
description: The short text description of this user |
584 |
4805aee792f0
|
''' |
585 |
4805aee792f0
|
self._description = description |
586 |
4805aee792f0
|
|
587 |
4805aee792f0
|
description = property(GetDescription, SetDescription, |
588 |
4805aee792f0
|
doc='The short text description of this user.') |
589 |
17f566981b41
|
|
590 |
4805aee792f0
|
def GetUrl(self): |
591 |
4805aee792f0
|
'''Get the homepage url of this user. |
592 |
4805aee792f0
|
|
593 |
4805aee792f0
|
Returns: |
594 |
4805aee792f0
|
The homepage url of this user |
595 |
4805aee792f0
|
''' |
596 |
4805aee792f0
|
return self._url |
597 |
4805aee792f0
|
|
598 |
4805aee792f0
|
def SetUrl(self, url): |
599 |
4805aee792f0
|
'''Set the homepage url of this user. |
600 |
4805aee792f0
|
|
601 |
4805aee792f0
|
Args: |
602 |
4805aee792f0
|
url: The homepage url of this user |
603 |
4805aee792f0
|
''' |
604 |
4805aee792f0
|
self._url = url |
605 |
4805aee792f0
|
|
606 |
4805aee792f0
|
url = property(GetUrl, SetUrl, |
607 |
4805aee792f0
|
doc='The homepage url of this user.') |
608 |
4805aee792f0
|
|
609 |
4805aee792f0
|
def GetProfileImageUrl(self): |
610 |
4805aee792f0
|
'''Get the url of the thumbnail of this user. |
611 |
4805aee792f0
|
|
612 |
4805aee792f0
|
Returns: |
613 |
4805aee792f0
|
The url of the thumbnail of this user |
614 |
4805aee792f0
|
''' |
615 |
4805aee792f0
|
return self._profile_image_url |
616 |
4805aee792f0
|
|
617 |
4805aee792f0
|
def SetProfileImageUrl(self, profile_image_url): |
618 |
4805aee792f0
|
'''Set the url of the thumbnail of this user. |
619 |
4805aee792f0
|
|
620 |
4805aee792f0
|
Args: |
621 |
4805aee792f0
|
profile_image_url: The url of the thumbnail of this user |
622 |
4805aee792f0
|
''' |
623 |
4805aee792f0
|
self._profile_image_url = profile_image_url |
624 |
4805aee792f0
|
|
625 |
4805aee792f0
|
profile_image_url= property(GetProfileImageUrl, SetProfileImageUrl, |
626 |
4805aee792f0
|
doc='The url of the thumbnail of this user.') |
627 |
4805aee792f0
|
|
628 |
1139636b672f
|
def GetProfileBackgroundTile(self): |
629 |
1139636b672f
|
'''Boolean for whether to tile the profile background image. |
630 |
1139636b672f
|
|
631 |
1139636b672f
|
Returns: |
632 |
1139636b672f
|
True if the background is to be tiled, False if not, None if unset. |
633 |
1139636b672f
|
''' |
634 |
1139636b672f
|
return self._profile_background_tile |
635 |
1139636b672f
|
|
636 |
1139636b672f
|
def SetProfileBackgroundTile(self, profile_background_tile): |
637 |
1139636b672f
|
'''Set the boolean flag for whether to tile the profile background image. |
638 |
1139636b672f
|
|
639 |
1139636b672f
|
Args: |
640 |
1139636b672f
|
profile_background_tile: Boolean flag for whether to tile or not. |
641 |
1139636b672f
|
''' |
642 |
1139636b672f
|
self._profile_background_tile = profile_background_tile |
643 |
1139636b672f
|
|
644 |
1139636b672f
|
profile_background_tile = property(GetProfileBackgroundTile, SetProfileBackgroundTile, |
645 |
1139636b672f
|
doc='Boolean for whether to tile the background image.') |
646 |
1139636b672f
|
|
647 |
1139636b672f
|
def GetProfileBackgroundImageUrl(self): |
648 |
1139636b672f
|
return self._profile_background_image_url |
649 |
1139636b672f
|
|
650 |
1139636b672f
|
def SetProfileBackgroundImageUrl(self, profile_background_image_url): |
651 |
1139636b672f
|
self._profile_background_image_url = profile_background_image_url |
652 |
1139636b672f
|
|
653 |
1139636b672f
|
profile_background_image_url = property(GetProfileBackgroundImageUrl, SetProfileBackgroundImageUrl, |
654 |
1139636b672f
|
doc='The url of the profile background of this user.') |
655 |
1139636b672f
|
|
656 |
1139636b672f
|
def GetProfileSidebarFillColor(self): |
657 |
1139636b672f
|
return self._profile_sidebar_fill_color |
658 |
1139636b672f
|
|
659 |
1139636b672f
|
def SetProfileSidebarFillColor(self, profile_sidebar_fill_color): |
660 |
1139636b672f
|
self._profile_sidebar_fill_color = profile_sidebar_fill_color |
661 |
1139636b672f
|
|
662 |
1139636b672f
|
profile_sidebar_fill_color = property(GetProfileSidebarFillColor, SetProfileSidebarFillColor) |
663 |
1139636b672f
|
|
664 |
1139636b672f
|
def GetProfileBackgroundColor(self): |
665 |
1139636b672f
|
return self._profile_background_color |
666 |
1139636b672f
|
|
667 |
1139636b672f
|
def SetProfileBackgroundColor(self, profile_background_color): |
668 |
1139636b672f
|
self._profile_background_color = profile_background_color |
669 |
1139636b672f
|
|
670 |
1139636b672f
|
profile_background_color = property(GetProfileBackgroundColor, SetProfileBackgroundColor) |
671 |
1139636b672f
|
|
672 |
1139636b672f
|
def GetProfileLinkColor(self): |
673 |
1139636b672f
|
return self._profile_link_color |
674 |
1139636b672f
|
|
675 |
1139636b672f
|
def SetProfileLinkColor(self, profile_link_color): |
676 |
1139636b672f
|
self._profile_link_color = profile_link_color |
677 |
1139636b672f
|
|
678 |
1139636b672f
|
profile_link_color = property(GetProfileLinkColor, SetProfileLinkColor) |
679 |
1139636b672f
|
|
680 |
1139636b672f
|
def GetProfileTextColor(self): |
681 |
1139636b672f
|
return self._profile_text_color |
682 |
1139636b672f
|
|
683 |
1139636b672f
|
def SetProfileTextColor(self, profile_text_color): |
684 |
1139636b672f
|
self._profile_text_color = profile_text_color |
685 |
1139636b672f
|
|
686 |
1139636b672f
|
profile_text_color = property(GetProfileTextColor, SetProfileTextColor) |
687 |
1139636b672f
|
|
688 |
1139636b672f
|
def GetProtected(self): |
689 |
1139636b672f
|
return self._protected |
690 |
1139636b672f
|
|
691 |
1139636b672f
|
def SetProtected(self, protected): |
692 |
1139636b672f
|
self._protected = protected |
693 |
1139636b672f
|
|
694 |
1139636b672f
|
protected = property(GetProtected, SetProtected) |
695 |
1139636b672f
|
|
696 |
1139636b672f
|
def GetUtcOffset(self): |
697 |
1139636b672f
|
return self._utc_offset |
698 |
1139636b672f
|
|
699 |
1139636b672f
|
def SetUtcOffset(self, utc_offset): |
700 |
1139636b672f
|
self._utc_offset = utc_offset |
701 |
1139636b672f
|
|
702 |
1139636b672f
|
utc_offset = property(GetUtcOffset, SetUtcOffset) |
703 |
1139636b672f
|
|
704 |
1139636b672f
|
def GetTimeZone(self): |
705 |
1139636b672f
|
'''Returns the current time zone string for the user. |
706 |
1139636b672f
|
|
707 |
1139636b672f
|
Returns: |
708 |
1139636b672f
|
The descriptive time zone string for the user. |
709 |
1139636b672f
|
''' |
710 |
1139636b672f
|
return self._time_zone |
711 |
1139636b672f
|
|
712 |
1139636b672f
|
def SetTimeZone(self, time_zone): |
713 |
1139636b672f
|
'''Sets the user's time zone string. |
714 |
1139636b672f
|
|
715 |
1139636b672f
|
Args: |
716 |
1139636b672f
|
time_zone: The descriptive time zone to assign for the user. |
717 |
1139636b672f
|
''' |
718 |
1139636b672f
|
self._time_zone = time_zone |
719 |
1139636b672f
|
|
720 |
1139636b672f
|
time_zone = property(GetTimeZone, SetTimeZone) |
721 |
1139636b672f
|
|
722 |
4805aee792f0
|
def GetStatus(self): |
723 |
4805aee792f0
|
'''Get the latest twitter.Status of this user. |
724 |
4805aee792f0
|
|
725 |
4805aee792f0
|
Returns: |
726 |
4805aee792f0
|
The latest twitter.Status of this user |
727 |
4805aee792f0
|
''' |
728 |
4805aee792f0
|
return self._status |
729 |
4805aee792f0
|
|
730 |
4805aee792f0
|
def SetStatus(self, status): |
731 |
4805aee792f0
|
'''Set the latest twitter.Status of this user. |
732 |
4805aee792f0
|
|
733 |
4805aee792f0
|
Args: |
734 |
4805aee792f0
|
status: The latest twitter.Status of this user |
735 |
4805aee792f0
|
''' |
736 |
4805aee792f0
|
self._status = status |
737 |
17f566981b41
|
|
738 |
4805aee792f0
|
status = property(GetStatus, SetStatus, |
739 |
4805aee792f0
|
doc='The latest twitter.Status of this user.') |
740 |
4805aee792f0
|
|
741 |
1139636b672f
|
def GetFriendsCount(self): |
742 |
1139636b672f
|
'''Get the friend count for this user. |
743 |
1139636b672f
|
|
744 |
1139636b672f
|
Returns: |
745 |
1139636b672f
|
The number of users this user has befriended. |
746 |
1139636b672f
|
''' |
747 |
1139636b672f
|
return self._friends_count |
748 |
1139636b672f
|
|
749 |
1139636b672f
|
def SetFriendsCount(self, count): |
750 |
1139636b672f
|
'''Set the friend count for this user. |
751 |
1139636b672f
|
|
752 |
1139636b672f
|
Args: |
753 |
1139636b672f
|
count: The number of users this user has befriended. |
754 |
1139636b672f
|
''' |
755 |
1139636b672f
|
self._friends_count = count |
756 |
1139636b672f
|
|
757 |
1139636b672f
|
friends_count = property(GetFriendsCount, SetFriendsCount, |
758 |
1139636b672f
|
doc='The number of friends for this user.') |
759 |
1139636b672f
|
|
760 |
1139636b672f
|
def GetFollowersCount(self): |
761 |
1139636b672f
|
'''Get the follower count for this user. |
762 |
1139636b672f
|
|
763 |
1139636b672f
|
Returns: |
764 |
1139636b672f
|
The number of users following this user. |
765 |
1139636b672f
|
''' |
766 |
1139636b672f
|
return self._followers_count |
767 |
1139636b672f
|
|
768 |
1139636b672f
|
def SetFollowersCount(self, count): |
769 |
1139636b672f
|
'''Set the follower count for this user. |
770 |
1139636b672f
|
|
771 |
1139636b672f
|
Args: |
772 |
1139636b672f
|
count: The number of users following this user. |
773 |
1139636b672f
|
''' |
774 |
1139636b672f
|
self._followers_count = count |
775 |
1139636b672f
|
|
776 |
1139636b672f
|
followers_count = property(GetFollowersCount, SetFollowersCount, |
777 |
1139636b672f
|
doc='The number of users following this user.') |
778 |
1139636b672f
|
|
779 |
1139636b672f
|
def GetStatusesCount(self): |
780 |
1139636b672f
|
'''Get the number of status updates for this user. |
781 |
1139636b672f
|
|
782 |
1139636b672f
|
Returns: |
783 |
1139636b672f
|
The number of status updates for this user. |
784 |
1139636b672f
|
''' |
785 |
1139636b672f
|
return self._statuses_count |
786 |
1139636b672f
|
|
787 |
1139636b672f
|
def SetStatusesCount(self, count): |
788 |
1139636b672f
|
'''Set the status update count for this user. |
789 |
1139636b672f
|
|
790 |
1139636b672f
|
Args: |
791 |
1139636b672f
|
count: The number of updates for this user. |
792 |
1139636b672f
|
''' |
793 |
1139636b672f
|
self._statuses_count = count |
794 |
1139636b672f
|
|
795 |
1139636b672f
|
statuses_count = property(GetStatusesCount, SetStatusesCount, |
796 |
1139636b672f
|
doc='The number of updates for this user.') |
797 |
1139636b672f
|
|
798 |
1139636b672f
|
def GetFavouritesCount(self): |
799 |
1139636b672f
|
'''Get the number of favourites for this user. |
800 |
1139636b672f
|
|
801 |
1139636b672f
|
Returns: |
802 |
1139636b672f
|
The number of favourites for this user. |
803 |
1139636b672f
|
''' |
804 |
1139636b672f
|
return self._favourites_count |
805 |
1139636b672f
|
|
806 |
1139636b672f
|
def SetFavouritesCount(self, count): |
807 |
1139636b672f
|
'''Set the favourite count for this user. |
808 |
1139636b672f
|
|
809 |
1139636b672f
|
Args: |
810 |
1139636b672f
|
count: The number of favourites for this user. |
811 |
1139636b672f
|
''' |
812 |
1139636b672f
|
self._favourites_count = count |
813 |
1139636b672f
|
|
814 |
1139636b672f
|
favourites_count = property(GetFavouritesCount, SetFavouritesCount, |
815 |
1139636b672f
|
doc='The number of favourites for this user.') |
816 |
1139636b672f
|
|
817 |
4805aee792f0
|
def __ne__(self, other): |
818 |
4805aee792f0
|
return not self.__eq__(other) |
819 |
17f566981b41
|
|
820 |
4805aee792f0
|
def __eq__(self, other): |
821 |
4805aee792f0
|
try: |
822 |
4805aee792f0
|
return other and \ |
823 |
4805aee792f0
|
self.id == other.id and \ |
824 |
4805aee792f0
|
self.name == other.name and \ |
825 |
4805aee792f0
|
self.screen_name == other.screen_name and \ |
826 |
4805aee792f0
|
self.location == other.location and \ |
827 |
4805aee792f0
|
self.description == other.description and \ |
828 |
4805aee792f0
|
self.profile_image_url == other.profile_image_url and \ |
829 |
1139636b672f
|
self.profile_background_tile == other.profile_background_tile and \ |
830 |
1139636b672f
|
self.profile_background_image_url == other.profile_background_image_url and \ |
831 |
1139636b672f
|
self.profile_sidebar_fill_color == other.profile_sidebar_fill_color and \ |
832 |
1139636b672f
|
self.profile_background_color == other.profile_background_color and \ |
833 |
1139636b672f
|
self.profile_link_color == other.profile_link_color and \ |
834 |
1139636b672f
|
self.profile_text_color == other.profile_text_color and \ |
835 |
1139636b672f
|
self.protected == other.protected and \ |
836 |
1139636b672f
|
self.utc_offset == other.utc_offset and \ |
837 |
1139636b672f
|
self.time_zone == other.time_zone and \ |
838 |
4805aee792f0
|
self.url == other.url and \ |
839 |
1139636b672f
|
self.statuses_count == other.statuses_count and \ |
840 |
1139636b672f
|
self.followers_count == other.followers_count and \ |
841 |
1139636b672f
|
self.favourites_count == other.favourites_count and \ |
842 |
1139636b672f
|
self.friends_count == other.friends_count and \ |
843 |
4805aee792f0
|
self.status == other.status |
844 |
4805aee792f0
|
except AttributeError: |
845 |
4805aee792f0
|
return False |
846 |
17f566981b41
|
|
847 |
4805aee792f0
|
def __str__(self): |
848 |
4805aee792f0
|
'''A string representation of this twitter.User instance. |
849 |
4805aee792f0
|
|
850 |
4805aee792f0
|
The return value is the same as the JSON string representation. |
851 |
4805aee792f0
|
|
852 |
4805aee792f0
|
Returns: |
853 |
17f566981b41
|
A string representation of this twitter.User instance. |
854 |
4805aee792f0
|
''' |
855 |
4805aee792f0
|
return self.AsJsonString() |
856 |
4805aee792f0
|
|
857 |
4805aee792f0
|
def AsJsonString(self): |
858 |
4805aee792f0
|
'''A JSON string representation of this twitter.User instance. |
859 |
4805aee792f0
|
|
860 |
4805aee792f0
|
Returns: |
861 |
4805aee792f0
|
A JSON string representation of this twitter.User instance |
862 |
17f566981b41
|
''' |
863 |
4805aee792f0
|
return simplejson.dumps(self.AsDict(), sort_keys=True) |
864 |
4805aee792f0
|
|
865 |
4805aee792f0
|
def AsDict(self): |
866 |
4805aee792f0
|
'''A dict representation of this twitter.User instance. |
867 |
4805aee792f0
|
|
868 |
4805aee792f0
|
The return value uses the same key names as the JSON representation. |
869 |
4805aee792f0
|
|
870 |
4805aee792f0
|
Return: |
871 |
4805aee792f0
|
A dict representing this twitter.User instance |
872 |
4805aee792f0
|
''' |
873 |
4805aee792f0
|
data = {} |
874 |
4805aee792f0
|
if self.id: |
875 |
4805aee792f0
|
data['id'] = self.id |
876 |
4805aee792f0
|
if self.name: |
877 |
4805aee792f0
|
data['name'] = self.name |
878 |
4805aee792f0
|
if self.screen_name: |
879 |
4805aee792f0
|
data['screen_name'] = self.screen_name |
880 |
4805aee792f0
|
if self.location: |
881 |
4805aee792f0
|
data['location'] = self.location |
882 |
4805aee792f0
|
if self.description: |
883 |
4805aee792f0
|
data['description'] = self.description |
884 |
4805aee792f0
|
if self.profile_image_url: |
885 |
4805aee792f0
|
data['profile_image_url'] = self.profile_image_url |
886 |
1139636b672f
|
if self.profile_background_tile is not None: |
887 |
1139636b672f
|
data['profile_background_tile'] = self.profile_background_tile |
888 |
1139636b672f
|
if self.profile_background_image_url: |
889 |
1139636b672f
|
data['profile_sidebar_fill_color'] = self.profile_background_image_url |
890 |
1139636b672f
|
if self.profile_background_color: |
891 |
1139636b672f
|
data['profile_background_color'] = self.profile_background_color |
892 |
1139636b672f
|
if self.profile_link_color: |
893 |
1139636b672f
|
data['profile_link_color'] = self.profile_link_color |
894 |
1139636b672f
|
if self.profile_text_color: |
895 |
1139636b672f
|
data['profile_text_color'] = self.profile_text_color |
896 |
1139636b672f
|
if self.protected is not None: |
897 |
1139636b672f
|
data['protected'] = self.protected |
898 |
1139636b672f
|
if self.utc_offset: |
899 |
1139636b672f
|
data['utc_offset'] = self.utc_offset |
900 |
1139636b672f
|
if self.time_zone: |
901 |
1139636b672f
|
data['time_zone'] = self.time_zone |
902 |
4805aee792f0
|
if self.url: |
903 |
4805aee792f0
|
data['url'] = self.url |
904 |
4805aee792f0
|
if self.status: |
905 |
4805aee792f0
|
data['status'] = self.status.AsDict() |
906 |
1139636b672f
|
if self.friends_count: |
907 |
1139636b672f
|
data['friends_count'] = self.friends_count |
908 |
1139636b672f
|
if self.followers_count: |
909 |
1139636b672f
|
data['followers_count'] = self.followers_count |
910 |
1139636b672f
|
if self.statuses_count: |
911 |
1139636b672f
|
data['statuses_count'] = self.statuses_count |
912 |
1139636b672f
|
if self.favourites_count: |
913 |
1139636b672f
|
data['favourites_count'] = self.favourites_count |
914 |
4805aee792f0
|
return data |
915 |
4805aee792f0
|
|
916 |
4805aee792f0
|
@staticmethod |
917 |
4805aee792f0
|
def NewFromJsonDict(data): |
918 |
4805aee792f0
|
'''Create a new instance based on a JSON dict. |
919 |
4805aee792f0
|
|
920 |
4805aee792f0
|
Args: |
921 |
4805aee792f0
|
data: A JSON dict, as converted from the JSON in the twitter API |
922 |
4805aee792f0
|
Returns: |
923 |
4805aee792f0
|
A twitter.User instance |
924 |
4805aee792f0
|
''' |
925 |
4805aee792f0
|
if 'status' in data: |
926 |
4805aee792f0
|
status = Status.NewFromJsonDict(data['status']) |
927 |
4805aee792f0
|
else: |
928 |
4805aee792f0
|
status = None |
929 |
4805aee792f0
|
return User(id=data.get('id', None), |
930 |
4805aee792f0
|
name=data.get('name', None), |
931 |
4805aee792f0
|
screen_name=data.get('screen_name', None), |
932 |
4805aee792f0
|
location=data.get('location', None), |
933 |
4805aee792f0
|
description=data.get('description', None), |
934 |
1139636b672f
|
statuses_count=data.get('statuses_count', None), |
935 |
1139636b672f
|
followers_count=data.get('followers_count', None), |
936 |
1139636b672f
|
favourites_count=data.get('favourites_count', None), |
937 |
1139636b672f
|
friends_count=data.get('friends_count', None), |
938 |
4805aee792f0
|
profile_image_url=data.get('profile_image_url', None), |
939 |
1139636b672f
|
profile_background_tile = data.get('profile_background_tile', None), |
940 |
1139636b672f
|
profile_background_image_url = data.get('profile_background_image_url', None), |
941 |
1139636b672f
|
profile_sidebar_fill_color = data.get('profile_sidebar_fill_color', None), |
942 |
1139636b672f
|
profile_background_color = data.get('profile_background_color', None), |
943 |
1139636b672f
|
profile_link_color = data.get('profile_link_color', None), |
944 |
1139636b672f
|
profile_text_color = data.get('profile_text_color', None), |
945 |
1139636b672f
|
protected = data.get('protected', None), |
946 |
1139636b672f
|
utc_offset = data.get('utc_offset', None), |
947 |
1139636b672f
|
time_zone = data.get('time_zone', None), |
948 |
4805aee792f0
|
url=data.get('url', None), |
949 |
4805aee792f0
|
status=status) |
950 |
4805aee792f0
|
|
951 |
c42880b017af
|
class DirectMessage(object): |
952 |
950d53433f5b
|
'''A class representing the DirectMessage structure used by the twitter API. |
953 |
950d53433f5b
|
|
954 |
950d53433f5b
|
The DirectMessage structure exposes the following properties: |
955 |
950d53433f5b
|
|
956 |
950d53433f5b
|
direct_message.id |
957 |
950d53433f5b
|
direct_message.created_at |
958 |
950d53433f5b
|
direct_message.created_at_in_seconds # read only |
959 |
950d53433f5b
|
direct_message.sender_id |
960 |
950d53433f5b
|
direct_message.sender_screen_name |
961 |
950d53433f5b
|
direct_message.recipient_id |
962 |
950d53433f5b
|
direct_message.recipient_screen_name |
963 |
950d53433f5b
|
direct_message.text |
964 |
950d53433f5b
|
''' |
965 |
c42880b017af
|
|
966 |
c42880b017af
|
def __init__(self, |
967 |
950d53433f5b
|
id=None, |
968 |
c42880b017af
|
created_at=None, |
969 |
950d53433f5b
|
sender_id=None, |
970 |
950d53433f5b
|
sender_screen_name=None, |
971 |
c42880b017af
|
recipient_id=None, |
972 |
950d53433f5b
|
recipient_screen_name=None, |
973 |
950d53433f5b
|
text=None): |
974 |
950d53433f5b
|
'''An object to hold a Twitter direct message. |
975 |
950d53433f5b
|
|
976 |
950d53433f5b
|
This class is normally instantiated by the twitter.Api class and |
977 |
950d53433f5b
|
returned in a sequence. |
978 |
950d53433f5b
|
|
979 |
950d53433f5b
|
Note: Dates are posted in the form "Sat Jan 27 04:17:38 +0000 2007" |
980 |
950d53433f5b
|
|
981 |
950d53433f5b
|
Args: |
982 |
950d53433f5b
|
id: The unique id of this direct message |
983 |
950d53433f5b
|
created_at: The time this direct message was posted |
984 |
950d53433f5b
|
sender_id: The id of the twitter user that sent this message |
985 |
950d53433f5b
|
sender_screen_name: The name of the twitter user that sent this message |
986 |
950d53433f5b
|
recipient_id: The id of the twitter that received this message |
987 |
950d53433f5b
|
recipient_screen_name: The name of the twitter that received this message |
988 |
950d53433f5b
|
text: The text of this direct message |
989 |
950d53433f5b
|
''' |
990 |
950d53433f5b
|
self.id = id |
991 |
c42880b017af
|
self.created_at = created_at |
992 |
950d53433f5b
|
self.sender_id = sender_id |
993 |
950d53433f5b
|
self.sender_screen_name = sender_screen_name |
994 |
c42880b017af
|
self.recipient_id = recipient_id |
995 |
950d53433f5b
|
self.recipient_screen_name = recipient_screen_name |
996 |
c42880b017af
|
self.text = text |
997 |
950d53433f5b
|
|
998 |
950d53433f5b
|
def GetId(self): |
999 |
950d53433f5b
|
'''Get the unique id of this direct message. |
1000 |
950d53433f5b
|
|
1001 |
950d53433f5b
|
Returns: |
1002 |
950d53433f5b
|
The unique id of this direct message |
1003 |
950d53433f5b
|
''' |
1004 |
950d53433f5b
|
return self._id |
1005 |
950d53433f5b
|
|
1006 |
950d53433f5b
|
def SetId(self, id): |
1007 |
950d53433f5b
|
'''Set the unique id of this direct message. |
1008 |
950d53433f5b
|
|
1009 |
950d53433f5b
|
Args: |
1010 |
950d53433f5b
|
id: The unique id of this direct message |
1011 |
950d53433f5b
|
''' |
1012 |
950d53433f5b
|
self._id = id |
1013 |
950d53433f5b
|
|
1014 |
950d53433f5b
|
id = property(GetId, SetId, |
1015 |
950d53433f5b
|
doc='The unique id of this direct message.') |
1016 |
950d53433f5b
|
|
1017 |
950d53433f5b
|
def GetCreatedAt(self): |
1018 |
950d53433f5b
|
'''Get the time this direct message was posted. |
1019 |
950d53433f5b
|
|
1020 |
950d53433f5b
|
Returns: |
1021 |
950d53433f5b
|
The time this direct message was posted |
1022 |
950d53433f5b
|
''' |
1023 |
950d53433f5b
|
return self._created_at |
1024 |
950d53433f5b
|
|
1025 |
950d53433f5b
|
def SetCreatedAt(self, created_at): |
1026 |
950d53433f5b
|
'''Set the time this direct message was posted. |
1027 |
950d53433f5b
|
|
1028 |
950d53433f5b
|
Args: |
1029 |
950d53433f5b
|
created_at: The time this direct message was created |
1030 |
950d53433f5b
|
''' |
1031 |
950d53433f5b
|
self._created_at = created_at |
1032 |
950d53433f5b
|
|
1033 |
950d53433f5b
|
created_at = property(GetCreatedAt, SetCreatedAt, |
1034 |
950d53433f5b
|
doc='The time this direct message was posted.') |
1035 |
950d53433f5b
|
|
1036 |
950d53433f5b
|
def GetCreatedAtInSeconds(self): |
1037 |
950d53433f5b
|
'''Get the time this direct message was posted, in seconds since the epoch. |
1038 |
950d53433f5b
|
|
1039 |
950d53433f5b
|
Returns: |
1040 |
950d53433f5b
|
The time this direct message was posted, in seconds since the epoch. |
1041 |
950d53433f5b
|
''' |
1042 |
3a4752d10bb7
|
return calendar.timegm(rfc822.parsedate(self.created_at)) |
1043 |
950d53433f5b
|
|
1044 |
950d53433f5b
|
created_at_in_seconds = property(GetCreatedAtInSeconds, |
1045 |
950d53433f5b
|
doc="The time this direct message was " |
1046 |
950d53433f5b
|
"posted, in seconds since the epoch") |
1047 |
950d53433f5b
|
|
1048 |
950d53433f5b
|
def GetSenderId(self): |
1049 |
950d53433f5b
|
'''Get the unique sender id of this direct message. |
1050 |
950d53433f5b
|
|
1051 |
950d53433f5b
|
Returns: |
1052 |
950d53433f5b
|
The unique sender id of this direct message |
1053 |
950d53433f5b
|
''' |
1054 |
950d53433f5b
|
return self._sender_id |
1055 |
950d53433f5b
|
|
1056 |
950d53433f5b
|
def SetSenderId(self, sender_id): |
1057 |
950d53433f5b
|
'''Set the unique sender id of this direct message. |
1058 |
950d53433f5b
|
|
1059 |
950d53433f5b
|
Args: |
1060 |
950d53433f5b
|
sender id: The unique sender id of this direct message |
1061 |
950d53433f5b
|
''' |
1062 |
950d53433f5b
|
self._sender_id = sender_id |
1063 |
950d53433f5b
|
|
1064 |
950d53433f5b
|
sender_id = property(GetSenderId, SetSenderId, |
1065 |
950d53433f5b
|
doc='The unique sender id of this direct message.') |
1066 |
950d53433f5b
|
|
1067 |
950d53433f5b
|
def GetSenderScreenName(self): |
1068 |
950d53433f5b
|
'''Get the unique sender screen name of this direct message. |
1069 |
950d53433f5b
|
|
1070 |
950d53433f5b
|
Returns: |
1071 |
950d53433f5b
|
The unique sender screen name of this direct message |
1072 |
950d53433f5b
|
''' |
1073 |
950d53433f5b
|
return self._sender_screen_name |
1074 |
950d53433f5b
|
|
1075 |
950d53433f5b
|
def SetSenderScreenName(self, sender_screen_name): |
1076 |
950d53433f5b
|
'''Set the unique sender screen name of this direct message. |
1077 |
950d53433f5b
|
|
1078 |
950d53433f5b
|
Args: |
1079 |
950d53433f5b
|
sender_screen_name: The unique sender screen name of this direct message |
1080 |
950d53433f5b
|
''' |
1081 |
950d53433f5b
|
self._sender_screen_name = sender_screen_name |
1082 |
950d53433f5b
|
|
1083 |
950d53433f5b
|
sender_screen_name = property(GetSenderScreenName, SetSenderScreenName, |
1084 |
950d53433f5b
|
doc='The unique sender screen name of this direct message.') |
1085 |
950d53433f5b
|
|
1086 |
950d53433f5b
|
def GetRecipientId(self): |
1087 |
950d53433f5b
|
'''Get the unique recipient id of this direct message. |
1088 |
950d53433f5b
|
|
1089 |
950d53433f5b
|
Returns: |
1090 |
950d53433f5b
|
The unique recipient id of this direct message |
1091 |
950d53433f5b
|
''' |
1092 |
950d53433f5b
|
return self._recipient_id |
1093 |
950d53433f5b
|
|
1094 |
950d53433f5b
|
def SetRecipientId(self, recipient_id): |
1095 |
950d53433f5b
|
'''Set the unique recipient id of this direct message. |
1096 |
950d53433f5b
|
|
1097 |
950d53433f5b
|
Args: |
1098 |
950d53433f5b
|
recipient id: The unique recipient id of this direct message |
1099 |
950d53433f5b
|
''' |
1100 |
950d53433f5b
|
self._recipient_id = recipient_id |
1101 |
950d53433f5b
|
|
1102 |
950d53433f5b
|
recipient_id = property(GetRecipientId, SetRecipientId, |
1103 |
950d53433f5b
|
doc='The unique recipient id of this direct message.') |
1104 |
950d53433f5b
|
|
1105 |
950d53433f5b
|
def GetRecipientScreenName(self): |
1106 |
950d53433f5b
|
'''Get the unique recipient screen name of this direct message. |
1107 |
950d53433f5b
|
|
1108 |
950d53433f5b
|
Returns: |
1109 |
950d53433f5b
|
The unique recipient screen name of this direct message |
1110 |
950d53433f5b
|
''' |
1111 |
950d53433f5b
|
return self._recipient_screen_name |
1112 |
950d53433f5b
|
|
1113 |
950d53433f5b
|
def SetRecipientScreenName(self, recipient_screen_name): |
1114 |
950d53433f5b
|
'''Set the unique recipient screen name of this direct message. |
1115 |
950d53433f5b
|
|
1116 |
950d53433f5b
|
Args: |
1117 |
950d53433f5b
|
recipient_screen_name: The unique recipient screen name of this direct message |
1118 |
950d53433f5b
|
''' |
1119 |
950d53433f5b
|
self._recipient_screen_name = recipient_screen_name |
1120 |
950d53433f5b
|
|
1121 |
950d53433f5b
|
recipient_screen_name = property(GetRecipientScreenName, SetRecipientScreenName, |
1122 |
950d53433f5b
|
doc='The unique recipient screen name of this direct message.') |
1123 |
950d53433f5b
|
|
1124 |
950d53433f5b
|
def GetText(self): |
1125 |
950d53433f5b
|
'''Get the text of this direct message. |
1126 |
950d53433f5b
|
|
1127 |
950d53433f5b
|
Returns: |
1128 |
950d53433f5b
|
The text of this direct message. |
1129 |
950d53433f5b
|
''' |
1130 |
950d53433f5b
|
return self._text |
1131 |
950d53433f5b
|
|
1132 |
950d53433f5b
|
def SetText(self, text): |
1133 |
950d53433f5b
|
'''Set the text of this direct message. |
1134 |
950d53433f5b
|
|
1135 |
950d53433f5b
|
Args: |
1136 |
950d53433f5b
|
text: The text of this direct message |
1137 |
950d53433f5b
|
''' |
1138 |
950d53433f5b
|
self._text = text |
1139 |
950d53433f5b
|
|
1140 |
950d53433f5b
|
text = property(GetText, SetText, |
1141 |
950d53433f5b
|
doc='The text of this direct message') |
1142 |
950d53433f5b
|
|
1143 |
950d53433f5b
|
def __ne__(self, other): |
1144 |
950d53433f5b
|
return not self.__eq__(other) |
1145 |
950d53433f5b
|
|
1146 |
950d53433f5b
|
def __eq__(self, other): |
1147 |
950d53433f5b
|
try: |
1148 |
950d53433f5b
|
return other and \ |
1149 |
950d53433f5b
|
self.id == other.id and \ |
1150 |
950d53433f5b
|
self.created_at == other.created_at and \ |
1151 |
950d53433f5b
|
self.sender_id == other.sender_id and \ |
1152 |
950d53433f5b
|
self.sender_screen_name == other.sender_screen_name and \ |
1153 |
950d53433f5b
|
self.recipient_id == other.recipient_id and \ |
1154 |
950d53433f5b
|
self.recipient_screen_name == other.recipient_screen_name and \ |
1155 |
950d53433f5b
|
self.text == other.text |
1156 |
950d53433f5b
|
except AttributeError: |
1157 |
950d53433f5b
|
return False |
1158 |
950d53433f5b
|
|
1159 |
950d53433f5b
|
def __str__(self): |
1160 |
950d53433f5b
|
'''A string representation of this twitter.DirectMessage instance. |
1161 |
950d53433f5b
|
|
1162 |
950d53433f5b
|
The return value is the same as the JSON string representation. |
1163 |
950d53433f5b
|
|
1164 |
950d53433f5b
|
Returns: |
1165 |
950d53433f5b
|
A string representation of this twitter.DirectMessage instance. |
1166 |
950d53433f5b
|
''' |
1167 |
950d53433f5b
|
return self.AsJsonString() |
1168 |
950d53433f5b
|
|
1169 |
950d53433f5b
|
def AsJsonString(self): |
1170 |
950d53433f5b
|
'''A JSON string representation of this twitter.DirectMessage instance. |
1171 |
950d53433f5b
|
|
1172 |
950d53433f5b
|
Returns: |
1173 |
950d53433f5b
|
A JSON string representation of this twitter.DirectMessage instance |
1174 |
950d53433f5b
|
''' |
1175 |
950d53433f5b
|
return simplejson.dumps(self.AsDict(), sort_keys=True) |
1176 |
950d53433f5b
|
|
1177 |
950d53433f5b
|
def AsDict(self): |
1178 |
950d53433f5b
|
'''A dict representation of this twitter.DirectMessage instance. |
1179 |
950d53433f5b
|
|
1180 |
950d53433f5b
|
The return value uses the same key names as the JSON representation. |
1181 |
950d53433f5b
|
|
1182 |
950d53433f5b
|
Return: |
1183 |
950d53433f5b
|
A dict representing this twitter.DirectMessage instance |
1184 |
950d53433f5b
|
''' |
1185 |
950d53433f5b
|
data = {} |
1186 |
950d53433f5b
|
if self.id: |
1187 |
950d53433f5b
|
data['id'] = self.id |
1188 |
950d53433f5b
|
if self.created_at: |
1189 |
950d53433f5b
|
data['created_at'] = self.created_at |
1190 |
950d53433f5b
|
if self.sender_id: |
1191 |
950d53433f5b
|
data['sender_id'] = self.sender_id |
1192 |
950d53433f5b
|
if self.sender_screen_name: |
1193 |
950d53433f5b
|
data['sender_screen_name'] = self.sender_screen_name |
1194 |
950d53433f5b
|
if self.recipient_id: |
1195 |
950d53433f5b
|
data['recipient_id'] = self.recipient_id |
1196 |
950d53433f5b
|
if self.recipient_screen_name: |
1197 |
950d53433f5b
|
data['recipient_screen_name'] = self.recipient_screen_name |
1198 |
950d53433f5b
|
if self.text: |
1199 |
950d53433f5b
|
data['text'] = self.text |
1200 |
950d53433f5b
|
return data |
1201 |
c42880b017af
|
|
1202 |
c42880b017af
|
@staticmethod |
1203 |
c42880b017af
|
def NewFromJsonDict(data): |
1204 |
c42880b017af
|
'''Create a new instance based on a JSON dict. |
1205 |
c42880b017af
|
|
1206 |
c42880b017af
|
Args: |
1207 |
c42880b017af
|
data: A JSON dict, as converted from the JSON in the twitter API |
1208 |
c42880b017af
|
Returns: |
1209 |
c42880b017af
|
A twitter.DirectMessage instance |
1210 |
c42880b017af
|
''' |
1211 |
c42880b017af
|
return DirectMessage(created_at=data.get('created_at', None), |
1212 |
c42880b017af
|
recipient_id=data.get('recipient_id', None), |
1213 |
c42880b017af
|
sender_id=data.get('sender_id', None), |
1214 |
c42880b017af
|
text=data.get('text', None), |
1215 |
c42880b017af
|
sender_screen_name=data.get('sender_screen_name', None), |
1216 |
c42880b017af
|
id=data.get('id', None), |
1217 |
c42880b017af
|
recipient_screen_name=data.get('recipient_screen_name', None)) |
1218 |
4805aee792f0
|
|
1219 |
4805aee792f0
|
class Api(object): |
1220 |
4805aee792f0
|
'''A python interface into the Twitter API |
1221 |
4805aee792f0
|
|
1222 |
4805aee792f0
|
By default, the Api caches results for 1 minute. |
1223 |
17f566981b41
|
|
1224 |
4805aee792f0
|
Example usage: |
1225 |
4805aee792f0
|
|
1226 |
ee84714ea665
|
To create an instance of the twitter.Api class, with no authentication: |
1227 |
4805aee792f0
|
|
1228 |
e67a0a1b407c
|
>>> import twitter |
1229 |
e67a0a1b407c
|
>>> api = twitter.Api() |
1230 |
4805aee792f0
|
|
1231 |
e67a0a1b407c
|
To fetch the most recently posted public twitter status messages: |
1232 |
4805aee792f0
|
|
1233 |
e67a0a1b407c
|
>>> statuses = api.GetPublicTimeline() |
1234 |
e67a0a1b407c
|
>>> print [s.user.name for s in statuses] |
1235 |
e67a0a1b407c
|
[u'DeWitt', u'Kesuke Miyagi', u'ev', u'Buzz Andersen', u'Biz Stone'] #... |
1236 |
4805aee792f0
|
|
1237 |
3e87a5de4fc0
|
To fetch a single user's public status messages, where "user" is either |
1238 |
3e87a5de4fc0
|
a Twitter "short name" or their user id. |
1239 |
4805aee792f0
|
|
1240 |
3e87a5de4fc0
|
>>> statuses = api.GetUserTimeline(user) |
1241 |
e67a0a1b407c
|
>>> print [s.text for s in statuses] |
1242 |
4805aee792f0
|
|
1243 |
ee84714ea665
|
To use authentication, instantiate the twitter.Api class with a |
1244 |
ee84714ea665
|
username and password: |
1245 |
e67a0a1b407c
|
|
1246 |
ee84714ea665
|
>>> api = twitter.Api(username='twitter user', password='twitter pass') |
1247 |
32a0266e88a8
|
|
1248 |
ee84714ea665
|
To fetch your friends (after being authenticated): |
1249 |
ee84714ea665
|
|
1250 |
ee84714ea665
|
>>> users = api.GetFriends() |
1251 |
e67a0a1b407c
|
>>> print [u.name for u in users] |
1252 |
e67a0a1b407c
|
|
1253 |
ee84714ea665
|
To post a twitter status message (after being authenticated): |
1254 |
17f566981b41
|
|
1255 |
ee84714ea665
|
>>> status = api.PostUpdate('I love python-twitter!') |
1256 |
e67a0a1b407c
|
>>> print status.text |
1257 |
e67a0a1b407c
|
I love python-twitter! |
1258 |
b9effe73b630
|
|
1259 |
b9effe73b630
|
There are many other methods, including: |
1260 |
b9effe73b630
|
|
1261 |
81cef10d2991
|
>>> api.PostUpdates(status) |
1262 |
b9effe73b630
|
>>> api.PostDirectMessage(user, text) |
1263 |
b9effe73b630
|
>>> api.GetUser(user) |
1264 |
b9effe73b630
|
>>> api.GetReplies() |
1265 |
b9effe73b630
|
>>> api.GetUserTimeline(user) |
1266 |
b9effe73b630
|
>>> api.GetStatus(id) |
1267 |
6c1724c3654d
|
>>> api.DestroyStatus(id) |
1268 |
b9effe73b630
|
>>> api.GetFriendsTimeline(user) |
1269 |
b9effe73b630
|
>>> api.GetFriends(user) |
1270 |
b9effe73b630
|
>>> api.GetFollowers() |
1271 |
b9effe73b630
|
>>> api.GetFeatured() |
1272 |
b9effe73b630
|
>>> api.GetDirectMessages() |
1273 |
b9effe73b630
|
>>> api.PostDirectMessage(user, text) |
1274 |
b9effe73b630
|
>>> api.DestroyDirectMessage(id) |
1275 |
b9effe73b630
|
>>> api.DestroyFriendship(user) |
1276 |
b9effe73b630
|
>>> api.CreateFriendship(user) |
1277 |
e2f8ed587060
|
>>> api.GetUserByEmail(email) |
1278 |
4805aee792f0
|
''' |
1279 |
4805aee792f0
|
|
1280 |
17f566981b41
|
DEFAULT_CACHE_TIMEOUT = 60 # cache for 1 minute |
1281 |
4805aee792f0
|
|
1282 |
4805aee792f0
|
_API_REALM = 'Twitter API' |
1283 |
17f566981b41
|
|
1284 |
90cd841771cf
|
def __init__(self, |
1285 |
90cd841771cf
|
username=None, |
1286 |
90cd841771cf
|
password=None, |
1287 |
90cd841771cf
|
input_encoding=None, |
1288 |
90cd841771cf
|
request_headers=None): |
1289 |
ee84714ea665
|
'''Instantiate a new twitter.Api object. |
1290 |
ee84714ea665
|
|
1291 |
ee84714ea665
|
Args: |
1292 |
ee84714ea665
|
username: The username of the twitter account. [optional] |
1293 |
ee84714ea665
|
password: The password for the twitter account. [optional] |
1294 |
90cd841771cf
|
input_encoding: The encoding used to encode input strings. [optional] |
1295 |
90cd841771cf
|
request_header: A dictionary of additional HTTP request headers. [optional] |
1296 |
ee84714ea665
|
''' |
1297 |
4805aee792f0
|
self._cache = _FileCache() |
1298 |
4805aee792f0
|
self._urllib = urllib2 |
1299 |
4805aee792f0
|
self._cache_timeout = Api.DEFAULT_CACHE_TIMEOUT |
1300 |
90cd841771cf
|
self._InitializeRequestHeaders(request_headers) |
1301 |
90cd841771cf
|
self._InitializeUserAgent() |
1302 |
cb10f131e83f
|
self._InitializeDefaultParameters() |
1303 |
4dfd36cb761d
|
self._input_encoding = input_encoding |
1304 |
ee84714ea665
|
self.SetCredentials(username, password) |
1305 |
4805aee792f0
|
|
1306 |
ee84714ea665
|
def GetPublicTimeline(self, since_id=None): |
1307 |
4805aee792f0
|
'''Fetch the sequnce of public twitter.Status message for all users. |
1308 |
4805aee792f0
|
|
1309 |
ee84714ea665
|
Args: |
1310 |
32a0266e88a8
|
since_id: |
1311 |
ee84714ea665
|
Returns only public statuses with an ID greater than (that is, |
1312 |
ee84714ea665
|
more recent than) the specified ID. [Optional] |
1313 |
32a0266e88a8
|
|
1314 |
4805aee792f0
|
Returns: |
1315 |
4805aee792f0
|
An sequence of twitter.Status instances, one for each message |
1316 |
4805aee792f0
|
''' |
1317 |
ee84714ea665
|
parameters = {} |
1318 |
ee84714ea665
|
if since_id: |
1319 |
ee84714ea665
|
parameters['since_id'] = since_id |
1320 |
4805aee792f0
|
url = 'http://twitter.com/statuses/public_timeline.json' |
1321 |
ee84714ea665
|
json = self._FetchUrl(url, parameters=parameters) |
1322 |
4805aee792f0
|
data = simplejson.loads(json) |
1323 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1324 |
4805aee792f0
|
return [Status.NewFromJsonDict(x) for x in data] |
1325 |
4805aee792f0
|
|
1326 |
11710035d0b9
|
def GetFriendsTimeline(self, |
1327 |
11710035d0b9
|
user=None, |
1328 |
11710035d0b9
|
count=None, |
1329 |
11710035d0b9
|
since=None, |
1330 |
11710035d0b9
|
since_id=None): |
1331 |
ee84714ea665
|
'''Fetch the sequence of twitter.Status messages for a user's friends |
1332 |
ee84714ea665
|
|
1333 |
ee84714ea665
|
The twitter.Api instance must be authenticated if the user is private. |
1334 |
ee84714ea665
|
|
1335 |
ee84714ea665
|
Args: |
1336 |
32a0266e88a8
|
user: |
1337 |
ee84714ea665
|
Specifies the ID or screen name of the user for whom to return |
1338 |
32a0266e88a8
|
the friends_timeline. If unspecified, the username and password |
1339 |
11710035d0b9
|
must be set in the twitter.Api instance. [Optional] |
1340 |
11710035d0b9
|
count: |
1341 |
11710035d0b9
|
Specifies the number of statuses to retrieve. May not be |
1342 |
11710035d0b9
|
greater than 200. [Optional] |
1343 |
ee84714ea665
|
since: |
1344 |
ee84714ea665
|
Narrows the returned results to just those statuses created |
1345 |
11710035d0b9
|
after the specified HTTP-formatted date. [Optional] |
1346 |
806829c7dc10
|
since_id: |
1347 |
806829c7dc10
|
Returns only public statuses with an ID greater than (that is, |
1348 |
806829c7dc10
|
more recent than) the specified ID. [Optional] |
1349 |
ee84714ea665
|
|
1350 |
ee84714ea665
|
Returns: |
1351 |
ee84714ea665
|
A sequence of twitter.Status instances, one for each message |
1352 |
ee84714ea665
|
''' |
1353 |
ee84714ea665
|
if user: |
1354 |
ee84714ea665
|
url = 'http://twitter.com/statuses/friends_timeline/%s.json' % user |
1355 |
ee84714ea665
|
elif not user and not self._username: |
1356 |
ee84714ea665
|
raise TwitterError("User must be specified if API is not authenticated.") |
1357 |
32a0266e88a8
|
else: |
1358 |
ee84714ea665
|
url = 'http://twitter.com/statuses/friends_timeline.json' |
1359 |
ee84714ea665
|
parameters = {} |
1360 |
11710035d0b9
|
if count is not None: |
1361 |
11710035d0b9
|
try: |
1362 |
11710035d0b9
|
if int(count) > 200: |
1363 |
11710035d0b9
|
raise TwitterError("'count' may not be greater than 200") |
1364 |
11710035d0b9
|
except ValueError: |
1365 |
11710035d0b9
|
raise TwitterError("'count' must be an integer") |
1366 |
11710035d0b9
|
parameters['count'] = count |
1367 |
ee84714ea665
|
if since: |
1368 |
ee84714ea665
|
parameters['since'] = since |
1369 |
806829c7dc10
|
if since_id: |
1370 |
806829c7dc10
|
parameters['since_id'] = since_id |
1371 |
ee84714ea665
|
json = self._FetchUrl(url, parameters=parameters) |
1372 |
ee84714ea665
|
data = simplejson.loads(json) |
1373 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1374 |
ee84714ea665
|
return [Status.NewFromJsonDict(x) for x in data] |
1375 |
ee84714ea665
|
|
1376 |
806829c7dc10
|
def GetUserTimeline(self, user=None, count=None, since=None, since_id=None): |
1377 |
4805aee792f0
|
'''Fetch the sequence of public twitter.Status messages for a single user. |
1378 |
4805aee792f0
|
|
1379 |
ee84714ea665
|
The twitter.Api instance must be authenticated if the user is private. |
1380 |
ee84714ea665
|
|
1381 |
4805aee792f0
|
Args: |
1382 |
e565d3a31699
|
user: |
1383 |
32a0266e88a8
|
either the username (short_name) or id of the user to retrieve. If |
1384 |
ee84714ea665
|
not specified, then the current authenticated user is used. [optional] |
1385 |
ee84714ea665
|
count: the number of status messages to retrieve [optional] |
1386 |
ee84714ea665
|
since: |
1387 |
ee84714ea665
|
Narrows the returned results to just those statuses created |
1388 |
ee84714ea665
|
after the specified HTTP-formatted date. [optional] |
1389 |
806829c7dc10
|
since_id: |
1390 |
806829c7dc10
|
Returns only public statuses with an ID greater than (that is, |
1391 |
806829c7dc10
|
more recent than) the specified ID. [Optional] |
1392 |
4805aee792f0
|
|
1393 |
4805aee792f0
|
Returns: |
1394 |
4805aee792f0
|
A sequence of twitter.Status instances, one for each message up to count |
1395 |
4805aee792f0
|
''' |
1396 |
4805aee792f0
|
try: |
1397 |
4805aee792f0
|
if count: |
1398 |
4805aee792f0
|
int(count) |
1399 |
4805aee792f0
|
except: |
1400 |
4805aee792f0
|
raise TwitterError("Count must be an integer") |
1401 |
ee84714ea665
|
parameters = {} |
1402 |
4805aee792f0
|
if count: |
1403 |
ee84714ea665
|
parameters['count'] = count |
1404 |
ee84714ea665
|
if since: |
1405 |
ee84714ea665
|
parameters['since'] = since |
1406 |
806829c7dc10
|
if since_id: |
1407 |
806829c7dc10
|
parameters['since_id'] = since_id |
1408 |
ee84714ea665
|
if user: |
1409 |
ee84714ea665
|
url = 'http://twitter.com/statuses/user_timeline/%s.json' % user |
1410 |
ee84714ea665
|
elif not user and not self._username: |
1411 |
ee84714ea665
|
raise TwitterError("User must be specified if API is not authenticated.") |
1412 |
4805aee792f0
|
else: |
1413 |
ee84714ea665
|
url = 'http://twitter.com/statuses/user_timeline.json' |
1414 |
4805aee792f0
|
json = self._FetchUrl(url, parameters=parameters) |
1415 |
4805aee792f0
|
data = simplejson.loads(json) |
1416 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1417 |
4805aee792f0
|
return [Status.NewFromJsonDict(x) for x in data] |
1418 |
32a0266e88a8
|
|
1419 |
ee84714ea665
|
def GetStatus(self, id): |
1420 |
ee84714ea665
|
'''Returns a single status message. |
1421 |
4805aee792f0
|
|
1422 |
ee84714ea665
|
The twitter.Api instance must be authenticated if the status message is private. |
1423 |
4805aee792f0
|
|
1424 |
4805aee792f0
|
Args: |
1425 |
32a0266e88a8
|
id: The numerical ID of the status you're trying to retrieve. |
1426 |
4805aee792f0
|
|
1427 |
4805aee792f0
|
Returns: |
1428 |
ee84714ea665
|
A twitter.Status instance representing that status message |
1429 |
4805aee792f0
|
''' |
1430 |
ee84714ea665
|
try: |
1431 |
ee84714ea665
|
if id: |
1432 |
ee84714ea665
|
int(id) |
1433 |
ee84714ea665
|
except: |
1434 |
ee84714ea665
|
raise TwitterError("id must be an integer") |
1435 |
ee84714ea665
|
url = 'http://twitter.com/statuses/show/%s.json' % id |
1436 |
ee84714ea665
|
json = self._FetchUrl(url) |
1437 |
4805aee792f0
|
data = simplejson.loads(json) |
1438 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1439 |
ee84714ea665
|
return Status.NewFromJsonDict(data) |
1440 |
4805aee792f0
|
|
1441 |
4da5ec4d173a
|
def DestroyStatus(self, id): |
1442 |
4da5ec4d173a
|
'''Destroys the status specified by the required ID parameter. |
1443 |
4da5ec4d173a
|
|
1444 |
4da5ec4d173a
|
The twitter.Api instance must be authenticated and thee |
1445 |
4da5ec4d173a
|
authenticating user must be the author of the specified status. |
1446 |
4da5ec4d173a
|
|
1447 |
4da5ec4d173a
|
Args: |
1448 |
4da5ec4d173a
|
id: The numerical ID of the status you're trying to destroy. |
1449 |
4da5ec4d173a
|
|
1450 |
4da5ec4d173a
|
Returns: |
1451 |
4da5ec4d173a
|
A twitter.Status instance representing the destroyed status message |
1452 |
4da5ec4d173a
|
''' |
1453 |
4da5ec4d173a
|
try: |
1454 |
4da5ec4d173a
|
if id: |
1455 |
4da5ec4d173a
|
int(id) |
1456 |
4da5ec4d173a
|
except: |
1457 |
4da5ec4d173a
|
raise TwitterError("id must be an integer") |
1458 |
4da5ec4d173a
|
url = 'http://twitter.com/statuses/destroy/%s.json' % id |
1459 |
4da5ec4d173a
|
json = self._FetchUrl(url, post_data={}) |
1460 |
4da5ec4d173a
|
data = simplejson.loads(json) |
1461 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1462 |
4da5ec4d173a
|
return Status.NewFromJsonDict(data) |
1463 |
4da5ec4d173a
|
|
1464 |
81cef10d2991
|
def PostUpdate(self, status, in_reply_to_status_id=None): |
1465 |
c42880b017af
|
'''Post a twitter status message from the authenticated user. |
1466 |
ee84714ea665
|
|
1467 |
ee84714ea665
|
The twitter.Api instance must be authenticated. |
1468 |
4805aee792f0
|
|
1469 |
4805aee792f0
|
Args: |
1470 |
81cef10d2991
|
status: |
1471 |
81cef10d2991
|
The message text to be posted. Must be less than or equal to |
1472 |
81cef10d2991
|
140 characters. |
1473 |
71b5f9cae083
|
in_reply_to_status_id: |
1474 |
71b5f9cae083
|
The ID of an existing status that the status to be posted is |
1475 |
71b5f9cae083
|
in reply to. This implicitly sets the in_reply_to_user_id |
1476 |
71b5f9cae083
|
attribute of the resulting status to the user ID of the |
1477 |
71b5f9cae083
|
message being replied to. Invalid/missing status IDs will be |
1478 |
71b5f9cae083
|
ignored. [Optional] |
1479 |
4805aee792f0
|
Returns: |
1480 |
81cef10d2991
|
A twitter.Status instance representing the message posted. |
1481 |
4805aee792f0
|
''' |
1482 |
ee84714ea665
|
if not self._username: |
1483 |
ee84714ea665
|
raise TwitterError("The twitter.Api instance must be authenticated.") |
1484 |
81cef10d2991
|
|
1485 |
c42880b017af
|
url = 'http://twitter.com/statuses/update.json' |
1486 |
81cef10d2991
|
|
1487 |
81cef10d2991
|
if len(status) > CHARACTER_LIMIT: |
1488 |
81cef10d2991
|
raise TwitterError("Text must be less than or equal to %d characters. " |
1489 |
81cef10d2991
|
"Consider using PostUpdates." % CHARACTER_LIMIT) |
1490 |
81cef10d2991
|
|
1491 |
81cef10d2991
|
data = {'status': status} |
1492 |
71b5f9cae083
|
if in_reply_to_status_id: |
1493 |
71b5f9cae083
|
data['in_reply_to_status_id'] = in_reply_to_status_id |
1494 |
79429eb1b54d
|
json = self._FetchUrl(url, post_data=data) |
1495 |
4805aee792f0
|
data = simplejson.loads(json) |
1496 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1497 |
4805aee792f0
|
return Status.NewFromJsonDict(data) |
1498 |
4805aee792f0
|
|
1499 |
8bdda4c8187b
|
def PostUpdates(self, status, continuation=None, **kwargs): |
1500 |
81cef10d2991
|
'''Post one or more twitter status messages from the authenticated user. |
1501 |
81cef10d2991
|
|
1502 |
81cef10d2991
|
Unlike api.PostUpdate, this method will post multiple status updates |
1503 |
81cef10d2991
|
if the message is longer than 140 characters. |
1504 |
81cef10d2991
|
|
1505 |
81cef10d2991
|
The twitter.Api instance must be authenticated. |
1506 |
81cef10d2991
|
|
1507 |
81cef10d2991
|
Args: |
1508 |
81cef10d2991
|
status: |
1509 |
81cef10d2991
|
The message text to be posted. May be longer than 140 characters. |
1510 |
8bdda4c8187b
|
continuation: |
1511 |
8bdda4c8187b
|
The character string, if any, to be appended to all but the |
1512 |
8bdda4c8187b
|
last message. Note that Twitter strips trailing '...' strings |
1513 |
8bdda4c8187b
|
from messages. Consider using the unicode \u2026 character |
1514 |
8bdda4c8187b
|
(horizontal ellipsis) instead. [Defaults to None] |
1515 |
81cef10d2991
|
**kwargs: |
1516 |
81cef10d2991
|
See api.PostUpdate for a list of accepted parameters. |
1517 |
81cef10d2991
|
Returns: |
1518 |
81cef10d2991
|
A of list twitter.Status instance representing the messages posted. |
1519 |
81cef10d2991
|
''' |
1520 |
81cef10d2991
|
results = list() |
1521 |
8bdda4c8187b
|
if continuation is None: |
1522 |
8bdda4c8187b
|
continuation = '' |
1523 |
8bdda4c8187b
|
line_length = CHARACTER_LIMIT - len(continuation) |
1524 |
8bdda4c8187b
|
lines = textwrap.wrap(status, line_length) |
1525 |
8bdda4c8187b
|
for line in lines[0:-1]: |
1526 |
8bdda4c8187b
|
results.append(self.PostUpdate(line + continuation, **kwargs)) |
1527 |
8bdda4c8187b
|
results.append(self.PostUpdate(lines[-1], **kwargs)) |
1528 |
81cef10d2991
|
return results |
1529 |
81cef10d2991
|
|
1530 |
935cf080b638
|
def GetReplies(self, since=None, since_id=None, page=None): |
1531 |
ee84714ea665
|
'''Get a sequence of status messages representing the 20 most recent |
1532 |
ee84714ea665
|
replies (status updates prefixed with @username) to the authenticating |
1533 |
ee84714ea665
|
user. |
1534 |
71b5f9cae083
|
|
1535 |
a10f9a46dc3d
|
Args: |
1536 |
935cf080b638
|
page: |
1537 |
a10f9a46dc3d
|
since: |
1538 |
a10f9a46dc3d
|
Narrows the returned results to just those statuses created |
1539 |
a10f9a46dc3d
|
after the specified HTTP-formatted date. [optional] |
1540 |
a10f9a46dc3d
|
since_id: |
1541 |
a10f9a46dc3d
|
Returns only public statuses with an ID greater than (that is, |
1542 |
a10f9a46dc3d
|
more recent than) the specified ID. [Optional] |
1543 |
ee84714ea665
|
|
1544 |
ee84714ea665
|
Returns: |
1545 |
ee84714ea665
|
A sequence of twitter.Status instances, one for each reply to the user. |
1546 |
32a0266e88a8
|
''' |
1547 |
ee84714ea665
|
url = 'http://twitter.com/statuses/replies.json' |
1548 |
ee84714ea665
|
if not self._username: |
1549 |
ee84714ea665
|
raise TwitterError("The twitter.Api instance must be authenticated.") |
1550 |
a10f9a46dc3d
|
parameters = {} |
1551 |
a10f9a46dc3d
|
if since: |
1552 |
a10f9a46dc3d
|
parameters['since'] = since |
1553 |
a10f9a46dc3d
|
if since_id: |
1554 |
a10f9a46dc3d
|
parameters['since_id'] = since_id |
1555 |
935cf080b638
|
if page: |
1556 |
935cf080b638
|
parameters['page'] = page |
1557 |
a10f9a46dc3d
|
json = self._FetchUrl(url, parameters=parameters) |
1558 |
ee84714ea665
|
data = simplejson.loads(json) |
1559 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1560 |
ee84714ea665
|
return [Status.NewFromJsonDict(x) for x in data] |
1561 |
ee84714ea665
|
|
1562 |
82aae45f64f2
|
def GetMentions(self, since_id=None, max_id=None, count=None, page=None): |
1563 |
82aae45f64f2
|
'''Returns a list of mentions of the authenticating user. |
1564 |
82aae45f64f2
|
|
1565 |
82aae45f64f2
|
The twitter.Api instance must be authenticated. |
1566 |
82aae45f64f2
|
|
1567 |
82aae45f64f2
|
Args: |
1568 |
82aae45f64f2
|
since_id: |
1569 |
82aae45f64f2
|
Returns only public statuses with an ID greater than (that is, |
1570 |
82aae45f64f2
|
more recent than) the specified ID. [Optional] |
1571 |
82aae45f64f2
|
max_id: |
1572 |
82aae45f64f2
|
Optional. Returns only statuses with an ID less than (that is, older than) |
1573 |
82aae45f64f2
|
or equal to the specified ID. |
1574 |
82aae45f64f2
|
count: |
1575 |
82aae45f64f2
|
Optional. Specifies the number of statuses to retrieve. May not be greater |
1576 |
82aae45f64f2
|
than 200. |
1577 |
82aae45f64f2
|
|
1578 |
82aae45f64f2
|
Returns: |
1579 |
82aae45f64f2
|
A sequence of twitter.Status instances |
1580 |
82aae45f64f2
|
''' |
1581 |
82aae45f64f2
|
url = 'http://twitter.com/statuses/mentions.json' |
1582 |
82aae45f64f2
|
if not self._username: |
1583 |
82aae45f64f2
|
raise TwitterError("The twitter.Api instance must be authenticated.") |
1584 |
82aae45f64f2
|
parameters = {} |
1585 |
82aae45f64f2
|
if since_id: |
1586 |
82aae45f64f2
|
parameters['since_id'] = since_id |
1587 |
82aae45f64f2
|
if max_id: |
1588 |
82aae45f64f2
|
parameters['max_id'] = max_id |
1589 |
82aae45f64f2
|
if count: |
1590 |
82aae45f64f2
|
parameters['count'] = count |
1591 |
82aae45f64f2
|
if page: |
1592 |
82aae45f64f2
|
parameters['page'] = page |
1593 |
82aae45f64f2
|
json = self._FetchUrl(url, parameters=parameters) |
1594 |
82aae45f64f2
|
data = simplejson.loads(json) |
1595 |
82aae45f64f2
|
self._CheckForTwitterError(data) |
1596 |
82aae45f64f2
|
return [Status.NewFromJsonDict(x) for x in data] |
1597 |
82aae45f64f2
|
|
1598 |
935cf080b638
|
def GetFriends(self, user=None, page=None): |
1599 |
ee84714ea665
|
'''Fetch the sequence of twitter.User instances, one for each friend. |
1600 |
ee84714ea665
|
|
1601 |
ee84714ea665
|
Args: |
1602 |
ee84714ea665
|
user: the username or id of the user whose friends you are fetching. If |
1603 |
ee84714ea665
|
not specified, defaults to the authenticated user. [optional] |
1604 |
ee84714ea665
|
|
1605 |
ee84714ea665
|
The twitter.Api instance must be authenticated. |
1606 |
ee84714ea665
|
|
1607 |
ee84714ea665
|
Returns: |
1608 |
ee84714ea665
|
A sequence of twitter.User instances, one for each friend |
1609 |
ee84714ea665
|
''' |
1610 |
ee84714ea665
|
if not self._username: |
1611 |
ee84714ea665
|
raise TwitterError("twitter.Api instance must be authenticated") |
1612 |
ee84714ea665
|
if user: |
1613 |
935cf080b638
|
url = 'http://twitter.com/statuses/friends/%s.json' % user |
1614 |
32a0266e88a8
|
else: |
1615 |
ee84714ea665
|
url = 'http://twitter.com/statuses/friends.json' |
1616 |
935cf080b638
|
parameters = {} |
1617 |
935cf080b638
|
if page: |
1618 |
935cf080b638
|
parameters['page'] = page |
1619 |
935cf080b638
|
json = self._FetchUrl(url, parameters=parameters) |
1620 |
ee84714ea665
|
data = simplejson.loads(json) |
1621 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1622 |
ee84714ea665
|
return [User.NewFromJsonDict(x) for x in data] |
1623 |
ee84714ea665
|
|
1624 |
935cf080b638
|
def GetFollowers(self, page=None): |
1625 |
ee84714ea665
|
'''Fetch the sequence of twitter.User instances, one for each follower |
1626 |
ee84714ea665
|
|
1627 |
ee84714ea665
|
The twitter.Api instance must be authenticated. |
1628 |
ee84714ea665
|
|
1629 |
ee84714ea665
|
Returns: |
1630 |
ee84714ea665
|
A sequence of twitter.User instances, one for each follower |
1631 |
ee84714ea665
|
''' |
1632 |
ee84714ea665
|
if not self._username: |
1633 |
ee84714ea665
|
raise TwitterError("twitter.Api instance must be authenticated") |
1634 |
ee84714ea665
|
url = 'http://twitter.com/statuses/followers.json' |
1635 |
935cf080b638
|
parameters = {} |
1636 |
935cf080b638
|
if page: |
1637 |
935cf080b638
|
parameters['page'] = page |
1638 |
935cf080b638
|
json = self._FetchUrl(url, parameters=parameters) |
1639 |
ee84714ea665
|
data = simplejson.loads(json) |
1640 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1641 |
ee84714ea665
|
return [User.NewFromJsonDict(x) for x in data] |
1642 |
ee84714ea665
|
|
1643 |
e3638dafb13c
|
def GetFeatured(self): |
1644 |
e3638dafb13c
|
'''Fetch the sequence of twitter.User instances featured on twitter.com |
1645 |
e3638dafb13c
|
|
1646 |
e3638dafb13c
|
The twitter.Api instance must be authenticated. |
1647 |
e3638dafb13c
|
|
1648 |
e3638dafb13c
|
Returns: |
1649 |
e3638dafb13c
|
A sequence of twitter.User instances |
1650 |
e3638dafb13c
|
''' |
1651 |
e3638dafb13c
|
url = 'http://twitter.com/statuses/featured.json' |
1652 |
e3638dafb13c
|
json = self._FetchUrl(url) |
1653 |
e3638dafb13c
|
data = simplejson.loads(json) |
1654 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1655 |
e3638dafb13c
|
return [User.NewFromJsonDict(x) for x in data] |
1656 |
e3638dafb13c
|
|
1657 |
ee84714ea665
|
def GetUser(self, user): |
1658 |
ee84714ea665
|
'''Returns a single user. |
1659 |
ee84714ea665
|
|
1660 |
ee84714ea665
|
The twitter.Api instance must be authenticated. |
1661 |
ee84714ea665
|
|
1662 |
ee84714ea665
|
Args: |
1663 |
ee84714ea665
|
user: The username or id of the user to retrieve. |
1664 |
ee84714ea665
|
|
1665 |
ee84714ea665
|
Returns: |
1666 |
ee84714ea665
|
A twitter.User instance representing that user |
1667 |
ee84714ea665
|
''' |
1668 |
ee84714ea665
|
url = 'http://twitter.com/users/show/%s.json' % user |
1669 |
ee84714ea665
|
json = self._FetchUrl(url) |
1670 |
ee84714ea665
|
data = simplejson.loads(json) |
1671 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1672 |
ee84714ea665
|
return User.NewFromJsonDict(data) |
1673 |
82aae45f64f2
|
|
1674 |
935cf080b638
|
def GetDirectMessages(self, since=None, since_id=None, page=None): |
1675 |
90377483d9fa
|
'''Returns a list of the direct messages sent to the authenticating user. |
1676 |
90377483d9fa
|
|
1677 |
90377483d9fa
|
The twitter.Api instance must be authenticated. |
1678 |
90377483d9fa
|
|
1679 |
32a0266e88a8
|
Args: |
1680 |
90377483d9fa
|
since: |
1681 |
90377483d9fa
|
Narrows the returned results to just those statuses created |
1682 |
90377483d9fa
|
after the specified HTTP-formatted date. [optional] |
1683 |
472ef0f2ea07
|
since_id: |
1684 |
472ef0f2ea07
|
Returns only public statuses with an ID greater than (that is, |
1685 |
472ef0f2ea07
|
more recent than) the specified ID. [Optional] |
1686 |
90377483d9fa
|
|
1687 |
90377483d9fa
|
Returns: |
1688 |
32a0266e88a8
|
A sequence of twitter.DirectMessage instances |
1689 |
90377483d9fa
|
''' |
1690 |
90377483d9fa
|
url = 'http://twitter.com/direct_messages.json' |
1691 |
90377483d9fa
|
if not self._username: |
1692 |
90377483d9fa
|
raise TwitterError("The twitter.Api instance must be authenticated.") |
1693 |
90377483d9fa
|
parameters = {} |
1694 |
90377483d9fa
|
if since: |
1695 |
90377483d9fa
|
parameters['since'] = since |
1696 |
472ef0f2ea07
|
if since_id: |
1697 |
472ef0f2ea07
|
parameters['since_id'] = since_id |
1698 |
935cf080b638
|
if page: |
1699 |
935cf080b638
|
parameters['page'] = page |
1700 |
90377483d9fa
|
json = self._FetchUrl(url, parameters=parameters) |
1701 |
90377483d9fa
|
data = simplejson.loads(json) |
1702 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1703 |
c42880b017af
|
return [DirectMessage.NewFromJsonDict(x) for x in data] |
1704 |
32a0266e88a8
|
|
1705 |
c42880b017af
|
def PostDirectMessage(self, user, text): |
1706 |
c42880b017af
|
'''Post a twitter direct message from the authenticated user |
1707 |
c42880b017af
|
|
1708 |
c42880b017af
|
The twitter.Api instance must be authenticated. |
1709 |
c42880b017af
|
|
1710 |
c42880b017af
|
Args: |
1711 |
c42880b017af
|
user: The ID or screen name of the recipient user. |
1712 |
c42880b017af
|
text: The message text to be posted. Must be less than 140 characters. |
1713 |
c42880b017af
|
|
1714 |
c42880b017af
|
Returns: |
1715 |
32a0266e88a8
|
A twitter.DirectMessage instance representing the message posted |
1716 |
c42880b017af
|
''' |
1717 |
c42880b017af
|
if not self._username: |
1718 |
c42880b017af
|
raise TwitterError("The twitter.Api instance must be authenticated.") |
1719 |
c42880b017af
|
url = 'http://twitter.com/direct_messages/new.json' |
1720 |
c42880b017af
|
data = {'text': text, 'user': user} |
1721 |
79429eb1b54d
|
json = self._FetchUrl(url, post_data=data) |
1722 |
32a0266e88a8
|
data = simplejson.loads(json) |
1723 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1724 |
32a0266e88a8
|
return DirectMessage.NewFromJsonDict(data) |
1725 |
32a0266e88a8
|
|
1726 |
32a0266e88a8
|
def DestroyDirectMessage(self, id): |
1727 |
32a0266e88a8
|
'''Destroys the direct message specified in the required ID parameter. |
1728 |
32a0266e88a8
|
|
1729 |
32a0266e88a8
|
The twitter.Api instance must be authenticated, and the |
1730 |
32a0266e88a8
|
authenticating user must be the recipient of the specified direct |
1731 |
32a0266e88a8
|
message. |
1732 |
32a0266e88a8
|
|
1733 |
32a0266e88a8
|
Args: |
1734 |
32a0266e88a8
|
id: The id of the direct message to be destroyed |
1735 |
32a0266e88a8
|
|
1736 |
32a0266e88a8
|
Returns: |
1737 |
32a0266e88a8
|
A twitter.DirectMessage instance representing the message destroyed |
1738 |
32a0266e88a8
|
''' |
1739 |
32a0266e88a8
|
url = 'http://twitter.com/direct_messages/destroy/%s.json' % id |
1740 |
79429eb1b54d
|
json = self._FetchUrl(url, post_data={}) |
1741 |
c42880b017af
|
data = simplejson.loads(json) |
1742 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1743 |
c42880b017af
|
return DirectMessage.NewFromJsonDict(data) |
1744 |
90377483d9fa
|
|
1745 |
79429eb1b54d
|
def CreateFriendship(self, user): |
1746 |
79429eb1b54d
|
'''Befriends the user specified in the user parameter as the authenticating user. |
1747 |
79429eb1b54d
|
|
1748 |
79429eb1b54d
|
The twitter.Api instance must be authenticated. |
1749 |
79429eb1b54d
|
|
1750 |
79429eb1b54d
|
Args: |
1751 |
79429eb1b54d
|
The ID or screen name of the user to befriend. |
1752 |
79429eb1b54d
|
Returns: |
1753 |
79429eb1b54d
|
A twitter.User instance representing the befriended user. |
1754 |
79429eb1b54d
|
''' |
1755 |
79429eb1b54d
|
url = 'http://twitter.com/friendships/create/%s.json' % user |
1756 |
79429eb1b54d
|
json = self._FetchUrl(url, post_data={}) |
1757 |
79429eb1b54d
|
data = simplejson.loads(json) |
1758 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1759 |
79429eb1b54d
|
return User.NewFromJsonDict(data) |
1760 |
79429eb1b54d
|
|
1761 |
79429eb1b54d
|
def DestroyFriendship(self, user): |
1762 |
79429eb1b54d
|
'''Discontinues friendship with the user specified in the user parameter. |
1763 |
79429eb1b54d
|
|
1764 |
79429eb1b54d
|
The twitter.Api instance must be authenticated. |
1765 |
79429eb1b54d
|
|
1766 |
79429eb1b54d
|
Args: |
1767 |
79429eb1b54d
|
The ID or screen name of the user with whom to discontinue friendship. |
1768 |
79429eb1b54d
|
Returns: |
1769 |
79429eb1b54d
|
A twitter.User instance representing the discontinued friend. |
1770 |
79429eb1b54d
|
''' |
1771 |
79429eb1b54d
|
url = 'http://twitter.com/friendships/destroy/%s.json' % user |
1772 |
79429eb1b54d
|
json = self._FetchUrl(url, post_data={}) |
1773 |
79429eb1b54d
|
data = simplejson.loads(json) |
1774 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1775 |
79429eb1b54d
|
return User.NewFromJsonDict(data) |
1776 |
79429eb1b54d
|
|
1777 |
a1e65b8c9435
|
def CreateFavorite(self, status): |
1778 |
a1e65b8c9435
|
'''Favorites the status specified in the status parameter as the authenticating user. |
1779 |
a1e65b8c9435
|
Returns the favorite status when successful. |
1780 |
a1e65b8c9435
|
|
1781 |
a1e65b8c9435
|
The twitter.Api instance must be authenticated. |
1782 |
a1e65b8c9435
|
|
1783 |
a1e65b8c9435
|
Args: |
1784 |
a1e65b8c9435
|
The twitter.Status instance to mark as a favorite. |
1785 |
a1e65b8c9435
|
Returns: |
1786 |
a1e65b8c9435
|
A twitter.Status instance representing the newly-marked favorite. |
1787 |
a1e65b8c9435
|
''' |
1788 |
a1e65b8c9435
|
url = 'http://twitter.com/favorites/create/%s.json' % status.id |
1789 |
a1e65b8c9435
|
json = self._FetchUrl(url, post_data={}) |
1790 |
a1e65b8c9435
|
data = simplejson.loads(json) |
1791 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1792 |
a1e65b8c9435
|
return Status.NewFromJsonDict(data) |
1793 |
a1e65b8c9435
|
|
1794 |
a1e65b8c9435
|
def DestroyFavorite(self, status): |
1795 |
a1e65b8c9435
|
'''Un-favorites the status specified in the ID parameter as the authenticating user. |
1796 |
a1e65b8c9435
|
Returns the un-favorited status in the requested format when successful. |
1797 |
a1e65b8c9435
|
|
1798 |
a1e65b8c9435
|
The twitter.Api instance must be authenticated. |
1799 |
a1e65b8c9435
|
|
1800 |
a1e65b8c9435
|
Args: |
1801 |
a1e65b8c9435
|
The twitter.Status to unmark as a favorite. |
1802 |
a1e65b8c9435
|
Returns: |
1803 |
a1e65b8c9435
|
A twitter.Status instance representing the newly-unmarked favorite. |
1804 |
a1e65b8c9435
|
''' |
1805 |
a1e65b8c9435
|
url = 'http://twitter.com/favorites/destroy/%s.json' % status.id |
1806 |
a1e65b8c9435
|
json = self._FetchUrl(url, post_data={}) |
1807 |
a1e65b8c9435
|
data = simplejson.loads(json) |
1808 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1809 |
a1e65b8c9435
|
return Status.NewFromJsonDict(data) |
1810 |
a1e65b8c9435
|
|
1811 |
e2f8ed587060
|
def GetUserByEmail(self, email): |
1812 |
e2f8ed587060
|
'''Returns a single user by email address. |
1813 |
e2f8ed587060
|
|
1814 |
e2f8ed587060
|
Args: |
1815 |
e2f8ed587060
|
email: The email of the user to retrieve. |
1816 |
e2f8ed587060
|
Returns: |
1817 |
e2f8ed587060
|
A twitter.User instance representing that user |
1818 |
e2f8ed587060
|
''' |
1819 |
e2f8ed587060
|
url = 'http://twitter.com/users/show.json?email=%s' % email |
1820 |
e2f8ed587060
|
json = self._FetchUrl(url) |
1821 |
e2f8ed587060
|
data = simplejson.loads(json) |
1822 |
265fcf2a1e01
|
self._CheckForTwitterError(data) |
1823 |
e2f8ed587060
|
return User.NewFromJsonDict(data) |
1824 |
e2f8ed587060
|
|
1825 |
ee84714ea665
|
def SetCredentials(self, username, password): |
1826 |
ee84714ea665
|
'''Set the username and password for this instance |
1827 |
ee84714ea665
|
|
1828 |
ee84714ea665
|
Args: |
1829 |
ee84714ea665
|
username: The twitter username. |
1830 |
ee84714ea665
|
password: The twitter password. |
1831 |
ee84714ea665
|
''' |
1832 |
ee84714ea665
|
self._username = username |
1833 |
ee84714ea665
|
self._password = password |
1834 |
ee84714ea665
|
|
1835 |
ee84714ea665
|
def ClearCredentials(self): |
1836 |
ee84714ea665
|
'''Clear the username and password for this instance |
1837 |
ee84714ea665
|
''' |
1838 |
ee84714ea665
|
self._username = None |
1839 |
ee84714ea665
|
self._password = None |
1840 |
4805aee792f0
|
|
1841 |
4805aee792f0
|
def SetCache(self, cache): |
1842 |
4805aee792f0
|
'''Override the default cache. Set to None to prevent caching. |
1843 |
4805aee792f0
|
|
1844 |
4805aee792f0
|
Args: |
1845 |
4805aee792f0
|
cache: an instance that supports the same API as the twitter._FileCache |
1846 |
4805aee792f0
|
''' |
1847 |
4805aee792f0
|
self._cache = cache |
1848 |
4805aee792f0
|
|
1849 |
4805aee792f0
|
def SetUrllib(self, urllib): |
1850 |
4805aee792f0
|
'''Override the default urllib implementation. |
1851 |
4805aee792f0
|
|
1852 |
4805aee792f0
|
Args: |
1853 |
4805aee792f0
|
urllib: an instance that supports the same API as the urllib2 module |
1854 |
4805aee792f0
|
''' |
1855 |
4805aee792f0
|
self._urllib = urllib |
1856 |
4805aee792f0
|
|
1857 |
4805aee792f0
|
def SetCacheTimeout(self, cache_timeout): |
1858 |
4805aee792f0
|
'''Override the default cache timeout. |
1859 |
4805aee792f0
|
|
1860 |
4805aee792f0
|
Args: |
1861 |
4805aee792f0
|
cache_timeout: time, in seconds, that responses should be reused. |
1862 |
4805aee792f0
|
''' |
1863 |
4805aee792f0
|
self._cache_timeout = cache_timeout |
1864 |
4805aee792f0
|
|
1865 |
4805aee792f0
|
def SetUserAgent(self, user_agent): |
1866 |
4805aee792f0
|
'''Override the default user agent |
1867 |
4805aee792f0
|
|
1868 |
4805aee792f0
|
Args: |
1869 |
4805aee792f0
|
user_agent: a string that should be send to the server as the User-agent |
1870 |
4805aee792f0
|
''' |
1871 |
90cd841771cf
|
self._request_headers['User-Agent'] = user_agent |
1872 |
90cd841771cf
|
|
1873 |
90cd841771cf
|
def SetXTwitterHeaders(self, client, url, version): |
1874 |
90cd841771cf
|
'''Set the X-Twitter HTTP headers that will be sent to the server. |
1875 |
90cd841771cf
|
|
1876 |
90cd841771cf
|
Args: |
1877 |
90cd841771cf
|
client: |
1878 |
90cd841771cf
|
The client name as a string. Will be sent to the server as |
1879 |
90cd841771cf
|
the 'X-Twitter-Client' header. |
1880 |
90cd841771cf
|
url: |
1881 |
90cd841771cf
|
The URL of the meta.xml as a string. Will be sent to the server |
1882 |
90cd841771cf
|
as the 'X-Twitter-Client-URL' header. |
1883 |
90cd841771cf
|
version: |
1884 |
90cd841771cf
|
The client version as a string. Will be sent to the server |
1885 |
90cd841771cf
|
as the 'X-Twitter-Client-Version' header. |
1886 |
90cd841771cf
|
''' |
1887 |
90cd841771cf
|
self._request_headers['X-Twitter-Client'] = client |
1888 |
90cd841771cf
|
self._request_headers['X-Twitter-Client-URL'] = url |
1889 |
90cd841771cf
|
self._request_headers['X-Twitter-Client-Version'] = version |
1890 |
4805aee792f0
|
|
1891 |
cb10f131e83f
|
def SetSource(self, source): |
1892 |
cb10f131e83f
|
'''Suggest the "from source" value to be displayed on the Twitter web site. |
1893 |
cb10f131e83f
|
|
1894 |
cb10f131e83f
|
The value of the 'source' parameter must be first recognized by |
1895 |
cb10f131e83f
|
the Twitter server. New source values are authorized on a case by |
1896 |
cb10f131e83f
|
case basis by the Twitter development team. |
1897 |
cb10f131e83f
|
|
1898 |
cb10f131e83f
|
Args: |
1899 |
cb10f131e83f
|
source: |
1900 |
cb10f131e83f
|
The source name as a string. Will be sent to the server as |
1901 |
cb10f131e83f
|
the 'source' parameter. |
1902 |
cb10f131e83f
|
''' |
1903 |
cb10f131e83f
|
self._default_params['source'] = source |
1904 |
cb10f131e83f
|
|
1905 |
4805aee792f0
|
def _BuildUrl(self, url, path_elements=None, extra_params=None): |
1906 |
4805aee792f0
|
# Break url into consituent parts |
1907 |
4805aee792f0
|
(scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url) |
1908 |
17f566981b41
|
|
1909 |
4805aee792f0
|
# Add any additional path elements to the path |
1910 |
4805aee792f0
|
if path_elements: |
1911 |
4805aee792f0
|
# Filter out the path elements that have a value of None |
1912 |
4805aee792f0
|
p = [i for i in path_elements if i] |
1913 |
4805aee792f0
|
if not path.endswith('/'): |
1914 |
4805aee792f0
|
path += '/' |
1915 |
4805aee792f0
|
path += '/'.join(p) |
1916 |
17f566981b41
|
|
1917 |
4805aee792f0
|
# Add any additional query parameters to the query string |
1918 |
4805aee792f0
|
if extra_params and len(extra_params) > 0: |
1919 |
32a0266e88a8
|
extra_query = self._EncodeParameters(extra_params) |
1920 |
b0bbd9fa96ce
|
# Add it to the existing query |
1921 |
b0bbd9fa96ce
|
if query: |
1922 |
b0bbd9fa96ce
|
query += '&' + extra_query |
1923 |
b0bbd9fa96ce
|
else: |
1924 |
b0bbd9fa96ce
|
query = extra_query |
1925 |
17f566981b41
|
|
1926 |
4805aee792f0
|
# Return the rebuilt URL |
1927 |
4805aee792f0
|
return urlparse.urlunparse((scheme, netloc, path, params, query, fragment)) |
1928 |
4805aee792f0
|
|
1929 |
90cd841771cf
|
def _InitializeRequestHeaders(self, request_headers): |
1930 |
90cd841771cf
|
if request_headers: |
1931 |
90cd841771cf
|
self._request_headers = request_headers |
1932 |
90cd841771cf
|
else: |
1933 |
90cd841771cf
|
self._request_headers = {} |
1934 |
90cd841771cf
|
|
1935 |
90cd841771cf
|
def _InitializeUserAgent(self): |
1936 |
90cd841771cf
|
user_agent = 'Python-urllib/%s (python-twitter/%s)' % \ |
1937 |
0ef37898cd2b
|
(self._urllib.__version__, __version__) |
1938 |
90cd841771cf
|
self.SetUserAgent(user_agent) |
1939 |
90cd841771cf
|
|
1940 |
cb10f131e83f
|
def _InitializeDefaultParameters(self): |
1941 |
cb10f131e83f
|
self._default_params = {} |
1942 |
cb10f131e83f
|
|
1943 |
f73c99cf9b51
|
def _AddAuthorizationHeader(self, username, password): |
1944 |
f73c99cf9b51
|
if username and password: |
1945 |
f73c99cf9b51
|
basic_auth = base64.encodestring('%s:%s' % (username, password))[:-1] |
1946 |
f73c99cf9b51
|
self._request_headers['Authorization'] = 'Basic %s' % basic_auth |
1947 |
f73c99cf9b51
|
|
1948 |
f73c99cf9b51
|
def _RemoveAuthorizationHeader(self): |
1949 |
f73c99cf9b51
|
if self._request_headers and 'Authorization' in self._request_headers: |
1950 |
f73c99cf9b51
|
del self._request_headers['Authorization'] |
1951 |
f73c99cf9b51
|
|
1952 |
4805aee792f0
|
def _GetOpener(self, url, username=None, password=None): |
1953 |
4805aee792f0
|
if username and password: |
1954 |
f73c99cf9b51
|
self._AddAuthorizationHeader(username, password) |
1955 |
4805aee792f0
|
handler = self._urllib.HTTPBasicAuthHandler() |
1956 |
4805aee792f0
|
(scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url) |
1957 |
4805aee792f0
|
handler.add_password(Api._API_REALM, netloc, username, password) |
1958 |
4805aee792f0
|
opener = self._urllib.build_opener(handler) |
1959 |
4805aee792f0
|
else: |
1960 |
4805aee792f0
|
opener = self._urllib.build_opener() |
1961 |
90cd841771cf
|
opener.addheaders = self._request_headers.items() |
1962 |
4805aee792f0
|
return opener |
1963 |
4805aee792f0
|
|
1964 |
4dfd36cb761d
|
def _Encode(self, s): |
1965 |
4dfd36cb761d
|
if self._input_encoding: |
1966 |
4dfd36cb761d
|
return unicode(s, self._input_encoding).encode('utf-8') |
1967 |
4dfd36cb761d
|
else: |
1968 |
4dfd36cb761d
|
return unicode(s).encode('utf-8') |
1969 |
4dfd36cb761d
|
|
1970 |
32a0266e88a8
|
def _EncodeParameters(self, parameters): |
1971 |
32a0266e88a8
|
'''Return a string in key=value&key=value form |
1972 |
32a0266e88a8
|
|
1973 |
32a0266e88a8
|
Values of None are not included in the output string. |
1974 |
32a0266e88a8
|
|
1975 |
32a0266e88a8
|
Args: |
1976 |
32a0266e88a8
|
parameters: |
1977 |
32a0266e88a8
|
A dict of (key, value) tuples, where value is encoded as |
1978 |
32a0266e88a8
|
specified by self._encoding |
1979 |
32a0266e88a8
|
Returns: |
1980 |
32a0266e88a8
|
A URL-encoded string in "key=value&key=value" form |
1981 |
32a0266e88a8
|
''' |
1982 |
32a0266e88a8
|
if parameters is None: |
1983 |
32a0266e88a8
|
return None |
1984 |
32a0266e88a8
|
else: |
1985 |
4dfd36cb761d
|
return urllib.urlencode(dict([(k, self._Encode(v)) for k, v in parameters.items() if v is not None])) |
1986 |
32a0266e88a8
|
|
1987 |
32a0266e88a8
|
def _EncodePostData(self, post_data): |
1988 |
32a0266e88a8
|
'''Return a string in key=value&key=value form |
1989 |
32a0266e88a8
|
|
1990 |
32a0266e88a8
|
Values are assumed to be encoded in the format specified by self._encoding, |
1991 |
32a0266e88a8
|
and are subsequently URL encoded. |
1992 |
32a0266e88a8
|
|
1993 |
32a0266e88a8
|
Args: |
1994 |
32a0266e88a8
|
post_data: |
1995 |
32a0266e88a8
|
A dict of (key, value) tuples, where value is encoded as |
1996 |
32a0266e88a8
|
specified by self._encoding |
1997 |
32a0266e88a8
|
Returns: |
1998 |
32a0266e88a8
|
A URL-encoded string in "key=value&key=value" form |
1999 |
32a0266e88a8
|
''' |
2000 |
32a0266e88a8
|
if post_data is None: |
2001 |
32a0266e88a8
|
return None |
2002 |
32a0266e88a8
|
else: |
2003 |
4dfd36cb761d
|
return urllib.urlencode(dict([(k, self._Encode(v)) for k, v in post_data.items()])) |
2004 |
32a0266e88a8
|
|
2005 |
265fcf2a1e01
|
def _CheckForTwitterError(self, data): |
2006 |
265fcf2a1e01
|
"""Raises a TwitterError if twitter returns an error message. |
2007 |
265fcf2a1e01
|
|
2008 |
265fcf2a1e01
|
Args: |
2009 |
265fcf2a1e01
|
data: A python dict created from the Twitter json response |
2010 |
265fcf2a1e01
|
Raises: |
2011 |
265fcf2a1e01
|
TwitterError wrapping the twitter error message if one exists. |
2012 |
265fcf2a1e01
|
""" |
2013 |
265fcf2a1e01
|
# Twitter errors are relatively unlikely, so it is faster |
2014 |
265fcf2a1e01
|
# to check first, rather than try and catch the exception |
2015 |
265fcf2a1e01
|
if 'error' in data: |
2016 |
265fcf2a1e01
|
raise TwitterError(data['error']) |
2017 |
265fcf2a1e01
|
|
2018 |
4805aee792f0
|
def _FetchUrl(self, |
2019 |
4805aee792f0
|
url, |
2020 |
32a0266e88a8
|
post_data=None, |
2021 |
4805aee792f0
|
parameters=None, |
2022 |
4805aee792f0
|
no_cache=None): |
2023 |
ed04d2ff26fc
|
'''Fetch a URL, optionally caching for a specified time. |
2024 |
4805aee792f0
|
|
2025 |
4805aee792f0
|
Args: |
2026 |
4805aee792f0
|
url: The URL to retrieve |
2027 |
b02aa8558d4f
|
post_data: |
2028 |
b02aa8558d4f
|
A dict of (str, unicode) key/value pairs. If set, POST will be used. |
2029 |
b02aa8558d4f
|
parameters: |
2030 |
b02aa8558d4f
|
A dict whose key/value pairs should encoded and added |
2031 |
b02aa8558d4f
|
to the query string. [OPTIONAL] |
2032 |
4805aee792f0
|
no_cache: If true, overrides the cache on the current request |
2033 |
4805aee792f0
|
|
2034 |
4805aee792f0
|
Returns: |
2035 |
4805aee792f0
|
A string containing the body of the response. |
2036 |
ed04d2ff26fc
|
''' |
2037 |
cb10f131e83f
|
# Build the extra parameters dict |
2038 |
cb10f131e83f
|
extra_params = {} |
2039 |
cb10f131e83f
|
if self._default_params: |
2040 |
cb10f131e83f
|
extra_params.update(self._default_params) |
2041 |
cb10f131e83f
|
if parameters: |
2042 |
cb10f131e83f
|
extra_params.update(parameters) |
2043 |
cb10f131e83f
|
|
2044 |
4805aee792f0
|
# Add key/value parameters to the query string of the url |
2045 |
cb10f131e83f
|
url = self._BuildUrl(url, extra_params=extra_params) |
2046 |
4805aee792f0
|
|
2047 |
4805aee792f0
|
# Get a url opener that can handle basic auth |
2048 |
ee84714ea665
|
opener = self._GetOpener(url, username=self._username, password=self._password) |
2049 |
4805aee792f0
|
|
2050 |
32a0266e88a8
|
encoded_post_data = self._EncodePostData(post_data) |
2051 |
c42880b017af
|
|
2052 |
4805aee792f0
|
# Open and return the URL immediately if we're not going to cache |
2053 |
32a0266e88a8
|
if encoded_post_data or no_cache or not self._cache or not self._cache_timeout: |
2054 |
32a0266e88a8
|
url_data = opener.open(url, encoded_post_data).read() |
2055 |
c1d12896a51f
|
opener.close() |
2056 |
4805aee792f0
|
else: |
2057 |
4805aee792f0
|
# Unique keys are a combination of the url and the username |
2058 |
ee84714ea665
|
if self._username: |
2059 |
ee84714ea665
|
key = self._username + ':' + url |
2060 |
4805aee792f0
|
else: |
2061 |
4805aee792f0
|
key = url |
2062 |
4805aee792f0
|
|
2063 |
4805aee792f0
|
# See if it has been cached before |
2064 |
4805aee792f0
|
last_cached = self._cache.GetCachedTime(key) |
2065 |
4805aee792f0
|
|
2066 |
4805aee792f0
|
# If the cached version is outdated then fetch another and store it |
2067 |
4805aee792f0
|
if not last_cached or time.time() >= last_cached + self._cache_timeout: |
2068 |
32a0266e88a8
|
url_data = opener.open(url, encoded_post_data).read() |
2069 |
c1d12896a51f
|
opener.close() |
2070 |
4805aee792f0
|
self._cache.Set(key, url_data) |
2071 |
4805aee792f0
|
else: |
2072 |
4805aee792f0
|
url_data = self._cache.Get(key) |
2073 |
17f566981b41
|
|
2074 |
4805aee792f0
|
# Always return the latest version |
2075 |
4805aee792f0
|
return url_data |
2076 |
4805aee792f0
|
|
2077 |
81cef10d2991
|
|
2078 |
4805aee792f0
|
class _FileCacheError(Exception): |
2079 |
4805aee792f0
|
'''Base exception class for FileCache related errors''' |
2080 |
4805aee792f0
|
|
2081 |
4805aee792f0
|
class _FileCache(object): |
2082 |
17f566981b41
|
|
2083 |
4805aee792f0
|
DEPTH = 3 |
2084 |
17f566981b41
|
|
2085 |
4805aee792f0
|
def __init__(self,root_directory=None): |
2086 |
4805aee792f0
|
self._InitializeRootDirectory(root_directory) |
2087 |
17f566981b41
|
|
2088 |
4805aee792f0
|
def Get(self,key): |
2089 |
4805aee792f0
|
path = self._GetPath(key) |
2090 |
4805aee792f0
|
if os.path.exists(path): |
2091 |
4805aee792f0
|
return open(path).read() |
2092 |
4805aee792f0
|
else: |
2093 |
4805aee792f0
|
return None |
2094 |
17f566981b41
|
|
2095 |
4805aee792f0
|
def Set(self,key,data): |
2096 |
4805aee792f0
|
path = self._GetPath(key) |
2097 |
4805aee792f0
|
directory = os.path.dirname(path) |
2098 |
4805aee792f0
|
if not os.path.exists(directory): |
2099 |
4805aee792f0
|
os.makedirs(directory) |
2100 |
4805aee792f0
|
if not os.path.isdir(directory): |
2101 |
4805aee792f0
|
raise _FileCacheError('%s exists but is not a directory' % directory) |
2102 |
4805aee792f0
|
temp_fd, temp_path = tempfile.mkstemp() |
2103 |
4805aee792f0
|
temp_fp = os.fdopen(temp_fd, 'w') |
2104 |
4805aee792f0
|
temp_fp.write(data) |
2105 |
4805aee792f0
|
temp_fp.close() |
2106 |
4805aee792f0
|
if not path.startswith(self._root_directory): |
2107 |
4805aee792f0
|
raise _FileCacheError('%s does not appear to live under %s' % |
2108 |
4805aee792f0
|
(path, self._root_directory)) |
2109 |
744e374963dc
|
if os.path.exists(path): |
2110 |
744e374963dc
|
os.remove(path) |
2111 |
4805aee792f0
|
os.rename(temp_path, path) |
2112 |
17f566981b41
|
|
2113 |
4805aee792f0
|
def Remove(self,key): |
2114 |
4805aee792f0
|
path = self._GetPath(key) |
2115 |
4805aee792f0
|
if not path.startswith(self._root_directory): |
2116 |
4805aee792f0
|
raise _FileCacheError('%s does not appear to live under %s' % |
2117 |
4805aee792f0
|
(path, self._root_directory )) |
2118 |
4805aee792f0
|
if os.path.exists(path): |
2119 |
17f566981b41
|
os.remove(path) |
2120 |
17f566981b41
|
|
2121 |
4805aee792f0
|
def GetCachedTime(self,key): |
2122 |
4805aee792f0
|
path = self._GetPath(key) |
2123 |
4805aee792f0
|
if os.path.exists(path): |
2124 |
4805aee792f0
|
return os.path.getmtime(path) |
2125 |
4805aee792f0
|
else: |
2126 |
4805aee792f0
|
return None |
2127 |
17f566981b41
|
|
2128 |
795f1c9d49c9
|
def _GetUsername(self): |
2129 |
3bef9042269d
|
'''Attempt to find the username in a cross-platform fashion.''' |
2130 |
d981d739f261
|
try: |
2131 |
d981d739f261
|
return os.getenv('USER') or \ |
2132 |
d981d739f261
|
os.getenv('LOGNAME') or \ |
2133 |
d981d739f261
|
os.getenv('USERNAME') or \ |
2134 |
d981d739f261
|
os.getlogin() or \ |
2135 |
d981d739f261
|
'nobody' |
2136 |
fc7763723e15
|
except (IOError, OSError), e: |
2137 |
d981d739f261
|
return 'nobody' |
2138 |
795f1c9d49c9
|
|
2139 |
795f1c9d49c9
|
def _GetTmpCachePath(self): |
2140 |
795f1c9d49c9
|
username = self._GetUsername() |
2141 |
795f1c9d49c9
|
cache_directory = 'python.cache_' + username |
2142 |
795f1c9d49c9
|
return os.path.join(tempfile.gettempdir(), cache_directory) |
2143 |
795f1c9d49c9
|
|
2144 |
4805aee792f0
|
def _InitializeRootDirectory(self, root_directory): |
2145 |
4805aee792f0
|
if not root_directory: |
2146 |
795f1c9d49c9
|
root_directory = self._GetTmpCachePath() |
2147 |
4805aee792f0
|
root_directory = os.path.abspath(root_directory) |
2148 |
4805aee792f0
|
if not os.path.exists(root_directory): |
2149 |
4805aee792f0
|
os.mkdir(root_directory) |
2150 |
4805aee792f0
|
if not os.path.isdir(root_directory): |
2151 |
4805aee792f0
|
raise _FileCacheError('%s exists but is not a directory' % |
2152 |
4805aee792f0
|
root_directory) |
2153 |
4805aee792f0
|
self._root_directory = root_directory |
2154 |
17f566981b41
|
|
2155 |
4805aee792f0
|
def _GetPath(self,key): |
2156 |
a58f4a7ad991
|
try: |
2157 |
a58f4a7ad991
|
hashed_key = md5(key).hexdigest() |
2158 |
a58f4a7ad991
|
except TypeError: |
2159 |
a58f4a7ad991
|
hashed_key = md5.new(key).hexdigest() |
2160 |
a58f4a7ad991
|
|
2161 |
4805aee792f0
|
return os.path.join(self._root_directory, |
2162 |
4805aee792f0
|
self._GetPrefix(hashed_key), |
2163 |
4805aee792f0
|
hashed_key) |
2164 |
17f566981b41
|
|
2165 |
4805aee792f0
|
def _GetPrefix(self,hashed_key): |
2166 |
4805aee792f0
|
return os.path.sep.join(hashed_key[0:_FileCache.DEPTH]) |