]>
Commit | Line | Data |
---|---|---|
568331a9 MH |
1 | from twitter.auth import Auth |
2 | ||
3 | from time import time | |
4 | from random import getrandbits | |
5 | from time import time | |
6 | import urllib | |
7 | import hashlib | |
8 | import hmac | |
9 | ||
10 | ||
1b31d642 MV |
11 | def write_token_file(filename, oauth_token, oauth_token_secret): |
12 | oauth_file = open(filename, 'w') | |
13 | print >> oauth_file, oauth_token | |
14 | print >> oauth_file, oauth_token_secret | |
15 | oauth_file.close() | |
16 | ||
17 | def read_token_file(filename): | |
18 | f = open(filename) | |
19 | return f.readline().strip(), f.readline().strip() | |
20 | ||
21 | ||
568331a9 | 22 | class OAuth(Auth): |
1cc9ab0b MV |
23 | """ |
24 | An OAuth authenticator. | |
25 | """ | |
568331a9 | 26 | def __init__(self, token, token_secret, consumer_key, consumer_secret): |
1cc9ab0b MV |
27 | """ |
28 | Create the authenticator. If you are in the initial stages of | |
29 | the OAuth dance and don't yet have a token or token_secret, | |
30 | pass empty strings for these params. | |
31 | """ | |
568331a9 MH |
32 | self.token = token |
33 | self.token_secret = token_secret | |
34 | self.consumer_key = consumer_key | |
35 | self.consumer_secret = consumer_secret | |
36 | ||
37 | def encode_params(self, base_url, method, params): | |
38 | params = params.copy() | |
39 | ||
6c527e72 MV |
40 | if self.token: |
41 | params['oauth_token'] = self.token | |
42 | ||
568331a9 MH |
43 | params['oauth_consumer_key'] = self.consumer_key |
44 | params['oauth_signature_method'] = 'HMAC-SHA1' | |
45 | params['oauth_version'] = '1.0' | |
46 | params['oauth_timestamp'] = str(int(time())) | |
47 | params['oauth_nonce'] = str(getrandbits(64)) | |
48 | ||
49 | enc_params = urlencode_noplus(sorted(params.iteritems())) | |
50 | ||
51 | key = self.consumer_secret + "&" + urllib.quote(self.token_secret, '') | |
52 | ||
53 | message = '&'.join( | |
54 | urllib.quote(i, '') for i in [method.upper(), base_url, enc_params]) | |
55 | ||
d20da7f3 MV |
56 | signature = hmac.new( |
57 | key, message, hashlib.sha1).digest().encode('base64')[:-1] | |
568331a9 MH |
58 | return enc_params + "&" + "oauth_signature=" + urllib.quote(signature, '') |
59 | ||
60 | def generate_headers(self): | |
61 | return {} | |
62 | ||
63 | # apparently contrary to the HTTP RFCs, spaces in arguments must be encoded as | |
64 | # %20 rather than '+' when constructing an OAuth signature (and therefore | |
65 | # also in the request itself.) | |
66 | # So here is a specialized version which does exactly that. | |
67 | def urlencode_noplus(query): | |
68 | if hasattr(query,"items"): | |
69 | # mapping objects | |
70 | query = query.items() | |
71 | ||
72 | encoded_bits = [] | |
73 | for n, v in query: | |
74 | # and do unicode here while we are at it... | |
75 | if isinstance(n, unicode): | |
76 | n = n.encode('utf-8') | |
77 | else: | |
78 | n = str(n) | |
79 | if isinstance(v, unicode): | |
80 | v = v.encode('utf-8') | |
81 | else: | |
82 | v = str(v) | |
83 | encoded_bits.append("%s=%s" % (urllib.quote(n, ""), urllib.quote(v, ""))) | |
84 | return "&".join(encoded_bits) |