]> jfr.im git - z_archive/twitter.git/blobdiff - twitter/oauth.py
Compare lowercase hostnames when testing.
[z_archive/twitter.git] / twitter / oauth.py
index 9ee4fd06ce52879d802a506da8d2084c3c7820a7..2df5ff0a1eb9a0319d6ad959ac21702d2edd05de 100644 (file)
@@ -22,6 +22,8 @@ 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::
 
+    from twitter import *
+
     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,
@@ -33,23 +35,23 @@ code it all goes like this::
         oauth_token, oauth_token_secret, CONSUMER_KEY, CONSUMER_SECRET))
 
     # Now work with Twitter
-    twitter.statuses.update('Hello, world!')
+    twitter.statuses.update(status='Hello, world!')
 
 """
 
 from __future__ import print_function
 
-from time import time
 from random import getrandbits
+from time import time
+
+from .util import PY_3_OR_HIGHER
 
 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
@@ -104,15 +106,15 @@ class OAuth(Auth):
 
         enc_params = urlencode_noplus(sorted(params.items()))
 
-        key = self.consumer_secret + "&" + urllib_parse.quote(self.token_secret, '')
+        key = self.consumer_secret + "&" + urllib_parse.quote(self.token_secret, safe='~')
 
         message = '&'.join(
-            urllib_parse.quote(i, '') for i in [method.upper(), base_url, enc_params])
+            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, '')
+        return enc_params + "&" + "oauth_signature=" + urllib_parse.quote(signature, safe='~')
 
     def generate_headers(self):
         return {}
@@ -121,12 +123,18 @@ class OAuth(Auth):
 # %20 rather than '+' when constructing an OAuth signature (and therefore
 # also in the request itself.)
 # So here is a specialized version which does exactly that.
+# In Python2, since there is no safe option for urlencode, we force it by hand
 def urlencode_noplus(query):
-    if not PY3:
+    if not PY_3_OR_HIGHER:
         new_query = []
+        TILDE = '____TILDE-PYTHON-TWITTER____'
         for k,v in query:
             if type(k) is unicode: k = k.encode('utf-8')
+            k = str(k).replace("~", TILDE)
             if type(v) is unicode: v = v.encode('utf-8')
+            v = str(v).replace("~", TILDE)
             new_query.append((k, v))
         query = new_query
-    return urlencode(query).replace("+", "%20")
+        return urlencode(query).replace(TILDE, "~").replace("+", "%20")
+
+    return urlencode(query, safe='~').replace("+", "%20")