~parinporecha/gtg/global_shortcut

« back to all changes in this revision

Viewing changes to GTG/backends/tweepy/binder.py

  • Committer: Izidor Matušov
  • Date: 2013-01-10 15:03:42 UTC
  • Revision ID: izidor.matusov@gmail.com-20130110150342-ajwnwmc2trh9ia2v
Removing broken twitter and tweepy services

I don't know anybody uses them. They are broken, and pretty artificial (more proof of the concept). We should focus our efforts on normal synchronization.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Tweepy
2
 
# Copyright 2009-2010 Joshua Roesslein
3
 
# See LICENSE for details.
4
 
 
5
 
import httplib
6
 
import urllib
7
 
import time
8
 
import re
9
 
 
10
 
from tweepy.error import TweepError
11
 
from tweepy.utils import convert_to_utf8_str
12
 
 
13
 
re_path_template = re.compile('{\w+}')
14
 
 
15
 
 
16
 
def bind_api(**config):
17
 
 
18
 
    class APIMethod(object):
19
 
 
20
 
        path = config['path']
21
 
        payload_type = config.get('payload_type', None)
22
 
        payload_list = config.get('payload_list', False)
23
 
        allowed_param = config.get('allowed_param', [])
24
 
        method = config.get('method', 'GET')
25
 
        require_auth = config.get('require_auth', False)
26
 
        search_api = config.get('search_api', False)
27
 
 
28
 
        def __init__(self, api, args, kargs):
29
 
            # If authentication is required and no credentials
30
 
            # are provided, throw an error.
31
 
            if self.require_auth and not api.auth:
32
 
                raise TweepError('Authentication required!')
33
 
 
34
 
            self.api = api
35
 
            self.post_data = kargs.pop('post_data', None)
36
 
            self.retry_count = kargs.pop('retry_count', api.retry_count)
37
 
            self.retry_delay = kargs.pop('retry_delay', api.retry_delay)
38
 
            self.retry_errors = kargs.pop('retry_errors', api.retry_errors)
39
 
            self.headers = kargs.pop('headers', {})
40
 
            self.build_parameters(args, kargs)
41
 
 
42
 
            # Pick correct URL root to use
43
 
            if self.search_api:
44
 
                self.api_root = api.search_root
45
 
            else:
46
 
                self.api_root = api.api_root
47
 
 
48
 
            # Perform any path variable substitution
49
 
            self.build_path()
50
 
 
51
 
            if api.secure:
52
 
                self.scheme = 'https://'
53
 
            else:
54
 
                self.scheme = 'http://'
55
 
 
56
 
            if self.search_api:
57
 
                self.host = api.search_host
58
 
            else:
59
 
                self.host = api.host
60
 
 
61
 
            # Manually set Host header to fix an issue in python 2.5
62
 
            # or older where Host is set including the 443 port.
63
 
            # This causes Twitter to issue 301 redirect.
64
 
            # See Issue http://github.com/joshthecoder/tweepy/issues/#issue/12
65
 
            self.headers['Host'] = self.host
66
 
 
67
 
        def build_parameters(self, args, kargs):
68
 
            self.parameters = {}
69
 
            for idx, arg in enumerate(args):
70
 
                if arg is None:
71
 
                    continue
72
 
 
73
 
                try:
74
 
                    self.parameters[self.allowed_param[idx]] = convert_to_utf8_str(arg)
75
 
                except IndexError:
76
 
                    raise TweepError('Too many parameters supplied!')
77
 
 
78
 
            for k, arg in kargs.items():
79
 
                if arg is None:
80
 
                    continue
81
 
                if k in self.parameters:
82
 
                    raise TweepError('Multiple values for parameter %s supplied!' % k)
83
 
 
84
 
                self.parameters[k] = convert_to_utf8_str(arg)
85
 
 
86
 
        def build_path(self):
87
 
            for variable in re_path_template.findall(self.path):
88
 
                name = variable.strip('{}')
89
 
 
90
 
                if name == 'user' and 'user' not in self.parameters and self.api.auth:
91
 
                    # No 'user' parameter provided, fetch it from Auth instead.
92
 
                    value = self.api.auth.get_username()
93
 
                else:
94
 
                    try:
95
 
                        value = urllib.quote(self.parameters[name])
96
 
                    except KeyError:
97
 
                        raise TweepError('No parameter value found for path variable: %s' % name)
98
 
                    del self.parameters[name]
99
 
 
100
 
                self.path = self.path.replace(variable, value)
101
 
 
102
 
        def execute(self):
103
 
            # Build the request URL
104
 
            url = self.api_root + self.path
105
 
            if len(self.parameters):
106
 
                url = '%s?%s' % (url, urllib.urlencode(self.parameters))
107
 
 
108
 
            # Query the cache if one is available
109
 
            # and this request uses a GET method.
110
 
            if self.api.cache and self.method == 'GET':
111
 
                cache_result = self.api.cache.get(url)
112
 
                # if cache result found and not expired, return it
113
 
                if cache_result:
114
 
                    # must restore api reference
115
 
                    if isinstance(cache_result, list):
116
 
                        for result in cache_result:
117
 
                            result._api = self.api
118
 
                    else:
119
 
                        cache_result._api = self.api
120
 
                    return cache_result
121
 
 
122
 
            # Continue attempting request until successful
123
 
            # or maximum number of retries is reached.
124
 
            retries_performed = 0
125
 
            while retries_performed < self.retry_count + 1:
126
 
                # Open connection
127
 
                # FIXME: add timeout
128
 
                if self.api.secure:
129
 
                    conn = httplib.HTTPSConnection(self.host)
130
 
                else:
131
 
                    conn = httplib.HTTPConnection(self.host)
132
 
 
133
 
                # Apply authentication
134
 
                if self.api.auth:
135
 
                    self.api.auth.apply_auth(
136
 
                            self.scheme + self.host + url,
137
 
                            self.method, self.headers, self.parameters
138
 
                    )
139
 
 
140
 
                # Execute request
141
 
                try:
142
 
                    conn.request(self.method, url, headers=self.headers, body=self.post_data)
143
 
                    resp = conn.getresponse()
144
 
                except Exception, e:
145
 
                    raise TweepError('Failed to send request: %s' % e)
146
 
 
147
 
                # Exit request loop if non-retry error code
148
 
                if self.retry_errors:
149
 
                    if resp.status not in self.retry_errors: break
150
 
                else:
151
 
                    if resp.status == 200: break
152
 
 
153
 
                # Sleep before retrying request again
154
 
                time.sleep(self.retry_delay)
155
 
                retries_performed += 1
156
 
 
157
 
            # If an error was returned, throw an exception
158
 
            self.api.last_response = resp
159
 
            if resp.status != 200:
160
 
                try:
161
 
                    error_msg = self.api.parser.parse_error(resp.read())
162
 
                except Exception:
163
 
                    error_msg = "Twitter error response: status code = %s" % resp.status
164
 
                raise TweepError(error_msg, resp)
165
 
 
166
 
            # Parse the response payload
167
 
            result = self.api.parser.parse(self, resp.read())
168
 
 
169
 
            conn.close()
170
 
 
171
 
            # Store result into cache if one is available.
172
 
            if self.api.cache and self.method == 'GET' and result:
173
 
                self.api.cache.store(url, result)
174
 
 
175
 
            return result
176
 
 
177
 
 
178
 
    def _call(api, *args, **kargs):
179
 
 
180
 
        method = APIMethod(api, args, kargs)
181
 
        return method.execute()
182
 
 
183
 
 
184
 
    # Set pagination mode
185
 
    if 'cursor' in APIMethod.allowed_param:
186
 
        _call.pagination_mode = 'cursor'
187
 
    elif 'page' in APIMethod.allowed_param:
188
 
        _call.pagination_mode = 'page'
189
 
 
190
 
    return _call
191