from base64 import b64encode
+from urllib import urlencode
import httplib
-import simplejson
+
+from exceptions import Exception
+
+def _py26OrGreater():
+ import sys
+ return sys.hexversion > 0x20600f0
+
+if _py26OrGreater():
+ import json
+else:
+ import simplejson as json
+
+class TwitterError(Exception):
+ """
+ Exception thrown by the Twitter object when there is an
+ error interacting with twitter.com.
+ """
+ pass
class TwitterCall(object):
- def __init__(self, username=None, password=None, uri=""):
+ def __init__(self, username, password, format, uri=""):
self.username = username
self.password = password
+ self.format = format
self.uri = uri
def __getattr__(self, k):
try:
return object.__getattr__(self, k)
except AttributeError:
return TwitterCall(
- self.username, self.password, self.uri + "/" + k)
+ self.username, self.password, self.format,
+ self.uri + "/" + k)
def __call__(self, **kwargs):
method = "GET"
- if self.uri.endswith('new') or self.uri.endswith('update'):
+ if (self.uri.endswith('new')
+ or self.uri.endswith('update')
+ or self.uri.endswith('create')
+ or self.uri.endswith('destroy')):
method = "POST"
+
+ encoded_kwargs = urlencode(kwargs.items())
argStr = ""
- if kwargs:
- argStr = "?" + "&".join([
- "%s=%s" %(k, v) for k, v in kwargs.iteritems()])
+ if kwargs and (method == "GET"):
+ argStr = "?" + encoded_kwargs
+
+ headers = {}
+ if (self.username):
+ headers["Authorization"] = "Basic " + b64encode("%s:%s" %(
+ self.username, self.password))
+ if method == "POST":
+ headers["Content-type"] = "application/x-www-form-urlencoded"
+ headers["Content-length"] = len(encoded_kwargs)
+
c = httplib.HTTPConnection("twitter.com")
try:
- c.putrequest(method, "/%s.json%s" %(self.uri, argStr))
- if (self.username):
- c.putheader("Authorization", "Basic "
- + b64encode("%s:%s" %(
- self.username, self.password)))
+ c.putrequest(method, "%s.%s%s" %(
+ self.uri, self.format, argStr))
+ for item in headers.iteritems():
+ c.putheader(*item)
c.endheaders()
+ if method == "POST":
+ c.send(encoded_kwargs)
r = c.getresponse()
+
if (r.status == 304):
return []
elif (r.status != 200):
- raise Exception("Twitter sent status %i: %s" %(
+ raise TwitterError("Twitter sent status %i: %s" %(
r.status, r.read()))
- return simplejson.loads(r.read())
+ if "json" == self.format:
+ return json.loads(r.read())
+ else:
+ return r.read()
finally:
c.close()
# The screen name of the user who wrote the first 'tweet'
x[0]['user']['screen_name']
+
+ Getting raw XML data::
+
+ If you prefer to get your Twitter data in XML format, pass
+ format="xml" to the Twitter object when you instantiate it:
+
+ twitter = Twitter(format="xml")
+ The output will not be parsed in any way. It will be a raw string
+ of XML.
"""
- def __init__(self, email=None, password=None):
+ def __init__(self, email=None, password=None, format="json"):
"""
Create a new twitter API connector using the specified
- credentials (email and password).
+ credentials (email and password). Format specifies the output
+ format ("json" (default) or "xml").
"""
- TwitterCall.__init__(self, email, password)
+ if (format not in ("json", "xml")):
+ raise TwitterError("Unknown data format '%s'" %(format))
+ TwitterCall.__init__(self, email, password, format)
-__all__ = ["Twitter"]
+__all__ = ["Twitter", "TwitterError"]