
import screenlets
import gobject
import threading
import urllib
import gtk

import traceback

# parse_qsl moved to urlparse module in v2.6
try:
	from urlparse import parse_qsl
except:
	from cgi import parse_qsl

try:
	import twitter
except:
	print "Couldn't import twitter. That's not good."

try:
	import oauth2 as oauth
except:
	print "Couldn't import oauth2. That's not good."
	
REQUEST_TOKEN_URL = 'https://api.twitter.com/oauth/request_token'
ACCESS_TOKEN_URL	= 'https://api.twitter.com/oauth/access_token'
AUTHORIZATION_URL = 'https://api.twitter.com/oauth/authorize'
SIGNIN_URL		= 'https://api.twitter.com/oauth/authenticate'

consumer_key	= "Hw59xrDzlSddJgpEMAoxg"
consumer_secret = "Te8dRb7Lk3MfIkJx9RdBdwRj4heELLsplUhIc0RQ"

class UserInfo:
	def __init__ (self, name=None, screen_name=None, iconPixbuf=None):
		self.name = name
		self.screen_name = screen_name
		self.iconPixbuf = iconPixbuf

class Timeline:
	statuses = []
	users = {}

	def __init__ (self, statuses=None, users=None):
		if statuses: self.statuses = list(statuses)
		if users: self.users = dict(users)
			
class TwitterResult:
	SUCCESS		= 1
	ERROR		= 2

class TwitterUpdateMethod:
	PUBLIC = 1
	FRIENDS = 2

_ = None

class TwitterBackend (gobject.GObject):
	"""The backend class which performs getting Twitter statuses"""

	statuses = []
	users = {}
	icon_cache = {}
	handler_ids = []

	__api = None

#	request_token = None
	oauth_consumer = None

	started = False

	__lock = threading.Lock()

	def __init__ (self, screenlet, update_method):
		print "TwitterBackend.__init__"
		gobject.GObject.__init__(self)
		# properties
		self.screenlet		= screenlet		# assigned TwitterScreenlet
		self.getting		= False			# not getting yet
		self.error					= ''		# human-readable error message
		self.options		= []				# ???additonal ptions for backend
		self.update_method		= update_method
		
		global _
		_ = screenlet.translator

		self.__api = self.get_twitter_api(self.screenlet.access_key, self.screenlet.access_secret)

	def open_access_url(self):

		print '*** Requesting temp token from Twitter ***'

		signature_method_hmac_sha1 = oauth.SignatureMethod_HMAC_SHA1()
		self.oauth_consumer			 = oauth.Consumer(key=consumer_key, secret=consumer_secret)
		oauth_client				 = oauth.Client(self.oauth_consumer)

		resp, content = oauth_client.request(REQUEST_TOKEN_URL, 'GET')

		if resp['status'] != '200':
			print 'Invalid respond from Twitter requesting temp token: %s' % resp['status']
		else:
			request_token = dict(parse_qsl(content))

	#		print resp
	#		print content

	#		print "REQUEST TOKEN: ", request_token
	#		print "REQUEST OAUTH TOKEN: ", request_token['oauth_token']
	#		print "REQUEST OAUTH TOKEN SECRET: ", request_token['oauth_token_secret']

			print ''
			print 'Please visit this Twitter page and retrieve the pincode to be used'
			print 'in the next step to obtaining an Authentication Token:'
			print ''
	#			print '%s?oauth_token=%s' % (AUTHORIZATION_URL, self.request_token['oauth_token'])
			print ''

			stttt = AUTHORIZATION_URL + '?oauth_token=' + request_token['oauth_token']
			print stttt
			print ''

			return [stttt, request_token]

	def get_access_key(self, pincode, request_key, request_secret):

		print "*** Generating and signing request for an access token ***"
		
#			print "PINCODE: ", pincode

#			if self.request_token is None:
#			print "REQUEST TOKEN not available yet!!!"
#			return None

#			print "REQUEST TOKEN: ", self.request_token
#			print "REQUEST OAUTH TOKEN: ", self.request_token['oauth_token']
#			print "REQUEST OAUTH TOKEN SECRET: ", self.request_token['oauth_token_secret']

		if self.oauth_consumer is None:
			signature_method_hmac_sha1 = oauth.SignatureMethod_HMAC_SHA1()
			self.oauth_consumer = oauth.Consumer(key=consumer_key, secret=consumer_secret)

		token = oauth.Token(request_key, request_secret)
		token.set_verifier(pincode.strip())

		oauth_client	= oauth.Client(self.oauth_consumer, token)
		resp, content = oauth_client.request(ACCESS_TOKEN_URL, method='POST', body='oauth_verifier=%s' % pincode)
		access_token	= dict(parse_qsl(content))

		if resp['status'] != '200':
			print 'The request for a Token did not succeed: %s' % resp['status']
	#		print access_token
		else:
			print 'Your Twitter Access Token key: %s' % access_token['oauth_token']
			print '			Access Token secret: %s' % access_token['oauth_token_secret']
			print ''
			return access_token

		return None



	def get_twitter_api(self, key = None, secret= None):

#	print "*** GET API ***"
#	print "ACCESS_TOKEN (KEY)", key
#	print "ACCESS_TOKEN_SECRET (SECRET)", secret

#	print consumer_key, consumer_secret

		api = twitter.Api(consumer_key=consumer_key, consumer_secret=consumer_secret, access_token_key=key,
							access_token_secret=secret, input_encoding="UTF-8")

		print "API OK", api
		# Mail to Alex...
		api.SetUserAgent('TwitterScreenlet')
		
		#api.SetCacheTimeout(0)
		return api

	def get_timeline_start(self):

		if self.getting: return		
		print "running thread"
		threading.Thread(target=self.__get).start()

	def post_message_start(self, text):
		threading.Thread(target=self.__post, args=(text,)).start()

	def __get (self):
		""" """
		self.getting = True
		result = TwitterResult.SUCCESS

		try:
			self.__lock.acquire()
			self.__get_timeline()
		except:
	#				traceback.print_exc()
			result = TwitterResult.ERROR
		finally:
			self.__lock.release()

		gobject.idle_add(self.screenlet.on_get_timeline, Timeline(self.statuses, self.users), result)
		self.getting = False

	def __post (self, text):
		""" post message to server"""
		try:
			self.__lock.acquire()
	#		print "U --- " + str(len(unicode(text))) + ": '" + text + "'"
	#		print "T --- " + str(len(text)) + ": '" + text + "'"
			#			self.__api.PostUpdate(unicode(text))
			self.__api.PostUpdate(text)
			gobject.idle_add(self.screenlet.on_post_message, TwitterResult.SUCCESS)
		except:
			gobject.idle_add(self.screenlet.on_post_message, TwitterResult.ERROR)
		finally:
			self.__lock.release()
	
	def __get_timeline(self):
		""" get twitter timeline data"""

		howmany = min(100, int(self.screenlet.num_of_statuses))

		print "trying to get some %d timelines..." % howmany

		try:

			if self.update_method == TwitterUpdateMethod.FRIENDS:
				self.statuses = self.__api.GetFriendsTimeline(count=howmany)
			else:
				self.statuses = self.__api.GetPublicTimeline()

		except twitter.TwitterError as message:
			self.screenlet.__notifier.notify(_("Twitter.com says: \"%s\"") % (str(message)))
			#traceback.print_exc()
		except:
			self.screenlet.__notifier.notify(_("Communication with Twitter.com failed."))
			#traceback.print_exc()

		new_icon_cache = {}

		if(len(self.users) > 200):
			self.users = {}

		print "working on usericons..."
		
		for status in self.statuses:

			if howmany == 0: break

			howmany -= 1
				
#		print status.GetUser().GetScreenName(), self.users.has_key(status.GetUser().GetId())
			if not self.users.has_key(status.GetUser().GetId()):

				user_name = status.GetUser().GetName()
				screen_name = status.GetUser().GetScreenName()

				# get Profile Image
				try:
					icon_url = status.GetUser().GetProfileImageUrl()
					if self.icon_cache.has_key(icon_url):
						icon_pixbuf = icon_cache[icon_url]
					elif new_icon_cache.has_key(icon_url):
						icon_pixbuf = new_icon_cache[icon_url]
					else:
						icon_path, headers = urllib.urlretrieve(urllib.quote(icon_url.encode("utf-8"), ':/'))
						icon_pixbuf = gtk.gdk.pixbuf_new_from_file(icon_path)

					new_icon_cache[icon_url] = icon_pixbuf
				except:

					#traceback.print_exc()
					print 'Failed to get icon pixbuf: ', icon_url, ' ignoring...'
					icon_pixbuf = None

				self.users[status.GetUser().GetId()] = UserInfo(user_name, screen_name, icon_pixbuf)

	#		self.users = self.users

			self.icon_cache = new_icon_cache
			urllib.urlcleanup()

		print "finished :)"

	def set_update_method(self, update_method):
#		self.__lock.acquire()
#		if update_method == TwitterUpdateMethod.FRIENDS:
			self.update_method = update_method
#		else:
 #			 self.__update_method = self.__api.GetPublicTimeline
 #		 self.__lock.release()
