Hello community, here is the log from the commit of package python-tweepy for openSUSE:Factory checked in at 2019-04-02 09:20:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-tweepy (Old) and /work/SRC/openSUSE:Factory/.python-tweepy.new.25356 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-tweepy" Tue Apr 2 09:20:47 2019 rev:10 rq:688352 version:3.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-tweepy/python-tweepy.changes 2018-08-12 20:54:08.857317992 +0200 +++ /work/SRC/openSUSE:Factory/.python-tweepy.new.25356/python-tweepy.changes 2019-04-02 09:20:50.656629454 +0200 @@ -1,0 +2,8 @@ +Mon Mar 25 15:32:12 UTC 2019 - pgajdos@suse.com + +- version update to 3.7.0 + * no upstream changelog (except git log) +- deleted patches + - tweepy-pip2.10.patch (upstreamed) + +------------------------------------------------------------------- Old: ---- tweepy-pip2.10.patch v3.6.0.tar.gz New: ---- 3.7.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-tweepy.spec ++++++ --- /var/tmp/diff_new_pack.3GTqEt/_old 2019-04-02 09:20:51.584630323 +0200 +++ /var/tmp/diff_new_pack.3GTqEt/_new 2019-04-02 09:20:51.588630327 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-tweepy # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,20 +12,19 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-tweepy -Version: 3.6.0 +Version: 3.7.0 Release: 0 Summary: Twitter library for python License: MIT Group: Development/Languages/Python URL: https://github.com/tweepy/tweepy -Source: https://github.com/tweepy/tweepy/archive/v%{version}.tar.gz -Patch0: tweepy-pip2.10.patch +Source: https://github.com/tweepy/tweepy/archive/%{version}.tar.gz BuildRequires: %{python_module PySocks >= 1.5.7} BuildRequires: %{python_module mock >= 1.0.1} BuildRequires: %{python_module nose} @@ -50,7 +49,6 @@ %prep %setup -q -n tweepy-%{version} -%patch0 -p1 %build %python_build ++++++ v3.6.0.tar.gz -> 3.7.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/.travis.yml new/tweepy-3.7.0/.travis.yml --- old/tweepy-3.6.0/.travis.yml 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/.travis.yml 2018-11-28 04:53:31.000000000 +0100 @@ -4,9 +4,7 @@ cache: pip python: -- '2.6' - '2.7' -- '3.3' - '3.4' - '3.5' - '3.6' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/CONTRIBUTORS new/tweepy-3.7.0/CONTRIBUTORS --- old/tweepy-3.6.0/CONTRIBUTORS 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/CONTRIBUTORS 2018-11-28 04:53:31.000000000 +0100 @@ -35,3 +35,4 @@ Mark Smith (@judy2k) Steven Skoczen (@skoczen) Samuel (@obskyr) +Patrick A. Levell (@palevell) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/README.md new/tweepy-3.7.0/README.md --- old/tweepy-3.6.0/README.md 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/README.md 2018-11-28 04:53:31.000000000 +0100 @@ -1,11 +1,11 @@ Tweepy: Twitter for Python! ====== -[![Join the chat at https://gitter.im/tweepy/tweepy](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/tweepy/tweepy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://img.shields.io/travis/tweepy/tweepy/master.svg?style=flat)](https://travis-ci.org/tweepy/tweepy) [![Documentation Status](http://img.shields.io/badge/docs-v3.6.0-brightgreen.svg?style=flat)](http://docs.tweepy.org) [![Version](http://img.shields.io/pypi/v/tweepy.svg?style=flat)](https://crate.io/packages/tweepy) [![Coverage Status](https://img.shields.io/coveralls/tweepy/tweepy/master.svg?style=flat)](https://coveralls.io/r/tweepy/tweepy?branch=master) +[![Discord](https://img.shields.io/discord/432685901596852224.svg)](https://discord.gg/bJvqnhg) Installation ------------ @@ -21,4 +21,9 @@ cd tweepy python setup.py install -Python 2.6 and 2.7, 3.3, 3.4, 3.5 & 3.6 are supported. +Python 2.7, 3.4, 3.5 & 3.6 are supported. + +Community +--------- +- [Discord Chat](https://discord.gg/bJvqnhg) + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/docs/api.rst new/tweepy-3.7.0/docs/api.rst --- old/tweepy-3.6.0/docs/api.rst 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/docs/api.rst 2018-11-28 04:53:31.000000000 +0100 @@ -103,6 +103,7 @@ Returns a single status specified by the ID parameter. :param id: |sid| + :tweet_mode: |Pass in 'extended' to get non truncated tweet text| :rtype: :class:`Status` object @@ -123,7 +124,7 @@ .. method:: API.update_with_media(filename, [status], [in_reply_to_status_id], [auto_populate_reply_metadata], [lat], [long], [source], [place_id], [file]) - Update the authenticated user's status. Statuses that are duplicates + *Deprecated*: Use :func:`API.media_upload` instead. Update the authenticated user's status. Statuses that are duplicates or too long will be silently ignored. :param filename: The filename of the image to upload. This will automatically be opened unless `file` is specified @@ -209,7 +210,7 @@ :param cursor: |cursor| :rtype: list of :class:`User` objects -.. method:: API.search_users(q, [per_page], [page]) +.. method:: API.search_users(q, [count], [page]) Run a search for users similar to Find People button on Twitter.com; the same results returned by people search on Twitter.com will be @@ -218,7 +219,7 @@ this API. :param q: The query to run against people search. - :param per_page: Specifies the number of statuses to retrieve. May not be greater than 20. + :param count: Specifies the number of statuses to retrieve. May not be greater than 20. :param page: |page| :rtype: list of :class:`User` objects @@ -613,7 +614,7 @@ :rtype: list of :class:`List` objects -.. method:: API.list_timeline(owner, slug, [since_id], [max_id], [per_page], [page]) +.. method:: API.list_timeline(owner, slug, [since_id], [max_id], [count], [page]) Show tweet timeline for members of the specified list. @@ -621,7 +622,7 @@ :param slug: |slug| :param since_id: |since_id| :param max_id: |max_id| - :param per_page: Number of results per a page + :param count: Number of results per a page :param page: |page| :rtype: list of :class:`Status` objects @@ -798,6 +799,16 @@ Returns the current configuration used by Twitter including twitter.com slugs which are not usernames, maximum photo resolutions, and t.co shortened URL length. It is recommended applications request this endpoint when they are loaded, but no more than once a day. +Media methods +------------- + +.. method:: API.media_upload() + + Uploads images to twitter and returns a `media_id`. + + :param media: The raw binary file content being uploaded. Cannot be used with `media_data`. + :param media_data: The base64-encoded file content being uploaded. Cannot be used with `media`. + :param additional_owners: A comma-separated list of user IDs to set as additional owners allowed to use the returned `media_id` in Tweets or Cards. Up to 100 additional owners may be specified. :mod:`tweepy.error` --- Exceptions ================================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/docs/cursor_tutorial.rst new/tweepy-3.7.0/docs/cursor_tutorial.rst --- old/tweepy-3.6.0/docs/cursor_tutorial.rst 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/docs/cursor_tutorial.rst 2018-11-28 04:53:31.000000000 +0100 @@ -19,7 +19,7 @@ Old way vs Cursor way --------------------- -First let's demonstrate iterating the statues in the authenticated +First let's demonstrate iterating the statuses in the authenticated user's timeline. Here is how we would do it the "old way" before Cursor object was introduced:: @@ -87,7 +87,23 @@ # Only iterate through the first 200 statuses for status in tweepy.Cursor(api.user_timeline).items(200): process_status(status) - + # Only iterate through the first 3 pages for page in tweepy.Cursor(api.user_timeline).pages(3): process_page(page) + + +Include Tweets > 140 Characters +------------------------------- + +Since twitter increased the maximum characters allowed in a tweet from 140 to 280, you may notice that tweets greater than 140 characters are truncated with a ... +If you want your results to include the full text of the long tweets make these simple changes: +- add the argument tweet_mode='extended' to your Cursor object call +- change your usages of .text to .full_text + +.. code-block :: python + +# example code +tweets = tweepy.Cursor(api.search, tweet_mode='extended') +for tweet in tweets: + content = tweet.full_text diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/requirements.txt new/tweepy-3.7.0/requirements.txt --- old/tweepy-3.6.0/requirements.txt 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/requirements.txt 2018-11-28 04:53:31.000000000 +0100 @@ -1,4 +1,3 @@ -requests>=2.11.1 -requests_oauthlib>=0.7.0 -six>=1.10.0 -PySocks>=1.5.7 +--index-url https://pypi.python.org/simple/ + +-e . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/setup.py new/tweepy-3.7.0/setup.py --- old/tweepy-3.6.0/setup.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/setup.py 2018-11-28 04:53:31.000000000 +0100 @@ -2,7 +2,6 @@ #from distutils.core import setup import re, uuid from setuptools import setup, find_packages -from pip.req import parse_requirements VERSIONFILE = "tweepy/__init__.py" ver_file = open(VERSIONFILE, "rt").read() @@ -14,9 +13,6 @@ else: raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,)) -install_reqs = parse_requirements('requirements.txt', session=uuid.uuid1()) -reqs = [str(req.req) for req in install_reqs] - setup(name="tweepy", version=version, description="Twitter library for python", @@ -25,8 +21,14 @@ author_email="tweepy@googlegroups.com", url="http://github.com/tweepy/tweepy", packages=find_packages(exclude=['tests']), - install_requires=reqs, + install_requires=[ + "requests>=2.11.1", + "requests_oauthlib>=0.7.0", + "six>=1.10.0", + "PySocks>=1.5.7", + ], keywords="twitter library", + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ 'Development Status :: 4 - Beta', 'Topic :: Software Development :: Libraries', @@ -34,10 +36,8 @@ 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/test_requirements.txt new/tweepy-3.7.0/test_requirements.txt --- old/tweepy-3.6.0/test_requirements.txt 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/test_requirements.txt 2018-11-28 04:53:31.000000000 +0100 @@ -1,4 +1,3 @@ tox>=1.7.2 vcrpy==1.10.3 mock==1.0.1 -unittest2 # Comment this line out if using Python 3. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tests/config.py new/tweepy-3.7.0/tests/config.py --- old/tweepy-3.6.0/tests/config.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tests/config.py 2018-11-28 04:53:31.000000000 +0100 @@ -1,15 +1,10 @@ import os - +import unittest import vcr from tweepy.auth import OAuthHandler from tweepy.api import API -import six -if six.PY3: - import unittest -else: - import unittest2 as unittest username = os.environ.get('TWITTER_USERNAME', 'tweepytest') oauth_consumer_key = os.environ.get('CONSUMER_KEY', '') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tests/test_api.py new/tweepy-3.7.0/tests/test_api.py --- old/tweepy-3.6.0/tests/test_api.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tests/test_api.py 2018-11-28 04:53:31.000000000 +0100 @@ -397,7 +397,7 @@ def testgeoapis(self): def place_name_in_list(place_name, place_list): """Return True if a given place_name is in place_list.""" - return any([x.full_name.lower() == place_name.lower() for x in place_list]) + return any(x.full_name.lower() == place_name.lower() for x in place_list) twitter_hq = self.api.geo_similar_places(lat='37.7821120598956', long='-122.400612831116', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tests/test_auth.py new/tweepy-3.7.0/tests/test_auth.py --- old/tweepy-3.6.0/tests/test_auth.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tests/test_auth.py 2018-11-28 04:53:31.000000000 +0100 @@ -3,13 +3,9 @@ from .config import * from tweepy import API, OAuthHandler -import six import random +import unittest -if six.PY3: - import unittest -else: - import unittest2 as unittest class TweepyAuthTests(unittest.TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tests/test_cursors.py new/tweepy-3.7.0/tests/test_cursors.py --- old/tweepy-3.6.0/tests/test_cursors.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tests/test_cursors.py 2018-11-28 04:53:31.000000000 +0100 @@ -1,13 +1,6 @@ from tweepy import Cursor -from .config import create_auth -from .config import TweepyTestCase, username, use_replay, tape - -import six -if six.PY3: - import unittest -else: - import unittest2 as unittest +from .config import TweepyTestCase, username, tape class TweepyCursorTests(TweepyTestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tests/test_rate_limit.py new/tweepy-3.7.0/tests/test_rate_limit.py --- old/tweepy-3.6.0/tests/test_rate_limit.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tests/test_rate_limit.py 2018-11-28 04:53:31.000000000 +0100 @@ -1,14 +1,9 @@ -import unittest import os +import unittest -from tweepy import API, Cursor +from tweepy import API from tweepy.error import TweepError -import six -if six.PY3: - import unittest -else: - import unittest2 as unittest from .config import create_auth testratelimit = 'TEST_RATE_LIMIT' in os.environ @@ -20,7 +15,7 @@ self.api = API(create_auth()) self.api.retry_count = 2 self.api.retry_delay = 5 - self.api.retry_errors = set([401, 404, 503]) + self.api.retry_errors = {401, 404, 503} self.api.wait_on_rate_limit = True def testratelimit(self): @@ -31,7 +26,7 @@ self.api.user_timeline(user_id=user_id, count=1, include_rts=True) except TweepError as e: # continue if we're not autherized to access the user's timeline or she doesn't exist anymore - if e.response is not None and e.response.status in set([401, 404]): + if e.response is not None and e.response.status in {401, 404}: continue raise e diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tests/test_streaming.py new/tweepy-3.7.0/tests/test_streaming.py --- old/tweepy-3.6.0/tests/test_streaming.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tests/test_streaming.py 2018-11-28 04:53:31.000000000 +0100 @@ -1,14 +1,8 @@ from __future__ import absolute_import, print_function -from .config import tape - import six -if six.PY3: - import unittest - from unittest.case import skip -else: - import unittest2 as unittest - from unittest2.case import skip +import unittest +from unittest.case import skip from tweepy.api import API from tweepy.auth import OAuthHandler @@ -105,7 +99,7 @@ def test_track_encoding(self): s = Stream(None, None) - s._start = lambda async: None + s._start = lambda is_async: None s.filter(track=[u'Caf\xe9']) # Should be UTF-8 encoded @@ -113,7 +107,7 @@ def test_follow_encoding(self): s = Stream(None, None) - s._start = lambda async: None + s._start = lambda is_async: None s.filter(follow=[u'Caf\xe9']) # Should be UTF-8 encoded diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tests/test_utils.py new/tweepy-3.7.0/tests/test_utils.py --- old/tweepy-3.6.0/tests/test_utils.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tests/test_utils.py 2018-11-28 04:53:31.000000000 +0100 @@ -1,13 +1,9 @@ -import six -if six.PY3: - import unittest -else: - import unittest2 as unittest - from tweepy.utils import * import random import string +import unittest + def mock_tweet(): """Generate some random tweet text.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tox.ini new/tweepy-3.7.0/tox.ini --- old/tweepy-3.6.0/tox.ini 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tox.ini 2018-11-28 04:53:31.000000000 +0100 @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py26, py27, py33, py34, py35, py36 +envlist = py27, py34, py35, py36 [base] deps = @@ -12,17 +12,6 @@ vcrpy==1.0.2 mock==1.0.1 -[py2] -deps = - {[base]deps} - unittest2==0.5.1 - -[testenv:py27] -deps = {[py2]deps} - -[testenv:py26] -deps = {[py2]deps} - [testenv] commands = nosetests -v tests.test_cursors tests.test_api tests.test_utils deps = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tweepy/__init__.py new/tweepy-3.7.0/tweepy/__init__.py --- old/tweepy-3.6.0/tweepy/__init__.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tweepy/__init__.py 2018-11-28 04:53:31.000000000 +0100 @@ -5,7 +5,7 @@ """ Tweepy Twitter API library """ -__version__ = '3.6.0' +__version__ = '3.7.0' __author__ = 'Joshua Roesslein' __license__ = 'MIT' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tweepy/api.py new/tweepy-3.7.0/tweepy/api.py --- old/tweepy-3.6.0/tweepy/api.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tweepy/api.py 2018-11-28 04:53:31.000000000 +0100 @@ -94,34 +94,35 @@ ) def statuses_lookup(self, id_, include_entities=None, - trim_user=None, map_=None): + trim_user=None, map_=None, tweet_mode=None): return self._statuses_lookup(list_to_csv(id_), include_entities, - trim_user, map_) + trim_user, map_, tweet_mode) @property def _statuses_lookup(self): """ :reference: https://dev.twitter.com/rest/reference/get/statuses/lookup - :allowed_param:'id', 'include_entities', 'trim_user', 'map' + :allowed_param:'id', 'include_entities', 'trim_user', 'map', 'tweet_mode' """ return bind_api( api=self, path='/statuses/lookup.json', payload_type='status', payload_list=True, - allowed_param=['id', 'include_entities', 'trim_user', 'map'], + allowed_param=['id', 'include_entities', 'trim_user', 'map', 'tweet_mode'], require_auth=True ) @property def user_timeline(self): """ :reference: https://dev.twitter.com/rest/reference/get/statuses/user_timeline - :allowed_param:'id', 'user_id', 'screen_name', 'since_id', 'max_id', 'count', 'include_rts' + :allowed_param:'id', 'user_id', 'screen_name', 'since_id', 'max_id', 'count', 'include_rts', 'trim_user', 'exclude_replies' """ return bind_api( api=self, path='/statuses/user_timeline.json', payload_type='status', payload_list=True, allowed_param=['id', 'user_id', 'screen_name', 'since_id', - 'max_id', 'count', 'include_rts'] + 'max_id', 'count', 'include_rts', 'trim_user', + 'exclude_replies'] ) @property @@ -322,8 +323,8 @@ allowed_param=['id', 'url', 'maxwidth', 'hide_media', 'omit_script', 'align', 'related', 'lang'] ) - def lookup_users(self, user_ids=None, screen_names=None, include_entities=None): - """ Perform bulk look up of users from user ID or screenname """ + def lookup_users(self, user_ids=None, screen_names=None, include_entities=None, tweet_mode=None): + """ Perform bulk look up of users from user ID or screen_name """ post_data = {} if include_entities is not None: include_entities = 'true' if include_entities else 'false' @@ -332,20 +333,22 @@ post_data['user_id'] = list_to_csv(user_ids) if screen_names: post_data['screen_name'] = list_to_csv(screen_names) + if tweet_mode: + post_data['tweet_mode'] = tweet_mode return self._lookup_users(post_data=post_data) @property def _lookup_users(self): """ :reference: https://dev.twitter.com/rest/reference/get/users/lookup - allowed_param='user_id', 'screen_name', 'include_entities' + allowed_param='user_id', 'screen_name', 'include_entities', 'tweet_mode' """ return bind_api( api=self, path='/users/lookup.json', payload_type='user', payload_list=True, method='POST', - allowed_param=['user_id', 'screen_name', 'include_entities'] + allowed_param=['user_id', 'screen_name', 'include_entities', 'tweet_mode'] ) def me(self): @@ -802,6 +805,46 @@ ) @property + def mutes_ids(self): + """ :reference: https://dev.twitter.com/rest/reference/get/mutes/users/ids """ + return bind_api( + api=self, + path='/mutes/users/ids.json', + payload_type='json', + require_auth=True + ) + + @property + def create_mute(self): + """ :reference: https://dev.twitter.com/rest/reference/post/mutes/users/create + :allowed_param:'id', 'user_id', 'screen_name' + """ + return bind_api( + api=self, + path='/mutes/users/create.json', + method='POST', + payload_type='user', + allowed_param=['id', 'user_id', 'screen_name'], + require_auth=True + ) + + @property + def destroy_mute(self): + """ :reference: https://dev.twitter.com/rest/reference/post/mutes/users/destroy + :allowed_param:'id', 'user_id', 'screen_name' + """ + return bind_api( + api=self, + path='/mutes/users/destroy.json', + method='POST', + payload_type='user', + allowed_param=['id', 'user_id', 'screen_name'], + require_auth=True + ) + + + + @property def blocks(self): """ :reference: https://dev.twitter.com/rest/reference/get/blocks/list :allowed_param:'cursor' @@ -1323,7 +1366,7 @@ filename = filename.encode("utf-8") BOUNDARY = b'Tw3ePy' - body = list() + body = [] body.append(b'--' + BOUNDARY) body.append('Content-Disposition: form-data; name="{0}";' ' filename="{1}"'.format(form_field, filename) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tweepy/cache.py new/tweepy-3.7.0/tweepy/cache.py --- old/tweepy-3.6.0/tweepy/cache.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tweepy/cache.py 2018-11-28 04:53:31.000000000 +0100 @@ -6,6 +6,7 @@ import time import datetime +import hashlib import threading import os import logging @@ -16,12 +17,6 @@ import pickle try: - import hashlib -except ImportError: - # python 2.4 - import md5 as hashlib - -try: import fcntl except ImportError: # Probably on a windows system diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tweepy/streaming.py new/tweepy-3.7.0/tweepy/streaming.py --- old/tweepy-3.6.0/tweepy/streaming.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tweepy/streaming.py 2018-11-28 04:53:31.000000000 +0100 @@ -189,8 +189,6 @@ class Stream(object): - host = 'stream.twitter.com' - def __init__(self, auth, listener, **options): self.auth = auth self.listener = listener @@ -220,6 +218,10 @@ self.body = None self.retry_time = self.retry_time_start self.snooze_time = self.snooze_time_step + + # Example: proxies = {'http': 'http://localhost:1080', 'https': 'http://localhost:1080'} + self.proxies = options.get("proxies") + self.host = options.get('host', 'stream.twitter.com') def new_session(self): self.session = requests.Session() @@ -247,7 +249,8 @@ timeout=self.timeout, stream=True, auth=auth, - verify=self.verify) + verify=self.verify, + proxies = self.proxies) if resp.status_code != 200: if self.listener.on_error(resp.status_code) is False: break @@ -313,11 +316,12 @@ while self.running and not resp.raw.closed: length = 0 while not resp.raw.closed: - line = buf.read_line().strip() - if not line: + line = buf.read_line() + stripped_line = line.strip() if line else line # line is sometimes None so we need to check here + if not stripped_line: self.listener.keep_alive() # keep-alive new lines are expected - elif line.strip().isdigit(): - length = int(line) + elif stripped_line.isdigit(): + length = int(stripped_line) break else: raise TweepError('Expecting length, unexpected value found') @@ -355,9 +359,9 @@ if resp.raw.closed: self.on_closed(resp) - def _start(self, async): + def _start(self, is_async): self.running = True - if async: + if is_async: self._thread = Thread(target=self._run) self._thread.start() else: @@ -373,7 +377,7 @@ replies=None, track=None, locations=None, - async=False, + is_async=False, encoding='utf8'): self.session.params = {'delimited': 'length'} if self.running: @@ -394,25 +398,25 @@ if track: self.session.params['track'] = u','.join(track).encode(encoding) - self._start(async) + self._start(is_async) - def firehose(self, count=None, async=False): + def firehose(self, count=None, is_async=False): self.session.params = {'delimited': 'length'} if self.running: raise TweepError('Stream object already connected!') self.url = '/%s/statuses/firehose.json' % STREAM_VERSION if count: self.url += '&count=%s' % count - self._start(async) + self._start(is_async) - def retweet(self, async=False): + def retweet(self, is_async=False): self.session.params = {'delimited': 'length'} if self.running: raise TweepError('Stream object already connected!') self.url = '/%s/statuses/retweet.json' % STREAM_VERSION - self._start(async) + self._start(is_async) - def sample(self, async=False, languages=None, stall_warnings=False): + def sample(self, is_async=False, languages=None, stall_warnings=False): self.session.params = {'delimited': 'length'} if self.running: raise TweepError('Stream object already connected!') @@ -421,9 +425,9 @@ self.session.params['language'] = ','.join(map(str, languages)) if stall_warnings: self.session.params['stall_warnings'] = 'true' - self._start(async) + self._start(is_async) - def filter(self, follow=None, track=None, async=False, locations=None, + def filter(self, follow=None, track=None, is_async=False, locations=None, stall_warnings=False, languages=None, encoding='utf8', filter_level=None): self.body = {} self.session.headers['Content-type'] = "application/x-www-form-urlencoded" @@ -446,11 +450,10 @@ if filter_level: self.body['filter_level'] = filter_level.encode(encoding) self.session.params = {'delimited': 'length'} - self.host = 'stream.twitter.com' - self._start(async) + self._start(is_async) def sitestream(self, follow, stall_warnings=False, - with_='user', replies=False, async=False): + with_='user', replies=False, is_async=False): self.body = {} if self.running: raise TweepError('Stream object already connected!') @@ -463,7 +466,7 @@ self.body['with'] = with_ if replies: self.body['replies'] = replies - self._start(async) + self._start(is_async) def disconnect(self): if self.running is False: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tweepy-3.6.0/tweepy/utils.py new/tweepy-3.7.0/tweepy/utils.py --- old/tweepy-3.6.0/tweepy/utils.py 2018-03-01 20:18:44.000000000 +0100 +++ new/tweepy-3.7.0/tweepy/utils.py 2018-11-28 04:53:31.000000000 +0100 @@ -7,7 +7,6 @@ from datetime import datetime import six -from six.moves.urllib.parse import quote from email.utils import parsedate @@ -41,14 +40,7 @@ try: import simplejson as json except ImportError: - try: - import json # Python 2.6+ - except ImportError: - try: - # Google App Engine - from django.utils import simplejson as json - except ImportError: - raise ImportError("Can't load a json library") + import json return json