finished binder. implemneted public timeline and friends timeline endpoints.
authorJosh Roesslein <jroesslein@gmail.com>
Mon, 6 Jul 2009 00:15:41 +0000 (19:15 -0500)
committerJosh Roesslein <jroesslein@gmail.com>
Mon, 6 Jul 2009 00:15:41 +0000 (19:15 -0500)
api.py
binder.py
error.py [new file with mode: 0644]
misc.py [deleted file]
parsers.py

diff --git a/api.py b/api.py
index bc961c790ed3e47a35b87f2b1e0b1f566a20a5fb..4d0c9d1f40e6c2e66eaa1a22125fd6b0c7674eda 100644 (file)
--- a/api.py
+++ b/api.py
@@ -2,26 +2,32 @@ import base64
 
 from binder import bind_api
 from parsers import *
+from models import User, Status
 
 """Twitter API"""
 class API(object):
 
-  def __init__(self, username=None, password=None):
+  def __init__(self, username=None, password=None, host='twitter.com', secure=False,
+                classes={'user': User, 'status': Status}):
     if username and password:
       self._b64up = base64.encode('%s:%s' % (username, password))
+    else:
+      self._b64up = None
+    self.host = host
+    self.secure = secure
+    self.classes = classes
 
-  """Twitter API endpoint bindings"""
-
-  """
-  Returns the 20 most recent statuses from non-protected users who have
-  set a custom icon. The public timeline is cached for 60 seconds
-  so requesting it more often than that is a waste of resources.
-
-  Requires Authentication: false
-  API Rate limited: true
-  Response: list of statuses
-  """
+  """Get public timeline"""
   public_timeline = bind_api(
       path = '/statuses/public_timeline.json',
-      parser = parse_test,
-      allowed_param = []) 
+      parser = parse_statuses,
+      allowed_param = []
+  )
+
+  """Get friends timeline"""
+  friends_timeline = bind_api(
+      path = '/statuses/friends_timeline.json',
+      parser = parse_statuses,
+      allowed_param = ['since_id', 'max_id', 'count', 'page'],
+      require_auth = True
+  )
index 7dd29f7c5411f4fb368eb171148aa55dd6cdd72d..c3961dbcdaa8d2cdbbb35cbd75dee0b7f722c05e 100644 (file)
--- a/binder.py
+++ b/binder.py
@@ -1,8 +1,15 @@
+import httplib
+
 from parsers import parse_error
+from error import TweepError
 
-def bind_api(path, parser, allowed_param=None, method='GET'):
+def bind_api(path, parser, allowed_param=None, method='GET', require_auth=False):
 
   def _call(api, **kargs):
+    # If require auth, throw exception if credentials not provided
+    if require_auth and not api._b64up:
+      raise TweepError('Authentication required!')
+
     # Filter out unallowed parameters
     if len(kargs) == 0:
       parameters = None
@@ -27,8 +34,8 @@ def bind_api(path, parser, allowed_param=None, method='GET'):
     headers = {
       'User-Agent': 'tweepy'
     }
-    if api.username and api.b64pass:
-      headers['Authorization'] = 'Basic %s' % api.b64pass
+    if api._b64up:
+      headers['Authorization'] = 'Basic %s' % api._b64up
 
     # Build request
     conn.request(method, url, headers=headers)
@@ -41,6 +48,6 @@ def bind_api(path, parser, allowed_param=None, method='GET'):
       raise TweepError(parse_error(resp.read()))
 
     # Pass returned body into parser and return parser output
-    return parser(resp.read())
+    return parser(resp.read(), api.classes)
 
   return _call
diff --git a/error.py b/error.py
new file mode 100644 (file)
index 0000000..23a9c0b
--- /dev/null
+++ b/error.py
@@ -0,0 +1,10 @@
+"""
+Tweepy exception
+"""
+class TweepError(Exception):
+
+  def __init__(self, reason):
+    self.reason = reason
+
+  def __str__(self):
+    return self.reason
diff --git a/misc.py b/misc.py
deleted file mode 100644 (file)
index db72838..0000000
--- a/misc.py
+++ /dev/null
@@ -1,36 +0,0 @@
-"""
-Only allow method to be called with authentication.
-"""
-def require_auth(func):
-  def wrapper(instance, *args, **kargs):
-    if instance._auth:
-      return func(instance, **kargs)
-    else:
-      print 'require auth'
-  return wrapper
-
-"""
-Process parameters. Perform validation. Build parameter list.
-"""
-def process_param(allowed_param):
-  def decorator(func):
-    def wrapper(instance, **kargs):
-      if len(kargs):
-        instance._parameters = {}
-        for k,v in kargs.items():
-          if k in allowed_param:
-            instance._parameters[k] = v
-      return func(instance, **kargs)
-    return wrapper
-  return decorator
-
-"""
-Tweepy exception
-"""
-class TweepError(Exception):
-
-  def __init__(self, reason):
-    self.reason = reason
-
-  def __str__(self):
-    return self.reason
index 7cf21a7f9f434721c0a0bc39b2250163fb924716..8330b846e94baea1fb5b00d6ceb38f92f2bfd9b8 100644 (file)
@@ -7,27 +7,33 @@ def parse_error(data):
 
   return json.loads(data)['error']
 
-def parse_test(data):
+def _parse_user(obj, classes):
 
-  return data
+  user = classes['user']()
+  for k,v in obj.items():
+    setattr(user, k, v)
+  return user
 
-def _parse_item(type, jsondata):
-  t = type()
-  for k,v in jsondata.items():
+def parse_users(data, classes):
+
+  users = []
+  for obj in json.loads(data):
+    users.append(_parse_user(obj, classes))
+  return users
+
+def _parse_status(obj, classes):
+
+  status = classes['status']()
+  for k,v in obj.items():
     if k == 'user':
-      setattr(t,k, _parse_item(type._User, v))
+      setattr(status, k, _parse_user(v, classes))
     else:
-      setattr(t,k,v)
-  return t
-
-def parse_item(type, data):
-  jsondata = json.loads(data)
-  return _parse_item(type, jsondata)
+      setattr(status, k, v)
+  return status
 
-def parse_list(type, data):
-  types = []
+def parse_statuses(data, classes):
 
+  statuses = []
   for obj in json.loads(data):
-    types.append(_parse_item(type, obj))
-
-  return types
+    statuses.append(_parse_status(obj, classes))
+  return statuses