[Python-apps-commits] r456 - in packages (6 files)
andyp-guest at users.alioth.debian.org
andyp-guest at users.alioth.debian.org
Sat Dec 29 14:18:20 UTC 2007
Date: Saturday, December 29, 2007 @ 14:18:19
Author: andyp-guest
Revision: 456
[svn-inject] Installing original source of twyt
Added:
packages/twyt/
packages/twyt/branches/
packages/twyt/branches/upstream/
packages/twyt/branches/upstream/current/
packages/twyt/branches/upstream/current/twyt/
packages/twyt/branches/upstream/current/twyt/twitter.py
Added: packages/twyt/branches/upstream/current/twyt/twitter.py
===================================================================
--- packages/twyt/branches/upstream/current/twyt/twitter.py (rev 0)
+++ packages/twyt/branches/upstream/current/twyt/twitter.py 2007-12-29 14:18:19 UTC (rev 456)
@@ -0,0 +1,234 @@
+# Copyright (c) 2007 Andrew Price
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import sys
+import urllib
+import urllib2
+import base64
+import user
+
+class TwitterException(Exception):
+
+ """A generic Exception class for when things go wrong wrt Twitter"""
+
+ def __init__(self, value):
+ self.parameter = value
+
+ def __str__(self):
+ return str(self.parameter)
+
+class TwitterAuthException(TwitterException):
+
+ """An exception to raise when Twitter auth fails"""
+
+ def __init__(self, value):
+ self.parameter = value
+
+ def __str__(self):
+ return str(self.parameter)
+
+class Twitter:
+
+ """Provides a simple interface to the Twitter API"""
+
+ def __init__(self):
+
+ """Initialise Twitter with sane defaults"""
+
+ self.baseurl = u'http://twitter.com/'
+ #self.baseurl = u'http://localhost:8080/' # Test - 'nc -l -p 8080' ftw
+ self.auth = ""
+ self.useragent = "Twyt"
+
+ def setauth(self, user, pwd):
+
+ str64 = base64.encodestring('%s:%s' % (user,pwd))[:-1]
+ self.auth = u'Basic %s' % str64
+
+ def post(self, data, handler):
+
+ """Sends a POST request to the given remote handler.
+ The data argument must be a list of pairs of strings."""
+
+ url = self.baseurl + handler
+ req = urllib2.Request(url, urllib.urlencode(data))
+
+ if not self.auth:
+ raise TwitterAuthException("No user/password specified")
+
+ req.add_header(u'X-Twitter-Client', self.useragent)
+ req.add_header(u'Authorization', self.auth)
+
+ result = ""
+ try:
+ handle = urllib2.urlopen(req)
+ result = handle.read()
+ except urllib2.HTTPError, e:
+ raise TwitterException(str(e))
+
+ return result
+
+
+ def get(self, data, handler, doauth=False):
+
+ """Sends a GET request to the given remote handler.
+ The data argument must be a list of pairs of strings.
+ """
+
+ url = self.baseurl + handler + '?' + urllib.urlencode(data)
+ req = urllib2.Request(url)
+ req.add_header(u'X-Twitter-Client', self.useragent)
+
+ if doauth:
+ if not self.auth:
+ raise TwitterAuthException("No user/password specified")
+
+ req.add_header(u'Authorization', self.auth)
+
+ result = ""
+ try:
+ handle = urllib2.urlopen(req)
+ result = handle.read()
+ except urllib2.HTTPError:
+ #raise TwitterException("Server returned " + str(e))
+ pass
+
+ return result
+
+
+ def status_update(self, msg=""):
+
+ """Updates the user's status on twitter, otherwise known as tweeting"""
+
+ msg = msg.strip()
+ if len(msg) > 140:
+ raise TwitterException("Message too long")
+
+ if len(msg) <= 0:
+ raise TwitterException("Message too short")
+
+ status = [("status", msg)]
+
+ return self.post(status, u'statuses/update.json')
+
+ def status_public_timeline(self, since_id=""):
+
+ """Returns the 20 most recent statuses from non-protected users
+ who have set a custom user icon. Does not require authentication.
+ """
+
+ handler = u'statuses/public_timeline.json'
+
+ data = []
+ if since_id != "":
+ data = [("since_id", since_id)]
+
+ return self.get(data, handler, doauth=False)
+
+
+ def status_friends_timeline(self, friend="", since=""):
+
+ """Returns the 20 most recent statuses posted in the last 24
+ hours from the authenticating user and that user's friends.
+ """
+
+ handler = u'statuses/friends_timeline'
+ if friend:
+ handler += u'/' + friend + u'.json'
+ else:
+ handler += u'.json'
+
+ data = []
+ if since:
+ data = [("since", since)]
+
+ return self.get(data, handler, doauth=True)
+
+ def status_user_timeline(self, id="", count=20, since=""):
+
+ """Returns the 20 (or count) most recent statuses posted in
+ the last 24 hours from the authenticating user. It's also
+ possible to request another user's timeline using id.
+ """
+
+ handler = u'statuses/user_timeline'
+ if id != "":
+ handler += u'/' + id + u'.json'
+ else:
+ handler += u'.json'
+
+ data = []
+ if since != "":
+ data = [("since", since)]
+
+ if 0 < count <= 20:
+ data.append(("count", count))
+ else:
+ raise TwitterException(
+ "'count' parameter out of range. Must be between 1 and 20.")
+
+ return self.get(data, handler, doauth=True)
+
+ def status_show(self, id):
+
+ """Returns a single status, specified by the id parameter."""
+
+ if not id:
+ raise TwitterException("No ID specified")
+
+ handler = u'statuses/show/%s.json' % id
+
+ return self.get([], handler, doauth=False)
+
+ def status_replies(self, page=1):
+
+ """Returns the 20 most recent replies (status updates prefixed
+ with @username posted by users who are friends with the user
+ being replied to). The page argument gets the Nth 20 replies.
+ """
+
+ if int(page) < 1:
+ raise TwitterException("Page number is out of range: " + page)
+
+ handler = u'statuses/replies.json'
+ data = [("page",page)]
+
+ return self.get(data, handler, doauth=True)
+
+ def status_destroy(self, id):
+
+ """Destroys the status specified by the required ID parameter.
+ The authenticating user must be the author of the specified
+ status.
+ """
+
+ if int(id) < 0:
+ raise TwitterException("ID out of range")
+
+ handler = u'statuses/destroy/%d.json' % id
+
+ return self.get([], handler, doauth=True)
+
+
More information about the Python-apps-commits
mailing list