[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