def _pack_image(filename, max_size): """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 TweepError('File is too big, must be less than 700kb.') except os.error, e: raise TweepError('Unable to access file')
def prev(self): if self.current_page is None: raise TweepError('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 TweepError('No more items') self.page_index -= 1 self.count -= 1 return self.current_page[self.page_index]
def get_xauth_access_token(self, username, password): """ Get an access token from an username and password combination. In order to get this working you need to create an app at http://twitter.com/apps, after that send a mail to [email protected] and request activation of xAuth for it. """ try: url = self._get_oauth_url('access_token', secure=True) # must use HTTPS request = oauth.OAuthRequest.from_consumer_and_token( oauth_consumer=self._consumer, http_method='POST', http_url=url, parameters={ 'x_auth_mode': 'client_auth', 'x_auth_username': username, 'x_auth_password': password }) request.sign_request(self._sigmethod, self._consumer, None) resp = urlopen(Request(url, data=request.to_postdata())) self.access_token = oauth.OAuthToken.from_string(resp.read()) return self.access_token except Exception, e: raise TweepError(e)
def prev(self): if self.prev_cursor == 0: raise TweepError('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 __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 TweepError('This method does not perform pagination')
def execute(self): # Build the request URL url = self.api_root + self.path if len(self.parameters): url = '%s?%s' % (url, 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: if isinstance(result, Model): result._api = self.api else: if isinstance(cache_result, Model): cache_result._api = self.api return cache_result # Continue attempting request until successful # or maximum number of retries is reached. 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 TweepError('Failed to send request: %s' % e) # 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 get_username(self): if self.username is None: api = API(self) user = api.verify_credentials() if user: self.username = user.screen_name else: raise TweepError("Unable to get username, invalid oauth token!") return self.username
def build_parameters(self, args, kargs): self.parameters = {} for idx, arg in enumerate(args): if arg is None: continue try: self.parameters[self.allowed_param[idx]] = convert_to_utf8_str(arg) except IndexError: raise TweepError('Too many parameters supplied!') for k, arg in kargs.items(): if arg is None: continue if k in self.parameters: raise TweepError('Multiple values for parameter %s supplied!' % k) self.parameters[k] = convert_to_utf8_str(arg)
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 TweepError(e)
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 TweepError('No parameter value found for path variable: %s' % name) del self.parameters[name] self.path = self.path.replace(variable, value)
def build_parameters(self, args, kargs): self.parameters = {} for idx, arg in enumerate(args): if isinstance(arg, unicode): arg = arg.encode('utf-8') elif not isinstance(arg, str): arg = str(arg) try: self.parameters[self.allowed_param[idx]] = arg except IndexError: raise TweepError('Too many parameters supplied!') for k, arg in kargs.items(): if arg is None: continue if k in self.parameters: raise TweepError('Multiple values for parameter %s supplied!' % k) if isinstance(arg, unicode): arg = arg.encode('utf-8') elif not isinstance(arg, str): arg = str(arg) self.parameters[k] = arg
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) return request.to_url() except Exception, e: raise TweepError(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 TweepError('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.timeout = kargs.pop('timeout', api.timeout) 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 https://github.com/tweepy/tweepy/issues/12 self.headers['Host'] = self.host
def parse(self, method, payload): try: if method.payload_type is None: return model = getattr(self.model_factory, method.payload_type) except AttributeError: raise TweepError('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: result = model.parse_list(method.api, json) else: result = model.parse(method.api, json) if cursors: return result, cursors else: return result
def get_access_token(self, verifier=None): """ After user has authorized the request token, get access token with user supplied verifier. """ try: url = self._get_oauth_url('access_token') # build request request = oauth.OAuthRequest.from_consumer_and_token( self._consumer, token=self.request_token, http_url=url, verifier=str(verifier) ) request.sign_request(self._sigmethod, self._consumer, self.request_token) # send request resp = urlopen(Request(url, headers=request.to_header())) self.access_token = oauth.OAuthToken.from_string(resp.read()) return self.access_token except Exception, e: raise TweepError(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 TweepError('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 TweepError('Too many parameters supplied!') for k, arg in kargs.items(): if arg is None: continue if k in self.parameters: raise TweepError( '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 'user' not in self.parameters and self.api.auth: # No 'user' parameter provided, fetch it from Auth instead. value = self.api.auth.get_username() else: try: value = urllib.quote(self.parameters[name]) except KeyError: raise TweepError( '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 len(self.parameters): url = '%s?%s' % (url, 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 # Continue attempting request until successful # or maximum number of retries is reached. 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 TweepError('Failed to send request: %s' % e) # 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 self.api.last_response = resp if resp.status != 200: try: error_msg = self.api.parser.parse_error(resp.read()) except Exception: error_msg = "Twitter error response: status code = %s" % resp.status raise TweepError(error_msg, resp) # Parse the response payload result = self.api.parser.parse(self, resp.read()) 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 prev(self): if (self.current_page == 1): raise TweepError('Can not page back more, at first page') self.current_page -= 1 return self.method(page=self.current_page, *self.args, **self.kargs)
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): 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 = {} 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 TweepError('Stream object already connected!') self.url = '/%i/statuses/firehose.json?delimited=length' % STREAM_VERSION if count: self.url += '&count=%s' % count self._start(async)
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) use_cache = config.get('use_cache', True) 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 TweepError('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.timeout = kargs.pop('timeout', api.timeout) 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 https://github.com/tweepy/tweepy/issues/12 self.headers['Host'] = self.host def build_parameters(self, args, kargs): self.parameters = {} for idx, arg in enumerate(args): if arg is None: continue try: self.parameters[ self.allowed_param[idx]] = convert_to_utf8_str(arg) except IndexError: raise TweepError('Too many parameters supplied!') for k, arg in kargs.items(): if arg is None: continue if k in self.parameters: raise TweepError( '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 'user' not in self.parameters and self.api.auth: # No 'user' parameter provided, fetch it from Auth instead. value = self.api.auth.get_username() else: try: value = urllib.quote(self.parameters[name]) except KeyError: raise TweepError( '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 len(self.parameters): # OK so it seems like twitter doesn't consider '.' as a valid character. # So we replace all the dot with %2E url = '%s?%s' % (url, urllib.urlencode( self.parameters).replace('.', '%2E')) # Query the cache if one is available # and this request uses a GET method. if self.use_cache and 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: if isinstance(result, Model): result._api = self.api else: if isinstance(cache_result, Model): cache_result._api = self.api return cache_result # Continue attempting request until successful # or maximum number of retries is reached. retries_performed = 0 connection_args = {'host': self.host} # Python 2.6+ httplib has support for timeout via the API if self.timeout is not None and sys.hexversion >= 0x02060000: connection_args['timeout'] = self.timeout while retries_performed < self.retry_count + 1: # Open connection if self.api.secure: conn = httplib.HTTPSConnection(**connection_args) else: conn = httplib.HTTPConnection(**connection_args) # Apply authentication if self.api.auth: self.api.auth.apply_auth(self.scheme + self.host + url, self.method, self.headers, self.parameters) if self.api.compression is not None: self.headers['Accept-Encoding'] = 'gzip' # Execute request try: conn.request(self.method, url, headers=self.headers, body=self.post_data) # Python <= 2.5 httplib doesn't support timeout via the API # so we have to set it manually on the socket if self.timeout is not None and sys.hexversion < 0x02060000: conn.sock.settimeout(self.timeout) resp = conn.getresponse() except Exception, e: raise TweepError('Failed to send request: %s' % e) # 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 self.api.last_response = resp if resp.status != 200: try: error_msg = self.api.parser.parse_error(resp.read()) except Exception: error_msg = "Twitter error response: status code = %s" % resp.status raise TweepError(error_msg, resp) # Parse the response payload body = resp.read() if resp.getheader('Content-Encoding', '') == 'gzip': try: zipper = gzip.GzipFile(fileobj=StringIO(body)) body = zipper.read() except Exception, e: raise TweepError('Failed to decompress data: %s' % e)
def execute(self): # Build the request URL url = self.api_root + self.path if len(self.parameters): # OK so it seems like twitter doesn't consider '.' as a valid character. # So we replace all the dot with %2E url = '%s?%s' % (url, urllib.urlencode( self.parameters).replace('.', '%2E')) # Query the cache if one is available # and this request uses a GET method. if self.use_cache and 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: if isinstance(result, Model): result._api = self.api else: if isinstance(cache_result, Model): cache_result._api = self.api return cache_result # Continue attempting request until successful # or maximum number of retries is reached. retries_performed = 0 connection_args = {'host': self.host} # Python 2.6+ httplib has support for timeout via the API if self.timeout is not None and sys.hexversion >= 0x02060000: connection_args['timeout'] = self.timeout while retries_performed < self.retry_count + 1: # Open connection if self.api.secure: conn = httplib.HTTPSConnection(**connection_args) else: conn = httplib.HTTPConnection(**connection_args) # Apply authentication if self.api.auth: self.api.auth.apply_auth(self.scheme + self.host + url, self.method, self.headers, self.parameters) if self.api.compression is not None: self.headers['Accept-Encoding'] = 'gzip' # Execute request try: conn.request(self.method, url, headers=self.headers, body=self.post_data) # Python <= 2.5 httplib doesn't support timeout via the API # so we have to set it manually on the socket if self.timeout is not None and sys.hexversion < 0x02060000: conn.sock.settimeout(self.timeout) resp = conn.getresponse() except Exception, e: raise TweepError('Failed to send request: %s' % e) # 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 parse(self, method, payload): try: json = self.json_lib.loads(payload) except Exception, e: raise TweepError('Failed to parse JSON payload: %s' % e)
class API(object): """Twitter API""" def __init__(self, auth_handler=None, host='api.twitter.com', search_host='search.twitter.com', cache=None, secure=False, api_root='/1', search_root='', retry_count=0, retry_delay=0, retry_errors=None, parser=None): self.auth = auth_handler self.host = host self.search_host = search_host self.api_root = api_root self.search_root = search_root self.cache = cache self.secure = secure self.retry_count = retry_count self.retry_delay = retry_delay self.retry_errors = retry_errors self.parser = parser or ModelParser() """ statuses/public_timeline """ public_timeline = bind_api(path='/statuses/public_timeline.json', payload_type='status', payload_list=True, allowed_param=[]) """ statuses/home_timeline """ home_timeline = bind_api( path='/statuses/home_timeline.json', payload_type='status', payload_list=True, allowed_param=['since_id', 'max_id', 'count', 'page'], require_auth=True) """ statuses/friends_timeline """ friends_timeline = bind_api( path='/statuses/friends_timeline.json', payload_type='status', payload_list=True, allowed_param=['since_id', 'max_id', 'count', 'page'], require_auth=True) """ statuses/user_timeline """ user_timeline = bind_api(path='/statuses/user_timeline.json', payload_type='status', payload_list=True, allowed_param=[ 'id', 'user_id', 'screen_name', 'since_id', 'max_id', 'count', 'page', 'include_rts' ]) """ statuses/mentions """ mentions = bind_api(path='/statuses/mentions.json', payload_type='status', payload_list=True, allowed_param=['since_id', 'max_id', 'count', 'page'], require_auth=True) """/statuses/:id/retweeted_by.format""" retweeted_by = bind_api(path='/statuses/{id}/retweeted_by.json', payload_type='status', payload_list=True, allowed_param=['id', 'count', 'page'], require_auth=True) """/statuses/:id/retweeted_by/ids.format""" retweeted_by_ids = bind_api(path='/statuses/{id}/retweeted_by/ids.json', payload_type='ids', allowed_param=['id', 'count', 'page'], require_auth=True) """ statuses/retweeted_by_me """ retweeted_by_me = bind_api( path='/statuses/retweeted_by_me.json', payload_type='status', payload_list=True, allowed_param=['since_id', 'max_id', 'count', 'page'], require_auth=True) """ statuses/retweeted_to_me """ retweeted_to_me = bind_api( path='/statuses/retweeted_to_me.json', payload_type='status', payload_list=True, allowed_param=['since_id', 'max_id', 'count', 'page'], require_auth=True) """ statuses/retweets_of_me """ retweets_of_me = bind_api( path='/statuses/retweets_of_me.json', payload_type='status', payload_list=True, allowed_param=['since_id', 'max_id', 'count', 'page'], require_auth=True) """ statuses/show """ get_status = bind_api(path='/statuses/show.json', payload_type='status', allowed_param=['id']) """ statuses/update """ update_status = bind_api(path='/statuses/update.json', method='POST', payload_type='status', allowed_param=[ 'status', 'in_reply_to_status_id', 'lat', 'long', 'source', 'place_id' ], require_auth=True) """ statuses/destroy """ destroy_status = bind_api(path='/statuses/destroy.json', method='DELETE', payload_type='status', allowed_param=['id'], require_auth=True) """ statuses/retweet """ retweet = bind_api(path='/statuses/retweet/{id}.json', method='POST', payload_type='status', allowed_param=['id'], require_auth=True) """ statuses/retweets """ retweets = bind_api(path='/statuses/retweets/{id}.json', payload_type='status', payload_list=True, allowed_param=['id', 'count'], require_auth=True) """ users/show """ get_user = bind_api(path='/users/show.json', payload_type='user', allowed_param=['id', 'user_id', 'screen_name']) """ Perform bulk look up of users from user ID or screenname """ def lookup_users(self, user_ids=None, screen_names=None): return self._lookup_users(list_to_csv(user_ids), list_to_csv(screen_names)) _lookup_users = bind_api(path='/users/lookup.json', payload_type='user', payload_list=True, allowed_param=['user_id', 'screen_name'], require_auth=True) """ Get the authenticated user """ def me(self): return self.get_user(screen_name=self.auth.get_username()) """ users/search """ search_users = bind_api(path='/users/search.json', payload_type='user', payload_list=True, require_auth=True, allowed_param=['q', 'per_page', 'page']) """ statuses/friends """ friends = bind_api( path='/statuses/friends.json', payload_type='user', payload_list=True, allowed_param=['id', 'user_id', 'screen_name', 'page', 'cursor']) """ statuses/followers """ followers = bind_api( path='/statuses/followers.json', payload_type='user', payload_list=True, allowed_param=['id', 'user_id', 'screen_name', 'page', 'cursor']) """ direct_messages """ direct_messages = bind_api( path='/direct_messages.json', payload_type='direct_message', payload_list=True, allowed_param=['since_id', 'max_id', 'count', 'page'], require_auth=True) """ direct_messages/sent """ sent_direct_messages = bind_api( path='/direct_messages/sent.json', payload_type='direct_message', payload_list=True, allowed_param=['since_id', 'max_id', 'count', 'page'], require_auth=True) """ direct_messages/new """ send_direct_message = bind_api( path='/direct_messages/new.json', method='POST', payload_type='direct_message', allowed_param=['user', 'screen_name', 'user_id', 'text'], require_auth=True) """ direct_messages/destroy """ destroy_direct_message = bind_api(path='/direct_messages/destroy.json', method='DELETE', payload_type='direct_message', allowed_param=['id'], require_auth=True) """ friendships/create """ create_friendship = bind_api( path='/friendships/create.json', method='POST', payload_type='user', allowed_param=['id', 'user_id', 'screen_name', 'follow'], require_auth=True) """ friendships/destroy """ destroy_friendship = bind_api( path='/friendships/destroy.json', method='DELETE', payload_type='user', allowed_param=['id', 'user_id', 'screen_name'], require_auth=True) """ friendships/exists """ exists_friendship = bind_api(path='/friendships/exists.json', payload_type='json', allowed_param=['user_a', 'user_b']) """ friendships/show """ show_friendship = bind_api(path='/friendships/show.json', payload_type='friendship', allowed_param=[ 'source_id', 'source_screen_name', 'target_id', 'target_screen_name' ]) """ friends/ids """ friends_ids = bind_api( path='/friends/ids.json', payload_type='ids', allowed_param=['id', 'user_id', 'screen_name', 'cursor']) """ friendships/incoming """ friendships_incoming = bind_api(path='/friendships/incoming.json', payload_type='ids', allowed_param=['cursor']) """ friendships/outgoing""" friendships_outgoing = bind_api(path='/friendships/outgoing.json', payload_type='ids', allowed_param=['cursor']) """ followers/ids """ followers_ids = bind_api( path='/followers/ids.json', payload_type='ids', allowed_param=['id', 'user_id', 'screen_name', 'cursor']) """ account/verify_credentials """ def verify_credentials(self): try: return bind_api(path='/account/verify_credentials.json', payload_type='user', require_auth=True)(self) except TweepError: return False """ account/rate_limit_status """ rate_limit_status = bind_api(path='/account/rate_limit_status.json', payload_type='json') """ account/update_delivery_device """ set_delivery_device = bind_api(path='/account/update_delivery_device.json', method='POST', allowed_param=['device'], payload_type='user', require_auth=True) """ account/update_profile_colors """ update_profile_colors = bind_api( path='/account/update_profile_colors.json', method='POST', payload_type='user', allowed_param=[ 'profile_background_color', 'profile_text_color', 'profile_link_color', 'profile_sidebar_fill_color', 'profile_sidebar_border_color' ], require_auth=True) """ account/update_profile_image """ def update_profile_image(self, filename): headers, post_data = API._pack_image(filename, 700) return bind_api(path='/account/update_profile_image.json', method='POST', payload_type='user', require_auth=True)(self, post_data=post_data, headers=headers) """ account/update_profile_background_image """ def update_profile_background_image(self, filename, *args, **kargs): headers, post_data = API._pack_image(filename, 800) bind_api(path='/account/update_profile_background_image.json', method='POST', payload_type='user', allowed_param=['tile'], require_auth=True)(self, post_data=post_data, headers=headers) """ account/update_profile """ update_profile = bind_api( path='/account/update_profile.json', method='POST', payload_type='user', allowed_param=['name', 'url', 'location', 'description'], require_auth=True) """ favorites """ favorites = bind_api(path='/favorites.json', payload_type='status', payload_list=True, allowed_param=['id', 'page']) """ favorites/create """ create_favorite = bind_api(path='/favorites/create/{id}.json', method='POST', payload_type='status', allowed_param=['id'], require_auth=True) """ favorites/destroy """ destroy_favorite = bind_api(path='/favorites/destroy/{id}.json', method='DELETE', payload_type='status', allowed_param=['id'], require_auth=True) """ notifications/follow """ enable_notifications = bind_api( path='/notifications/follow.json', method='POST', payload_type='user', allowed_param=['id', 'user_id', 'screen_name'], require_auth=True) """ notifications/leave """ disable_notifications = bind_api( path='/notifications/leave.json', method='POST', payload_type='user', allowed_param=['id', 'user_id', 'screen_name'], require_auth=True) """ blocks/create """ create_block = bind_api(path='/blocks/create.json', method='POST', payload_type='user', allowed_param=['id', 'user_id', 'screen_name'], require_auth=True) """ blocks/destroy """ destroy_block = bind_api(path='/blocks/destroy.json', method='DELETE', payload_type='user', allowed_param=['id', 'user_id', 'screen_name'], require_auth=True) """ blocks/exists """ def exists_block(self, *args, **kargs): try: bind_api(path='/blocks/exists.json', allowed_param=['id', 'user_id', 'screen_name'], require_auth=True)(self, *args, **kargs) except TweepError: return False return True """ blocks/blocking """ blocks = bind_api(path='/blocks/blocking.json', payload_type='user', payload_list=True, allowed_param=['page'], require_auth=True) """ blocks/blocking/ids """ blocks_ids = bind_api(path='/blocks/blocking/ids.json', payload_type='json', require_auth=True) """ report_spam """ report_spam = bind_api(path='/report_spam.json', method='POST', payload_type='user', allowed_param=['id', 'user_id', 'screen_name'], require_auth=True) """ saved_searches """ saved_searches = bind_api(path='/saved_searches.json', payload_type='saved_search', payload_list=True, require_auth=True) """ saved_searches/show """ get_saved_search = bind_api(path='/saved_searches/show/{id}.json', payload_type='saved_search', allowed_param=['id'], require_auth=True) """ saved_searches/create """ create_saved_search = bind_api(path='/saved_searches/create.json', method='POST', payload_type='saved_search', allowed_param=['query'], require_auth=True) """ saved_searches/destroy """ destroy_saved_search = bind_api(path='/saved_searches/destroy/{id}.json', method='DELETE', payload_type='saved_search', allowed_param=['id'], require_auth=True) """ help/test """ def test(self): try: bind_api(path='/help/test.json', )(self) except TweepError: return False return True def create_list(self, *args, **kargs): return bind_api(path='/%s/lists.json' % self.auth.get_username(), method='POST', payload_type='list', allowed_param=['name', 'mode', 'description'], require_auth=True)(self, *args, **kargs) def destroy_list(self, slug): return bind_api(path='/%s/lists/%s.json' % (self.auth.get_username(), slug), method='DELETE', payload_type='list', require_auth=True)(self) def update_list(self, slug, *args, **kargs): return bind_api(path='/%s/lists/%s.json' % (self.auth.get_username(), slug), method='POST', payload_type='list', allowed_param=['name', 'mode', 'description'], require_auth=True)(self, *args, **kargs) lists = bind_api(path='/{user}/lists.json', payload_type='list', payload_list=True, allowed_param=['user', 'cursor'], require_auth=True) lists_memberships = bind_api(path='/{user}/lists/memberships.json', payload_type='list', payload_list=True, allowed_param=['user', 'cursor'], require_auth=True) lists_subscriptions = bind_api(path='/{user}/lists/subscriptions.json', payload_type='list', payload_list=True, allowed_param=['user', 'cursor'], require_auth=True) list_timeline = bind_api(path='/{owner}/lists/{slug}/statuses.json', payload_type='status', payload_list=True, allowed_param=[ 'owner', 'slug', 'since_id', 'max_id', 'per_page', 'page' ]) get_list = bind_api(path='/{owner}/lists/{slug}.json', payload_type='list', allowed_param=['owner', 'slug']) def add_list_member(self, slug, *args, **kargs): return bind_api(path='/%s/%s/members.json' % (self.auth.get_username(), slug), method='POST', payload_type='list', allowed_param=['id'], require_auth=True)(self, *args, **kargs) def remove_list_member(self, slug, *args, **kargs): return bind_api(path='/%s/%s/members.json' % (self.auth.get_username(), slug), method='DELETE', payload_type='list', allowed_param=['id'], require_auth=True)(self, *args, **kargs) list_members = bind_api(path='/{owner}/{slug}/members.json', payload_type='user', payload_list=True, allowed_param=['owner', 'slug', 'cursor']) def is_list_member(self, owner, slug, user_id): try: return bind_api(path='/%s/%s/members/%s.json' % (owner, slug, user_id), payload_type='user')(self) except TweepError: return False subscribe_list = bind_api(path='/{owner}/{slug}/subscribers.json', method='POST', payload_type='list', allowed_param=['owner', 'slug'], require_auth=True) unsubscribe_list = bind_api(path='/{owner}/{slug}/subscribers.json', method='DELETE', payload_type='list', allowed_param=['owner', 'slug'], require_auth=True) list_subscribers = bind_api(path='/{owner}/{slug}/subscribers.json', payload_type='user', payload_list=True, allowed_param=['owner', 'slug', 'cursor']) def is_subscribed_list(self, owner, slug, user_id): try: return bind_api(path='/%s/%s/subscribers/%s.json' % (owner, slug, user_id), payload_type='user')(self) except TweepError: return False """ trends/available """ trends_available = bind_api(path='/trends/available.json', payload_type='json', allowed_param=['lat', 'long']) """ trends/location """ trends_location = bind_api(path='/trends/{woeid}.json', payload_type='json', allowed_param=['woeid']) """ search """ search = bind_api(search_api=True, path='/search.json', payload_type='search_result', payload_list=True, allowed_param=[ 'q', 'lang', 'locale', 'rpp', 'page', 'since_id', 'geocode', 'show_user', 'max_id', 'since', 'until', 'result_type' ]) search.pagination_mode = 'page' """ trends """ trends = bind_api(path='/trends.json', payload_type='json') """ trends/current """ trends_current = bind_api(path='/trends/current.json', payload_type='json', allowed_param=['exclude']) """ trends/daily """ trends_daily = bind_api(path='/trends/daily.json', payload_type='json', allowed_param=['date', 'exclude']) """ trends/weekly """ trends_weekly = bind_api(path='/trends/weekly.json', payload_type='json', allowed_param=['date', 'exclude']) """ geo/reverse_geocode """ reverse_geocode = bind_api(path='/geo/reverse_geocode.json', payload_type='json', allowed_param=[ 'lat', 'long', 'accuracy', 'granularity', 'max_results' ]) """ geo/nearby_places """ nearby_places = bind_api(path='/geo/nearby_places.json', payload_type='json', allowed_param=[ 'lat', 'long', 'ip', 'accuracy', 'granularity', 'max_results' ]) """ geo/id """ geo_id = bind_api(path='/geo/id/{id}.json', payload_type='json', allowed_param=['id']) """ Internal use only """ @staticmethod def _pack_image(filename, max_size): """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 TweepError('File is too big, must be less than 700kb.') except os.error, e: raise TweepError('Unable to access file') # image must be gif, jpeg, or png file_type = mimetypes.guess_type(filename) if file_type is None: raise TweepError('Could not determine file type') file_type = file_type[0] if file_type not in ['image/gif', 'image/jpeg', 'image/png']: raise TweepError('Invalid file type for image: %s' % file_type) # build the mulitpart-formdata body fp = open(filename, 'rb') BOUNDARY = 'Tw3ePy' body = [] body.append('--' + BOUNDARY) body.append( 'Content-Disposition: form-data; name="image"; filename="%s"' % filename) body.append('Content-Type: %s' % file_type) body.append('') body.append(fp.read()) body.append('--' + BOUNDARY + '--') body.append('') fp.close() body = '\r\n'.join(body) # build headers headers = { 'Content-Type': 'multipart/form-data; boundary=Tw3ePy', 'Content-Length': len(body) } return headers, body
# 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): self.parameters = {'delimited': 'length'} if self.running: raise TweepError('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): self.parameters = {'delimited': 'length'} if self.running: raise TweepError('Stream object already connected!') self.url = '/%i/statuses/retweet.json?delimited=length' % STREAM_VERSION self._start(async) def sample(self, count=None, async=False): self.parameters = {'delimited': 'length'} if self.running: