--- /dev/null
+from org.maemo.hermes.engine.twitter.user import User
+import urllib, urllib2
+import base64
+import simplejson
+import urlparse
+
+class TwitterApi():
+ """Twitter backend for Hermes. Inspired by
+ http://code.google.com/p/python-twitter/source/browse/twitter.py
+
+ Copyright (c) Andrew Flegg <andrew@bleb.org> 2010.
+ Released under the Artistic Licence."""
+
+
+ # -----------------------------------------------------------------------
+ def __init__(self, username, password):
+ self._username = username
+ self._password = password
+
+
+ # -----------------------------------------------------------------------
+ def get_friends(self):
+ '''Return the full list of people being followed by 'username'.'''
+
+ url = 'https://twitter.com/statuses/friends.json'
+ cursor = -1
+ users = []
+ while True:
+ json = self._FetchUrl(url, parameters = { 'cursor': cursor})
+ data = simplejson.loads(json)
+ if 'error' in data:
+ raise Exception(data['error'])
+
+ for x in data['users']:
+ users.append(User.NewFromJsonDict(x))
+
+ cursor = data['next_cursor']
+ if cursor <= data['previous_cursor']:
+ break
+
+ return users
+
+
+ # -----------------------------------------------------------------------
+ def _FetchUrl(self,
+ url,
+ parameters=None):
+ '''Fetch a URL, optionally caching for a specified time.
+
+ Args:
+ url:
+ The URL to retrieve
+ parameters:
+ A dict whose key/value pairs should encoded and added
+ to the query string. [optional]
+
+ Returns:
+ A string containing the body of the response.
+ '''
+
+ # Build the extra parameters dict
+ extra_params = {}
+ if parameters:
+ extra_params.update(parameters)
+
+ # Add key/value parameters to the query string of the url
+ url = self._BuildUrl(url, extra_params=extra_params)
+
+ # Get a url opener that can handle basic auth
+ basic_auth = base64.encodestring('%s:%s' % (self._username, self._password))[:-1]
+
+ handler = urllib2.HTTPBasicAuthHandler()
+ (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
+ handler.add_password('Twitter API', netloc, self._username, self._password)
+ opener = urllib2.build_opener(handler)
+ opener.addheaders = {'Authorization': 'Basic %s' % basic_auth}.items()
+
+ url_data = opener.open(url, None).read()
+ opener.close()
+ return url_data
+
+
+ # -----------------------------------------------------------------------
+ def _BuildUrl(self, url, path_elements=None, extra_params=None):
+ # Break url into consituent parts
+ (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
+
+ # Add any additional path elements to the path
+ if path_elements:
+ # Filter out the path elements that have a value of None
+ p = [i for i in path_elements if i]
+ if not path.endswith('/'):
+ path += '/'
+ path += '/'.join(p)
+
+ # Add any additional query parameters to the query string
+ if extra_params and len(extra_params) > 0:
+ extra_query = self._EncodeParameters(extra_params)
+ # Add it to the existing query
+ if query:
+ query += '&' + extra_query
+ else:
+ query = extra_query
+
+ # Return the rebuilt URL
+ return urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
+
+
+
+ # -----------------------------------------------------------------------
+ def _EncodeParameters(self, parameters):
+ '''Return a string in key=value&key=value form
+
+ Values of None are not included in the output string.
+
+ Args:
+ parameters:
+ A dict of (key, value) tuples, where value is encoded as
+ specified by self._encoding
+ Returns:
+ A URL-encoded string in "key=value&key=value" form
+ '''
+ if parameters is None:
+ return None
+ else:
+ return urllib.urlencode(dict([(k, unicode(v).encode('utf-8')) for k, v in parameters.items() if v is not None]))
+