def test_join_url_preserves_original_url(self, r_request): """Test that original url is not touched when joining urls.""" url = Url('http://domain.com/') r_request = MagicMock(return_value=None) new_url = url.join('/path') new_url.get() requests.request.assert_called_with('GET', 'http://domain.com/path') new_url = url.join('/path/') new_url.get() requests.request.assert_called_with('GET', 'http://domain.com/path/')
def test_all_methods(self): """Test all HTTP methods""" url = Url('http://domain.com') self._test_all_methods(url, 'http://domain.com') new_url = url.join('path/a/b') self._test_all_methods(new_url, 'http://domain.com/path/a/b')
def test_join_url_preserves_original_url(self, r_request): """Test that original url is not touched when joining urls.""" url = Url('http://domain.com/') r_request = MagicMock(return_value=None) new_url = url.join('/path') new_url.get() requests.request.assert_called_with( 'GET', 'http://domain.com/path' ) new_url = url.join('/path/') new_url.get() requests.request.assert_called_with( 'GET', 'http://domain.com/path/' )
def test_non_root_base_url_with_slash(self, r_request): """Test creating non-root base url with slash""" url = Url('http://domain.com/api/') r_request = MagicMock(return_value=None) new_url = url.join('/path/a/b') new_url.get() requests.request.assert_called_with('GET', 'http://domain.com/api/path/a/b')
def test_join_urls(self, r_request): """Test creating new sub-Urls""" url = Url('http://domain.com') r_request = MagicMock(return_value=None) new_url = url.join('/path/a/b') new_url.get() requests.request.assert_called_with('GET', 'http://domain.com/path/a/b')
def test_joined_urls_option_passing(self, r_request): """Test that original options are correctly passed to joined urls""" url = Url('http://domain.com', auth=('user', 'pass')) r_request = MagicMock(return_value=None) new_url = url.join('path') new_url.get() requests.request.assert_called_with('GET', 'http://domain.com/path', auth=('user', 'pass'))
def test_non_root_base_url_with_slash(self, r_request): """Test creating non-root base url with slash""" url = Url('http://domain.com/api/') r_request = MagicMock(return_value=None) new_url = url.join('/path/a/b') new_url.get() requests.request.assert_called_with( 'GET', 'http://domain.com/api/path/a/b' )
def test_join_urls(self, r_request): """Test creating new sub-Urls""" url = Url('http://domain.com') r_request = MagicMock(return_value=None) new_url = url.join('/path/a/b') new_url.get() requests.request.assert_called_with( 'GET', 'http://domain.com/path/a/b' )
def test_joined_urls_option_passing(self, r_request): """Test that original options are correctly passed to joined urls""" url = Url( 'http://domain.com', auth=('user', 'pass') ) r_request = MagicMock(return_value=None) new_url = url.join('path') new_url.get() requests.request.assert_called_with( 'GET', 'http://domain.com/path', auth=('user', 'pass') )
class GestusClient(object): _connected = False _websites_map = {} client_headers = { 'client_agent': 'gestus-client/{0}'.format(client_version), 'content-type': 'application/json', } endpoint_eggs_path = 'eggs/' endpoint_websites_path = 'websites/' endpoint_environments_path = 'environments/' website_id = None website_name = None environment_url = None environment_id = None environment_name = None environment_server = None environment_eggs = '' def __init__(self, root_url, auth_settings, debug_requests=True): self.logger = logging.getLogger('gestus_client') self.root_url = root_url self.auth_settings = auth_settings self.debug_requests = debug_requests def connect(self, dry_run=False): """ Connecting to endpoints """ #self.api_base = JsonApi(self.root_url, auth=self.auth_settings) self.api_base = Url(self.root_url, auth=self.auth_settings) self.api_endpoint_eggs = self.api_base.join(self.endpoint_eggs_path) self.api_endpoint_websites = self.api_base.join(self.endpoint_websites_path) self.api_endpoint_environments = self.api_base.join(self.endpoint_environments_path) # Trying to connect to the base to check if the service is reachable if not dry_run: self.logger.info("Connecting to Gestus service on: %s", self.root_url) response = self.api_base.get() if response.status_code != 200: response.raise_for_status() self.map_websites() self._connected = True def map_websites(self): """ Get the websites list and map it to a dict """ self.logger.debug("Getting the website list") websites = self.api_endpoint_websites.get().json() #print websites.get('results') for item in websites.get('results'): self._websites_map[item.get('name')] = item def print_reason(self, response_json): """ Print out API exception reason """ msg = [] for k,v in response_json.items(): v = [item.encode('UTF8') for item in v] msg.append("- {0}: {1}".format(k, ', '.join(v))) return msg def _post_json(self, endpoint, payload): """ Just a shortcut for endpoint.post to avoid to redo headers, json dump, etc.. ``endpoint`` is the the api endpoint Url (a nap.Url object), payload is the dict of data to POST. """ response = endpoint.post(data=json.dumps(payload), headers=self.client_headers) if response.status_code == 400: raise WebsitePostException('\n'.join(['Unable to POST datas, reasons are:']+self.print_reason(response.json()))) elif response.status_code != 200: response.raise_for_status() return response.json() def _register_website(self, website_id, name=None): self.website_id = website_id self.website_name = name self.website_detail_url = self.api_endpoint_websites.join('{0}/'.format(self.website_id)) def _register_environment(self, environment_id, name=None, url=None, server=None): self.environment_id = environment_id self.environment_name = name self.environment_url = url self.environment_server = server self.environment_detail_url = self.api_endpoint_environments.join('{0}/'.format(self.environment_id)) def register(self, name, environment_url, environment_name, environment_server=platform.node()): """ Register the website environment Required arguments: @name: website name to search or create @environment_url: website environment url to use for creating a new website entry @environment_name: website environment name to search or create @environment_server: website environment server to use for creating a new environment entry """ # Determine the hostname environment_server = environment_server or 'unknow' # Get or create the website if name not in self._websites_map: self.logger.info("Creating new website entry for: {0}".format(name)) payload = {'name':name, 'enabled':True} entry = self._post_json(self.api_endpoint_websites, payload) else: entry = self._websites_map[name] self.logger.debug("Website entry '{0}' allready exists".format(name)) self._register_website(entry['id'], entry['name']) # Get or create the environment finder = lambda x: x['name']==environment_name envs = self.website_detail_url.get().json()['environments'] try: environment = filter(finder, envs)[0] except IndexError: self.logger.info("Creating new environment entry for: {0}".format(environment_name)) payload = {'name': environment_name, 'url':environment_url, 'server': environment_server, 'website': self.website_id, 'enabled':True} environment = self._post_json(self.api_endpoint_environments, payload) else: self.logger.debug("Environment entry '{0}' allready exists".format(environment_name)) self._register_environment(environment['id'], environment['name'], environment['url'], environment['server']) return self.website_id, self.environment_id def register_eggs(self, egg_dir, commit=True): """ Send the installed eggs infos for the registred environment """ self.logger.debug("Scanning for eggs in directory: {0}".format(egg_dir)) finder = egg_finder.BuildoutEggdirFinder(egg_dir) finder.crawl() #egg_list = finder.render() eggs_map = finder.get_eggs_dict() if commit: self.logger.info("Sending eggs ({0} items)".format(len(finder.eggs))) #response = self.environment_detail_url.patch(data=json.dumps({'egg_list': egg_list}), headers=self.client_headers) response = self.environment_detail_url.patch(data=str(json.dumps({'egg_list': eggs_map})), headers=self.client_headers) if response.status_code != 200: if self.debug_requests: print response.json() response.raise_for_status() return eggs_map def update(self, website_kwargs={}, environment_kwargs={}, egg_dir=None): """ Update a registered website and its environment """ if website_kwargs: response = self.website_detail_url.patch(data=json.dumps(website_kwargs), headers=self.client_headers) if response.status_code != 200: if self.debug_requests: print response.json(indent=4) response.raise_for_status() # If egg directory is given, add the egg list to the update if egg_dir: environment_kwargs.update({'egg_list':self.register_eggs(egg_dir, commit=False)}) if environment_kwargs: response = self.environment_detail_url.patch(data=json.dumps(environment_kwargs), headers=self.client_headers) if response.status_code != 200: if self.debug_requests: print response.json() response.raise_for_status()
class POProjectClient(object): """ THE client """ _connected = False _projects_map = {} client_headers = { 'client_agent': 'po-projects-client/{0}'.format(client_version), 'content-type': 'application/json', } endpoint_projects_path = 'projects/' endpoint_projectcurrent_path = 'projects/current/' project_id = None project_slug = None project_tarball_url = None def __init__(self, root_url, auth_settings, debug_requests=True): self.logger = logging.getLogger('po_projects_client') self.root_url = root_url self.auth_settings = auth_settings self.debug_requests = debug_requests def connect(self, dry_run=False): """ Connecting to endpoints """ self.api_base = Url(self.root_url, auth=self.auth_settings) self.api_endpoint_projects = self.api_base.join(self.endpoint_projects_path) self.api_endpoint_projectcurrent = self.api_base.join(self.endpoint_projectcurrent_path) # Trying to connect to the base to check if the service is reachable if not dry_run: self.logger.info("Connecting to PO-Projects service on: %s", self.root_url) response = self.api_base.get() if response.status_code != 200: response.raise_for_status() #self.map_projects() self._connected = True def get_project(self, slug): """ Try to get the project details to see if it exists """ self.project_detail_url = self.api_endpoint_projectcurrent.join('{0}/'.format(slug)) response = self.project_detail_url.get()#.json() if response.status_code == 404: raise ProjectDoesNotExistException("Project with slug '{0}' does not exist.".format(slug)) elif response.status_code != 200: response.raise_for_status() datas = response.json() self.project_id = datas['id'] self.project_slug = datas['slug'] self.project_tarball_url = datas['tarball_url'] def pull(self, slug, destination, kind, commit=True): """ Get the tarball to install updated PO files @commit arg to effectively install PO files or not """ self.logger.debug("Downloading the tarball") # Get project datas self.get_project(slug) tarball_url = Url(self.project_tarball_url, params={'kind': kind}, auth=self.auth_settings) # Get the tarball response = tarball_url.get(stream=True) # Get a temporary directory tmpdir = tempfile.mkdtemp(suffix='_po-projects-client') self.logger.debug("Opening the tarball") # Write the tarball in memory fp = StringIO.StringIO() for chunk in response.iter_content(1024): fp.write(chunk) fp.seek(0) # Extract the file to the temp directory tar = tarfile.open(fileobj=fp) tar.extractall(path=tmpdir) tar.close() fp.close() if commit: self.logger.debug("Installing the tarball") # Remove the previous locale dir if any if os.path.exists(destination): shutil.rmtree(destination) # Put the new locale dir shutil.move(os.path.join(tmpdir, 'locale'), destination) # Remove the temp dir os.removedirs(tmpdir) if commit: self.logger.info("Succeed to install the tarball to: %s", destination) else: self.logger.info("Succeed to download the tarball") return self.project_id, self.project_slug def push(self, slug, locale_path, kind, django_default_locale=None, commit=True): """ Send the current locale POT file to the service to trigger the project catalogs update from the given POT @commit arg to effectively install PO files or not """ self.logger.debug("Sending current POT file") # Get project datas self.get_project(slug) # Resolve and validate the POT file path pot_filepath = os.path.join(locale_path, "LC_MESSAGES/messages.pot") if kind == 'django': pot_filepath = os.path.join(locale_path, django_default_locale, "LC_MESSAGES/django.po") if not os.path.exists(pot_filepath): raise PotDoesNotExistException("Catalog file does not exists: '{0}'".format(pot_filepath)) # Open the file path with open(pot_filepath, 'r') as infile: pot_file_content = infile.read() # Send the current POT file content response = self.project_detail_url.patch(data=json.dumps({'pot': pot_file_content}), headers=self.client_headers) if response.status_code != 200: if self.debug_requests: print response.json() response.raise_for_status()
from nap.url import Url from blinker import signal pr2hub = Url("https://pr2hub.com/") levels = pr2hub.join("levels/") files = pr2hub.join("files/") emblems = pr2hub.join("emblems/") # will fire when get_servers_info is called and there's an hh on_happy_hour = signal('hh') def __error_check(response): """checks if a pr2hub response is an error""" if response.content.startswith(b"error="): raise PR2HubError(str(response.content)[6:]) elif response.content.startswith(b"{\"error\":\""): raise PR2HubError(response.json()["error"]) def get_player_info(player_name: str): """returns a Player class instance""" resp = pr2hub.get("get_player_info_2.php", params={"name": player_name}) __error_check(resp) return Player(resp.json()) def get_guild_info(guild_name: str, get_members: bool): """returns a Guild class instance""" if get_members: get_members = "yes"
class GestusClient(object): _connected = False _websites_map = {} client_headers = { 'client_agent': 'gestus-client/{0}'.format(client_version), 'content-type': 'application/json', } endpoint_eggs_path = 'eggs/' endpoint_websites_path = 'websites/' endpoint_environments_path = 'environments/' website_id = None website_name = None environment_url = None environment_id = None environment_name = None environment_server = None environment_eggs = '' def __init__(self, root_url, auth_settings, debug_requests=True): self.logger = logging.getLogger('gestus_client') self.root_url = root_url self.auth_settings = auth_settings self.debug_requests = debug_requests def connect(self, dry_run=False): """ Connecting to endpoints """ #self.api_base = JsonApi(self.root_url, auth=self.auth_settings) self.api_base = Url(self.root_url, auth=self.auth_settings) self.api_endpoint_eggs = self.api_base.join(self.endpoint_eggs_path) self.api_endpoint_websites = self.api_base.join(self.endpoint_websites_path) self.api_endpoint_environments = self.api_base.join(self.endpoint_environments_path) # Trying to connect to the base to check if the service is reachable if not dry_run: self.logger.info("Connecting to Gestus service on: %s", self.root_url) response = self.api_base.get() if response.status_code != 200: response.raise_for_status() self.map_websites() self._connected = True def map_websites(self): """ Get the websites list and map it to a dict """ self.logger.debug("Getting the website list") websites = self.api_endpoint_websites.get().json() #print websites.get('results') for item in websites.get('results'): self._websites_map[item.get('name')] = item def print_reason(self, response_json): """ Print out API exception reason """ msg = [] for k,v in list(response_json.items()): v = [item.encode('UTF8') for item in v] msg.append("- {0}: {1}".format(k, ', '.join(v))) return msg def _post_json(self, endpoint, payload): """ Just a shortcut for endpoint.post to avoid to redo headers, json dump, etc.. ``endpoint`` is the the api endpoint Url (a nap.Url object), payload is the dict of data to POST. """ response = endpoint.post(data=json.dumps(payload), headers=self.client_headers) if response.status_code == 400: raise WebsitePostException('\n'.join(['Unable to POST datas, reasons are:']+self.print_reason(response.json()))) elif response.status_code != 200: response.raise_for_status() return response.json() def _register_website(self, website_id, name=None): self.website_id = website_id self.website_name = name self.website_detail_url = self.api_endpoint_websites.join('{0}/'.format(self.website_id)) def _register_environment(self, environment_id, name=None, url=None, server=None): self.environment_id = environment_id self.environment_name = name self.environment_url = url self.environment_server = server self.environment_detail_url = self.api_endpoint_environments.join('{0}/'.format(self.environment_id)) def register(self, name, environment_url, environment_name, environment_server=platform.node()): """ Register the website environment Required arguments: @name: website name to search or create @environment_url: website environment url to use for creating a new website entry @environment_name: website environment name to search or create @environment_server: website environment server to use for creating a new environment entry """ # Determine the hostname environment_server = environment_server or 'unknow' # Get or create the website if name not in self._websites_map: self.logger.info("Creating new website entry for: {0}".format(name)) payload = {'name':name, 'enabled':True} entry = self._post_json(self.api_endpoint_websites, payload) else: entry = self._websites_map[name] self.logger.debug("Website entry '{0}' allready exists".format(name)) self._register_website(entry['id'], entry['name']) # Get or create the environment finder = lambda x: x['name']==environment_name envs = self.website_detail_url.get().json()['environments'] try: environment = filter(finder, envs)[0] except IndexError: self.logger.info("Creating new environment entry for: {0}".format(environment_name)) payload = {'name': environment_name, 'url':environment_url, 'server': environment_server, 'website': self.website_id, 'enabled':True} environment = self._post_json(self.api_endpoint_environments, payload) else: self.logger.debug("Environment entry '{0}' allready exists".format(environment_name)) self._register_environment(environment['id'], environment['name'], environment['url'], environment['server']) return self.website_id, self.environment_id def register_eggs(self, egg_dir, commit=True): """ Send the installed eggs infos for the registred environment """ self.logger.debug("Scanning for eggs in directory: {0}".format(egg_dir)) finder = egg_finder.BuildoutEggdirFinder(egg_dir) finder.crawl() #egg_list = finder.render() eggs_map = finder.get_eggs_dict() if commit: self.logger.info("Sending eggs ({0} items)".format(len(finder.eggs))) #response = self.environment_detail_url.patch(data=json.dumps({'egg_list': egg_list}), headers=self.client_headers) response = self.environment_detail_url.patch(data=str(json.dumps({'egg_list': eggs_map})), headers=self.client_headers) if response.status_code != 200: if self.debug_requests: print(response.json()) response.raise_for_status() return eggs_map def update(self, website_kwargs={}, environment_kwargs={}, egg_dir=None): """ Update a registered website and its environment """ if website_kwargs: response = self.website_detail_url.patch(data=json.dumps(website_kwargs), headers=self.client_headers) if response.status_code != 200: if self.debug_requests: print(response.json(indent=4)) response.raise_for_status() # If egg directory is given, add the egg list to the update if egg_dir: environment_kwargs.update({'egg_list':self.register_eggs(egg_dir, commit=False)}) if environment_kwargs: response = self.environment_detail_url.patch(data=json.dumps(environment_kwargs), headers=self.client_headers) if response.status_code != 200: if self.debug_requests: print(response.json()) response.raise_for_status()
class POProjectClient(object): """ THE client """ _connected = False _projects_map = {} client_headers = { 'client_agent': 'po-projects-client/{0}'.format(client_version), 'content-type': 'application/json', } endpoint_projects_path = 'projects/' endpoint_projectcurrent_path = 'projects/current/' project_id = None project_slug = None project_tarball_url = None def __init__(self, root_url, auth_settings, debug_requests=True): self.logger = logging.getLogger('po_projects_client') self.root_url = root_url self.auth_settings = auth_settings self.debug_requests = debug_requests def connect(self, dry_run=False): """ Connecting to endpoints """ self.api_base = Url(self.root_url, auth=self.auth_settings) self.api_endpoint_projects = self.api_base.join( self.endpoint_projects_path) self.api_endpoint_projectcurrent = self.api_base.join( self.endpoint_projectcurrent_path) # Trying to connect to the base to check if the service is reachable if not dry_run: self.logger.info("Connecting to PO-Projects service on: %s", self.root_url) response = self.api_base.get() if response.status_code != 200: response.raise_for_status() #self.map_projects() self._connected = True def get_project(self, slug): """ Try to get the project details to see if it exists """ self.project_detail_url = self.api_endpoint_projectcurrent.join( '{0}/'.format(slug)) response = self.project_detail_url.get() #.json() if response.status_code == 404: raise ProjectDoesNotExistException( "Project with slug '{0}' does not exist.".format(slug)) elif response.status_code != 200: response.raise_for_status() datas = response.json() self.project_id = datas['id'] self.project_slug = datas['slug'] self.project_tarball_url = datas['tarball_url'] def pull(self, slug, destination, kind, commit=True): """ Get the tarball to install updated PO files @commit arg to effectively install PO files or not """ self.logger.debug("Downloading the tarball") # Get project datas self.get_project(slug) tarball_url = Url(self.project_tarball_url, params={'kind': kind}, auth=self.auth_settings) # Get the tarball response = tarball_url.get(stream=True) # Get a temporary directory tmpdir = tempfile.mkdtemp(suffix='_po-projects-client') self.logger.debug("Opening the tarball") # Write the tarball in memory fp = io.StringIO() for chunk in response.iter_content(1024): fp.write(chunk) fp.seek(0) # Extract the file to the temp directory tar = tarfile.open(fileobj=fp) tar.extractall(path=tmpdir) tar.close() fp.close() if commit: self.logger.debug("Installing the tarball") # Remove the previous locale dir if any if os.path.exists(destination): shutil.rmtree(destination) # Put the new locale dir shutil.move(os.path.join(tmpdir, 'locale'), destination) # Remove the temp dir os.removedirs(tmpdir) if commit: self.logger.info("Succeed to install the tarball to: %s", destination) else: self.logger.info("Succeed to download the tarball") return self.project_id, self.project_slug def push(self, slug, locale_path, kind, django_default_locale=None, commit=True): """ Send the current locale POT file to the service to trigger the project catalogs update from the given POT @commit arg to effectively install PO files or not """ self.logger.debug("Sending current POT file") # Get project datas self.get_project(slug) # Resolve and validate the POT file path pot_filepath = os.path.join(locale_path, "LC_MESSAGES/messages.pot") if kind == 'django': pot_filepath = os.path.join(locale_path, django_default_locale, "LC_MESSAGES/django.po") if not os.path.exists(pot_filepath): raise PotDoesNotExistException( "Catalog file does not exists: '{0}'".format(pot_filepath)) # Open the file path with open(pot_filepath, 'r') as infile: pot_file_content = infile.read() # Send the current POT file content response = self.project_detail_url.patch(data=json.dumps( {'pot': pot_file_content}), headers=self.client_headers) if response.status_code != 200: if self.debug_requests: print(response.json()) response.raise_for_status()