<s> import urllib <EOL> from . oauth2 import OAuth2Request <EOL> import re <EOL> from . json_import import simplejson <EOL> import hmac <EOL> from hashlib import sha256 <EOL> import six <EOL> from six . moves . urllib . parse import quote <EOL> import sys <EOL> re_path_template = re . compile ( '<STR_LIT>' ) <EOL> def encode_string ( value ) : <EOL> return value . encode ( '<STR_LIT:utf-8>' ) if isinstance ( value , six . text_type ) else str ( value ) <EOL> class InstagramClientError ( Exception ) : <EOL> def __init__ ( self , error_message , status_code = None ) : <EOL> self . status_code = status_code <EOL> self . error_message = error_message <EOL> def __str__ ( self ) : <EOL> if self . status_code : <EOL> return "<STR_LIT>" % ( self . status_code , self . error_message ) <EOL> else : <EOL> return self . error_message <EOL> class InstagramAPIError ( Exception ) : <EOL> def __init__ ( self , status_code , error_type , error_message , * args , ** kwargs ) : <EOL> self . status_code = status_code <EOL> self . error_type = error_type <EOL> self . error_message = error_message <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT>" % ( self . status_code , self . error_type , self . error_message ) <EOL> def bind_method ( ** config ) : <EOL> class InstagramAPIMethod ( object ) : <EOL> path = config [ '<STR_LIT:path>' ] <EOL> method = config . get ( '<STR_LIT>' , '<STR_LIT:GET>' ) <EOL> accepts_parameters = config . get ( "<STR_LIT>" , [ ] ) <EOL> signature = config . get ( "<STR_LIT>" , False ) <EOL> requires_target_user = config . get ( '<STR_LIT>' , False ) <EOL> paginates = config . get ( '<STR_LIT>' , False ) <EOL> root_class = config . get ( '<STR_LIT>' , None ) <EOL> response_type = config . get ( "<STR_LIT>" , "<STR_LIT:list>" ) <EOL> include_secret = config . get ( "<STR_LIT>" , False ) <EOL> objectify_response = config . get ( "<STR_LIT>" , True ) <EOL> exclude_format = config . get ( '<STR_LIT>' , False ) <EOL> def __init__ ( self , api , * args , ** kwargs ) : <EOL> self . api = api <EOL> self . as_generator = kwargs . pop ( "<STR_LIT>" , False ) <EOL> if self . as_generator : <EOL> self . pagination_format = '<STR_LIT>' <EOL> else : <EOL> self . pagination_format = kwargs . pop ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> self . return_json = kwargs . pop ( "<STR_LIT>" , False ) <EOL> self . max_pages = kwargs . pop ( "<STR_LIT>" , <NUM_LIT:3> ) <EOL> self . with_next_url = kwargs . pop ( "<STR_LIT>" , None ) <EOL> self . parameters = { } <EOL> self . _build_parameters ( args , kwargs ) <EOL> self . _build_path ( ) <EOL> def _build_parameters ( self , args , kwargs ) : <EOL> for index , value in enumerate ( args ) : <EOL> if value is None : <EOL> continue <EOL> try : <EOL> self . parameters [ self . accepts_parameters [ index ] ] = encode_string ( value ) <EOL> except IndexError : <EOL> raise InstagramClientError ( "<STR_LIT>" ) <EOL> for key , value in six . iteritems ( kwargs ) : <EOL> if value is None : <EOL> continue <EOL> if key in self . parameters : <EOL> raise InstagramClientError ( "<STR_LIT>" % key ) <EOL> self . parameters [ key ] = encode_string ( value ) <EOL> if '<STR_LIT>' in self . accepts_parameters and not '<STR_LIT>' in self . parameters and not self . requires_target_user : <EOL> self . parameters [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> def _build_path ( self ) : <EOL> for variable in re_path_template . findall ( self . path ) : <EOL> name = variable . strip ( '<STR_LIT:{}>' ) <EOL> try : <EOL> value = quote ( self . parameters [ name ] ) <EOL> except KeyError : <EOL> raise Exception ( '<STR_LIT>' % name ) <EOL> del self . parameters [ name ] <EOL> self . path = self . path . replace ( variable , value ) <EOL> if self . api . format and not self . exclude_format : <EOL> self . path = self . path + '<STR_LIT>' % self . api . format <EOL> def _build_pagination_info ( self , content_obj ) : <EOL> """<STR_LIT>""" <EOL> pagination = content_obj . get ( '<STR_LIT>' , { } ) <EOL> if self . pagination_format == '<STR_LIT>' : <EOL> return pagination . get ( '<STR_LIT>' ) <EOL> if self . pagination_format == '<STR_LIT>' : <EOL> return pagination <EOL> raise Exception ( '<STR_LIT>' % self . pagination_format ) <EOL> def _do_api_request ( self , url , method = "<STR_LIT:GET>" , body = None , headers = None ) : <EOL> headers = headers or { } <EOL> if self . signature and self . api . client_ips != None and self . api . client_secret != None : <EOL> secret = self . api . client_secret <EOL> ips = self . api . client_ips <EOL> signature = hmac . new ( secret , ips , sha256 ) . hexdigest ( ) <EOL> headers [ '<STR_LIT>' ] = '<STR_LIT:|>' . join ( [ ips , signature ] ) <EOL> response , content = OAuth2Request ( self . api ) . make_request ( url , method = method , body = body , headers = headers ) <EOL> if response [ '<STR_LIT:status>' ] == '<STR_LIT>' or response [ '<STR_LIT:status>' ] == '<STR_LIT>' : <EOL> raise InstagramAPIError ( response [ '<STR_LIT:status>' ] , "<STR_LIT>" , "<STR_LIT>" ) <EOL> try : <EOL> content_obj = simplejson . loads ( content ) <EOL> except ValueError : <EOL> raise InstagramClientError ( '<STR_LIT>' , status_code = response [ '<STR_LIT:status>' ] ) <EOL> if '<STR_LIT>' not in content_obj : <EOL> if content_obj . get ( '<STR_LIT:code>' ) == <NUM_LIT> or content_obj . get ( '<STR_LIT:code>' ) == <NUM_LIT> : <EOL> error_message = content_obj . get ( '<STR_LIT>' ) or "<STR_LIT>" <EOL> raise InstagramAPIError ( content_obj . get ( '<STR_LIT:code>' ) , "<STR_LIT>" , error_message ) <EOL> raise InstagramAPIError ( content_obj . get ( '<STR_LIT:code>' ) , content_obj . get ( '<STR_LIT>' ) , content_obj . get ( '<STR_LIT>' ) ) <EOL> api_responses = [ ] <EOL> status_code = content_obj [ '<STR_LIT>' ] [ '<STR_LIT:code>' ] <EOL> self . api . x_ratelimit_remaining = response . get ( "<STR_LIT>" , None ) <EOL> self . api . x_ratelimit = response . get ( "<STR_LIT>" , None ) <EOL> if status_code == <NUM_LIT:200> : <EOL> if not self . objectify_response : <EOL> return content_obj , None <EOL> if self . response_type == '<STR_LIT:list>' : <EOL> for entry in content_obj [ '<STR_LIT:data>' ] : <EOL> if self . return_json : <EOL> api_responses . append ( entry ) <EOL> else : <EOL> obj = self . root_class . object_from_dictionary ( entry ) <EOL> api_responses . append ( obj ) <EOL> elif self . response_type == '<STR_LIT>' : <EOL> data = content_obj [ '<STR_LIT:data>' ] <EOL> if self . return_json : <EOL> api_responses = data <EOL> else : <EOL> api_responses = self . root_class . object_from_dictionary ( data ) <EOL> elif self . response_type == '<STR_LIT>' : <EOL> pass <EOL> return api_responses , self . _build_pagination_info ( content_obj ) <EOL> else : <EOL> raise InstagramAPIError ( status_code , content_obj [ '<STR_LIT>' ] [ '<STR_LIT>' ] , content_obj [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> def _paginator_with_url ( self , url , method = "<STR_LIT:GET>" , body = None , headers = None ) : <EOL> headers = headers or { } <EOL> pages_read = <NUM_LIT:0> <EOL> while url and ( self . max_pages is None or pages_read < self . max_pages ) : <EOL> api_responses , url = self . _do_api_request ( url , method , body , headers ) <EOL> pages_read += <NUM_LIT:1> <EOL> yield api_responses , url <EOL> return <EOL> def _get_with_next_url ( self , url , method = "<STR_LIT:GET>" , body = None , headers = None ) : <EOL> headers = headers or { } <EOL> content , next = self . _do_api_request ( url , method , body , headers ) <EOL> return content , next <EOL> def execute ( self ) : <EOL> url , method , body , headers = OAuth2Request ( self . api ) . prepare_request ( self . method , <EOL> self . path , <EOL> self . parameters , <EOL> include_secret = self . include_secret ) <EOL> if self . with_next_url : <EOL> return self . _get_with_next_url ( self . with_next_url , method , body , headers ) <EOL> if self . as_generator : <EOL> return self . _paginator_with_url ( url , method , body , headers ) <EOL> else : <EOL> content , next = self . _do_api_request ( url , method , body , headers ) <EOL> if self . paginates : <EOL> return content , next <EOL> else : <EOL> return content <EOL> def _call ( api , * args , ** kwargs ) : <EOL> method = InstagramAPIMethod ( api , * args , ** kwargs ) <EOL> return method . execute ( ) <EOL> return _call </s>
