Example #1
0
 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]
Example #2
0
        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)
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
    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
Example #6
0
 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')
Example #7
0
 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
Example #8
0
 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
Example #9
0
 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)
Example #10
0
    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
Example #11
0
        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)
Example #12
0
    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)
Example #13
0
    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)
Example #14
0
        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
Example #15
0
 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)
Example #16
0
        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
Example #17
0
        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:
Example #18
0
    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
Example #19
0
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)
Example #20
0
 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)
Example #21
0
    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())
Example #22
0
        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
Example #23
0
        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
Example #24
0
    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
Example #25
0
            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()