-from twitter.auth import Auth
+"""
+Visit the Twitter developer page and create a new application:
+
+ https://dev.twitter.com/apps/new
+
+This will get you a CONSUMER_KEY and CONSUMER_SECRET.
+
+When users run your application they have to authenticate your app
+with their Twitter account. A few HTTP calls to twitter are required
+to do this. Please see the twitter.oauth_dance module to see how this
+is done. If you are making a command-line app, you can use the
+oauth_dance() function directly.
+
+Performing the "oauth dance" gets you an ouath token and oauth secret
+that authenticate the user with Twitter. You should save these for
+later so that the user doesn't have to do the oauth dance again.
+
+read_token_file and write_token_file are utility methods to read and
+write OAuth token and secret key values. The values are stored as
+strings in the file. Not terribly exciting.
+
+Finally, you can use the OAuth authenticator to connect to Twitter. In
+code it all goes like this::
+
+ MY_TWITTER_CREDS = os.path.expanduser('~/.my_app_credentials')
+ if not os.path.exists(MY_TWITTER_CREDS):
+ oauth_dance("My App Name", CONSUMER_KEY, CONSUMER_SECRET,
+ MY_TWITTER_CREDS)
+
+ oauth_token, oauth_secret = read_token_file(MY_TWITTER_CREDS)
+
+ twitter = Twitter(auth=OAuth(
+ oauth_token, oauth_token_secret, CONSUMER_KEY, CONSUMER_SECRET))
+
+ # Now work with Twitter
+ twitter.statuses.update(status='Hello, world!')
+
+"""
+
+from __future__ import print_function
from time import time
from random import getrandbits
-from time import time
-import urllib
+
+try:
+ import urllib.parse as urllib_parse
+ from urllib.parse import urlencode
+ PY3 = True
+except ImportError:
+ import urllib2 as urllib_parse
+ from urllib import urlencode
+ PY3 = False
+
import hashlib
import hmac
+import base64
+
+from .auth import Auth
+
+
+def write_token_file(filename, oauth_token, oauth_token_secret):
+ """
+ Write a token file to hold the oauth token and oauth token secret.
+ """
+ oauth_file = open(filename, 'w')
+ print(oauth_token, file=oauth_file)
+ print(oauth_token_secret, file=oauth_file)
+ oauth_file.close()
+
+def read_token_file(filename):
+ """
+ Read a token file and return the oauth token and oauth token secret.
+ """
+ f = open(filename)
+ return f.readline().strip(), f.readline().strip()
-# An OAuth implementation with various helpers...
class OAuth(Auth):
+ """
+ An OAuth authenticator.
+ """
def __init__(self, token, token_secret, consumer_key, consumer_secret):
+ """
+ Create the authenticator. If you are in the initial stages of
+ the OAuth dance and don't yet have a token or token_secret,
+ pass empty strings for these params.
+ """
self.token = token
self.token_secret = token_secret
self.consumer_key = consumer_key
params['oauth_timestamp'] = str(int(time()))
params['oauth_nonce'] = str(getrandbits(64))
- enc_params = urlencode_noplus(sorted(params.iteritems()))
+ enc_params = urlencode_noplus(sorted(params.items()))
- key = self.consumer_secret + "&" + urllib.quote(self.token_secret, '')
+ key = self.consumer_secret + "&" + urllib_parse.quote(self.token_secret, safe='~')
message = '&'.join(
- urllib.quote(i, '') for i in [method.upper(), base_url, enc_params])
-
- signature = hmac.new(
- key, message, hashlib.sha1).digest().encode('base64')[:-1]
- return enc_params + "&" + "oauth_signature=" + urllib.quote(signature, '')
+ urllib_parse.quote(i, safe='~') for i in [method.upper(), base_url, enc_params])
+
+ signature = (base64.b64encode(hmac.new(
+ key.encode('ascii'), message.encode('ascii'), hashlib.sha1)
+ .digest()))
+ return enc_params + "&" + "oauth_signature=" + urllib_parse.quote(signature, safe='~')
def generate_headers(self):
return {}
# also in the request itself.)
# So here is a specialized version which does exactly that.
def urlencode_noplus(query):
- if hasattr(query,"items"):
- # mapping objects
- query = query.items()
-
- encoded_bits = []
- for n, v in query:
- # and do unicode here while we are at it...
- if isinstance(n, unicode):
- n = n.encode('utf-8')
- else:
- n = str(n)
- if isinstance(v, unicode):
- v = v.encode('utf-8')
- else:
- v = str(v)
- encoded_bits.append("%s=%s" % (urllib.quote(n, ""), urllib.quote(v, "")))
- return "&".join(encoded_bits)
+ if not PY3:
+ new_query = []
+ for k,v in query:
+ if type(k) is unicode: k = k.encode('utf-8')
+ if type(v) is unicode: v = v.encode('utf-8')
+ new_query.append((k, v))
+ query = new_query
+ return urlencode(query).replace("+", "%20")
+
+ return urlencode(query, safe='~').replace("+", "%20")
\ No newline at end of file