def prev(self): if self.current_page is None: raise WeibopError('Can not go back more, at first page') if self.page_index == 0: # At the beginning of the current page, move to next... self.current_page = self.page_iterator.prev() self.page_index = len(self.current_page) if self.page_index == 0: raise WeibopError('No more items') self.page_index -= 1 self.count -= 1 return self.current_page[self.page_index]
def build_parameters(self, args, kargs): self.parameters = {} for idx, arg in enumerate(args): try: self.parameters[self.allowed_param[idx]] = convert_to_utf8_str(arg) except IndexError: raise WeibopError('Too many parameters supplied!') for k, arg in kargs.items(): if arg is None: continue if k in self.parameters: raise WeibopError('Multiple values for parameter %s supplied!' % k) self.parameters[k] = convert_to_utf8_str(arg)
def get_access_token(self, code=None): """ After user has authorized the request token, get access token with user supplied cod3. """ try: url = self._get_oauth_url('access_token') parameters = { 'client_id': self._consumer.key, 'client_secret': self._consumer.secret, 'grant_type': 'authorization_code', 'redirect_uri': self.callback, 'code': code } request = oauth.OAuthRequest('POST', url, parameters) resp = urlopen(Request(url, data=request.to_postdata())) data = resp.read() r = import_simplejson().loads(str(data)) self.access_token = r['access_token'] return self.access_token except Exception, e: raise WeibopError(e)
def get_access_token(self, verifier=None): """ After user has authorized the requestAuth token, get access token with user supplied verifier. """ try: url = self._get_oauth_url('access_token') # build requestAuth requestAuth = oauth.OAuthRequest.from_consumer_and_token( self._consumer, token=self.request_token, http_url=url, verifier=str(verifier) ) requestAuth.sign_request(self._sigmethod, self._consumer, self.request_token) # send requestAuth resp = request.urlopen(request.Request(url, headers=requestAuth.to_header())) self.access_token = oauth.OAuthToken.from_string((resp.read()).decode('UTF-8')) print('Access token key: '+ str(self.access_token.key)) print('Access token secret: '+ str(self.access_token.secret)) return self.access_token except Exception as e: raise WeibopError(e)
def parse(self, method, payload): try: if method.payload_type is None: return model = getattr(self.model_factory, method.payload_type) except AttributeError: raise WeibopError('No model for this payload type: %s' % method.payload_type) json = JSONParser.parse(self, method, payload) if isinstance(json, tuple): json, cursors = json else: cursors = None if method.payload_list: if method.payload_type == 'status': json = json['statuses'] result = model.parse_list(method.api, json) else: result = model.parse(method.api, json) if cursors: return result, cursors else: return result
def __init__(self, method, *args, **kargs): if hasattr(method, 'pagination_mode'): if method.pagination_mode == 'cursor': self.iterator = CursorIterator(method, args, kargs) else: self.iterator = PageIterator(method, args, kargs) else: raise WeibopError('This method does not perform pagination')
def prev(self): if self.prev_cursor == 0: raise WeibopError('Can not page back more, at first page') data, self.next_cursor, self.prev_cursor = self.method( cursor=self.prev_cursor, *self.args, **self.kargs ) self.count -= 1 return data
def get_username(self): if self.username is None: api = API(self) user = api.verify_credentials() if user: self.username = user.screen_name else: raise WeibopError("Unable to get username, invalid oauth token!") return self.username
def _get_request_token(self): try: url = self._get_oauth_url('request_token') request = oauth.OAuthRequest.from_consumer_and_token( self._consumer, http_url=url, callback=self.callback) request.sign_request(self._sigmethod, self._consumer, None) resp = urlopen(Request(url, headers=request.to_header())) return oauth.OAuthToken.from_string(resp.read()) except Exception, e: raise WeibopError(e)
def parse(self, method, payload): try: json = self.json_lib.loads(payload) except Exception as e: print("Failed to parse JSON payload:" + str(payload)) raise WeibopError('Failed to parse JSON payload: %s' % e) #if isinstance(json, dict) and 'previous_cursor' in json and 'next_cursor' in json: # cursors = json['previous_cursor'], json['next_cursor'] # return json, cursors #else: return json
def build_path(self): for variable in re_path_template.findall(self.path): name = variable.strip('{}') if name == 'user' and self.api.auth: value = self.api.auth.get_username() else: try: value = urllib.quote(self.parameters[name]) except KeyError: raise WeibopError('No parameter value found for path variable: %s' % name) del self.parameters[name] self.path = self.path.replace(variable, value)
def get_authorization_url(self, signin_with_twitter=False): """Get the authorization URL to redirect the user""" try: # build auth request and return as url url = self._get_oauth_url('authorize') parameters = { 'client_id': self._consumer.key, 'response_type': 'code', 'redirect_uri': self.callback, } request = oauth.OAuthRequest('GET', url, parameters) return request.to_url() except Exception, e: raise WeibopError(e)
def get_authorization_url(self, signin_with_twitter=False): """Get the authorization URL to redirect the user""" try: # get the request token self.request_token = self._get_request_token() # build auth request and return as url if signin_with_twitter: url = self._get_oauth_url('authenticate') else: url = self._get_oauth_url('authorize') request = oauth.OAuthRequest.from_token_and_callback( token=self.request_token, http_url=url, callback=self.callback) return request.to_url() except Exception, e: raise WeibopError(e)
def __init__(self, api, args, kargs): # If authentication is required and no credentials # are provided, throw an error. if self.require_auth and not api.auth: raise WeibopError('Authentication required!') self.api = api self.post_data = kargs.pop('post_data', None) self.retry_count = kargs.pop('retry_count', api.retry_count) self.retry_delay = kargs.pop('retry_delay', api.retry_delay) self.retry_errors = kargs.pop('retry_errors', api.retry_errors) self.headers = kargs.pop('headers', {}) self.build_parameters(args, kargs) # Pick correct URL root to use if self.search_api: self.api_root = api.search_root else: self.api_root = api.api_root # Perform any path variable substitution self.build_path() if api.secure: self.scheme = 'https://' else: self.scheme = 'http://' if self.search_api: self.host = api.search_host else: self.host = api.host # Manually set Host header to fix an issue in python 2.5 # or older where Host is set including the 443 port. # This causes Twitter to issue 301 redirect. # See Issue http://github.com/joshthecoder/tweepy/issues/#issue/12 self.headers['Host'] = self.host
def prev(self): if (self.current_page == 1): raise WeibopError('Can not page back more, at first page') self.current_page -= 1 return self.method(page=self.current_page, *self.args, **self.kargs)
def execute(self): # Build the request URL url = self.api_root + self.path if self.api.source is not None: self.parameters.setdefault('source',self.api.source) if len(self.parameters): if self.method == 'GET' or self.method == 'DELETE': url = '%s?%s' % (url, urllib.urlencode(self.parameters)) else: self.headers.setdefault("User-Agent","python") if self.post_data is None: self.headers.setdefault("Accept","text/html") self.headers.setdefault("Content-Type","application/x-www-form-urlencoded") self.post_data = urllib.urlencode(self.parameters) # Query the cache if one is available # and this request uses a GET method. if self.api.cache and self.method == 'GET': cache_result = self.api.cache.get(url) # if cache result found and not expired, return it if cache_result: # must restore api reference if isinstance(cache_result, list): for result in cache_result: result._api = self.api else: cache_result._api = self.api return cache_result #urllib.urlencode(self.parameters) # Continue attempting request until successful # or maximum number of retries is reached. sTime = time.time() retries_performed = 0 while retries_performed < self.retry_count + 1: # Apply authentication if self.api.auth: self.api.auth.apply_auth( self.scheme + self.host + url, self.method, self.headers, self.parameters ) # Execute request resp =None action_url = self.scheme + self.host + url req = urllib2.Request(action_url, self.post_data, self.headers) req.method = self.method # FIXME: When to retry and when to raise? try: resp = urllib2.urlopen(req) except urllib2.URLError, e: raise WeibopError('Failed to send request: %s, url %s, headers %s' % (e, action_url, self.headers)) # If no exception and status is OK if resp and resp.code == 200: break # Something wrong if self.retry_errors: if resp.code not in self.retry_errors: break # Sleep before retrying request again time.sleep(self.retry_delay) retries_performed += 1
if async: Thread(target=self._run).start() else: self._run() def firehose(self, count=None, async=False): if self.running: raise WeibopError('Stream object already connected!') self.url = '/%i/statuses/firehose.json?delimited=length' % STREAM_VERSION if count: self.url += '&count=%s' % count self._start(async) def retweet(self, async=False): if self.running: raise WeibopError('Stream object already connected!') self.url = '/%i/statuses/retweet.json?delimited=length' % STREAM_VERSION self._start(async) def sample(self, count=None, async=False): if self.running: raise WeibopError('Stream object already connected!') self.url = '/%i/statuses/sample.json?delimited=length' % STREAM_VERSION if count: self.url += '&count=%s' % count self._start(async) def filter(self, follow=None, track=None, async=False): params = {} self.headers['Content-type'] = "application/x-www-form-urlencoded" if self.running:
class APIMethod(object): path = config['path'] payload_type = config.get('payload_type', None) payload_list = config.get('payload_list', False) allowed_param = config.get('allowed_param', []) method = config.get('method', 'GET') require_auth = config.get('require_auth', False) search_api = config.get('search_api', False) def __init__(self, api, args, kargs): # If authentication is required and no credentials # are provided, throw an error. if self.require_auth and not api.auth: raise WeibopError('Authentication required!') self.api = api self.post_data = kargs.pop('post_data', None) self.retry_count = kargs.pop('retry_count', api.retry_count) self.retry_delay = kargs.pop('retry_delay', api.retry_delay) self.retry_errors = kargs.pop('retry_errors', api.retry_errors) self.headers = kargs.pop('headers', {}) self.build_parameters(args, kargs) # Pick correct URL root to use if self.search_api: self.api_root = api.search_root else: self.api_root = api.api_root # Perform any path variable substitution self.build_path() if api.secure: self.scheme = 'https://' else: self.scheme = 'http://' if self.search_api: self.host = api.search_host else: self.host = api.host # Manually set Host header to fix an issue in python 2.5 # or older where Host is set including the 443 port. # This causes Twitter to issue 301 redirect. # See Issue http://github.com/joshthecoder/tweepy/issues/#issue/12 self.headers['Host'] = self.host def build_parameters(self, args, kargs): self.parameters = {} for idx, arg in enumerate(args): try: self.parameters[self.allowed_param[idx]] = convert_to_utf8_str(arg) except IndexError: raise WeibopError('Too many parameters supplied!') for k, arg in kargs.items(): if arg is None: continue if k in self.parameters: raise WeibopError('Multiple values for parameter %s supplied!' % k) self.parameters[k] = convert_to_utf8_str(arg) def build_path(self): for variable in re_path_template.findall(self.path): name = variable.strip('{}') if name == 'user' and self.api.auth: value = self.api.auth.get_username() else: try: value = urllib.quote(self.parameters[name]) except KeyError: raise WeibopError('No parameter value found for path variable: %s' % name) del self.parameters[name] self.path = self.path.replace(variable, value) def execute(self): # Build the request URL url = self.api_root + self.path if self.api.source is not None: self.parameters.setdefault('source',self.api.source) if len(self.parameters): if self.method == 'GET' or self.method == 'DELETE': url = '%s?%s' % (url, urllib.urlencode(self.parameters)) else: self.headers.setdefault("User-Agent","python") if self.post_data is None: self.headers.setdefault("Accept","text/html") self.headers.setdefault("Content-Type","application/x-www-form-urlencoded") self.post_data = urllib.urlencode(self.parameters) # Query the cache if one is available # and this request uses a GET method. if self.api.cache and self.method == 'GET': cache_result = self.api.cache.get(url) # if cache result found and not expired, return it if cache_result: # must restore api reference if isinstance(cache_result, list): for result in cache_result: result._api = self.api else: cache_result._api = self.api return cache_result #urllib.urlencode(self.parameters) # Continue attempting request until successful # or maximum number of retries is reached. sTime = time.time() retries_performed = 0 while retries_performed < self.retry_count + 1: # Apply authentication if self.api.auth: self.api.auth.apply_auth( self.scheme + self.host + url, self.method, self.headers, self.parameters ) # Execute request resp =None action_url = self.scheme + self.host + url req = urllib2.Request(action_url, self.post_data, self.headers) req.method = self.method # FIXME: When to retry and when to raise? try: resp = urllib2.urlopen(req) except urllib2.URLError, e: raise WeibopError('Failed to send request: %s, url %s, headers %s' % (e, action_url, self.headers)) # If no exception and status is OK if resp and resp.code == 200: break # Something wrong if self.retry_errors: if resp.code not in self.retry_errors: break # Sleep before retrying request again time.sleep(self.retry_delay) retries_performed += 1 # If an error was returned, throw an exception body = '' if resp: body = resp.read() self.api.last_response = resp if self.api.log is not None: requestUrl = "URL:http://"+ self.host + url eTime = '%.0f' % ((time.time() - sTime) * 1000) postData = "" if self.post_data is not None: postData = ",post:"+ self.post_data[0:500] self.api.log.debug(requestUrl +",time:"+ str(eTime)+ postData+",result:"+ body ) # FIXME: What about resp is None? if resp and resp.code != 200: try: json = self.api.parser.parse_error(self, body) error_code = json['error_code'] error = json['error'] error_msg = 'error_code:' + error_code +','+ error except Exception: error_msg = "Weibo error response: status code = %s" % resp.code raise WeibopError(error_msg) # Parse the response payload result = self.api.parser.parse(self, body) # Store result into cache if one is available. if self.api.cache and self.method == 'GET' and result: self.api.cache.store(url, result) return result
class Stream(object): host = 'stream.twitter.com' def __init__(self, username, password, listener, timeout=5.0, retry_count = None, retry_time = 10.0, snooze_time = 5.0, buffer_size=1500, headers=None): self.auth = BasicAuthHandler(username, password) self.running = False self.timeout = timeout self.retry_count = retry_count self.retry_time = retry_time self.snooze_time = snooze_time self.buffer_size = buffer_size self.listener = listener self.api = API() self.headers = headers or {} self.body = None def _run(self): # setup self.auth.apply_auth(None, None, self.headers, None) # enter loop error_counter = 0 conn = None while self.running: if self.retry_count and error_counter > self.retry_count: # quit if error count greater than retry count break try: conn = httplib.HTTPConnection(self.host) conn.connect() conn.sock.settimeout(self.timeout) conn.request('POST', self.url, self.body, headers=self.headers) resp = conn.getresponse() if resp.status != 200: if self.listener.on_error(resp.status) is False: break error_counter += 1 sleep(self.retry_time) else: error_counter = 0 self._read_loop(resp) except timeout: if self.listener.on_timeout() == False: break if self.running is False: break conn.close() sleep(self.snooze_time) except Exception: # any other exception is fatal, so kill loop break # cleanup self.running = False if conn: conn.close() def _read_loop(self, resp): data = '' while self.running: if resp.isclosed(): break # read length length = '' while True: c = resp.read(1) if c == '\n': break length += c length = length.strip() if length.isdigit(): length = int(length) else: continue # read data and pass into listener data = resp.read(length) if self.listener.on_data(data) is False: self.running = False def _start(self, async): self.running = True if async: Thread(target=self._run).start() else: self._run() def firehose(self, count=None, async=False): if self.running: raise WeibopError('Stream object already connected!') self.url = '/%i/statuses/firehose.json?delimited=length' % STREAM_VERSION if count: self.url += '&count=%s' % count self._start(async)
def parse(self, method, payload): try: json = self.json_lib.loads(payload) except Exception, e: print "Failed to parse JSON payload:" + str(payload) raise WeibopError('Failed to parse JSON payload: %s' % e)
class APIMethod(object): path = config['path'] payload_type = config.get('payload_type', None) payload_list = config.get('payload_list', False) allowed_param = config.get('allowed_param', []) method = config.get('method', 'GET') require_auth = config.get('require_auth', False) search_api = config.get('search_api', False) def __init__(self, api, args, kargs): # If authentication is required and no credentials # are provided, throw an error. if self.require_auth and not api.auth: raise WeibopError('Authentication required!') self.api = api self.post_data = kargs.pop('post_data', None) self.retry_count = kargs.pop('retry_count', api.retry_count) self.retry_delay = kargs.pop('retry_delay', api.retry_delay) self.retry_errors = kargs.pop('retry_errors', api.retry_errors) self.headers = kargs.pop('headers', {}) self.build_parameters(args, kargs) # Pick correct URL root to use if self.search_api: self.api_root = api.search_root else: self.api_root = api.api_root # Perform any path variable substitution self.build_path() if api.secure: self.scheme = 'https://' else: self.scheme = 'http://' if self.search_api: self.host = api.search_host else: self.host = api.host # Manually set Host header to fix an issue in python 2.5 # or older where Host is set including the 443 port. # This causes Twitter to issue 301 redirect. # See Issue http://github.com/joshthecoder/tweepy/issues/#issue/12 self.headers['Host'] = self.host def build_parameters(self, args, kargs): self.parameters = {} for idx, arg in enumerate(args): try: self.parameters[self.allowed_param[idx]] = convert_to_utf8_str(arg) except IndexError: raise WeibopError('Too many parameters supplied!') for k, arg in kargs.items(): if arg is None: continue if k in self.parameters: raise WeibopError('Multiple values for parameter %s supplied!' % k) self.parameters[k] = convert_to_utf8_str(arg) def build_path(self): for variable in re_path_template.findall(self.path): name = variable.strip('{}') if name == 'user' and self.api.auth: value = self.api.auth.get_username() else: try: value = urllib.quote(self.parameters[name]) except KeyError: raise WeibopError('No parameter value found for path variable: %s' % name) del self.parameters[name] self.path = self.path.replace(variable, value) def execute(self): # Build the request URL url = self.api_root + self.path if self.api.source is not None: self.parameters.setdefault('source',self.api.source) if len(self.parameters): if self.method == 'GET' or self.method == 'DELETE': url = '%s?%s' % (url, urllib.urlencode(self.parameters)) else: self.headers.setdefault("User-Agent","python") if self.post_data is None: self.headers.setdefault("Accept","text/html") self.headers.setdefault("Content-Type","application/x-www-form-urlencoded") self.post_data = urllib.urlencode(self.parameters) # Query the cache if one is available # and this request uses a GET method. if self.api.cache and self.method == 'GET': cache_result = self.api.cache.get(url) # if cache result found and not expired, return it if cache_result: # must restore api reference if isinstance(cache_result, list): for result in cache_result: result._api = self.api else: cache_result._api = self.api return cache_result #urllib.urlencode(self.parameters) # Continue attempting request until successful # or maximum number of retries is reached. sTime = time.time() retries_performed = 0 while retries_performed < self.retry_count + 1: # Open connection # FIXME: add timeout # Use taras proxy if 'taras_proxy_addr' in os.environ: proxy_addr = os.environ['taras_proxy_addr'] proxy_port = int(os.environ['taras_proxy_port']) proxy_user = os.environ['taras_proxy_user'] proxy_passwd = os.environ['taras_proxy_passwd'] else: proxy_addr = '' proxy_info = None if proxy_addr == '' else httplib2.ProxyInfo(socks.PROXY_TYPE_SOCKS5, proxy_addr, proxy_port, proxy_user = proxy_user, proxy_pass = proxy_passwd) conn = httplib2.Http(proxy_info = proxy_info, timeout = 20) # Apply authentication if self.api.auth: self.api.auth.apply_auth( self.scheme + self.host + url, self.method, self.headers, self.parameters ) # Execute request try: print "headers:(%s)" % self.headers print "parameters:(%s)" % self.parameters resp, content = conn.request(uri = self.scheme + self.host + url, method = self.method, headers = self.headers, body = self.post_data) except ProxyError, err: self.api.taras.agent.update_proxy_log(proxy_addr, log_type="fail") raise Exception("Got ProxyError: %s, IP:%s, port:%d, user:%s, passwd:%s" % (err, proxy_addr, proxy_port, proxy_user, proxy_passwd)) except socket.error, err: self.api.taras.agent.update_proxy_log(proxy_addr, log_type="fail") raise Exception("Got ProxyError: %s, IP:%s, port:%d, user:%s, passwd:%s" % (err, proxy_addr, proxy_port, proxy_user, proxy_passwd)) except Exception, e: if str(e) == "timed out": self.api.taras.agent.update_proxy_log(proxy_addr, log_type="fail") raise WeibopError('Failed to send request: %s' % e + ", url=" + str(url) +",self.headers="+ str(self.headers) + " %s" % traceback.format_exc())
def execute(self): url = self.api_root + self.path if self.api.source is not None: self.parameters.setdefault('source', self.api.source) if len(self.parameters): if self.method == 'GET' or self.method == 'DELETE': url = '%s?%s' % (url, urllib.parse.urlencode(self.parameters)) else: self.headers.setdefault("User-Agent", "python") if self.post_data is None: self.headers.setdefault("Accept", "text/html") self.headers.setdefault( "Content-Type", "application/x-www-form-urlencoded") self.post_data = urllib.parse.urlencode( self.parameters) # Query the cache if one is available # and this request uses a GET method. if self.api.cache and self.method == 'GET': cache_result = self.api.cache.get(url) # if cache result found and not expired, return it if cache_result: # must restore api reference if isinstance(cache_result, list): for result in cache_result: result._api = self.api else: cache_result._api = self.api return cache_result #urllib.urlencode(self.parameters) # Continue attempting request until successful # or maximum number of retries is reached. sTime = time.time() retries_performed = 0 while retries_performed < self.retry_count + 1: # Open connection # FIXME: add timeout if self.api.secure: conn = http.client.HTTPSConnection(self.host) else: conn = http.client.HTTPConnection(self.host) # Apply authentication if self.api.auth: self.api.auth.apply_auth(self.scheme + self.host + url, self.method, self.headers, self.parameters) # Execute request try: conn.request(self.method, url, headers=self.headers, body=self.post_data) resp = conn.getresponse() except Exception as e: raise WeibopError('Failed to send request: %s' % str(e) + ".<url=" + str(url) + ",self.headers=" + str(self.headers) + '>') # Exit request loop if non-retry error code if self.retry_errors: if resp.status not in self.retry_errors: break else: if resp.status == 200: break # Sleep before retrying request again time.sleep(self.retry_delay) retries_performed += 1 # If an error was returned, throw an exception body = resp.read() body = body.decode('utf-8') self.api.last_response = resp if self.api.log is not None: requestUrl = "URL:http://" + self.host + url eTime = '%.0f' % ((time.time() - sTime) * 1000) postData = "" if self.post_data is not None: postData = ",post:" + self.post_data[0:500] self.api.log.debug(requestUrl + ",time:" + str(eTime) + postData + ",result:" + body) if resp.status != 200: try: json = self.api.parser.parse_error(self, body) error_code = json['error_code'] error = json['error'] error_msg = 'error_code:' + error_code + ',' + error except Exception: error_msg = "Twitter error response: status code = %s" % resp.status raise WeibopError(error_msg) # Parse the response payload result = self.api.parser.parse(self, body) conn.close() # Store result into cache if one is available. if self.api.cache and self.method == 'GET' and result: self.api.cache.store(url, result) return result
def execute(self): # Build the request URL url = self.api_root + self.path #if self.path == "/statuses/update.json": # url = "http://sinaproxy.heroku.com/statuses/update.json" if self.api.source is not None: self.parameters.setdefault('source', self.api.source) if len(self.parameters): if self.method == 'GET': url = '%s?%s' % (url, urllib.urlencode(self.parameters)) else: #self.headers.setdefault("User-Agent","python") if self.post_data is None: self.headers.setdefault("Accept", "text/html") self.headers.setdefault( "Content-Type", "application/x-www-form-urlencoded") self.post_data = urllib.urlencode(self.parameters) # Query the cache if one is available # and this request uses a GET method. if self.api.cache and self.method == 'GET': cache_result = self.api.cache.get(url) # if cache result found and not expired, return it if cache_result: # must restore api reference if isinstance(cache_result, list): for result in cache_result: result._api = self.api else: cache_result._api = self.api return cache_result #urllib.urlencode(self.parameters) # Continue attempting request until successful # or maximum number of retries is reached. sTime = time.time() retries_performed = 0 while retries_performed < self.retry_count + 1: # Open connection # FIXME: add timeout if self.api.secure: conn = httplib.HTTPSConnection(self.host) else: conn = httplib.HTTPConnection(self.host) # Apply authentication if self.api.auth: self.api.auth.apply_auth(self.scheme + self.host + url, self.method, self.headers, self.parameters) # Execute request try: conn.request(self.method, url, headers=self.headers, body=self.post_data) resp = conn.getresponse() except Exception, e: raise WeibopError('Failed to send request: %s' % e + "url=" + str(url) + ",self.headers=" + str(self.headers)) # Exit request loop if non-retry error code if self.retry_errors: if resp.status not in self.retry_errors: break else: if resp.status == 200: break # Sleep before retrying request again time.sleep(self.retry_delay) retries_performed += 1
def _pack_image(filename, max_size, source=None, status=None, lat=None, long=None, contentname="image"): """Pack image from file into multipart-formdata post body""" # image must be less than 700kb in size try: if os.path.getsize(filename) > (max_size * 1024): raise WeibopError('File is too big, must be less than 700kb.') #except os.error, e: except os.error: raise WeibopError('Unable to access file') # image must be gif, jpeg, or png file_type = mimetypes.guess_type(filename) if file_type is None: raise WeibopError('Could not determine file type') file_type = file_type[0] if file_type not in ['image/gif', 'image/jpeg', 'image/png']: raise WeibopError('Invalid file type for image: %s' % file_type) # build the mulitpart-formdata body fp = open(filename, 'rb') BOUNDARY = 'Tw3ePy' body = [] if status is not None: body.append('--' + BOUNDARY) body.append('Content-Disposition: form-data; name="status"') body.append('Content-Type: text/plain; charset=US-ASCII') body.append('Content-Transfer-Encoding: 8bit') body.append('') body.append(status) if source is not None: body.append('--' + BOUNDARY) body.append('Content-Disposition: form-data; name="source"') body.append('Content-Type: text/plain; charset=US-ASCII') body.append('Content-Transfer-Encoding: 8bit') body.append('') body.append(source) if lat is not None: body.append('--' + BOUNDARY) body.append('Content-Disposition: form-data; name="lat"') body.append('Content-Type: text/plain; charset=US-ASCII') body.append('Content-Transfer-Encoding: 8bit') body.append('') body.append(lat) if long is not None: body.append('--' + BOUNDARY) body.append('Content-Disposition: form-data; name="long"') body.append('Content-Type: text/plain; charset=US-ASCII') body.append('Content-Transfer-Encoding: 8bit') body.append('') body.append(long) body.append('--' + BOUNDARY) body.append('Content-Disposition: form-data; name="' + contentname + '"; filename="%s"' % filename) body.append('Content-Type: %s' % file_type) body.append('Content-Transfer-Encoding: binary') body.append('') body.append(fp.read()) body.append('--' + BOUNDARY + '--') body.append('') fp.close() body.append('--' + BOUNDARY + '--') body.append('') body = '\r\n'.join(body) # build headers headers = { 'Content-Type': 'multipart/form-data; boundary=Tw3ePy', 'Content-Length': len(body) } return headers, body
if self.api.log is not None: requestUrl = "URL:http://"+ self.host + url eTime = '%.0f' % ((time.time() - sTime) * 1000) postData = "" if self.post_data is not None: postData = ",post:"+ self.post_data[0:500] self.api.log.debug(requestUrl +",time:"+ str(eTime)+ postData+",result:"+ body ) if resp['status'] != '200': try: json = self.api.parser.parse_error(self, body) error_code = json['error_code'] error = json['error'] error_msg = 'error_code:' + error_code +','+ error except Exception: error_msg = "Weibo error response: status code = %s" % resp['status'] raise WeibopError(error_msg) # Parse the response payload #print 'body: %s' % body result = self.api.parser.parse(self, body) # Store result into cache if one is available. if self.api.cache and self.method == 'GET' and result: self.api.cache.store(url, result) return result def _call(api, *args, **kargs): method = APIMethod(api, args, kargs) return method.execute()