twitter.py 8.3 KB

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