twitter.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. '''
  2. twitter.py contains a handful of methods for interacting
  3. with Twitter data and returning the responses as JSON.
  4. '''
  5. import urlparse
  6. import oauth2 as oauth
  7. import requests
  8. import base64, random
  9. import urllib
  10. import binascii
  11. import time, collections, hmac, hashlib
  12. import simplejson as json2
  13. REQUEST_TOKEN_URL = 'https://api.twitter.com/oauth/request_token'
  14. ACCESS_TOKEN_URL = 'https://api.twitter.com/oauth/access_token'
  15. AUTHORIZE_URL = 'https://api.twitter.com/oauth/authorize'
  16. class TwitterOauthClient(object):
  17. '''
  18. Python Client for Twitter API.
  19. '''
  20. oauth_token = None
  21. oauth_token_secret = None
  22. username = None
  23. is_authorized = False
  24. def __init__(self, consumer_key, consumer_secret, access_token, access_token_secret):
  25. '''
  26. Parameters:
  27. consumer_key: String
  28. - The consumer_key from registering application
  29. on Instagram.
  30. consumer_secret: String
  31. - The consumer_secret from registering application
  32. on Instagram.
  33. '''
  34. self.consumer_key = consumer_key
  35. self.consumer_secret = consumer_secret
  36. self.access_token = access_token
  37. self.access_token_secret = access_token_secret
  38. self.consumer = oauth.Consumer(key=self.consumer_key, secret=self.consumer_secret)
  39. def get_authorize_url(self):
  40. '''
  41. Obtained oauth_token and oauth_token_secret from request_token_url,
  42. returns an authorize url.
  43. From the redirect url, we obtain the oauth verifier.
  44. Returns:
  45. authURL: String
  46. - The authorization url.
  47. '''
  48. client = oauth.Client(self.consumer)
  49. resp, content = client.request(REQUEST_TOKEN_URL, 'GET')
  50. if int(resp['status']) != 200:
  51. raise Exception('Invalid response %s' %resp['status'])
  52. requestToken = dict(urlparse.parse_qsl(content))
  53. #temporary
  54. self.oauth_token = requestToken['oauth_token']
  55. self.oauth_token_secret = requestToken['oauth_token_secret']
  56. #print self.oauth_token
  57. #link to authorize app access twitter data and return to twitter api example page
  58. redirectUri = '&redirect_uri=http%3A%2F%2Flocalhost%3A8000/hackathon/twitter/'
  59. authURL = AUTHORIZE_URL+"?oauth_token="+self.oauth_token+redirectUri
  60. return authURL
  61. def get_access_token_url(self, oauthVerifier):
  62. '''
  63. Get access token from redirect url.
  64. Parameters:
  65. oauthVerifier: String
  66. - A paramater retrieved from scraping the redirect url.
  67. Returns:
  68. data: Dictionary
  69. - A dictionary containing recent tagged 120 media
  70. counts data pertaining to each media.
  71. '''
  72. token = oauth.Token(self.oauth_token, self.oauth_token_secret)
  73. token.set_verifier(oauthVerifier)
  74. client = oauth.Client(self.consumer, token)
  75. resp, content = client.request(ACCESS_TOKEN_URL, 'POST')
  76. if int(resp['status']) != 200:
  77. raise Exception('Invalid response %s' %resp['status'])
  78. #print content
  79. accessToken = dict(urlparse.parse_qsl(content))
  80. #permanent
  81. self.oauth_token = accessToken['oauth_token']
  82. self.oauth_token_secret = accessToken['oauth_token_secret']
  83. self.username = accessToken['screen_name']
  84. self.is_authorized = True
  85. def get_tweets(self):
  86. '''
  87. Get tweets of relevant search query.
  88. '''
  89. method = 'get'
  90. link = 'https://api.twitter.com/1.1/search/tweets.json'
  91. linkParameters = {'q':'obama', 'count': '100', 'result_type': 'popular'}
  92. oauthParameters = getOauthParameters(
  93. self.consumer_key,
  94. self.access_token
  95. )
  96. oauthParameters['oauth_signature'] = generateSignature(
  97. method,
  98. link,
  99. linkParameters,
  100. oauthParameters,
  101. self.consumer_secret,
  102. self.access_token_secret
  103. )
  104. headers = {'Authorization': createAuthHeader(oauthParameters)}
  105. link += '?' + urllib.urlencode(linkParameters)
  106. req = requests.get(link, headers=headers)
  107. if int(req.status_code) != 200:
  108. raise Exception('Invalid response %s' %req.status_code)
  109. content = json2.loads(req.content)
  110. return content['statuses']
  111. def get_trends_available(self, yahooConsumerKey):
  112. '''
  113. Get the locations that Twitter has trending topic information for.
  114. '''
  115. method = 'get'
  116. link = 'https://api.twitter.com/1.1/trends/available.json'
  117. linkParameters = {}
  118. oauthParameters = getOauthParameters(
  119. self.consumer_key,
  120. self.access_token
  121. )
  122. oauthParameters['oauth_signature'] = generateSignature(
  123. method,
  124. link,
  125. linkParameters,
  126. oauthParameters,
  127. self.consumer_secret,
  128. self.access_token_secret
  129. )
  130. headers = {'Authorization': createAuthHeader(oauthParameters)}
  131. if linkParameters:
  132. link += '?'+urllib.urlencode(linkParameters)
  133. req = requests.get(link, headers=headers)
  134. #print req.status_code
  135. if int(req.status_code) != 200:
  136. raise Exception('Invalid response %s' %req.status_code)
  137. content = json2.loads(req.content)
  138. #print len(content)
  139. for place in content:
  140. for item in place:
  141. if item == 'url':
  142. url = place[item]+'/neighbors?appid='+yahooConsumerKey+'&format=json'
  143. requestNeighborData = requests.get(url)
  144. #print request_neighbor_data.status_code
  145. if requestNeighborData.status_code == 200:
  146. neighbor = json2.loads(requestNeighborData.content)
  147. else:
  148. neighbor = {}
  149. place['neighbor'] = neighbor
  150. #print place
  151. return content
  152. def percentEncode(string):
  153. '''
  154. Percent encode strings.
  155. '''
  156. return urllib.quote(string, safe='~')
  157. def getNonce():
  158. '''
  159. Generate unique token per request.
  160. '''
  161. nonce = base64.b64encode(''.join([str(random.randint(0, 9)) for i in range(24)]))
  162. return nonce
  163. def generateSignature(method, link, linkParameters, oauthParameters,
  164. oauthConsumerSecret, oauthTokenSecret=None):
  165. '''
  166. Generate signature.
  167. '''
  168. if linkParameters:
  169. newDict = dict(oauthParameters, **linkParameters)
  170. params = urllib.urlencode(collections.OrderedDict(sorted(newDict.items())))
  171. else:
  172. params = urllib.urlencode(collections.OrderedDict(sorted(oauthParameters.items())))
  173. #Create your Signature Base String
  174. signatureBaseString = (method.upper()+'&'+percentEncode(str(link))+'&'+percentEncode(params))
  175. #Get the signing key
  176. signingKey = createSigningKey(oauthConsumerSecret, oauthTokenSecret)
  177. return calculateSignature(signingKey, signatureBaseString)
  178. def calculateSignature(signingKey, signatureBaseString):
  179. '''
  180. Calculate signature using HMAC-SHA1 hashing algorithm.
  181. '''
  182. hashed = hmac.new(signingKey, signatureBaseString, hashlib.sha1)
  183. sig = binascii.b2a_base64(hashed.digest())[:-1]
  184. return percentEncode(sig)
  185. def createSigningKey(oauthConsumerSecret, oauthTokenSecret):
  186. '''
  187. Creates a key to sign the request with.
  188. '''
  189. signingKey = percentEncode(oauthConsumerSecret) + '&' + percentEncode(oauthTokenSecret)
  190. return signingKey
  191. def createAuthHeader(parameters):
  192. '''
  193. Format authorization header with oath parameters.
  194. '''
  195. orderedParameters = collections.OrderedDict(sorted(parameters.items()))
  196. authHeader = ('%s="%s"' % (k, v) for k, v in orderedParameters.iteritems())
  197. return "OAuth " + ', '.join(authHeader)
  198. def getOauthParameters(consumerKey, accessToken):
  199. '''
  200. Returns parameters for making requests.
  201. '''
  202. oauthParameters = {
  203. 'oauth_timestamp': str(int(time.time())),
  204. 'oauth_signature_method': "HMAC-SHA1",
  205. 'oauth_version': "1.0",
  206. 'oauth_token': accessToken,
  207. 'oauth_nonce': getNonce(),
  208. 'oauth_consumer_key': consumerKey
  209. }
  210. return oauthParameters