|
14 | 14 | from requests_oauthlib import OAuth1, OAuth2 |
15 | 15 |
|
16 | 16 | from . import __version__ |
| 17 | +from .advisory import TwythonDeprecationWarning |
17 | 18 | from .compat import json, urlencode, parse_qsl, quote_plus, str, is_py2 |
18 | 19 | from .endpoints import EndpointsMixin |
19 | 20 | from .exceptions import TwythonError, TwythonAuthError, TwythonRateLimitError |
20 | 21 | from .helpers import _transparent_params |
21 | 22 |
|
| 23 | +import warnings |
| 24 | + |
| 25 | +warnings.simplefilter('always', TwythonDeprecationWarning) # For Python 2.7 > |
| 26 | + |
22 | 27 |
|
23 | 28 | class Twython(EndpointsMixin, object): |
24 | 29 | def __init__(self, app_key=None, app_secret=None, oauth_token=None, |
@@ -376,22 +381,65 @@ def search_gen(self, search_query, **params): |
376 | 381 | >>> print result |
377 | 382 |
|
378 | 383 | """ |
379 | | - content = self.search(q=search_query, **params) |
| 384 | + warnings.warn( |
| 385 | + 'This method is deprecated. You should use Twython.cursor instead. [eg. Twython.cursor(Twython.search, q=\'your_query\')]', |
| 386 | + TwythonDeprecationWarning, |
| 387 | + stacklevel=2 |
| 388 | + ) |
| 389 | + return self.cursor(self.search, q=search_query, **params) |
| 390 | + |
| 391 | + def cursor(self, function, **params): |
| 392 | + """Returns a generator for results that match a specified query. |
| 393 | +
|
| 394 | + :param function: Instance of a Twython function (Twython.get_home_timeline, Twython.search) |
| 395 | + :param \*\*params: Extra parameters to send with your request (usually parameters excepted by the Twitter API endpoint) |
| 396 | + :rtype: generator |
| 397 | +
|
| 398 | + Usage:: |
380 | 399 |
|
381 | | - if not content.get('statuses'): |
| 400 | + >>> from twython import Twython |
| 401 | + >>> twitter = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET) |
| 402 | +
|
| 403 | + >>> results = twitter.cursor(twitter.search, q='python') |
| 404 | + >>> for result in results: |
| 405 | + >>> print result |
| 406 | +
|
| 407 | + """ |
| 408 | + if not hasattr(function, 'iter_mode'): |
| 409 | + raise TwythonError('Unable to create generator for Twython method "%s"' % function.__name__) |
| 410 | + |
| 411 | + content = function(**params) |
| 412 | + |
| 413 | + if not content: |
382 | 414 | raise StopIteration |
383 | 415 |
|
384 | | - for tweet in content['statuses']: |
385 | | - yield tweet |
| 416 | + if function.iter_mode == 'cursor' and content['next_cursor_str'] == '0': |
| 417 | + raise StopIteration |
| 418 | + |
| 419 | + if hasattr(function, 'iter_key'): |
| 420 | + results = content.get(function.iter_key) |
| 421 | + else: |
| 422 | + results = content |
| 423 | + |
| 424 | + for result in results: |
| 425 | + yield result |
386 | 426 |
|
387 | 427 | try: |
388 | | - if not 'since_id' in params: |
389 | | - params['since_id'] = (int(content['statuses'][0]['id_str']) + 1) |
| 428 | + if function.iter_mode == 'id': |
| 429 | + if not 'max_id' in params: |
| 430 | + # Add 1 to the id because since_id and max_id are inclusive |
| 431 | + if hasattr(function, 'iter_metadata'): |
| 432 | + since_id = content[function.iter_metadata].get('since_id_str') |
| 433 | + else: |
| 434 | + since_id = content[0]['id_str'] |
| 435 | + params['since_id'] = (int(since_id) - 1) |
| 436 | + elif function.iter_mode == 'cursor': |
| 437 | + params['cursor'] = content['next_cursor_str'] |
390 | 438 | except (TypeError, ValueError): # pragma: no cover |
391 | 439 | raise TwythonError('Unable to generate next page of search results, `page` is not a number.') |
392 | 440 |
|
393 | | - for tweet in self.search_gen(search_query, **params): |
394 | | - yield tweet |
| 441 | + for result in self.cursor(function, **params): |
| 442 | + yield result |
395 | 443 |
|
396 | 444 | @staticmethod |
397 | 445 | def unicode2utf8(text): |
|
0 commit comments