Merge lp:~terrycojones/tickery/fix-pep8-798273 into lp:tickery
- fix-pep8-798273
- Merge into trunk
Proposed by
Terry Jones
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Esteve Fernandez | ||||
Approved revision: | 4 | ||||
Merged at revision: | 5 | ||||
Proposed branch: | lp:~terrycojones/tickery/fix-pep8-798273 | ||||
Merge into: | lp:tickery | ||||
Diff against target: |
2144 lines (+446/-245) 42 files modified
bin/create-twitter-namespaces-and-tags.py (+3/-0) bin/print-caches.py (+2/-1) doc/conf.py (+6/-4) tickery/adder.py (+18/-14) tickery/admin/index.py (+10/-2) tickery/admin/size.py (+2/-0) tickery/api.py (+2/-0) tickery/cache.py (+2/-1) tickery/cacheutils.py (+2/-1) tickery/endpoint.py (+2/-0) tickery/error.py (+1/-0) tickery/friendscache.py (+1/-1) tickery/ftwitter.py (+83/-28) tickery/login.py (+1/-0) tickery/looper.py (+3/-1) tickery/oauth.py (+28/-17) tickery/oidcache.py (+1/-1) tickery/query.py (+17/-6) tickery/querycache.py (+2/-2) tickery/service.py (+90/-83) tickery/test/test_looper.py (+4/-1) tickery/test/test_query.py (+0/-2) tickery/twitter.py (+20/-11) tickery/usercache.py (+4/-1) tickery/utils.py (+2/-2) tickery/www/Popups.py (+9/-6) tickery/www/about.py (+21/-9) tickery/www/advanced.py (+35/-19) tickery/www/banner.py (+2/-1) tickery/www/defaults.py (+1/-1) tickery/www/index.py (+3/-1) tickery/www/intermediate.py (+1/-1) tickery/www/login.py (+9/-3) tickery/www/results.py (+1/-1) tickery/www/simple.py (+13/-6) tickery/www/tabs.py (+6/-1) tickery/www/tickerytab.py (+15/-10) tickery/www/tweet.py (+3/-1) tickery/www/unknown.py (+4/-2) tickery/www/userlist.py (+8/-1) tickery/www/utils.py (+5/-0) twisted/plugins/tickery_service.py (+4/-3) |
||||
To merge this branch: | bzr merge lp:~terrycojones/tickery/fix-pep8-798273 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Esteve Fernandez | Approve | ||
Review via email: mp+64860@code.launchpad.net |
Commit message
Description of the change
Tons of simple edits to clean up pep8 complaints.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/create-twitter-namespaces-and-tags.py' |
2 | --- bin/create-twitter-namespaces-and-tags.py 2011-06-14 20:36:36 +0000 |
3 | +++ bin/create-twitter-namespaces-and-tags.py 2011-06-16 16:17:19 +0000 |
4 | @@ -38,6 +38,7 @@ |
5 | print msg |
6 | return result |
7 | |
8 | + |
9 | def ignorePreexistingErrror(failure, msg): |
10 | failure.trap(error.Error) |
11 | if int(failure.value.status) == http.PRECONDITION_FAILED: |
12 | @@ -45,10 +46,12 @@ |
13 | else: |
14 | return failure |
15 | |
16 | + |
17 | def addCallbacks(d, msg): |
18 | d.addCallbacks(report, ignorePreexistingErrror, |
19 | callbackArgs=(msg,), errbackArgs=(msg,)) |
20 | |
21 | + |
22 | @defer.inlineCallbacks |
23 | def create(endpoint): |
24 | ns = Namespace(TWITTER_USERNAME) |
25 | |
26 | === modified file 'bin/print-caches.py' |
27 | --- bin/print-caches.py 2010-07-20 09:47:02 +0000 |
28 | +++ bin/print-caches.py 2011-06-16 16:17:19 +0000 |
29 | @@ -16,8 +16,9 @@ |
30 | |
31 | from tickery.cache import TickeryCache |
32 | |
33 | + |
34 | def printHeader(what): |
35 | - print '\n%s[ %s ]%s' % ('-' * 5, what, '-' * (70 - len(what))) |
36 | + print '\n%s[ %s ]%s' % ('-' * 5, what, '-' * (70 - len(what))) |
37 | |
38 | |
39 | if __name__ == '__main__': |
40 | |
41 | === modified file 'doc/conf.py' |
42 | --- doc/conf.py 2011-06-14 20:49:53 +0000 |
43 | +++ doc/conf.py 2011-06-16 16:17:19 +0000 |
44 | @@ -62,7 +62,8 @@ |
45 | # for source files. |
46 | exclude_trees = ['_build'] |
47 | |
48 | -# The reST default role (used for this markup: `text`) to use for all documents. |
49 | +# The reST default role (used for this markup: `text`) to use for all |
50 | +# documents. |
51 | #default_role = None |
52 | |
53 | # If true, '()' will be appended to :func: etc. cross-reference text. |
54 | @@ -83,7 +84,7 @@ |
55 | #modindex_common_prefix = [] |
56 | |
57 | |
58 | -# -- Options for HTML output --------------------------------------------------- |
59 | +# -- Options for HTML output ------------------------------------------------- |
60 | |
61 | # The theme to use for HTML and HTML Help pages. Major themes that come with |
62 | # Sphinx are currently 'default' and 'sphinxdoc'. |
63 | @@ -157,7 +158,7 @@ |
64 | htmlhelp_basename = 'fluidDBdoc' |
65 | |
66 | |
67 | -# -- Options for LaTeX output -------------------------------------------------- |
68 | +# -- Options for LaTeX output ------------------------------------------------ |
69 | |
70 | # The paper size ('letter' or 'a4'). |
71 | #latex_paper_size = 'letter' |
72 | @@ -166,7 +167,8 @@ |
73 | #latex_font_size = '10pt' |
74 | |
75 | # Grouping the document tree into LaTeX files. List of tuples |
76 | -# (source start file, target name, title, author, documentclass [howto/manual]). |
77 | +# (source start file, target name, title, author, documentclass |
78 | +# [howto/manual]). |
79 | latex_documents = [ |
80 | ('index', 'tickery.tex', u'Tickery Docs', |
81 | u'Fluidinfo Ltd', 'manual'), |
82 | |
83 | === modified file 'tickery/adder.py' |
84 | --- tickery/adder.py 2011-06-14 20:36:36 +0000 |
85 | +++ tickery/adder.py 2011-06-16 16:17:19 +0000 |
86 | @@ -29,11 +29,11 @@ |
87 | _states = ('queued', 'underway', 'added', 'canceled', 'failed') |
88 | |
89 | _illegalTransitions = { |
90 | - 'queued' : ('added', 'failed'), |
91 | - 'underway' : ('queued',), |
92 | - 'added' : ('queued', 'underway', 'canceled', 'failed'), |
93 | - 'canceled' : ('underway', 'added', 'failed'), |
94 | - 'failed' : ('underway', 'added'), |
95 | + 'queued': ('added', 'failed'), |
96 | + 'underway': ('queued',), |
97 | + 'added': ('queued', 'underway', 'canceled', 'failed'), |
98 | + 'canceled': ('underway', 'added', 'failed'), |
99 | + 'failed': ('underway', 'added'), |
100 | } |
101 | |
102 | def __init__(self, screenname, nFriends): |
103 | @@ -88,7 +88,8 @@ |
104 | |
105 | def __repr__(self): |
106 | return '<%s screenname=%r state=%r nFriends=%d>' % ( |
107 | - self.__class__.__name__, self.screenname, self.state, self.nFriends) |
108 | + self.__class__.__name__, self.screenname, self.state, |
109 | + self.nFriends) |
110 | |
111 | |
112 | class AdderCache(DumpingCache): |
113 | @@ -130,7 +131,7 @@ |
114 | self.clean = False |
115 | |
116 | def __str__(self): |
117 | - s = [ '%d users in adder cache' % len(self.users) ] |
118 | + s = ['%d users in adder cache' % len(self.users)] |
119 | for key in sorted(self.users.keys()): |
120 | s.append(str(self.users[key])) |
121 | return '\n'.join(s) |
122 | @@ -153,6 +154,7 @@ |
123 | user.setState('added') |
124 | self.clean = False |
125 | return result |
126 | + |
127 | def _failed(fail): |
128 | self.clean = False |
129 | if fail.check(ftwitter.Canceled): |
130 | @@ -162,6 +164,7 @@ |
131 | else: |
132 | user.setState('failed') |
133 | log.msg('Failed to add %r: %s' % (user.screenname, fail)) |
134 | + |
135 | log.msg('User %r received from request queue.' % user.screenname) |
136 | user.setState('underway') |
137 | d = ftwitter.addUserByScreenname(self.cache, self.endpoint, user) |
138 | @@ -179,7 +182,8 @@ |
139 | if user.state == 'underway': |
140 | for item in self.rdq.underway(): |
141 | if item.job.screenname == screenname: |
142 | - log.msg('Cancelling underway %r addition.' % screenname) |
143 | + log.msg('Cancelling underway %r addition.' % |
144 | + screenname) |
145 | item.cancel() |
146 | user.setState('canceled') |
147 | break |
148 | @@ -254,12 +258,12 @@ |
149 | (screenname, state)) |
150 | |
151 | return { |
152 | - 'queued' : queued, |
153 | - 'underway' : underway, |
154 | - 'added' : added, # NB: 'added' is referred to in ftwitter.py |
155 | - 'failed' : failed, |
156 | - 'canceled' : canceled, |
157 | - 'unknown' : unknown, |
158 | + 'queued': queued, |
159 | + 'underway': underway, |
160 | + 'added': added, # NB: 'added' is referred to in ftwitter.py |
161 | + 'failed': failed, |
162 | + 'canceled': canceled, |
163 | + 'unknown': unknown, |
164 | } |
165 | |
166 | @defer.inlineCallbacks |
167 | |
168 | === modified file 'tickery/admin/index.py' |
169 | --- tickery/admin/index.py 2011-06-14 20:36:36 +0000 |
170 | +++ tickery/admin/index.py 2011-06-16 16:17:19 +0000 |
171 | @@ -18,8 +18,16 @@ |
172 | from pyjamas.ui.Label import Label |
173 | from pyjamas.ui.Image import Image |
174 | |
175 | -import width, size, friends, results, directadd, pause |
176 | -import underway, queued, requests, cancel |
177 | +import width |
178 | +import size |
179 | +import friends |
180 | +import results |
181 | +import directadd |
182 | +import pause |
183 | +import underway |
184 | +import queued |
185 | +import requests |
186 | +import cancel |
187 | |
188 | |
189 | class Admin(VerticalPanel): |
190 | |
191 | === modified file 'tickery/admin/size.py' |
192 | --- tickery/admin/size.py 2010-07-20 09:47:02 +0000 |
193 | +++ tickery/admin/size.py 2011-06-16 16:17:19 +0000 |
194 | @@ -18,7 +18,9 @@ |
195 | |
196 | import server |
197 | |
198 | + |
199 | class QueueSize(HorizontalPanel): |
200 | + |
201 | def __init__(self): |
202 | HorizontalPanel.__init__(self, Spacing=4) |
203 | self.add(Label('Queue size:', StyleName='section')) |
204 | |
205 | === modified file 'tickery/api.py' |
206 | --- tickery/api.py 2011-06-14 20:36:36 +0000 |
207 | +++ tickery/api.py 2011-06-16 16:17:19 +0000 |
208 | @@ -15,6 +15,7 @@ |
209 | from twisted.python import log |
210 | from twisted.web import server, resource, error, http |
211 | |
212 | + |
213 | def _returnUID(obj, request): |
214 | uid = str(obj.uuid) |
215 | request.setHeader('Content-length', str(len(uid))) |
216 | @@ -22,6 +23,7 @@ |
217 | request.write(uid) |
218 | request.finish() |
219 | |
220 | + |
221 | def _error(failure, request): |
222 | if failure.check(error.Error): |
223 | code = int(failure.value.status) |
224 | |
225 | === modified file 'tickery/cache.py' |
226 | --- tickery/cache.py 2011-06-14 20:36:36 +0000 |
227 | +++ tickery/cache.py 2011-06-16 16:17:19 +0000 |
228 | @@ -12,7 +12,8 @@ |
229 | # implied. See the License for the specific language governing |
230 | # permissions and limitations under the License. |
231 | |
232 | -import os, functools |
233 | +import os |
234 | +import functools |
235 | |
236 | from twisted.internet import defer |
237 | from twisted.application import service |
238 | |
239 | === modified file 'tickery/cacheutils.py' |
240 | --- tickery/cacheutils.py 2011-06-14 20:36:36 +0000 |
241 | +++ tickery/cacheutils.py 2011-06-16 16:17:19 +0000 |
242 | @@ -12,7 +12,8 @@ |
243 | # implied. See the License for the specific language governing |
244 | # permissions and limitations under the License. |
245 | |
246 | -import os, cPickle as pickle |
247 | +import os |
248 | +import cPickle as pickle |
249 | |
250 | from twisted.python import log |
251 | # xxx: from twisted.internet import task |
252 | |
253 | === modified file 'tickery/endpoint.py' |
254 | --- tickery/endpoint.py 2010-07-20 09:47:02 +0000 |
255 | +++ tickery/endpoint.py 2011-06-16 16:17:19 +0000 |
256 | @@ -18,6 +18,7 @@ |
257 | |
258 | from tickery.www.defaults import TWITTER_USERNAME, TWITTER_PASSWORD_VAR |
259 | |
260 | + |
261 | def twitterPassword(): |
262 | try: |
263 | return os.environ[TWITTER_PASSWORD_VAR] |
264 | @@ -25,6 +26,7 @@ |
265 | raise Exception('Please set %r in your environment.' % |
266 | TWITTER_PASSWORD_VAR) |
267 | |
268 | + |
269 | def twitterEndpoint(URL): |
270 | return Endpoint(baseURL=URL, |
271 | creds=BasicCreds(TWITTER_USERNAME, twitterPassword())) |
272 | |
273 | === modified file 'tickery/error.py' |
274 | --- tickery/error.py 2010-07-20 09:47:02 +0000 |
275 | +++ tickery/error.py 2011-06-16 16:17:19 +0000 |
276 | @@ -12,5 +12,6 @@ |
277 | # implied. See the License for the specific language governing |
278 | # permissions and limitations under the License. |
279 | |
280 | + |
281 | class NoSuchCookie(Exception): |
282 | pass |
283 | |
284 | === modified file 'tickery/friendscache.py' |
285 | --- tickery/friendscache.py 2011-06-14 20:36:36 +0000 |
286 | +++ tickery/friendscache.py 2011-06-16 16:17:19 +0000 |
287 | @@ -42,7 +42,7 @@ |
288 | return d |
289 | |
290 | def __str__(self): |
291 | - s = [ '%d names in friends cache' % len(self._friends) ] |
292 | + s = ['%d names in friends cache' % len(self._friends)] |
293 | for key in sorted(self._friends.keys()): |
294 | s.append('%s: nFriends=%s' % (key, len(self._friends[key]))) |
295 | return '\n'.join(s) |
296 | |
297 | === modified file 'tickery/ftwitter.py' |
298 | --- tickery/ftwitter.py 2011-06-14 20:36:36 +0000 |
299 | +++ tickery/ftwitter.py 2011-06-16 16:17:19 +0000 |
300 | @@ -12,7 +12,8 @@ |
301 | # implied. See the License for the specific language governing |
302 | # permissions and limitations under the License. |
303 | |
304 | -import time, urllib |
305 | +import time |
306 | +import urllib |
307 | |
308 | from twisted.internet import defer, task |
309 | from twisted.python import log, failure |
310 | @@ -40,9 +41,9 @@ |
311 | |
312 | # Put this into www/defaults and re-org stuff in www/*.py in another branch. |
313 | tabName = { |
314 | - 'simple' : 'simple', |
315 | - 'intermediate' : 'intermediate', |
316 | - 'advanced' : 'advanced', |
317 | + 'simple': 'simple', |
318 | + 'intermediate': 'intermediate', |
319 | + 'advanced': 'advanced', |
320 | } |
321 | |
322 | _hashTag = '#tickery' |
323 | @@ -74,24 +75,59 @@ |
324 | # The Twitter tags we additionally add to user objects. There are several |
325 | # others we could add to this. |
326 | extraTags = { |
327 | - TWITTER_N_FRIENDS_TAG_NAME : nFriendsTag, |
328 | - TWITTER_N_FOLLOWERS_TAG_NAME : nFollowersTag, |
329 | - TWITTER_N_STATUSES_TAG_NAME : nStatusesTag, |
330 | + TWITTER_N_FRIENDS_TAG_NAME: nFriendsTag, |
331 | + TWITTER_N_FOLLOWERS_TAG_NAME: nFollowersTag, |
332 | + TWITTER_N_STATUSES_TAG_NAME: nStatusesTag, |
333 | } |
334 | |
335 | |
336 | -class UnknownScreenname(Exception): pass |
337 | -class UnaddedScreennames(Exception): pass |
338 | -class ScreennameErrors(Exception): pass |
339 | -class NonExistentScreennames(Exception): pass |
340 | -class ProtectedScreenname(Exception): pass |
341 | -class ProtectedScreennames(Exception): pass |
342 | -class TooManyFriends(Exception): pass |
343 | -class FluidDBParseError(Exception): pass |
344 | -class FluidDBNonexistentAttribute(Exception): pass |
345 | -class FluidDBPermissionDenied(Exception): pass |
346 | -class FluidDBError(Exception): pass |
347 | -class Canceled(Exception): pass |
348 | +class UnknownScreenname(Exception): |
349 | + pass |
350 | + |
351 | + |
352 | +class UnaddedScreennames(Exception): |
353 | + pass |
354 | + |
355 | + |
356 | +class ScreennameErrors(Exception): |
357 | + pass |
358 | + |
359 | + |
360 | +class NonExistentScreennames(Exception): |
361 | + pass |
362 | + |
363 | + |
364 | +class ProtectedScreenname(Exception): |
365 | + pass |
366 | + |
367 | + |
368 | +class ProtectedScreennames(Exception): |
369 | + pass |
370 | + |
371 | + |
372 | +class TooManyFriends(Exception): |
373 | + pass |
374 | + |
375 | + |
376 | +class FluidDBParseError(Exception): |
377 | + pass |
378 | + |
379 | + |
380 | +class FluidDBNonexistentAttribute(Exception): |
381 | + pass |
382 | + |
383 | + |
384 | +class FluidDBPermissionDenied(Exception): |
385 | + pass |
386 | + |
387 | + |
388 | +class FluidDBError(Exception): |
389 | + pass |
390 | + |
391 | + |
392 | +class Canceled(Exception): |
393 | + pass |
394 | + |
395 | |
396 | def _ignoreHTTPStatus(fail, status): |
397 | fail.trap(error.Error) |
398 | @@ -282,6 +318,7 @@ |
399 | |
400 | userJob.workDone = userJob.workToDo |
401 | |
402 | + |
403 | def friendOf(cache, endpoint, screenname1, screenname2): |
404 | # Does the object for the user screenname2 have a screenname1 |
405 | # follows tag on it? |
406 | @@ -306,13 +343,16 @@ |
407 | d.addErrback(filter404) |
408 | return d |
409 | |
410 | + |
411 | def intermediateQuery(cache, endpoint, queryTree): |
412 | screennames = set() |
413 | query.queryTreeExtractScreennames(queryTree, screennames) |
414 | d = cache.userCache.usersByScreennames(screennames) |
415 | - d.addCallback(cb_intermediateQuery, screennames, cache, endpoint, queryTree) |
416 | + d.addCallback(cb_intermediateQuery, screennames, cache, endpoint, |
417 | + queryTree) |
418 | return d |
419 | |
420 | + |
421 | def cb_intermediateQuery(users, screennames, cache, endpoint, queryTree): |
422 | # Make sure all users exist, that there were no other errors in |
423 | # fetching them, and that none of them are protected. |
424 | @@ -341,9 +381,9 @@ |
425 | # Make sure to use defaults.FRIENDS_LIMIT here, not to import |
426 | # that value. That's because we can change the value (in the |
427 | # defaults module) using the admin interface. |
428 | - tooMany = [(name, users[name]['friends_count']) for name in users if |
429 | - (users[name]['friends_count'] > defaults.FRIENDS_LIMIT and |
430 | - not cache.adderCache.added(name))] |
431 | + tooMany = [(name, users[name]['friends_count']) for name in users if |
432 | + (users[name]['friends_count'] > defaults.FRIENDS_LIMIT and |
433 | + not cache.adderCache.added(name))] |
434 | if tooMany: |
435 | raise TooManyFriends(tooMany) |
436 | |
437 | @@ -380,11 +420,12 @@ |
438 | return defer.succeed(result) |
439 | |
440 | _fluidDBErrors = { |
441 | - 'TParseError' : FluidDBParseError, |
442 | - 'TPathPermissionDenied' : FluidDBPermissionDenied, |
443 | - 'TNonexistentAttribute' : FluidDBNonexistentAttribute, |
444 | + 'TParseError': FluidDBParseError, |
445 | + 'TPathPermissionDenied': FluidDBPermissionDenied, |
446 | + 'TNonexistentAttribute': FluidDBNonexistentAttribute, |
447 | } |
448 | |
449 | + |
450 | def _queryErr(fail, query): |
451 | fail.trap(error.Error) |
452 | errorClass = fail.value.response_headers.get('x-fluiddb-error-class') |
453 | @@ -399,16 +440,19 @@ |
454 | log.msg('Error Class %r' % (errorClass,)) |
455 | raise _fluidDBErrors[errorClass]() |
456 | except KeyError: |
457 | - log.msg('Unhandled Fluiddb error class %r Query %r got HTTP status %s' % |
458 | + log.msg('Unhandled Fluiddb error class %r Query %r got ' |
459 | + 'HTTP status %s' % |
460 | (errorClass, query, fail.value.status)) |
461 | raise FluidDBError() |
462 | |
463 | + |
464 | def fluidDBQuery(endpoint, query): |
465 | d = Object.query(endpoint, query) |
466 | d.addCallback(lambda results: [r.uuid for r in results]) |
467 | d.addErrback(_queryErr, query) |
468 | return d |
469 | |
470 | + |
471 | def simpleTweetURL(screennames, sortKey): |
472 | return '%s?tab=%s&name1=%s&name2=%s&sort=%s' % ( |
473 | TICKERY_URL, tabName['simple'], |
474 | @@ -416,6 +460,7 @@ |
475 | urllib.quote(screennames[1].encode('utf-8')), |
476 | sortKey) |
477 | |
478 | + |
479 | def simpleUpdate(cookie, cookieDict, screennames, nUsers, sortKey, useAtSigns): |
480 | for i, name in enumerate(screennames): |
481 | if useAtSigns: |
482 | @@ -435,9 +480,12 @@ |
483 | text = '%s %s' % (basic, url) |
484 | return twitter.updateStatus(text, cookie, cookieDict) |
485 | |
486 | + |
487 | def tweetURL(query, tabName, sortKey): |
488 | return '%s?tab=%s&query=%s&sort=%s' % ( |
489 | - TICKERY_URL, tabName, urllib.quote_plus(query.encode('utf-8')), sortKey) |
490 | + TICKERY_URL, tabName, urllib.quote_plus(query.encode('utf-8')), |
491 | + sortKey) |
492 | + |
493 | |
494 | def update(cookie, cookieDict, text, query, tabName, sortKey): |
495 | url = tweetURL(query, tabName, sortKey) |
496 | @@ -447,6 +495,7 @@ |
497 | text = '%s %s' % (text, url) |
498 | return twitter.updateStatus(text, cookie, cookieDict) |
499 | |
500 | + |
501 | def _lookupCookie(cookie, cache, fname): |
502 | try: |
503 | return cache.cookieCache[cookie] |
504 | @@ -454,6 +503,7 @@ |
505 | log.err('%s: Could not find cookie %r.' % (fname, cookie)) |
506 | raise terror.NoSuchCookie() |
507 | |
508 | + |
509 | def follow(cookie, cache, endpoint, uid): |
510 | user, _ = _lookupCookie(cookie, cache, 'follow') |
511 | tag = Tag(TWITTER_USERNAME, TWITTER_FRIENDS_NAMESPACE_NAME, |
512 | @@ -465,6 +515,7 @@ |
513 | d.addErrback(_ignoreHTTPStatus, http.NOT_FOUND) |
514 | return d |
515 | |
516 | + |
517 | def unfollow(cookie, cache, endpoint, uid): |
518 | user, _ = _lookupCookie(cookie, cache, 'unfollow') |
519 | tag = Tag(TWITTER_USERNAME, TWITTER_FRIENDS_NAMESPACE_NAME, |
520 | @@ -476,6 +527,7 @@ |
521 | d.addErrback(_ignoreHTTPStatus, http.NOT_FOUND) |
522 | return d |
523 | |
524 | + |
525 | def friendsIdFetcher(cookie, cache, screenname): |
526 | # Note: only use the friends cache if the user is not protected. That's |
527 | # because the cache only contains public users, to prevent people who |
528 | @@ -493,6 +545,7 @@ |
529 | d = cache.friendsIdCache[screenname] |
530 | return d |
531 | |
532 | + |
533 | @defer.inlineCallbacks |
534 | def directAddUser(cache, screenname): |
535 | # Make sure the user exists, that there are no errors in fetching them, |
536 | @@ -516,6 +569,7 @@ |
537 | else: |
538 | cache.adderCache.put(screenname, user['friends_count']) |
539 | |
540 | + |
541 | @defer.inlineCallbacks |
542 | def bulkAddUsers(cache, screennames): |
543 | # Add all users. Return a list of error messages. |
544 | @@ -542,6 +596,7 @@ |
545 | cache.adderCache.put(screenname, user['friends_count']) |
546 | defer.returnValue(errs) |
547 | |
548 | + |
549 | def addExtraTwitterTags(endpoint, userObject, user): |
550 | # Add additional Twitter info tags to the user's object. We do this |
551 | # asynchronously, and all taggings are launched at once (not |
552 | |
553 | === modified file 'tickery/login.py' |
554 | --- tickery/login.py 2010-07-20 09:47:02 +0000 |
555 | +++ tickery/login.py 2011-06-16 16:17:19 +0000 |
556 | @@ -19,6 +19,7 @@ |
557 | from tickery.www import defaults |
558 | from tickery.looper import RetryingCall |
559 | |
560 | + |
561 | def getTwitterOAuthURL(oauthTokenDict): |
562 | log.msg('Got login URL request.') |
563 | |
564 | |
565 | === modified file 'tickery/looper.py' |
566 | --- tickery/looper.py 2011-06-14 20:36:36 +0000 |
567 | +++ tickery/looper.py 2011-06-16 16:17:19 +0000 |
568 | @@ -19,6 +19,7 @@ |
569 | from twisted.internet import reactor, defer, task |
570 | from twisted.python import log, failure |
571 | |
572 | + |
573 | def simpleBackoffIterator(maxResults=10, maxDelay=120.0, now=True, |
574 | initDelay=0.01, incFunc=None): |
575 | assert maxResults > 0 |
576 | @@ -99,7 +100,8 @@ |
577 | d.addCallbacks(self._deferred.callback, self._err) |
578 | |
579 | def start(self, backoffIterator=None, failureTester=None): |
580 | - self._backoffIterator = iter(backoffIterator or simpleBackoffIterator()) |
581 | + self._backoffIterator = iter(backoffIterator or |
582 | + simpleBackoffIterator()) |
583 | self._failureTester = failureTester or (lambda _: None) |
584 | self._deferred = defer.Deferred() |
585 | self.failure = None |
586 | |
587 | === modified file 'tickery/oauth.py' |
588 | --- tickery/oauth.py 2011-06-14 20:49:53 +0000 |
589 | +++ tickery/oauth.py 2011-06-16 16:17:19 +0000 |
590 | @@ -34,7 +34,7 @@ |
591 | import binascii |
592 | |
593 | |
594 | -VERSION = '1.0' # Hi Blaine! |
595 | +VERSION = '1.0' # Hi Blaine! |
596 | HTTP_METHOD = 'GET' |
597 | SIGNATURE_METHOD = 'PLAINTEXT' |
598 | |
599 | @@ -44,14 +44,17 @@ |
600 | def __init__(self, message='OAuth error occured.'): |
601 | self.message = message |
602 | |
603 | + |
604 | def build_authenticate_header(realm=''): |
605 | """Optional WWW-Authenticate header (401 error)""" |
606 | return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} |
607 | |
608 | + |
609 | def escape(s): |
610 | """Escape a URL including any /.""" |
611 | return urllib.quote(s, safe='~') |
612 | |
613 | + |
614 | def _utf8_str(s): |
615 | """Convert unicode to utf-8.""" |
616 | if isinstance(s, unicode): |
617 | @@ -59,14 +62,17 @@ |
618 | else: |
619 | return str(s) |
620 | |
621 | + |
622 | def generate_timestamp(): |
623 | """Get seconds since epoch (UTC).""" |
624 | return int(time.time()) |
625 | |
626 | + |
627 | def generate_nonce(length=8): |
628 | """Generate pseudorandom number.""" |
629 | return ''.join([str(random.randint(0, 9)) for i in range(length)]) |
630 | |
631 | + |
632 | def generate_verifier(length=8): |
633 | """Generate pseudorandom number.""" |
634 | return ''.join([str(random.randint(0, 9)) for i in range(length)]) |
635 | @@ -88,8 +94,8 @@ |
636 | |
637 | |
638 | class OAuthToken(object): |
639 | - """OAuthToken is a data type that represents an End User via either an access |
640 | - or request token. |
641 | + """OAuthToken is a data type that represents an End User via either an |
642 | + access or request token. |
643 | |
644 | key -- the token |
645 | secret -- the token secret |
646 | @@ -148,7 +154,7 @@ |
647 | try: |
648 | token.callback_confirmed = params['oauth_callback_confirmed'][0] |
649 | except KeyError: |
650 | - pass # 1.0, no callback confirmed. |
651 | + pass # 1.0, no callback confirmed. |
652 | return token |
653 | from_string = staticmethod(from_string) |
654 | |
655 | @@ -170,12 +176,13 @@ |
656 | - oauth_verifier |
657 | ... any additional parameters, as defined by the Service Provider. |
658 | """ |
659 | - parameters = None # OAuth parameters. |
660 | + parameters = None # OAuth parameters. |
661 | http_method = HTTP_METHOD |
662 | http_url = None |
663 | version = VERSION |
664 | |
665 | - def __init__(self, http_method=HTTP_METHOD, http_url=None, parameters=None): |
666 | + def __init__(self, http_method=HTTP_METHOD, http_url=None, |
667 | + parameters=None): |
668 | self.http_method = http_method |
669 | self.http_url = http_url |
670 | self.parameters = parameters or {} |
671 | @@ -231,7 +238,7 @@ |
672 | pass |
673 | # Escape key values before sorting. |
674 | key_values = [(escape(_utf8_str(k)), escape(_utf8_str(v))) \ |
675 | - for k,v in params.items()] |
676 | + for k, v in params.items()] |
677 | # Sort lexicographically, first after key, then after value. |
678 | key_values.sort() |
679 | # Combine key value pairs into a string. |
680 | @@ -291,7 +298,7 @@ |
681 | parameters.update(query_params) |
682 | |
683 | # URL parameters. |
684 | - param_str = urlparse.urlparse(http_url)[4] # query |
685 | + param_str = urlparse.urlparse(http_url)[4] # query |
686 | url_params = OAuthRequest._split_url_string(param_str) |
687 | parameters.update(url_params) |
688 | |
689 | @@ -369,9 +376,10 @@ |
690 | return parameters |
691 | _split_url_string = staticmethod(_split_url_string) |
692 | |
693 | + |
694 | class OAuthServer(object): |
695 | """A worker to check the validity of a request against a data store.""" |
696 | - timestamp_threshold = 300 # In seconds, five minutes. |
697 | + timestamp_threshold = 300 # In seconds, five minutes. |
698 | version = VERSION |
699 | signature_methods = None |
700 | data_store = None |
701 | @@ -404,7 +412,7 @@ |
702 | try: |
703 | callback = self.get_callback(oauth_request) |
704 | except OAuthError: |
705 | - callback = None # 1.0, no callback specified. |
706 | + callback = None # 1.0, no callback specified. |
707 | self._check_signature(oauth_request, consumer, None) |
708 | # Fetch a new token. |
709 | token = self.data_store.fetch_request_token(consumer, callback) |
710 | @@ -423,7 +431,8 @@ |
711 | # Get the request token. |
712 | token = self._get_token(oauth_request, 'request') |
713 | self._check_signature(oauth_request, consumer, token) |
714 | - new_token = self.data_store.fetch_access_token(consumer, token, verifier) |
715 | + new_token = self.data_store.fetch_access_token( |
716 | + consumer, token, verifier) |
717 | return new_token |
718 | |
719 | def verify_request(self, oauth_request): |
720 | @@ -471,8 +480,8 @@ |
721 | signature_method = self.signature_methods[signature_method] |
722 | except: |
723 | signature_method_names = ', '.join(self.signature_methods.keys()) |
724 | - raise OAuthError('Signature method %s not supported try one of the ' |
725 | - 'following: %s' % (signature_method, signature_method_names)) |
726 | + raise OAuthError('Signature method %s not supported try one of the' |
727 | + ' following: %s' % (signature_method, signature_method_names)) |
728 | |
729 | return signature_method |
730 | |
731 | @@ -488,7 +497,8 @@ |
732 | token_field = oauth_request.get_parameter('oauth_token') |
733 | token = self.data_store.lookup_token(token_type, token_field) |
734 | if not token: |
735 | - raise OAuthError('Invalid %s token: %s' % (token_type, token_field)) |
736 | + raise OAuthError('Invalid %s token: %s' % ( |
737 | + token_type, token_field)) |
738 | return token |
739 | |
740 | def _get_verifier(self, oauth_request): |
741 | @@ -592,7 +602,8 @@ |
742 | """-> str.""" |
743 | raise NotImplementedError |
744 | |
745 | - def build_signature_base_string(self, oauth_request, oauth_consumer, oauth_token): |
746 | + def build_signature_base_string(self, oauth_request, oauth_consumer, |
747 | + oauth_token): |
748 | """-> str key, str raw.""" |
749 | raise NotImplementedError |
750 | |
751 | @@ -630,10 +641,10 @@ |
752 | |
753 | # HMAC object. |
754 | try: |
755 | - import hashlib # 2.5 |
756 | + import hashlib # 2.5 |
757 | hashed = hmac.new(key, raw, hashlib.sha1) |
758 | except: |
759 | - import sha # Deprecated |
760 | + import sha # Deprecated |
761 | hashed = hmac.new(key, raw, sha) |
762 | |
763 | # Calculate the digest base 64. |
764 | |
765 | === modified file 'tickery/oidcache.py' |
766 | --- tickery/oidcache.py 2011-06-14 20:36:36 +0000 |
767 | +++ tickery/oidcache.py 2011-06-16 16:17:19 +0000 |
768 | @@ -55,7 +55,7 @@ |
769 | self.screennameToObjectId[item.screenname.lower()] = oid |
770 | |
771 | def __str__(self): |
772 | - s = [ '%d oids in oid/uid/name cache' % len(self.objectIdToItem) ] |
773 | + s = ['%d oids in oid/uid/name cache' % len(self.objectIdToItem)] |
774 | for key in sorted(self.objectIdToItem.keys()): |
775 | s.append('%s: %s' % (key, self.objectIdToItem[key])) |
776 | return '\n'.join(s) |
777 | |
778 | === modified file 'tickery/query.py' |
779 | --- tickery/query.py 2011-06-14 20:36:36 +0000 |
780 | +++ tickery/query.py 2011-06-16 16:17:19 +0000 |
781 | @@ -14,17 +14,26 @@ |
782 | |
783 | import ply.lex as lex |
784 | import ply.yacc as yacc |
785 | -import re, sys |
786 | - |
787 | -class QueryError(Exception): pass |
788 | -class UnparseableError(QueryError): pass |
789 | +import re |
790 | +import sys |
791 | + |
792 | + |
793 | +class QueryError(Exception): |
794 | + pass |
795 | + |
796 | + |
797 | +class UnparseableError(QueryError): |
798 | + pass |
799 | + |
800 | |
801 | class TokenError(QueryError): |
802 | + |
803 | def __init__(self, t): |
804 | Exception.__init__(self) |
805 | self.value = t.value |
806 | self.offset = t.lexpos |
807 | |
808 | + |
809 | class QueryLexer(object): |
810 | |
811 | # Ignore whitespace |
812 | @@ -44,8 +53,8 @@ |
813 | |
814 | reserved = (u'and', u'or', u'except') |
815 | |
816 | - t_LPAREN = '\(' |
817 | - t_RPAREN = '\)' |
818 | + t_LPAREN = '\(' |
819 | + t_RPAREN = '\)' |
820 | |
821 | def t_EXCEPTSYM(self, t): |
822 | r'-' |
823 | @@ -178,6 +187,7 @@ |
824 | except RuntimeError: |
825 | raise UnparseableError() |
826 | |
827 | + |
828 | def queryTreeToString(queryTree, fdbUsername, fdbNamespace): |
829 | """Return a query string that can be sent to FluidDB. Note that we turn |
830 | all screennames into lowercase in the complete tag names. That's |
831 | @@ -203,6 +213,7 @@ |
832 | else: |
833 | raise Exception('WTF? Node type is %r' % (nodeType,)) |
834 | |
835 | + |
836 | def queryTreeExtractScreennames(queryTree, screennames): |
837 | """Pull all the screennames out of a query tree. Do this in a |
838 | case-insensitive way. Return a set of names that preserves case (first |
839 | |
840 | === modified file 'tickery/querycache.py' |
841 | --- tickery/querycache.py 2011-06-14 20:36:36 +0000 |
842 | +++ tickery/querycache.py 2011-06-16 16:17:19 +0000 |
843 | @@ -29,7 +29,7 @@ |
844 | self._queries, self._screennameIndex = data |
845 | |
846 | def __str__(self): |
847 | - s = [ '%d queries in cache' % len(self._queries) ] |
848 | + s = ['%d queries in cache' % len(self._queries)] |
849 | for key in sorted(self._queries.keys()): |
850 | s.append('size %4d: %s' % (len(self._queries[key]), key)) |
851 | return '\n'.join(s) |
852 | @@ -43,7 +43,7 @@ |
853 | try: |
854 | self._screennameIndex[screenname].append(query) |
855 | except KeyError: |
856 | - self._screennameIndex[screenname] = [ query ] |
857 | + self._screennameIndex[screenname] = [query] |
858 | self.clean = False |
859 | |
860 | def invalidate(self, screenname): |
861 | |
862 | === modified file 'tickery/service.py' |
863 | --- tickery/service.py 2011-06-14 20:36:36 +0000 |
864 | +++ tickery/service.py 2011-06-16 16:17:19 +0000 |
865 | @@ -24,14 +24,16 @@ |
866 | from tickery.www import defaults |
867 | |
868 | |
869 | -class TooManyResults(Exception): pass |
870 | +class TooManyResults(Exception): |
871 | + pass |
872 | + |
873 | |
874 | screennameListErrors = { |
875 | - ftwitter.NonExistentScreennames : 'nonexistent', |
876 | - ftwitter.ScreennameErrors : 'othererror', |
877 | - ftwitter.ProtectedScreennames : 'protected', |
878 | - ftwitter.TooManyFriends : 'toomany', |
879 | - TooManyResults : 'toomanyresults', |
880 | + ftwitter.NonExistentScreennames: 'nonexistent', |
881 | + ftwitter.ScreennameErrors: 'othererror', |
882 | + ftwitter.ProtectedScreennames: 'protected', |
883 | + ftwitter.TooManyFriends: 'toomany', |
884 | + TooManyResults: 'toomanyresults', |
885 | } |
886 | |
887 | _noScreenname = '<None>' |
888 | @@ -46,12 +48,12 @@ |
889 | self.ASTBuilder = ASTBuilder() |
890 | |
891 | def jsonrpc_nUsers(self): |
892 | - return {'result' : self.cache.oidUidScreennameCache.nUsers()} |
893 | + return {'result': self.cache.oidUidScreennameCache.nUsers()} |
894 | |
895 | def jsonrpc_spideredScreennames(self, *screennames): |
896 | log.msg('spideredScreenname called with %r.' % (screennames,)) |
897 | - return { 'result' : |
898 | - [ self.cache.adderCache.added(s) for s in screennames ]} |
899 | + return {'result': |
900 | + [self.cache.adderCache.added(s) for s in screennames]} |
901 | |
902 | def _objectIdsToUsers(self, (users, ids)): |
903 | '''Convert a list of FluidDB object ids to a JSON RPC result dict |
904 | @@ -59,16 +61,16 @@ |
905 | if ids: |
906 | log.err('Unexpected object ids matched query: %r' % (ids,)) |
907 | return { |
908 | - 'result' : { |
909 | - 'result' : True, |
910 | - 'users' : users}} |
911 | + 'result': { |
912 | + 'result': True, |
913 | + 'users': users}} |
914 | |
915 | def _objectIdsToUsersWherePossible(self, (users, ids)): |
916 | return { |
917 | - 'result' : { |
918 | - 'result' : True, |
919 | - 'users' : users, |
920 | - 'objectIds' : ids}} |
921 | + 'result': { |
922 | + 'result': True, |
923 | + 'users': users, |
924 | + 'objectIds': ids}} |
925 | |
926 | def jsonrpc_friendOf(self, screenname1, screenname2): |
927 | # Return True if screenname1 follows screenname2 (i.e., screenname2 |
928 | @@ -76,7 +78,7 @@ |
929 | log.msg('FriendOf %r and %r.' % (screenname1, screenname2)) |
930 | d = ftwitter.friendOf(self.cache, self.endpoint, |
931 | screenname1, screenname2) |
932 | - d.addCallback(lambda result: { 'result' : result }) |
933 | + d.addCallback(lambda result: {'result': result}) |
934 | d.addErrback(log.err) |
935 | return d |
936 | |
937 | @@ -93,9 +95,9 @@ |
938 | def _screennameListError(self, fail): |
939 | listErr = fail.trap(*screennameListErrors.keys()) |
940 | result = { |
941 | - 'result' : { |
942 | - 'result' : False, |
943 | - screennameListErrors[listErr] : list(fail.value.args[0]), |
944 | + 'result': { |
945 | + 'result': False, |
946 | + screennameListErrors[listErr]: list(fail.value.args[0]), |
947 | } |
948 | } |
949 | # Add the current friends limit if we have that kind of error. |
950 | @@ -108,9 +110,9 @@ |
951 | def _unaddedError(self, fail): |
952 | fail.trap(ftwitter.UnaddedScreennames) |
953 | return { |
954 | - 'result' : { |
955 | - 'result' : False, |
956 | - 'unadded' : fail.value.args[0], |
957 | + 'result': { |
958 | + 'result': False, |
959 | + 'unadded': fail.value.args[0], |
960 | } |
961 | } |
962 | |
963 | @@ -122,28 +124,30 @@ |
964 | else: |
965 | screenname = data[0]['screen_name'] |
966 | |
967 | - log.msg('QUERY: tab=%s user=%r query=%r' % (tabName, screenname, query)) |
968 | + log.msg('QUERY: tab=%s user=%r query=%r' % ( |
969 | + tabName, screenname, query)) |
970 | |
971 | try: |
972 | parseTree = self.ASTBuilder.build(query) |
973 | except TokenError, p: |
974 | log.msg('User %r sent malformed query %r' % (screenname, query)) |
975 | return { |
976 | - 'result' : { |
977 | - 'result' : False, |
978 | - 'value' : p.value, |
979 | - 'offset' : p.offset, |
980 | + 'result': { |
981 | + 'result': False, |
982 | + 'value': p.value, |
983 | + 'offset': p.offset, |
984 | } |
985 | } |
986 | except UnparseableError: |
987 | log.msg('User %r sent unparsable query %r' % (screenname, query)) |
988 | return { |
989 | - 'result' : { |
990 | - 'result' : False, |
991 | + 'result': { |
992 | + 'result': False, |
993 | } |
994 | } |
995 | else: |
996 | - d = ftwitter.intermediateQuery(self.cache, self.endpoint, parseTree) |
997 | + d = ftwitter.intermediateQuery( |
998 | + self.cache, self.endpoint, parseTree) |
999 | d.addCallback(self._checkTooManyResults) |
1000 | d.addCallback( |
1001 | self.cache.oidUidScreennameCache.objectIdsToUsers, |
1002 | @@ -166,9 +170,9 @@ |
1003 | else: |
1004 | errorClass = err.__name__ |
1005 | return { |
1006 | - 'result' : { |
1007 | - 'result' : False, |
1008 | - 'errorClass' : errorClass, |
1009 | + 'result': { |
1010 | + 'result': False, |
1011 | + 'errorClass': errorClass, |
1012 | } |
1013 | } |
1014 | |
1015 | @@ -179,30 +183,31 @@ |
1016 | screenname = _noScreenname |
1017 | else: |
1018 | screenname = data[0]['screen_name'] |
1019 | - log.msg('QUERY: tab=%s user=%r query=%r' % (tabName, screenname, query)) |
1020 | + log.msg('QUERY: tab=%s user=%r query=%r' % ( |
1021 | + tabName, screenname, query)) |
1022 | d = ftwitter.fluidDBQuery(self.endpoint, query) |
1023 | d.addCallback(self._checkTooManyResults) |
1024 | d.addCallback( |
1025 | self.cache.oidUidScreennameCache.objectIdsToUsers, |
1026 | self.cache.userCache) |
1027 | d.addCallback(self._objectIdsToUsersWherePossible) |
1028 | - d.addErrback(self._screennameListError) # Catches TooManyResults |
1029 | + d.addErrback(self._screennameListError) # Catches TooManyResults |
1030 | d.addErrback(self._fluidDBError, query) |
1031 | return d |
1032 | |
1033 | def _loginRedirectURL(self, URL): |
1034 | return { |
1035 | - 'result' : { |
1036 | - 'result' : True, |
1037 | - 'URL' : URL, |
1038 | + 'result': { |
1039 | + 'result': True, |
1040 | + 'URL': URL, |
1041 | } |
1042 | } |
1043 | |
1044 | def _loginRedirectErr(self, failure): |
1045 | return { |
1046 | - 'result' : { |
1047 | - 'result' : False, |
1048 | - 'error' : str(failure), |
1049 | + 'result': { |
1050 | + 'result': False, |
1051 | + 'error': str(failure), |
1052 | } |
1053 | } |
1054 | |
1055 | @@ -216,16 +221,16 @@ |
1056 | data = self.cache.cookieCache[cookie] |
1057 | except KeyError: |
1058 | return { |
1059 | - 'result' : { |
1060 | - 'result' : False, |
1061 | + 'result': { |
1062 | + 'result': False, |
1063 | } |
1064 | } |
1065 | else: |
1066 | user, _ = data |
1067 | return { |
1068 | - 'result' : { |
1069 | - 'result' : True, |
1070 | - 'screen_name' : user['screen_name'], |
1071 | + 'result': { |
1072 | + 'result': True, |
1073 | + 'screen_name': user['screen_name'], |
1074 | } |
1075 | } |
1076 | |
1077 | @@ -239,24 +244,24 @@ |
1078 | user, _ = data |
1079 | log.msg('Logging out user %r.' % user['screen_name']) |
1080 | return { |
1081 | - 'result' : True, |
1082 | + 'result': True, |
1083 | } |
1084 | |
1085 | def _tweetURL(self, response): |
1086 | import pprint |
1087 | log.msg('Update got response %s' % pprint.pformat(response)) |
1088 | return { |
1089 | - 'result' : { |
1090 | - 'result' : True, |
1091 | - 'URL' : twitter.statusURLFromUpdateResponse(response), |
1092 | + 'result': { |
1093 | + 'result': True, |
1094 | + 'URL': twitter.statusURLFromUpdateResponse(response), |
1095 | } |
1096 | } |
1097 | |
1098 | def _tweetError(self, failure): |
1099 | return { |
1100 | - 'result' : { |
1101 | - 'result' : False, |
1102 | - 'error' : str(failure), |
1103 | + 'result': { |
1104 | + 'result': False, |
1105 | + 'error': str(failure), |
1106 | } |
1107 | } |
1108 | |
1109 | @@ -278,7 +283,7 @@ |
1110 | log.msg('Getting friend ids for %r.' % screenname) |
1111 | d = ftwitter.friendsIdFetcher(cookie, self.cache, screenname) |
1112 | d.addCallback(lambda friendsIds: { |
1113 | - 'result' : { 'friendsIds' : friendsIds, }, |
1114 | + 'result': {'friendsIds': friendsIds}, |
1115 | }) |
1116 | return d |
1117 | |
1118 | @@ -287,7 +292,7 @@ |
1119 | d = twitter.follow(cookie, self.cache, uid) |
1120 | d.addCallback(lambda _: ftwitter.follow(cookie, self.cache, |
1121 | self.endpoint, uid)) |
1122 | - d.addCallback(lambda _: { 'result' : True }) |
1123 | + d.addCallback(lambda _: {'result': True}) |
1124 | return d |
1125 | |
1126 | def jsonrpc_unfollow(self, cookie, uid): |
1127 | @@ -295,7 +300,7 @@ |
1128 | d = twitter.unfollow(cookie, self.cache, uid) |
1129 | d.addCallback(lambda _: ftwitter.unfollow(cookie, self.cache, |
1130 | self.endpoint, uid)) |
1131 | - d.addCallback(lambda _: { 'result' : True }) |
1132 | + d.addCallback(lambda _: {'result': True}) |
1133 | return d |
1134 | |
1135 | |
1136 | @@ -306,37 +311,37 @@ |
1137 | self.cache = cache |
1138 | |
1139 | def jsonrpc_getQueueWidth(self): |
1140 | - return { 'result' : self.cache.adderCache.rdq.width } |
1141 | + return {'result': self.cache.adderCache.rdq.width} |
1142 | |
1143 | def jsonrpc_setQueueWidth(self, width): |
1144 | try: |
1145 | width = int(width) |
1146 | except ValueError: |
1147 | - return { 'result' : False } |
1148 | + return {'result': False} |
1149 | else: |
1150 | self.cache.adderCache.rdq.width = width |
1151 | - return { 'result' : True } |
1152 | + return {'result': True} |
1153 | |
1154 | def jsonrpc_queueSize(self): |
1155 | - return { 'result' : self.cache.adderCache.rdq.size() } |
1156 | + return {'result': self.cache.adderCache.rdq.size()} |
1157 | |
1158 | def jsonrpc_queuePaused(self): |
1159 | - return { 'result' : self.cache.adderCache.rdq.paused } |
1160 | + return {'result': self.cache.adderCache.rdq.paused} |
1161 | |
1162 | def jsonrpc_pause(self): |
1163 | d = self.cache.adderCache.rdq.pause() |
1164 | - d.addCallback(lambda _: { 'result' : True }) |
1165 | + d.addCallback(lambda _: {'result': True}) |
1166 | return d |
1167 | |
1168 | def jsonrpc_resume(self): |
1169 | self.cache.adderCache.rdq.resume() |
1170 | - return { 'result' : True } |
1171 | + return {'result': True} |
1172 | |
1173 | def jsonrpc_getQueued(self): |
1174 | pending = self.cache.adderCache.rdq.pending() |
1175 | result = [[u.screenname, u.nFriends, time.ctime(u.queuedAt)] |
1176 | for u in pending] |
1177 | - return { 'result' : result } |
1178 | + return {'result': result} |
1179 | |
1180 | def jsonrpc_getUnderway(self): |
1181 | underway = self.cache.adderCache.rdq.underway() |
1182 | @@ -348,53 +353,55 @@ |
1183 | u.job.nFriends, |
1184 | pct, |
1185 | time.ctime(u.job.queuedAt), |
1186 | - time.ctime(u.startTime),] |
1187 | + time.ctime(u.startTime)] |
1188 | ) |
1189 | - return { 'result' : result } |
1190 | + return {'result': result} |
1191 | |
1192 | def jsonrpc_getMaxRequestsLimit(self): |
1193 | - return { 'result' : ftwitter.MAX_SIMULTANEOUS_REQUESTS } |
1194 | + return {'result': ftwitter.MAX_SIMULTANEOUS_REQUESTS} |
1195 | |
1196 | def jsonrpc_setMaxRequestsLimit(self, limit): |
1197 | try: |
1198 | ftwitter.MAX_SIMULTANEOUS_REQUESTS = int(limit) |
1199 | except ValueError: |
1200 | - return { 'result' : False } |
1201 | + return {'result': False} |
1202 | else: |
1203 | - return { 'result' : True } |
1204 | + return {'result': True} |
1205 | |
1206 | def jsonrpc_getFriendsLimit(self): |
1207 | - return { 'result' : defaults.FRIENDS_LIMIT } |
1208 | + return {'result': defaults.FRIENDS_LIMIT} |
1209 | |
1210 | def jsonrpc_setFriendsLimit(self, limit): |
1211 | try: |
1212 | defaults.FRIENDS_LIMIT = int(limit) |
1213 | except ValueError: |
1214 | - return { 'result' : False } |
1215 | + return {'result': False} |
1216 | else: |
1217 | - return { 'result' : True } |
1218 | + return {'result': True} |
1219 | |
1220 | def jsonrpc_getResultsLimit(self): |
1221 | - return { 'result' : defaults.RESULTS_LIMIT } |
1222 | + return {'result': defaults.RESULTS_LIMIT} |
1223 | |
1224 | def jsonrpc_setResultsLimit(self, limit): |
1225 | try: |
1226 | defaults.RESULTS_LIMIT = int(limit) |
1227 | except ValueError: |
1228 | - return { 'result' : False } |
1229 | + return {'result': False} |
1230 | else: |
1231 | - return { 'result' : True } |
1232 | + return {'result': True} |
1233 | |
1234 | def jsonrpc_directAddUser(self, screenname): |
1235 | def _err(fail): |
1236 | return { |
1237 | - 'error' : None, |
1238 | - 'message' : str(fail.value), |
1239 | + 'error': None, |
1240 | + 'message': str(fail.value), |
1241 | } |
1242 | + |
1243 | def _ok(result): |
1244 | return { |
1245 | - 'result' : True, |
1246 | + 'result': True, |
1247 | } |
1248 | + |
1249 | d = ftwitter.directAddUser(self.cache, screenname) |
1250 | d.addCallbacks(_ok, _err) |
1251 | return d |
1252 | @@ -405,11 +412,11 @@ |
1253 | log.msg('Errs is %r' % (errs,)) |
1254 | if errs: |
1255 | return { |
1256 | - 'message' : errs, |
1257 | + 'message': errs, |
1258 | } |
1259 | else: |
1260 | return { |
1261 | - 'result' : True, |
1262 | + 'result': True, |
1263 | } |
1264 | |
1265 | d = ftwitter.bulkAddUsers(self.cache, screennames.split()) |
1266 | @@ -421,9 +428,9 @@ |
1267 | self.cache.adderCache.cancel(screenname) |
1268 | except Exception, e: |
1269 | return { |
1270 | - 'message' : str(e) |
1271 | + 'message': str(e) |
1272 | } |
1273 | else: |
1274 | return { |
1275 | - 'result' : True, |
1276 | + 'result': True, |
1277 | } |
1278 | |
1279 | === modified file 'tickery/test/test_looper.py' |
1280 | --- tickery/test/test_looper.py 2011-06-14 20:36:36 +0000 |
1281 | +++ tickery/test/test_looper.py 2011-06-16 16:17:19 +0000 |
1282 | @@ -91,7 +91,7 @@ |
1283 | self.succeeded = False |
1284 | |
1285 | def __call__(self, *args, **kw): |
1286 | - # Make sure we're called with the args we're supposed to be called with. |
1287 | + # Make sure we're called with args we're supposed to be called with. |
1288 | assert self.args == args |
1289 | assert self.kw == kw |
1290 | |
1291 | @@ -113,6 +113,7 @@ |
1292 | assert self.nFails == self.failCount, '%d != %d' % (self.nFails, |
1293 | self.failCount) |
1294 | |
1295 | + |
1296 | class CallCounter(object): |
1297 | """Provide a callable that counts the number of times it's invoked.""" |
1298 | def __init__(self): |
1299 | @@ -158,9 +159,11 @@ |
1300 | def testSimpleDeferredReturner(self): |
1301 | result1 = 15 |
1302 | result2 = 16 |
1303 | + |
1304 | def _ret(result): |
1305 | self.assertEqual(result, result1) |
1306 | return result2 |
1307 | + |
1308 | rc = RetryingCall(lambda: defer.succeed(result1)) |
1309 | d = rc.start() |
1310 | d.addCallback(_ret) |
1311 | |
1312 | === modified file 'tickery/test/test_query.py' |
1313 | --- tickery/test/test_query.py 2011-06-14 20:49:53 +0000 |
1314 | +++ tickery/test/test_query.py 2011-06-16 16:17:19 +0000 |
1315 | @@ -70,10 +70,8 @@ |
1316 | ): |
1317 | self._simpleTokenErrorCheck(query, value, offset) |
1318 | |
1319 | - |
1320 | def testSimpleUnparseableErrors(self): |
1321 | for query in ('', |
1322 | '(', |
1323 | ): |
1324 | self._simpleUnparseableCheck(query) |
1325 | - |
1326 | |
1327 | === modified file 'tickery/twitter.py' |
1328 | --- tickery/twitter.py 2011-06-14 20:49:53 +0000 |
1329 | +++ tickery/twitter.py 2011-06-16 16:17:19 +0000 |
1330 | @@ -12,8 +12,10 @@ |
1331 | # implied. See the License for the specific language governing |
1332 | # permissions and limitations under the License. |
1333 | |
1334 | -import urllib, functools, time |
1335 | +import functools |
1336 | import json |
1337 | +import time |
1338 | +import urllib |
1339 | |
1340 | from twisted.internet import defer |
1341 | from twisted.internet.error import ConnectionLost |
1342 | @@ -43,18 +45,17 @@ |
1343 | http.SERVICE_UNAVAILABLE, http.GATEWAY_TIMEOUT) |
1344 | |
1345 | POSTHeaders = { |
1346 | - 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8', |
1347 | - 'X-Twitter-Client' : 'Tickery', |
1348 | - 'X-Twitter-Client-Version' : version.version, |
1349 | - 'X-Twitter-Client-URL' : defaults.TICKERY_URL, |
1350 | + 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', |
1351 | + 'X-Twitter-Client': 'Tickery', |
1352 | + 'X-Twitter-Client-Version': version.version, |
1353 | + 'X-Twitter-Client-URL': defaults.TICKERY_URL, |
1354 | } |
1355 | |
1356 | |
1357 | - |
1358 | class _Fetcher(object): |
1359 | baseURL = TWITTER_URL + '/' |
1360 | - URITemplate = None # Override in subclass. |
1361 | - dataKey = None # Override in subclass. |
1362 | + URITemplate = None # Override in subclass. |
1363 | + dataKey = None # Override in subclass. |
1364 | headers = {} |
1365 | maxErrs = 10 |
1366 | |
1367 | @@ -66,7 +67,7 @@ |
1368 | self.nextCursor = -1 |
1369 | self.deferred = defer.Deferred() |
1370 | self.URL = self.baseURL + ( |
1371 | - self.URITemplate % { 'name' : urllib.quote(name.encode('utf-8'))}) |
1372 | + self.URITemplate % {'name': urllib.quote(name.encode('utf-8'))}) |
1373 | self.token = token |
1374 | |
1375 | def _reportElapsed(self, result): |
1376 | @@ -182,6 +183,7 @@ |
1377 | elif status not in okErrs: |
1378 | return fail |
1379 | |
1380 | + |
1381 | def userByScreenname(screenname): |
1382 | r = RetryingCall(client.getPage, |
1383 | '%s/users/show.json?screen_name=%s' % |
1384 | @@ -191,6 +193,7 @@ |
1385 | d.addCallback(lambda j: json.loads(j)) |
1386 | return d |
1387 | |
1388 | + |
1389 | def userById(uid): |
1390 | r = RetryingCall(client.getPage, |
1391 | '%s/users/show.json?user_id=%s' % (TWITTER_URL, uid)) |
1392 | @@ -199,6 +202,7 @@ |
1393 | d.addCallback(lambda j: json.loads(j)) |
1394 | return d |
1395 | |
1396 | + |
1397 | def _urlencodeDict(d): |
1398 | result = [] |
1399 | for k, v in d.iteritems(): |
1400 | @@ -206,6 +210,7 @@ |
1401 | urllib.quote(v.encode("utf-8")))) |
1402 | return '&'.join(result) |
1403 | |
1404 | + |
1405 | def updateStatus(status, cookie, cookieDict): |
1406 | log.msg('Sending tweet %r' % status) |
1407 | try: |
1408 | @@ -214,7 +219,7 @@ |
1409 | log.err('updateStatus: Could not find cookie' % cookie) |
1410 | return defer.fail(terror.NoSuchCookie()) |
1411 | |
1412 | - parameters = { 'status' : status } |
1413 | + parameters = {'status': status} |
1414 | oaRequest = oauth.OAuthRequest.from_consumer_and_token( |
1415 | consumer.consumer, token=accessToken, parameters=parameters, |
1416 | http_url=UPDATE_STATUS_URL, http_method='POST') |
1417 | @@ -231,6 +236,7 @@ |
1418 | d.addCallback(lambda j: json.loads(j)) |
1419 | return d |
1420 | |
1421 | + |
1422 | def statusURLFromUpdateResponse(response): |
1423 | 'Response is the JSON returned by a statuses/update.json API call.' |
1424 | return '%s/%s/status/%s' % ( |
1425 | @@ -238,14 +244,17 @@ |
1426 | urllib.quote(response[u'user'][u'screen_name'].encode('utf-8')), |
1427 | response[u'id']) |
1428 | |
1429 | + |
1430 | def _updateUserCache_cb(user, cache): |
1431 | cache.userCache.add(user) |
1432 | return user |
1433 | |
1434 | + |
1435 | def _invalidateResultCache_cb(result, cache, screenname): |
1436 | cache.queryCache.invalidateQueriesForScreenname(screenname) |
1437 | return result |
1438 | |
1439 | + |
1440 | def _followOrUnfollow(follow, cookie, cache, uid): |
1441 | try: |
1442 | user, accessToken = cache.cookieCache[cookie] |
1443 | @@ -258,7 +267,7 @@ |
1444 | else: |
1445 | url = UNFOLLOW_URL |
1446 | |
1447 | - parameters = { 'user_id' : str(uid) } |
1448 | + parameters = {'user_id': str(uid)} |
1449 | oaRequest = oauth.OAuthRequest.from_consumer_and_token( |
1450 | consumer.consumer, token=accessToken, parameters=parameters, |
1451 | http_url=url, http_method='POST') |
1452 | |
1453 | === modified file 'tickery/usercache.py' |
1454 | --- tickery/usercache.py 2011-06-14 20:36:36 +0000 |
1455 | +++ tickery/usercache.py 2011-06-16 16:17:19 +0000 |
1456 | @@ -28,6 +28,7 @@ |
1457 | u'screen_name', |
1458 | u'statuses_count',) |
1459 | |
1460 | + |
1461 | def dictSubset(d, names): |
1462 | '''Return a new dict consisting of the items in d that are in names.''' |
1463 | return dict([(key, d[key]) for key in names if key in d]) |
1464 | @@ -46,7 +47,7 @@ |
1465 | (u['screen_name'].lower(), u) for u in self.uidToUser.values()) |
1466 | |
1467 | def __str__(self): |
1468 | - s = [ '%d names in Twitter user cache' % len(self.screennameToUser) ] |
1469 | + s = ['%d names in Twitter user cache' % len(self.screennameToUser)] |
1470 | for key in sorted(self.screennameToUser.keys()): |
1471 | item = self.screennameToUser[key] |
1472 | s.append('%s: id=%s' % (key, item['id'])) |
1473 | @@ -71,8 +72,10 @@ |
1474 | def usersByScreennames(self, screennames): |
1475 | # Return a dict of screenname -> user or failure. |
1476 | result = {} |
1477 | + |
1478 | def _done(what, screenname): |
1479 | result[screenname] = what |
1480 | + |
1481 | deferreds = [] |
1482 | for screenname in screennames: |
1483 | d = self.userByScreenname(screenname) |
1484 | |
1485 | === modified file 'tickery/utils.py' |
1486 | --- tickery/utils.py 2011-06-14 20:36:36 +0000 |
1487 | +++ tickery/utils.py 2011-06-16 16:17:19 +0000 |
1488 | @@ -43,8 +43,8 @@ |
1489 | def create(cls, endpoint, username, name, password, email): |
1490 | def _parseResponse(response): |
1491 | return cls(username, response[u'id']) |
1492 | - data = { 'userName' : username, 'name' : name, |
1493 | - 'password' : password, 'email' : email } |
1494 | + data = {'userName': username, 'name': name, |
1495 | + 'password': password, 'email': email} |
1496 | d = endpoint.submit(endpoint.getRootURL() + 'users', |
1497 | method='POST', data=data) |
1498 | return d.addCallback(_parseResponse) |
1499 | |
1500 | === modified file 'tickery/www/Popups.py' |
1501 | --- tickery/www/Popups.py 2011-06-14 20:36:36 +0000 |
1502 | +++ tickery/www/Popups.py 2011-06-16 16:17:19 +0000 |
1503 | @@ -23,14 +23,17 @@ |
1504 | |
1505 | modal_popups = {} |
1506 | |
1507 | + |
1508 | def ModalPopupActive(title): |
1509 | - return modal_popups.has_key(title) |
1510 | + return title in modal_popups |
1511 | + |
1512 | |
1513 | def ModalPopupCloseAll(): |
1514 | while len(modal_popups) > 0: |
1515 | k = modal_popups.keys()[0] |
1516 | modal_popups[k].hide() |
1517 | |
1518 | + |
1519 | class DialogBoxModal(PopupPanel): |
1520 | def __init__(self, identifier, autoHide=None, modal=False, rootpanel=None): |
1521 | PopupPanel.__init__(self, autoHide, modal, rootpanel) |
1522 | @@ -146,15 +149,15 @@ |
1523 | top = 0 |
1524 | |
1525 | element = self.getElement() |
1526 | - DOM.setStyleAttribute(element, 'left', '%dpx' % left ) |
1527 | + DOM.setStyleAttribute(element, 'left', '%dpx' % left) |
1528 | DOM.setStyleAttribute(element, 'top', '%dpx' % top) |
1529 | |
1530 | def show(self): |
1531 | if self.showing: |
1532 | return |
1533 | |
1534 | - if modal_popups.has_key(self.identifier) and \ |
1535 | - modal_popups[self.identifier] != self: |
1536 | + if (self.identifier in modal_popups and |
1537 | + modal_popups[self.identifier] != self): |
1538 | return |
1539 | modal_popups[self.identifier] = self |
1540 | |
1541 | @@ -164,7 +167,7 @@ |
1542 | if not self.showing: |
1543 | return |
1544 | |
1545 | - if modal_popups.has_key(self.identifier): |
1546 | + if self.identifier in modal_popups: |
1547 | del modal_popups[self.identifier] |
1548 | |
1549 | PopupPanel.hide(self) |
1550 | @@ -185,7 +188,7 @@ |
1551 | class PopupFrame(DialogBoxModal): |
1552 | |
1553 | def __init__(self, identifier, title, iframe): |
1554 | - if modal_popups.has_key(identifier): |
1555 | + if identifier in modal_popups: |
1556 | return |
1557 | modal_popups[identifier] = self |
1558 | |
1559 | |
1560 | === modified file 'tickery/www/about.py' |
1561 | --- tickery/www/about.py 2011-06-14 20:36:36 +0000 |
1562 | +++ tickery/www/about.py 2011-06-16 16:17:19 +0000 |
1563 | @@ -16,7 +16,8 @@ |
1564 | from pyjamas.ui.Grid import Grid |
1565 | |
1566 | body = """ |
1567 | -<a href=\"http://fluidinfo.com\"><img src=\"fluidinfo.png\" class=\"about-logo\"/></a><h2>About Tickery</h2> |
1568 | +<a href=\"http://fluidinfo.com\"><img src=\"fluidinfo.png\" \ |
1569 | +class=\"about-logo\"/></a><h2>About Tickery</h2> |
1570 | |
1571 | <p> |
1572 | |
1573 | @@ -75,7 +76,9 @@ |
1574 | At Fluidinfo, we believe it will one day be <em>much</em> easier to work |
1575 | with information. We've built FluidDB to show you what we think the future |
1576 | will look like. It's a future in which we'll work with information in more |
1577 | -flexible ways, and with data that is <a href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/24/truly-social-data/\">truly social</a>. |
1578 | +flexible ways, and with data that is |
1579 | +<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/24/\ |
1580 | +truly-social-data/\">truly social</a>. |
1581 | |
1582 | </p> |
1583 | |
1584 | @@ -91,13 +94,21 @@ |
1585 | href=\"http://blogs.fluidinfo.com/fluidDB\">FluidDB blog</a>. In particular, |
1586 | the following articles provide a good set of viewpoints: |
1587 | |
1588 | -<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/24/truly-social-data/\">Truly Social Data</a>, |
1589 | -<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/25/kaleidoscope-10-takes-on-fluiddb/\">Kaleidoscope: 10 Takes on FluidDB</a>, |
1590 | -<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/28/information-naturally/\">Information. Naturally.</a>, |
1591 | -<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/10/03/fluiddb-as-a-universal-metadata-engine/\">FluidDB as a Universal Metadata Engine</a>, |
1592 | -<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/11/12/why-are-post-it-notes-sticky/\">Why are Post-It Notes Sticky?</a>, |
1593 | +<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/24/\ |
1594 | +truly-social-data/\">Truly Social Data</a>, |
1595 | +<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/25/\ |
1596 | +kaleidoscope-10-takes-on-fluiddb/\">Kaleidoscope: 10 Takes on FluidDB</a>, |
1597 | +<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/28/\ |
1598 | +information-naturally/\">Information. Naturally.</a>, |
1599 | +<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/10/03/\ |
1600 | +fluiddb-as-a-universal-metadata-engine/\">FluidDB as a Universal Metadata |
1601 | +Engine</a>, |
1602 | +<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/11/12/\ |
1603 | +why-are-post-it-notes-sticky/\">Why are Post-It Notes Sticky?</a>, |
1604 | and |
1605 | -<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/12/01/putting-metadata-onto-tweets-with-fluiddb/\">Putting Metadata onto Tweets with FluidDB</a>. |
1606 | +<a href=\"http://blogs.fluidinfo.com/fluidDB/2009/12/01/\ |
1607 | +putting-metadata-onto-tweets-with-fluiddb/\">Putting Metadata onto Tweets |
1608 | +with FluidDB</a>. |
1609 | |
1610 | <p> |
1611 | |
1612 | @@ -105,7 +116,8 @@ |
1613 | href=\"http://fluidinfo.com/accounts/new\">reserve a FluidDB username</a> |
1614 | and then <a href=\"mailto:api@fluidinfo.com\">send us mail</a> to get a |
1615 | password. Note that FluidDB is still in an early <a |
1616 | -href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/17/a-private-alpha-launch/\">private alpha</a> phase. |
1617 | +href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/17/\ |
1618 | +a-private-alpha-launch/\">private alpha</a> phase. |
1619 | |
1620 | </p> |
1621 | |
1622 | |
1623 | === modified file 'tickery/www/advanced.py' |
1624 | --- tickery/www/advanced.py 2011-06-14 20:36:36 +0000 |
1625 | +++ tickery/www/advanced.py 2011-06-16 16:17:19 +0000 |
1626 | @@ -13,7 +13,8 @@ |
1627 | # permissions and limitations under the License. |
1628 | |
1629 | from tickerytab import LargeQueryTab |
1630 | -import simple, defaults |
1631 | +import simple |
1632 | +import defaults |
1633 | |
1634 | from pyjamas.ui.HTML import HTML |
1635 | |
1636 | @@ -56,7 +57,9 @@ |
1637 | class=\"example\">%(simpleUser1)s</span> and <span |
1638 | class=\"example\">%(simpleUser2)s</span> results in the query |
1639 | |
1640 | -<a href=\"%(advancedq)shas+%(friends)s/%(simpleUser1)s+and+has+%(friends)s/%(simpleUser2)s\">has %(friends)s/%(simpleUser1)s and has %(friends)s/%(simpleUser2)s</a> |
1641 | +<a href=\"%(advancedq)shas+%(friends)s/%(simpleUser1)s+and+has+\ |
1642 | +%(friends)s/%(simpleUser2)s\">has %(friends)s/%(simpleUser1)s and \ |
1643 | +has %(friends)s/%(simpleUser2)s</a> |
1644 | |
1645 | being sent to FluidDB. I.e., Tickery asks FluidDB for all objects that have |
1646 | a <span class=\"example\">%(friends)s/%(simpleUser1)s</span> tag and also a |
1647 | @@ -71,7 +74,8 @@ |
1648 | |
1649 | results in the FluidDB query: |
1650 | |
1651 | -<a href=\"%(advancedq)shas+%(friends)s/biz+except+has+%(friends)s/ev\">has %(friends)s/biz except has %(friends)s/ev</a>. |
1652 | +<a href=\"%(advancedq)shas+%(friends)s/biz+except+has+%(friends)s/ev\">\ |
1653 | +has %(friends)s/biz except has %(friends)s/ev</a>. |
1654 | |
1655 | That is, Tickery asks FluidDB for all objects that have a |
1656 | <span class=\"example\">%(friends)s/biz</span> |
1657 | @@ -104,10 +108,13 @@ |
1658 | <a href=\"%(advancedq)stwitter.com/users/id<100\">twitter.com/users/id < |
1659 | 100</a>, or we can look for a particular user: |
1660 | |
1661 | -<a href='%(advancedq)stwitter.com/users/screen_name+=+\"%(simpleUser1)s\"'>twitter.com/users/screen_name = \"%(simpleUser1)s\"</a>. FluidDB has some other |
1662 | -Twitter tags on its objects too. For example, you can query |
1663 | +<a href='%(advancedq)stwitter.com/users/screen_name+=+\"%(simpleUser1)s\"'>\ |
1664 | +twitter.com/users/screen_name = \"%(simpleUser1)s\"</a>. |
1665 | +FluidDB has some other Twitter tags on its objects too. For example, you |
1666 | +can query |
1667 | |
1668 | -<a href='%(advancedq)stwitter.com/users/followers_count+>+100000'>twitter.com/users/followers_count > 100000</a>. |
1669 | +<a href='%(advancedq)stwitter.com/users/followers_count+>+100000'>\ |
1670 | +twitter.com/users/followers_count > 100000</a>. |
1671 | |
1672 | <p/> |
1673 | |
1674 | @@ -126,11 +133,14 @@ |
1675 | class=\"example\">terrycojones/met</span> tag to FluidDB's objects for |
1676 | Twitter people that I've met in person. So the query |
1677 | |
1678 | -<a href='%(advancedq)shas+%(friends)s/terrycojones+and+has+terrycojones/met'>has %(friends)s/terrycojones and has terrycojones/met</a> |
1679 | +<a href='%(advancedq)shas+%(friends)s/terrycojones+and+has+terrycojones/met'>\ |
1680 | +has %(friends)s/terrycojones and has terrycojones/met</a> |
1681 | |
1682 | shows the Twitter people I follow that I have also met, while |
1683 | |
1684 | -<a href='%(advancedq)shas+%(friends)s/terrycojones+except+has+terrycojones/met'>has %(friends)s/terrycojones except has terrycojones/met</a> |
1685 | +<a href='%(advancedq)shas+%(friends)s/\ |
1686 | +terrycojones+except+has+terrycojones/met'>has %(friends)s/terrycojones \ |
1687 | +except has terrycojones/met</a> |
1688 | |
1689 | shows those I have not met. |
1690 | |
1691 | @@ -142,11 +152,16 @@ |
1692 | class=\"example\">esteve/met</span> tags to the people he follows and has |
1693 | met. The query |
1694 | |
1695 | -<a href='%(advancedq)s(has+%(friends)s/terrycojones+and+has+%(friends)s/esteve)+except+(has+terrycojones/met+or+has+esteve/met)'>(has %(friends)s/terrycojones and has %(friends)s/esteve) except (has terrycojones/met or has esteve/met)</a> |
1696 | +<a href='%(advancedq)s(has+%(friends)s/terrycojones+and+has+%(friends)s\ |
1697 | +/esteve)+except+(has+terrycojones/met+or+has+esteve/met)'>(has %(friends)s\ |
1698 | +/terrycojones and has %(friends)s/esteve) except (has terrycojones/met or \ |
1699 | +has esteve/met)</a> |
1700 | |
1701 | shows people we both follow but which neither of us has met. And |
1702 | |
1703 | -<a href='%(advancedq)s(has+%(friends)s/esteve+and+has+terrycojones/met)+except+has+esteve/met'>(has %(friends)s/esteve and has terrycojones/met) except has esteve/met</a> |
1704 | +<a href='%(advancedq)s(has+%(friends)s/esteve+and+has+terrycojones/met)+\ |
1705 | +except+has+esteve/met'>(has %(friends)s/esteve and has terrycojones/met) \ |
1706 | +except has esteve/met</a> |
1707 | |
1708 | shows people Esteve follows that I have met in person but whom he has |
1709 | not—we could use this, and its complement, to figure out who we |
1710 | @@ -183,31 +198,32 @@ |
1711 | href=\"http://fluidinfo.com/accounts/new\">reserve a FluidDB username</a> |
1712 | and then <a href=\"mailto:api@fluidinfo.com\">send us mail</a> to get a |
1713 | password. Note that FluidDB is still in an early <a |
1714 | -href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/17/a-private-alpha-launch/\">private alpha</a> phase. |
1715 | +href=\"http://blogs.fluidinfo.com/fluidDB/2009/08/17/\ |
1716 | +a-private-alpha-launch/\">private alpha</a> phase. |
1717 | |
1718 | </p> |
1719 | |
1720 | """ % { |
1721 | - 'simpleUser1' : simple._defaultName1, |
1722 | - 'simpleUser2' : simple._defaultName2, |
1723 | - 'friends' : '%s/%s' % (defaults.TWITTER_USERNAME, |
1724 | + 'simpleUser1': simple._defaultName1, |
1725 | + 'simpleUser2': simple._defaultName2, |
1726 | + 'friends': '%s/%s' % (defaults.TWITTER_USERNAME, |
1727 | defaults.TWITTER_FRIENDS_NAMESPACE_NAME), |
1728 | - 'intq' : '%s/?tab=intermediate&query=' % defaults.TICKERY_URL, |
1729 | - 'advancedq' : '%s/?tab=advanced&query=' % defaults.TICKERY_URL, |
1730 | + 'intq': '%s/?tab=intermediate&query=' % defaults.TICKERY_URL, |
1731 | + 'advancedq': '%s/?tab=advanced&query=' % defaults.TICKERY_URL, |
1732 | } |
1733 | |
1734 | |
1735 | - |
1736 | class Advanced(LargeQueryTab): |
1737 | |
1738 | tabName = 'advanced' |
1739 | |
1740 | defaultQuery = ( |
1741 | '''has %(tw)s/%(fr)s/jack and has %(tw)s/%(fr)s/ev''' % |
1742 | - { 'tw' : 'twitter.com', 'fr' : 'friends', }) |
1743 | + {'tw': 'twitter.com', 'fr': 'friends'}) |
1744 | |
1745 | def __init__(self, topPanel): |
1746 | self.goButtonRemoteMethod = 'fluidDBQuery' |
1747 | self.instructions = HTML(_instructions) |
1748 | - self.instructionsTitle = 'The FluidDB query language & the advanced tab' |
1749 | + self.instructionsTitle = ('The FluidDB query language ' |
1750 | + '& the advanced tab') |
1751 | LargeQueryTab.__init__(self, topPanel) |
1752 | |
1753 | === modified file 'tickery/www/banner.py' |
1754 | --- tickery/www/banner.py 2010-07-20 09:47:02 +0000 |
1755 | +++ tickery/www/banner.py 2011-06-16 16:17:19 +0000 |
1756 | @@ -12,7 +12,8 @@ |
1757 | # implied. See the License for the specific language governing |
1758 | # permissions and limitations under the License. |
1759 | |
1760 | -import utils, server |
1761 | +import utils |
1762 | +import server |
1763 | |
1764 | from pyjamas.ui.Image import Image |
1765 | from pyjamas.ui.HTML import HTML |
1766 | |
1767 | === modified file 'tickery/www/defaults.py' |
1768 | --- tickery/www/defaults.py 2010-07-20 09:47:02 +0000 |
1769 | +++ tickery/www/defaults.py 2011-06-16 16:17:19 +0000 |
1770 | @@ -47,7 +47,7 @@ |
1771 | |
1772 | FLUIDDB_ENDPOINT = 'http://fluiddb.fluidinfo.com/' |
1773 | SANDBOX_ENDPOINT = 'http://sandbox.fluidinfo.com/' |
1774 | -LOCAL_ENDPOINT = 'http://localhost:8080/' |
1775 | +LOCAL_ENDPOINT = 'http://localhost:8080/' |
1776 | |
1777 | FRIENDS_LIMIT = 1000 |
1778 | RESULTS_LIMIT = 1000 |
1779 | |
1780 | === modified file 'tickery/www/index.py' |
1781 | --- tickery/www/index.py 2011-06-14 20:36:36 +0000 |
1782 | +++ tickery/www/index.py 2011-06-16 16:17:19 +0000 |
1783 | @@ -17,7 +17,9 @@ |
1784 | from pyjamas.ui.SimplePanel import SimplePanel |
1785 | from pyjamas import Timer, DeferredCommand, Window |
1786 | |
1787 | -import tabs, userlist, defaults |
1788 | +import tabs |
1789 | +import userlist |
1790 | +import defaults |
1791 | |
1792 | |
1793 | class Tickery(SimplePanel): |
1794 | |
1795 | === modified file 'tickery/www/intermediate.py' |
1796 | --- tickery/www/intermediate.py 2010-07-20 09:47:02 +0000 |
1797 | +++ tickery/www/intermediate.py 2011-06-16 16:17:19 +0000 |
1798 | @@ -103,7 +103,7 @@ |
1799 | </p> |
1800 | |
1801 | """ % { |
1802 | - 'intq' : '%s/?tab=intermediate&query=' % defaults.TICKERY_URL, |
1803 | + 'intq': '%s/?tab=intermediate&query=' % defaults.TICKERY_URL, |
1804 | } |
1805 | |
1806 | |
1807 | |
1808 | === modified file 'tickery/www/login.py' |
1809 | --- tickery/www/login.py 2011-06-14 20:36:36 +0000 |
1810 | +++ tickery/www/login.py 2011-06-16 16:17:19 +0000 |
1811 | @@ -12,7 +12,10 @@ |
1812 | # implied. See the License for the specific language governing |
1813 | # permissions and limitations under the License. |
1814 | |
1815 | -import defaults, utils, server, tickerytab |
1816 | +import defaults |
1817 | +import server |
1818 | +import tickerytab |
1819 | +import utils |
1820 | |
1821 | from pyjamas.ui.Grid import Grid |
1822 | from pyjamas.ui.HTML import HTML |
1823 | @@ -22,6 +25,7 @@ |
1824 | from pyjamas.ui import HasAlignment, Event |
1825 | from pyjamas import Window, Cookies, DOM |
1826 | |
1827 | + |
1828 | def _deleteCookie(): |
1829 | # Set the cookie back in time a few years. |
1830 | Cookies.setCookie(defaults.OAUTH_COOKIE, '', -100000000) |
1831 | @@ -207,7 +211,6 @@ |
1832 | self.sender.notLoggedIn() |
1833 | |
1834 | |
1835 | - |
1836 | class SetFriends(object): |
1837 | def __init__(self, screenname, sender): |
1838 | self.screenname = screenname |
1839 | @@ -218,7 +221,10 @@ |
1840 | d = {} |
1841 | for fid in friendsIds: |
1842 | d[fid] = None |
1843 | - self.sender.friendsIds = d #ict.fromkeys(friendsIds) |
1844 | + # TODO: figure out if the next line is right or an accidental |
1845 | + # insertion of " #" that just happens to have created valid |
1846 | + # code. The "d #ict" code is running on tickery.net |
1847 | + self.sender.friendsIds = d # ict.fromkeys(friendsIds) |
1848 | self.sender.loggedIn = True |
1849 | # All done, finalize the setup of all existing UserListPanels so |
1850 | # they can filter users based on the friendsIds we just retrieved. |
1851 | |
1852 | === modified file 'tickery/www/results.py' |
1853 | --- tickery/www/results.py 2010-07-20 09:47:02 +0000 |
1854 | +++ tickery/www/results.py 2011-06-16 16:17:19 +0000 |
1855 | @@ -35,7 +35,7 @@ |
1856 | users = result['users'] |
1857 | title = self.titleMaker(users) |
1858 | if users: |
1859 | - kw = { 'query' : self.query } |
1860 | + kw = {'query': self.query} |
1861 | if self.tabName == 'simple': |
1862 | kw['screennames'] = self.sender.getNames() |
1863 | self.sender.results.setUsers(title, users, kw) |
1864 | |
1865 | === modified file 'tickery/www/simple.py' |
1866 | --- tickery/www/simple.py 2011-06-14 20:36:36 +0000 |
1867 | +++ tickery/www/simple.py 2011-06-16 16:17:19 +0000 |
1868 | @@ -12,7 +12,13 @@ |
1869 | # implied. See the License for the specific language governing |
1870 | # permissions and limitations under the License. |
1871 | |
1872 | -import urllib, utils, userlist, go, server, text, defaults |
1873 | +import urllib |
1874 | +import utils |
1875 | +import userlist |
1876 | +import go |
1877 | +import server |
1878 | +import text |
1879 | +import defaults |
1880 | from results import ResultHandler |
1881 | |
1882 | from tickerytab import TickeryTab |
1883 | @@ -27,6 +33,7 @@ |
1884 | _defaultName1 = 'timoreilly' |
1885 | _defaultName2 = 'timbray' |
1886 | |
1887 | + |
1888 | class Simple(TickeryTab): |
1889 | |
1890 | tabName = 'simple' |
1891 | @@ -173,11 +180,11 @@ |
1892 | def resultsLink(self): |
1893 | name1, name2 = self.getNames() |
1894 | d = { |
1895 | - 'name1' : name1, |
1896 | - 'name2' : name2, |
1897 | - 'sort' : userlist._sortKey, |
1898 | - 'icon' : userlist._iconSize, |
1899 | - 'tab' : self.tabName, |
1900 | + 'name1': name1, |
1901 | + 'name2': name2, |
1902 | + 'sort': userlist._sortKey, |
1903 | + 'icon': userlist._iconSize, |
1904 | + 'tab': self.tabName, |
1905 | } |
1906 | |
1907 | return '%s?%s' % (defaults.TICKERY_URL, urllib.urlencode(d)) |
1908 | |
1909 | === modified file 'tickery/www/tabs.py' |
1910 | --- tickery/www/tabs.py 2011-06-14 20:36:36 +0000 |
1911 | +++ tickery/www/tabs.py 2011-06-16 16:17:19 +0000 |
1912 | @@ -12,7 +12,12 @@ |
1913 | # implied. See the License for the specific language governing |
1914 | # permissions and limitations under the License. |
1915 | |
1916 | -import toppanel, simple, intermediate, advanced, about, login |
1917 | +import toppanel |
1918 | +import simple |
1919 | +import intermediate |
1920 | +import advanced |
1921 | +import about |
1922 | +import login |
1923 | |
1924 | from pyjamas.ui.TabPanel import TabPanel |
1925 | from pyjamas.ui.HTML import HTML |
1926 | |
1927 | === modified file 'tickery/www/tickerytab.py' |
1928 | --- tickery/www/tickerytab.py 2011-06-14 20:36:36 +0000 |
1929 | +++ tickery/www/tickerytab.py 2011-06-16 16:17:19 +0000 |
1930 | @@ -14,7 +14,12 @@ |
1931 | |
1932 | import urllib |
1933 | |
1934 | -import go, userlist, server, text, results, defaults |
1935 | +import go |
1936 | +import userlist |
1937 | +import server |
1938 | +import text |
1939 | +import results |
1940 | +import defaults |
1941 | |
1942 | from pyjamas.ui.Label import Label |
1943 | from pyjamas.ui.Button import Button |
1944 | @@ -47,15 +52,16 @@ |
1945 | |
1946 | SHORT_INSTRUCTIONS = { |
1947 | # Don't put line breaks into the following strings. MSIE preserves them! |
1948 | - 'intermediate' : |
1949 | + 'intermediate': |
1950 | """Explore sets of Twitter friends by querying on their user names""", |
1951 | |
1952 | - 'advanced' : |
1953 | + 'advanced': |
1954 | """Query Twitter friends & more with the full FluidDB query language""", |
1955 | } |
1956 | |
1957 | HELP_TEXT = 'huh?' |
1958 | |
1959 | + |
1960 | def titleMaker(users): |
1961 | if users: |
1962 | nUsers = len(users) |
1963 | @@ -68,17 +74,16 @@ |
1964 | return 'Results set is empty.' |
1965 | |
1966 | |
1967 | - |
1968 | class TickeryTab(VerticalPanel): |
1969 | |
1970 | - process = None # Define in subclass. |
1971 | + process = None # Define in subclass. |
1972 | |
1973 | def __init__(self, topPanel, **kwargs): |
1974 | VerticalPanel.__init__(self, |
1975 | HorizontalAlignment=HasAlignment.ALIGN_LEFT, |
1976 | StyleName='tickery-tab', |
1977 | **kwargs) |
1978 | - self.topPanel = topPanel # don't add this yet! |
1979 | + self.topPanel = topPanel # don't add this yet! |
1980 | self.topGrid = Grid(1, 2, StyleName='tickery-tab-top-grid', |
1981 | HorizontalAlignment=HasAlignment.ALIGN_LEFT) |
1982 | self.add(self.topGrid) |
1983 | @@ -199,10 +204,10 @@ |
1984 | |
1985 | def resultsLink(self): |
1986 | d = { |
1987 | - 'query' : self.query.getText().strip(), |
1988 | - 'sort' : userlist._sortKey, |
1989 | - 'icon' : userlist._iconSize, |
1990 | - 'tab' : self.tabName, |
1991 | + 'query': self.query.getText().strip(), |
1992 | + 'sort': userlist._sortKey, |
1993 | + 'icon': userlist._iconSize, |
1994 | + 'tab': self.tabName, |
1995 | } |
1996 | |
1997 | return '%s?%s' % (defaults.TICKERY_URL, urllib.urlencode(d)) |
1998 | |
1999 | === modified file 'tickery/www/tweet.py' |
2000 | --- tickery/www/tweet.py 2011-06-14 20:36:36 +0000 |
2001 | +++ tickery/www/tweet.py 2011-06-16 16:17:19 +0000 |
2002 | @@ -12,7 +12,9 @@ |
2003 | # implied. See the License for the specific language governing |
2004 | # permissions and limitations under the License. |
2005 | |
2006 | -import server, userlist, text |
2007 | +import server |
2008 | +import userlist |
2009 | +import text |
2010 | |
2011 | from pyjamas.ui.HTML import HTML |
2012 | from pyjamas.ui.Label import Label |
2013 | |
2014 | === modified file 'tickery/www/unknown.py' |
2015 | --- tickery/www/unknown.py 2011-06-14 20:36:36 +0000 |
2016 | +++ tickery/www/unknown.py 2011-06-16 16:17:19 +0000 |
2017 | @@ -17,7 +17,8 @@ |
2018 | from pyjamas.ui.Grid import Grid |
2019 | from pyjamas.ui.VerticalPanel import VerticalPanel |
2020 | |
2021 | -import utils, go |
2022 | +import utils |
2023 | +import go |
2024 | |
2025 | |
2026 | class UserList(VerticalPanel): |
2027 | @@ -78,7 +79,8 @@ |
2028 | |
2029 | class UnaddedUsers(VerticalPanel): |
2030 | def __init__(self, statusSummary, sender): |
2031 | - VerticalPanel.__init__(self, Spacing=10, StyleName='userlist-error-box') |
2032 | + VerticalPanel.__init__(self, Spacing=10, |
2033 | + StyleName='userlist-error-box') |
2034 | self.add(HTML("We're currently working on users you mentioned", |
2035 | StyleName='userlist-error-title')) |
2036 | |
2037 | |
2038 | === modified file 'tickery/www/userlist.py' |
2039 | --- tickery/www/userlist.py 2011-06-14 20:36:36 +0000 |
2040 | +++ tickery/www/userlist.py 2011-06-16 16:17:19 +0000 |
2041 | @@ -12,7 +12,10 @@ |
2042 | # implied. See the License for the specific language governing |
2043 | # permissions and limitations under the License. |
2044 | |
2045 | -import utils, tweet, server, defaults |
2046 | +import utils |
2047 | +import tweet |
2048 | +import server |
2049 | +import defaults |
2050 | |
2051 | from pyjamas.ui.Label import Label |
2052 | from pyjamas.ui.Image import Image |
2053 | @@ -33,6 +36,7 @@ |
2054 | ('Large', 'large'), |
2055 | ) |
2056 | |
2057 | + |
2058 | def setIconSize(size): |
2059 | global _iconSize |
2060 | if size and size in [d[1] for d in _iconData]: |
2061 | @@ -57,6 +61,7 @@ |
2062 | (u'Public (true/false)', 'protected'), |
2063 | ) |
2064 | |
2065 | + |
2066 | def setSortKey(key): |
2067 | global _sortKey |
2068 | if key and key in [d[1] for d in _sortKeyData]: |
2069 | @@ -409,6 +414,7 @@ |
2070 | decreasing = _sortKey in ( |
2071 | 'friends_count', 'followers_count', 'statuses_count') |
2072 | alpha = _sortKey in ('screen_name', 'name', 'location') |
2073 | + |
2074 | def _keyFunc(n): |
2075 | value = self.users[n][_sortKey] |
2076 | if decreasing: |
2077 | @@ -504,6 +510,7 @@ |
2078 | def adjustSize(self, width, height): |
2079 | self.adjustWidths(width) |
2080 | |
2081 | + |
2082 | class IconAdder(object): |
2083 | |
2084 | _updatesPerLoop = 5 |
2085 | |
2086 | === modified file 'tickery/www/utils.py' |
2087 | --- tickery/www/utils.py 2010-07-20 09:47:02 +0000 |
2088 | +++ tickery/www/utils.py 2011-06-16 16:17:19 +0000 |
2089 | @@ -14,19 +14,24 @@ |
2090 | |
2091 | import urllib |
2092 | |
2093 | + |
2094 | def screennameToTwitterURL(s): |
2095 | return 'http://twitter.com/%s' % urllib.quote(s) |
2096 | |
2097 | + |
2098 | def screennameToTwitterLink(s, text=None): |
2099 | text = text or s |
2100 | return '<a href="%s">%s</a>' % (screennameToTwitterURL(s), text) |
2101 | |
2102 | + |
2103 | def screennameToTwitterFriendsLink(s, text): |
2104 | return '<a href="%s/following">%s</a>' % (screennameToTwitterURL(s), text) |
2105 | |
2106 | + |
2107 | def screennameToTwitterFollowersLink(s, text): |
2108 | return '<a href="%s/followers">%s</a>' % (screennameToTwitterURL(s), text) |
2109 | |
2110 | + |
2111 | def splitthousands(n, sep=','): |
2112 | # From http://code.activestate.com/recipes/498181/ |
2113 | s = '%s' % n # This to keep MSIE quiet? |
2114 | |
2115 | === modified file 'twisted/plugins/tickery_service.py' |
2116 | --- twisted/plugins/tickery_service.py 2011-06-14 20:36:36 +0000 |
2117 | +++ twisted/plugins/tickery_service.py 2011-06-16 16:17:19 +0000 |
2118 | @@ -33,7 +33,7 @@ |
2119 | optParameters = [ |
2120 | ['cache-dir', None, 'CACHE', 'The directory for cache files.'], |
2121 | ['queue-width', None, 3, 'The initial size of the dispatch queue.'], |
2122 | - ['port', None, defaults.TICKERY_SERVICE_PORT, 'The port to listen on.'], |
2123 | + ['port', None, defaults.TICKERY_SERVICE_PORT, 'Port to listen on.'], |
2124 | ] |
2125 | optFlags = [ |
2126 | ['noisy-logging', None, "If True, let factories log verbosely."], |
2127 | @@ -62,7 +62,8 @@ |
2128 | |
2129 | root = File('www/output') |
2130 | root.putChild('tickery', RegularService(cache, endpoint)) |
2131 | - root.putChild(defaults.TICKERY_CALLBACK_CHILD, callback.Callback(cache)) |
2132 | + root.putChild(defaults.TICKERY_CALLBACK_CHILD, |
2133 | + callback.Callback(cache)) |
2134 | |
2135 | adminRoot = File('admin/output') |
2136 | adminRoot.putChild('tickery', AdminService(cache)) |
2137 | @@ -74,7 +75,7 @@ |
2138 | if options['promiscuous']: |
2139 | kw = {} |
2140 | else: |
2141 | - kw = { 'interface' : 'localhost' } |
2142 | + kw = {'interface': 'localhost'} |
2143 | tickeryServer = internet.TCPServer(int(options['port']), factory, **kw) |
2144 | tickeryServer.setServiceParent(tickeryService) |
2145 |
+1 I reviewed every single line of the 2K diff and it looks good to me.