]> jfr.im git - z_archive/twitter.git/blobdiff - twitter/api.py
Py3 exception fix
[z_archive/twitter.git] / twitter / api.py
index 141f077cce05a9bc83ef9711fa37d2c2be18b10d..9914ce6894a4153f2646c2d3d024cc0e478f7f58 100644 (file)
@@ -15,15 +15,18 @@ from twitter.auth import NoAuth
 
 import re
 import gzip
+import httplib
 
 try:
     import json
 except ImportError:
     import simplejson as json
 
+
 class _DEFAULT(object):
     pass
 
+
 class TwitterError(Exception):
     """
     Base Exception thrown by the Twitter object when there is a
@@ -31,6 +34,7 @@ class TwitterError(Exception):
     """
     pass
 
+
 class TwitterHTTPError(TwitterError):
     """
     Exception thrown by the Twitter object when there is an
@@ -52,10 +56,11 @@ class TwitterHTTPError(TwitterError):
         fmt = ("." + self.format) if self.format else ""
         return (
             "Twitter sent status %i for URL: %s%s using parameters: "
-            "(%s)\ndetails: %s" %(
+            "(%s)\ndetails: %s" % (
                 self.e.code, self.uri, fmt, self.uriparts,
                 self.response_data))
 
+
 class TwitterResponse(object):
     """
     Response from a twitter request. Behaves like a list or a string
@@ -103,19 +108,18 @@ def wrap_response(response, headers):
         def __init__(self, response, headers):
             response_typ.__init__(self, response)
             TwitterResponse.__init__(self, headers)
+
         def __new__(cls, response, headers):
             return response_typ.__new__(cls, response)
 
-
     return WrappedTwitterResponse(response, headers)
 
 
-
 class TwitterCall(object):
 
     def __init__(
-        self, auth, format, domain, callable_cls, uri="",
-        uriparts=None, secure=True):
+            self, auth, format, domain, callable_cls, uri="",
+            uriparts=None, secure=True):
         self.auth = auth
         self.format = format
         self.domain = domain
@@ -131,8 +135,8 @@ class TwitterCall(object):
             def extend_call(arg):
                 return self.callable_cls(
                     auth=self.auth, format=self.format, domain=self.domain,
-                    callable_cls=self.callable_cls, uriparts=self.uriparts \
-                        + (arg,),
+                    callable_cls=self.callable_cls, uriparts=self.uriparts
+                    + (arg,),
                     secure=self.secure)
             if k == "_":
                 return extend_call
@@ -160,7 +164,7 @@ class TwitterCall(object):
         # the list of uriparts, assume the id goes at the end.
         id = kwargs.pop('id', None)
         if id:
-            uri += "/%s" %(id)
+            uri += "/%s" % (id)
 
         # If an _id kwarg is present, this is treated as id as a CGI
         # param.
@@ -177,8 +181,8 @@ class TwitterCall(object):
         dot = ""
         if self.format:
             dot = "."
-        uriBase = "http%s://%s/%s%s%s" %(
-                    secure_str, self.domain, uri, dot, self.format)
+        uriBase = "http%s://%s/%s%s%s" % (
+            secure_str, self.domain, uri, dot, self.format)
 
         headers = {'Accept-Encoding': 'gzip'}
         if self.auth:
@@ -201,14 +205,17 @@ class TwitterCall(object):
             handle = urllib_request.urlopen(req, **kwargs)
             if handle.headers['Content-Type'] in ['image/jpeg', 'image/png']:
                 return handle
-            elif handle.info().get('Content-Encoding') == 'gzip':
+            try:
+                data = handle.read()
+            except httplib.IncompleteRead as e:
+                # Even if we don't get all the bytes we should have there
+                # may be a complete response in e.partial
+                data = e.partial
+            if handle.info().get('Content-Encoding') == 'gzip':
                 # Handle gzip decompression
-                buf = StringIO(handle.read())
+                buf = StringIO(data)
                 f = gzip.GzipFile(fileobj=buf)
                 data = f.read()
-            else:
-                data = handle.read()
-
             if "json" == self.format:
                 res = json.loads(data.decode('utf8'))
                 return wrap_response(res, handle.headers)
@@ -221,6 +228,7 @@ class TwitterCall(object):
             else:
                 raise TwitterHTTPError(e, uri, self.format, arg_data)
 
+
 class Twitter(TwitterCall):
     """
     The minimalist yet fully featured Twitter API class.
@@ -238,8 +246,8 @@ class Twitter(TwitterCall):
         t = Twitter(
             auth=OAuth(token, token_key, con_secret, con_secret_key)))
 
-        # Get the public timeline
-        t.statuses.public_timeline()
+        # Get your "home" timeline
+        t.statuses.home_timeline()
 
         # Get a particular friend's timeline
         t.statuses.friends_timeline(id="billybob")
@@ -274,13 +282,8 @@ class Twitter(TwitterCall):
 
     Searching Twitter::
 
-        twitter_search = Twitter(domain="search.twitter.com")
-
-        # Find the latest search trends
-        twitter_search.trends()
-
-        # Search for the latest News on #gaza
-        twitter_search.search(q="#gaza")
+        # Search for the latest tweets about #pycon
+        t.search.tweets(q="#pycon")
 
 
     Using the data returned
@@ -289,7 +292,7 @@ class Twitter(TwitterCall):
     Twitter API calls return decoded JSON. This is converted into
     a bunch of Python lists, dicts, ints, and strings. For example::
 
-        x = twitter.statuses.public_timeline()
+        x = twitter.statuses.home_timeline()
 
         # The first 'tweet' in the timeline
         x[0]
@@ -311,9 +314,9 @@ class Twitter(TwitterCall):
 
     """
     def __init__(
-        self, format="json",
-        domain="api.twitter.com", secure=True, auth=None,
-        api_version=_DEFAULT):
+            self, format="json",
+            domain="api.twitter.com", secure=True, auth=None,
+            api_version=_DEFAULT):
         """
         Create a new twitter API connector.
 
@@ -326,20 +329,19 @@ class Twitter(TwitterCall):
 
 
         `domain` lets you change the domain you are connecting. By
-        default it's `api.twitter.com` but `search.twitter.com` may be
-        useful too.
+        default it's `api.twitter.com`.
 
         If `secure` is False you will connect with HTTP instead of
         HTTPS.
 
         `api_version` is used to set the base uri. By default it's
-        '1'. If you are using "search.twitter.com" set this to None.
+        '1.1'.
         """
         if not auth:
             auth = NoAuth()
 
         if (format not in ("json", "xml", "")):
-            raise ValueError("Unknown data format '%s'" %(format))
+            raise ValueError("Unknown data format '%s'" % (format))
 
         if api_version is _DEFAULT:
             if domain == 'api.twitter.com':