<commit_before>#!/usr/bin/python

"""
    NOTE: Tango is being renamed to Twython; all basic strings have been changed below, but there's still work ongoing in this department.

	Twython is an up-to-date library for Python that wraps the Twitter API.
	Other Python Twitter libraries seem to have fallen a bit behind, and
	Twitter's API has evolved a bit. Here's hoping this helps.

	TODO: OAuth, Streaming API?

	Questions, comments? <EMAIL>
"""

import httplib, urllib, urllib2, mimetypes, mimetools

from urlparse import urlparse
from urllib2 import HTTPError

__author__ = "<NAME> <<EMAIL>>"
__version__ = "0.6"

"""Twython - Easy Twitter utilities in Python"""

try:
	import simplejson
except ImportError:
	try:
		import json as simplejson
	except:
		raise Exception("Twython requires the simplejson library (or Python 2.6) to work. http://www.undefined.org/python/")

try:
	import oauth
except ImportError:
	pass

class TangoError(Exception):
	def __init__(self, msg, error_code=None):
		self.msg = msg
		if error_code == 400:
			raise APILimit(msg)
	def __str__(self):
		return repr(self.msg)

class APILimit(TangoError):
	def __init__(self, msg):
		self.msg = msg
	def __str__(self):
		return repr(self.msg)

class setup:
	def __init__(self, authtype = "OAuth", username = None, password = None, consumer_secret = None, consumer_key = None, headers = None):
		self.authtype = authtype
		self.authenticated = False
		self.username = username
		self.password = password
		# OAuth specific variables below
		self.request_token_url = 'https://twitter.com/oauth/request_token'
		self.access_token_url = 'https://twitter.com/oauth/access_token'
		self.authorization_url = 'http://twitter.com/oauth/authorize'
		self.signin_url = 'http://twitter.com/oauth/authenticate'
		self.consumer_key = consumer_key
		self.consumer_secret = consumer_secret
		self.request_token = None
		self.access_token = None
		# Check and set up authentication
		if self.username is not None and self.password is not None:
			if self.authtype == "Basic":
				# Basic authentication ritual
				self.auth_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
				self.auth_manager.add_password(None, "http://twitter.com", self.username, self.password)
				self.handler = urllib2.HTTPBasicAuthHandler(self.auth_manager)
				self.opener = urllib2.build_opener(self.handler)
				if headers is not None:
					self.opener.addheaders = [('User-agent', headers)]
				try:
					simplejson.load(self.opener.open("http://twitter.com/account/verify_credentials.json"))
					self.authenticated = True
				except HTTPError, e:
					raise TangoError("Authentication failed with your provided credentials. Try again? (%s failure)" % `e.code`, e.code)
			else:
				self.signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()
				# Awesome OAuth authentication ritual
				if consumer_secret is not None and consumer_key is not None:
					#req = oauth.OAuthRequest.from_consumer_and_token
					#req.sign_request(self.signature_method, self.consumer_key, self.token)
					#self.opener = urllib2.build_opener()
					pass
				else:
					raise TwythonError("Woah there, buddy. We've defaulted to OAuth authentication, but you didn't provide API keys. Try again.")
	
	def getRequestToken(self):
		response = self.oauth_request(self.request_token_url)
		token = self.parseOAuthResponse(response)
		self.request_token = oauth.OAuthConsumer(token['oauth_token'],token['oauth_token_secret'])
		return self.request_token
	
	def parseOAuthResponse(self, response_string):
		# Partial credit goes to <NAME> for this gem.
		lol = {}
		for param in response_string.split("&"):
			pair = param.split("=")
			if(len(pair) != 2):
				break
			lol[pair[0]] = pair[1]
		return lol
	
	# URL Shortening function huzzah
	def shortenURL(self, url_to_shorten, shortener = "http://is.gd/api.php", query = "longurl"):
		try:
			return urllib2.urlopen(shortener + "?" + urllib.urlencode({query: url_to_shorten})).read()
		except HTTPError, e:
			raise TangoError("shortenURL() failed with a %s error code." % `e.code`)
	
	def constructApiURL(self, base_url, params):
		return base_url + "?" + "&".join(["%s=%s" %(key, value) for (key, value) in params.iteritems()])
	
	def getRateLimitStatus(self, rate_for = "requestingIP"):
		try:
			if rate_for == "requestingIP":
				return simplejson.load(urllib2.urlopen("http://twitter.com/account/rate_limit_status.json"))
			else:
				if self.authenticated is True:
					return simplejson.load(self.opener.open("http://twitter.com/account/rate_limit_status.json"))
				else:
					raise TangoError("You need to be authenticated to check a rate limit status on an account.")
		except HTTPError, e:
			raise TangoError("It seems that there's something wrong. Twitter gave you a %s error code; are you doing something you shouldn't be?" % `e.code`, e.code)
	
	def getPublicTimeline(self):
		try:
			return simplejson.load(urllib2.urlopen("http://twitter.com/statuses/public_timeline.json"))
		except HTTPError, e:
			raise TangoError("getPublicTimeline() failed with a %s error code." % `e.code`)
	
	def getFriendsTimeline(self, **kwargs):
		if self.authenticated is True:
			try:
				friendsTimelineURL = self.constructApiURL("http://twitter.com/statuses/friends_timeline.json", kwargs)
				return simplejson.load(self.opener.open(friendsTimelineURL))
			except HTTPError, e:<commit_msg>Added getHomeTimeline() support - this isn't a supported feature of the Twitter API just yet, but it's not bad to throw support for it in Twython now. (Twython3k will get an update soon that has this)<commit_after>#!/usr/bin/python

"""
    NOTE: Tango is being renamed to Twython; all basic strings have been changed below, but there's still work ongoing in this department.

	Twython is an up-to-date library for Python that wraps the Twitter API.
	Other Python Twitter libraries seem to have fallen a bit behind, and
	Twitter's API has evolved a bit. Here's hoping this helps.

	TODO: OAuth, Streaming API?

	Questions, comments? <EMAIL>
"""

import httplib, urllib, urllib2, mimetypes, mimetools

from urlparse import urlparse
from urllib2 import HTTPError

__author__ = "<NAME> <<EMAIL>>"
__version__ = "0.6"

"""Twython - Easy Twitter utilities in Python"""

try:
	import simplejson
except ImportError:
	try:
		import json as simplejson
	except:
		raise Exception("Twython requires the simplejson library (or Python 2.6) to work. http://www.undefined.org/python/")

try:
	import oauth
except ImportError:
	pass

class TangoError(Exception):
	def __init__(self, msg, error_code=None):
		self.msg = msg
		if error_code == 400:
			raise APILimit(msg)
	def __str__(self):
		return repr(self.msg)

class APILimit(TangoError):
	def __init__(self, msg):
		self.msg = msg
	def __str__(self):
		return repr(self.msg)

class setup:
	def __init__(self, authtype = "OAuth", username = None, password = <PASSWORD>, consumer_secret = None, consumer_key = None, headers = None):
		self.authtype = authtype
		self.authenticated = False
		self.username = username
		self.password = password
		# OAuth specific variables below
		self.request_token_url = 'https://twitter.com/oauth/request_token'
		self.access_token_url = 'https://twitter.com/oauth/access_token'
		self.authorization_url = 'http://twitter.com/oauth/authorize'
		self.signin_url = 'http://twitter.com/oauth/authenticate'
		self.consumer_key = consumer_key
		self.consumer_secret = consumer_secret
		self.request_token = None
		self.access_token = None
		# Check and set up authentication
		if self.username is not None and self.password is not None:
			if self.authtype == "Basic":
				# Basic authentication ritual
				self.auth_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
				self.auth_manager.add_password(None, "http://twitter.com", self.username, self.password)
				self.handler = urllib2.HTTPBasicAuthHandler(self.auth_manager)
				self.opener = urllib2.build_opener(self.handler)
				if headers is not None:
					self.opener.addheaders = [('User-agent', headers)]
				try:
					simplejson.load(self.opener.open("http://twitter.com/account/verify_credentials.json"))
					self.authenticated = True
				except HTTPError, e:
					raise TangoError("Authentication failed with your provided credentials. Try again? (%s failure)" % `e.code`, e.code)
			else:
				self.signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()
				# Awesome OAuth authentication ritual
				if consumer_secret is not None and consumer_key is not None:
					#req = oauth.OAuthRequest.from_consumer_and_token
					#req.sign_request(self.signature_method, self.consumer_key, self.token)
					#self.opener = urllib2.build_opener()
					pass
				else:
					raise TwythonError("Woah there, buddy. We've defaulted to OAuth authentication, but you didn't provide API keys. Try again.")
	
	def getRequestToken(self):
		response = self.oauth_request(self.request_token_url)
		token = self.parseOAuthResponse(response)
		self.request_token = oauth.OAuthConsumer(token['oauth_token'],token['oauth_token_secret'])
		return self.request_token
	
	def parseOAuthResponse(self, response_string):
		# Partial credit goes to <NAME> for this gem.
		lol = {}
		for param in response_string.split("&"):
			pair = param.split("=")
			if(len(pair) != 2):
				break
			lol[pair[0]] = pair[1]
		return lol
	
	# URL Shortening function huzzah
	def shortenURL(self, url_to_shorten, shortener = "http://is.gd/api.php", query = "longurl"):
		try:
			return urllib2.urlopen(shortener + "?" + urllib.urlencode({query: url_to_shorten})).read()
		except HTTPError, e:
			raise TangoError("shortenURL() failed with a %s error code." % `e.code`)
	
	def constructApiURL(self, base_url, params):
		return base_url + "?" + "&".join(["%s=%s" %(key, value) for (key, value) in params.iteritems()])
	
	def getRateLimitStatus(self, rate_for = "requestingIP"):
		try:
			if rate_for == "requestingIP":
				return simplejson.load(urllib2.urlopen("http://twitter.com/account/rate_limit_status.json"))
			else:
				if self.authenticated is True:
					return simplejson.load(self.opener.open("http://twitter.com/account/rate_limit_status.json"))
				else:
					raise TangoError("You need to be authenticated to check a rate limit status on an account.")
		except HTTPError, e:
			raise TangoError("It seems that there's something wrong. Twitter gave you a %s error code; are you doing something you shouldn't be?" % `e.code`, e.code)
	
	def getPublicTimeline(self):
		try:
			return simplejson.load(urllib2.urlopen("http://twitter.com/statuses/public_timeline.json"))
		except HTTPError, e:
			raise TangoError("getPublicTimeline() failed with a %s error code." % `e.code`)
	
	def getHomeTimeline(self, **kwargs):
		if self.authenticated is True:
			try:
				friendsTimelineURL = self.constructApiURL("http://twitter.com/statuses/home_timeline.json", kwargs)
				return simplejson.load(self.opener.open(friendsTimelineURL))
			except HTTPError, e:
				raise TangoError("getHomeTimeline() failed with a %s error code. (This is an upcoming feature in the Twitter API, and may not be implemented yet)" % `e.code`)
		else:
			raise TangoError("getHomeTimeline() requires you to be authenticated.")
	
	def getFriendsTimeline(self, **kwargs):
		if self.authenticated is True:
			try:
				friendsTimelineURL = self.constructApiURL("http://twitter.com/statuses/friends_timeline.json", kwargs)
				return simplejson.load(self.opener.open(friendsTimelineURL))
			except HTTPError, e:
{'fraction_non_alphanumeric': 0.11203501094091904, 'fraction_numerical': 0.003588621444201313, 'mean_word_length': 4.404919583727531, 'pattern_counts': {'":': 4, '<': 14, '<?xml version=': 0, '>': 14, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '590700', 'n_tokens_mistral': 4084, 'n_tokens_neox': 3666, 'n_words': 1003}