commit d293eb8b52a1bf23e9ac1767cc7fdc0c54a12520 Author: Damian Johnson atagar@torproject.org Date: Mon Apr 20 21:01:03 2015 -0700
Simplifying twitter example
Replacing the KEY_DICT global and helpers with a shorter script. I don't have a Twitter account so unfortunately can't exercise this sucker, but should be equivalent to what we had previously.
This and the prior commit are for...
https://trac.torproject.org/projects/tor/ticket/9003 --- docs/tutorials/to_russia_with_love.rst | 87 +++++++++++++------------------- 1 file changed, 36 insertions(+), 51 deletions(-)
diff --git a/docs/tutorials/to_russia_with_love.rst b/docs/tutorials/to_russia_with_love.rst index 7d91f4b..6bb4252 100644 --- a/docs/tutorials/to_russia_with_love.rst +++ b/docs/tutorials/to_russia_with_love.rst @@ -121,93 +121,78 @@ Besides SocksiPy, you can also use `PycURL http://pycurl.sourceforge.net/`_ to Reading Twitter ---------------
-Now lets do somthing a little more interesting, and read a Twitter feed over Tor. This can be easily done `using thier API https://dev.twitter.com/rest/reference/get/statuses/user_timeline`_ +Now lets do somthing a little more interesting, and read a Twitter feed over Tor. This can be done `using thier API https://dev.twitter.com/rest/reference/get/statuses/user_timeline`_, for authentication `see their instructions https://dev.twitter.com/oauth/overview/application-owner-access-tokens`_...
::
+ import binascii + import hashlib + import hmac import json import socket + import time import urllib import urllib2 - import time - import binascii - import hmac - from hashlib import sha1, md5
import socks # SockiPy module import stem.process
SOCKS_PORT = 7000 - KEY_DICT = dict() TWITTER_API_URL = "https://api.twitter.com/1.1/statuses/user_timeline.json" CONSUMER_KEY = "" CONSUMER_SECRET = "" ACCESS_TOKEN = "" ACCESS_TOKEN_SECRET = "" - HTTP_METHOD = "GET" - OAUTH_VERSION = "1.0" + + HEADER_AUTH_KEYS = ['oauth_consumer_key', 'oauth_nonce', 'oauth_signature', + 'oauth_signature_method', 'oauth_timestamp', 'oauth_token', 'oauth_version']
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', SOCKS_PORT) socket.socket = socks.socksocket
+ def oauth_signature(key_dict): + fin_key = ""
- def init_key_dict(): - """ - Initializes KEY_DICT - """ - - global KEY_DICT - KEY_DICT['oauth_consumer_key'] = urllib.quote(CONSUMER_KEY, '') - KEY_DICT['oauth_nonce'] = urllib.quote(md5(str(time.time())).hexdigest(), '') - KEY_DICT['oauth_signature_method'] = urllib.quote("HMAC-SHA1", '') - KEY_DICT['oauth_timestamp'] = urllib.quote(str(int(time.time())), '') - KEY_DICT['oauth_token'] = urllib.quote(ACCESS_TOKEN, '') - KEY_DICT['oauth_version'] = urllib.quote(OAUTH_VERSION, '') + for key in sorted(key_dict.keys()): + fin_key += key + "=" + key_dict[key] + "&"
- def get_signature(values): - """ - Generates KEY_DICT['oauth_signature'] - """ - for value in values: - KEY_DICT[value] = urllib.quote(values[value], '') - fin_key = "" - for key in sorted(KEY_DICT.keys()): - fin_key += key + "=" + KEY_DICT[key] + "&" fin_key = fin_key[:-1] - fin_key = HTTP_METHOD + "&" + urllib.quote(TWITTER_API_URL, '') + "&" + urllib.quote(fin_key, '') + fin_key = 'GET' + "&" + urllib.quote(TWITTER_API_URL, '') + "&" + urllib.quote(fin_key, '') key = urllib.quote(CONSUMER_SECRET, '') + "&" + urllib.quote(ACCESS_TOKEN_SECRET, '') - hashed = hmac.new(key, fin_key, sha1) + hashed = hmac.new(key, fin_key, hashlib.sha1) fin_key = binascii.b2a_base64(hashed.digest())[:-1] - KEY_DICT['oauth_signature'] = urllib.quote(fin_key, '') - - def get_header_string(): - """ - Returns the header string - """ - ret = "OAuth " - key_list =['oauth_consumer_key', 'oauth_nonce', 'oauth_signature', 'oauth_signature_method', 'oauth_timestamp', 'oauth_token', 'oauth_version'] - for key in key_list: - ret = ret + key + "="" + KEY_DICT[key] + "", " - ret = ret[:-2] - return ret + return urllib.quote(fin_key, '')
def poll_twitter_feed(user_id, tweet_count): """ Polls Twitter for the tweets from a given user. """
- init_key_dict() - values = {'screen_name': user_id, 'count': str(tweet_count), 'include_rts': '1'} - api_url = TWITTER_API_URL - get_signature(values) - headers = {'Authorization': get_header_string()} - data = urllib.urlencode(values) - api_request = urllib2.Request(api_url + "?" + data, headers= headers) + key_dict = { + 'oauth_consumer_key': urllib.quote(CONSUMER_KEY, ''), + 'oauth_nonce': urllib.quote(hashlib.md5(str(time.time())).hexdigest(), ''), + 'oauth_signature_method': urllib.quote("HMAC-SHA1", ''), + 'oauth_timestamp': urllib.quote(str(int(time.time())), ''), + 'oauth_token': urllib.quote(ACCESS_TOKEN, ''), + 'oauth_version': urllib.quote('1.0', ''), + } + + url_values = {'screen_name': user_id, 'count': str(tweet_count), 'include_rts': '1'} + + for key, value in url_values.items(): + key_dict[key] = urllib.quote(value, '') + + key_dict['oauth_signature'] = oauth_signature(key_dict) + + header_auth = 'OAuth ' + ', '.join(['%s="%s"' % (key, key_dict[key]) for key in HEADER_AUTH_KEYS]) + + data = urllib.urlencode(url_values) + api_request = urllib2.Request(TWITTER_API_URL + "?" + data, headers = {'Authorization': header_auth})
try: api_response = urllib2.urlopen(api_request).read() except: - raise IOError("Unable to reach %s" % api_url) + raise IOError("Unable to reach %s" % TWITTER_API_URL)
return json.loads(api_response)