From b4d36b2d3ef75af741a9fa96bb48cd37db8f1e13 Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Tue, 25 Jul 2017 21:19:51 +0200 Subject: [PATCH] [mod] more eleguant way of removing globals: from moulinette import m18n, pkg works --- moulinette/__init__.py | 21 ++++++++++----- moulinette/actionsmap.py | 38 +++++++++++++-------------- moulinette/authenticators/__init__.py | 12 ++++----- moulinette/authenticators/ldap.py | 14 +++++----- moulinette/core.py | 19 +++++++------- moulinette/interfaces/__init__.py | 23 ++++++++-------- moulinette/interfaces/api.py | 31 +++++++++++----------- moulinette/interfaces/cli.py | 29 ++++++++++---------- moulinette/m18n.py | 3 +++ moulinette/pkg.py | 3 +++ moulinette/utils/filesystem.py | 30 ++++++++++----------- moulinette/utils/network.py | 14 +++++----- 12 files changed, 125 insertions(+), 112 deletions(-) create mode 100644 moulinette/m18n.py create mode 100644 moulinette/pkg.py diff --git a/moulinette/__init__.py b/moulinette/__init__.py index 67981bb9..b2dd9a84 100755 --- a/moulinette/__init__.py +++ b/moulinette/__init__.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- +from moulinette import m18n, pkg from moulinette.core import init_interface, MoulinetteError, MoulinetteSignals __title__ = 'moulinette' @@ -33,8 +34,6 @@ __all__ = [ msignals = MoulinetteSignals() msettings = dict() -pkg = None -m18n = None # Package functions @@ -60,11 +59,21 @@ def init(logging_config=None, **kwargs): configure_logging(logging_config) - global pkg, m18n - # Define and instantiate global objects - pkg = Package(**kwargs) - m18n = Moulinette18n(pkg) + + # here I need to add attributes/methods to modules because those globals + # are only initialized here and using empty modules is the only working + # solution I've found for that (using globals() doesn't work because of the + # order of importation) + _pkg = Package(**kwargs) + for i in dir(_pkg): + if not i.startswith("_"): + setattr(pkg, i, getattr(_pkg, i)) + + _m18n = Moulinette18n(pkg) + for i in dir(_m18n): + if not i.startswith("_"): + setattr(m18n, i, getattr(_m18n, i)) # Add library directory to python path sys.path.insert(0, pkg.libdir) diff --git a/moulinette/actionsmap.py b/moulinette/actionsmap.py index c8c3f142..3b401ed8 100644 --- a/moulinette/actionsmap.py +++ b/moulinette/actionsmap.py @@ -9,7 +9,7 @@ import cPickle as pickle from time import time from collections import OrderedDict -import moulinette +from moulinette import m18n, msignals, pkg from moulinette.core import (MoulinetteError, MoulinetteLock) from moulinette.interfaces import ( BaseActionsMapParser, GLOBAL_SECTION, TO_RETURN_PROP @@ -99,7 +99,7 @@ class AskParameter(_ExtraParameter): try: # Ask for the argument value - return moulinette.msignals.prompt(moulinette.m18n.n(message)) + return msignals.prompt(m18n.n(message)) except NotImplementedError: return arg_value @@ -132,7 +132,7 @@ class PasswordParameter(AskParameter): try: # Ask for the password - return moulinette.msignals.prompt(moulinette.m18n.n(message), True, True) + return msignals.prompt(m18n.n(message), True, True) except NotImplementedError: return arg_value @@ -161,12 +161,12 @@ class PatternParameter(_ExtraParameter): v, arg_name, pattern) # Attempt to retrieve message translation - msg = moulinette.m18n.n(message) + msg = m18n.n(message) if msg == message: - msg = moulinette.m18n.g(message) + msg = m18n.g(message) raise MoulinetteError(errno.EINVAL, - moulinette.m18n.g('invalid_argument', + m18n.g('invalid_argument', argument=arg_name, error=msg)) return arg_value @@ -197,7 +197,7 @@ class RequiredParameter(_ExtraParameter): logger.debug("argument '%s' is required", arg_name) raise MoulinetteError(errno.EINVAL, - moulinette.m18n.g('argument_required', + m18n.g('argument_required', argument=arg_name)) return arg_value @@ -262,7 +262,7 @@ class ExtraArgumentParser(object): except Exception as e: logger.error("unable to validate extra parameter '%s' " "for argument '%s': %s", p, arg_name, e) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) return parameters @@ -374,10 +374,10 @@ class ActionsMap(object): for n in namespaces: logger.debug("loading actions map namespace '%s'", n) - actionsmap_yml = '%s/actionsmap/%s.yml' % (moulinette.pkg.datadir, n) + actionsmap_yml = '%s/actionsmap/%s.yml' % (pkg.datadir, n) actionsmap_yml_stat = os.stat(actionsmap_yml) actionsmap_pkl = '%s/actionsmap/%s-%d-%d.pkl' % ( - moulinette.pkg.cachedir, + pkg.cachedir, n, actionsmap_yml_stat.st_size, actionsmap_yml_stat.st_mtime @@ -400,7 +400,7 @@ class ActionsMap(object): actionsmaps[n] = ordered_yaml_load(f) # Load translations - moulinette.m18n.load_namespace(n) + m18n.load_namespace(n) # Generate parsers self.extraparser = ExtraArgumentParser(parser_class.interface) @@ -467,7 +467,7 @@ class ActionsMap(object): except (AttributeError, ImportError): logger.exception("unable to load function %s.%s.%s", namespace, category, func_name) - raise MoulinetteError(errno.EIO, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EIO, m18n.g('error_see_log')) else: log_id = start_action_logging() if logger.isEnabledFor(logging.DEBUG): @@ -479,7 +479,7 @@ class ActionsMap(object): log_id, namespace, category, action) # Load translation and process the action - moulinette.m18n.load_namespace(namespace) + m18n.load_namespace(namespace) start = time() try: return func(**arguments) @@ -499,7 +499,7 @@ class ActionsMap(object): """ namespaces = [] - for f in os.listdir('%s/actionsmap' % moulinette.pkg.datadir): + for f in os.listdir('%s/actionsmap' % pkg.datadir): if f.endswith('.yml'): namespaces.append(f[:-4]) return namespaces @@ -525,23 +525,23 @@ class ActionsMap(object): logger.debug("generating cache for actions map namespace '%s'", n) # Read actions map from yaml file - am_file = '%s/actionsmap/%s.yml' % (moulinette.pkg.datadir, n) + am_file = '%s/actionsmap/%s.yml' % (pkg.datadir, n) with open(am_file, 'r') as f: actionsmaps[n] = ordered_yaml_load(f) # at installation, cachedir might not exists - if os.path.exists('%s/actionsmap/' % moulinette.pkg.cachedir): + if os.path.exists('%s/actionsmap/' % pkg.cachedir): # clean old cached files - for i in os.listdir('%s/actionsmap/' % moulinette.pkg.cachedir): + for i in os.listdir('%s/actionsmap/' % pkg.cachedir): if i.endswith(".pkl"): - os.remove('%s/actionsmap/%s' % (moulinette.pkg.cachedir, i)) + os.remove('%s/actionsmap/%s' % (pkg.cachedir, i)) # Cache actions map into pickle file am_file_stat = os.stat(am_file) pkl = '%s-%d-%d.pkl' % (n, am_file_stat.st_size, am_file_stat.st_mtime) - with moulinette.pkg.open_cachefile(pkl, 'w', subdir='actionsmap') as f: + with pkg.open_cachefile(pkl, 'w', subdir='actionsmap') as f: pickle.dump(actionsmaps[n], f) return actionsmaps diff --git a/moulinette/authenticators/__init__.py b/moulinette/authenticators/__init__.py index 1f407588..8ffc96ff 100644 --- a/moulinette/authenticators/__init__.py +++ b/moulinette/authenticators/__init__.py @@ -4,7 +4,7 @@ import errno import gnupg import logging -import moulinette +from moulinette import m18n, pkg from moulinette.core import MoulinetteError logger = logging.getLogger('moulinette.authenticator') @@ -96,7 +96,7 @@ class BaseAuthenticator(object): except TypeError: logger.error("unable to extract token parts from '%s'", token) if password is None: - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) logger.info("session will not be stored") store_session = False @@ -113,7 +113,7 @@ class BaseAuthenticator(object): except: logger.exception("authentication (name: '%s', vendor: '%s') fails", self.name, self.vendor) - raise MoulinetteError(errno.EACCES, moulinette.m18n.g('unable_authenticate')) + raise MoulinetteError(errno.EACCES, m18n.g('unable_authenticate')) # Store session if store_session: @@ -130,7 +130,7 @@ class BaseAuthenticator(object): def _open_sessionfile(self, session_id, mode='r'): """Open a session file for this instance in given mode""" - return moulinette.pkg.open_cachefile('%s.asc' % session_id, mode, + return pkg.open_cachefile('%s.asc' % session_id, mode, subdir='session/%s' % self.name) def _store_session(self, session_id, session_hash, password): @@ -149,7 +149,7 @@ class BaseAuthenticator(object): except IOError: logger.debug("unable to retrieve session", exc_info=1) raise MoulinetteError(errno.ENOENT, - moulinette.m18n.g('unable_retrieve_session')) + m18n.g('unable_retrieve_session')) else: gpg = gnupg.GPG() gpg.encoding = 'utf-8' @@ -159,5 +159,5 @@ class BaseAuthenticator(object): logger.error("unable to decrypt password for the session: %s", decrypted.status) raise MoulinetteError(errno.EINVAL, - moulinette.m18n.g('unable_retrieve_session')) + m18n.g('unable_retrieve_session')) return decrypted.data diff --git a/moulinette/authenticators/ldap.py b/moulinette/authenticators/ldap.py index 7f7c736d..e3035b71 100644 --- a/moulinette/authenticators/ldap.py +++ b/moulinette/authenticators/ldap.py @@ -7,7 +7,7 @@ import logging import ldap import ldap.modlist as modlist -import moulinette +from moulinette import m18n from moulinette.core import MoulinetteError from moulinette.authenticators import BaseAuthenticator @@ -76,10 +76,10 @@ class Authenticator(BaseAuthenticator): else: con.simple_bind_s() except ldap.INVALID_CREDENTIALS: - raise MoulinetteError(errno.EACCES, moulinette.m18n.g('invalid_password')) + raise MoulinetteError(errno.EACCES, m18n.g('invalid_password')) except ldap.SERVER_DOWN: logger.exception('unable to reach the server to authenticate') - raise MoulinetteError(169, moulinette.m18n.g('ldap_server_down')) + raise MoulinetteError(169, m18n.g('ldap_server_down')) else: self.con = con @@ -140,7 +140,7 @@ class Authenticator(BaseAuthenticator): except: logger.exception("error during LDAP add operation with: rdn='%s', " "attr_dict=%s", rdn, attr_dict) - raise MoulinetteError(169, moulinette.m18n.g('ldap_operation_error')) + raise MoulinetteError(169, m18n.g('ldap_operation_error')) else: return True @@ -160,7 +160,7 @@ class Authenticator(BaseAuthenticator): self.con.delete_s(dn) except: logger.exception("error during LDAP delete operation with: rdn='%s'", rdn) - raise MoulinetteError(169, moulinette.m18n.g('ldap_operation_error')) + raise MoulinetteError(169, m18n.g('ldap_operation_error')) else: return True @@ -190,7 +190,7 @@ class Authenticator(BaseAuthenticator): except: logger.exception("error during LDAP update operation with: rdn='%s', " "attr_dict=%s, new_rdn=%s", rdn, attr_dict, new_rdn) - raise MoulinetteError(169, moulinette.m18n.g('ldap_operation_error')) + raise MoulinetteError(169, m18n.g('ldap_operation_error')) else: return True @@ -212,6 +212,6 @@ class Authenticator(BaseAuthenticator): logger.info("attribute '%s' with value '%s' is not unique", attr, value) raise MoulinetteError(errno.EEXIST, - moulinette.m18n.g('ldap_attribute_already_exists', + m18n.g('ldap_attribute_already_exists', attribute=attr, value=value)) return True diff --git a/moulinette/core.py b/moulinette/core.py index 2fa9317a..6465e898 100644 --- a/moulinette/core.py +++ b/moulinette/core.py @@ -8,7 +8,8 @@ import logging from importlib import import_module -import moulinette +from moulinette import m18n, pkg + logger = logging.getLogger('moulinette.core') @@ -452,7 +453,7 @@ def init_interface(name, kwargs={}, actionsmap={}): mod = import_module('moulinette.interfaces.%s' % name) except ImportError: logger.exception("unable to load interface '%s'", name) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) else: try: # Retrieve interface classes @@ -460,7 +461,7 @@ def init_interface(name, kwargs={}, actionsmap={}): interface = mod.Interface except AttributeError: logger.exception("unable to retrieve classes of interface '%s'", name) - raise MoulinetteError(errno.EIO, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EIO, m18n.g('error_see_log')) # Instantiate or retrieve ActionsMap if isinstance(actionsmap, dict): @@ -469,7 +470,7 @@ def init_interface(name, kwargs={}, actionsmap={}): amap = actionsmap else: logger.error("invalid actionsmap value %r", actionsmap) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) return interface(amap, **kwargs) @@ -490,7 +491,7 @@ def init_authenticator((vendor, name), kwargs={}): mod = import_module('moulinette.authenticators.%s' % vendor) except ImportError: logger.exception("unable to load authenticator vendor '%s'", vendor) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) else: return mod.Authenticator(name, **kwargs) @@ -506,7 +507,7 @@ def clean_session(session_id, profiles=[]): - profiles -- A list of profiles to clean """ - sessiondir = moulinette.pkg.get_cachedir('session') + sessiondir = pkg.get_cachedir('session') if not profiles: profiles = os.listdir(sessiondir) @@ -580,7 +581,7 @@ class MoulinetteLock(object): if self.timeout is not None and (time.time() - start_time) > self.timeout: raise MoulinetteError(errno.EBUSY, - moulinette.m18n.g('instance_already_running')) + m18n.g('instance_already_running')) # Wait before checking again time.sleep(self.interval) @@ -607,8 +608,8 @@ class MoulinetteLock(object): except IOError: raise MoulinetteError( errno.EPERM, '%s. %s.'.format( - moulinette.m18n.g('permission_denied'), - moulinette.m18n.g('root_required'))) + m18n.g('permission_denied'), + m18n.g('root_required'))) def __enter__(self): if not self._locked: diff --git a/moulinette/interfaces/__init__.py b/moulinette/interfaces/__init__.py index 7c54e458..28fb27eb 100644 --- a/moulinette/interfaces/__init__.py +++ b/moulinette/interfaces/__init__.py @@ -7,8 +7,7 @@ import logging import argparse from collections import deque -import moulinette -from moulinette import msignals, msettings +from moulinette import msignals, msettings, m18n from moulinette.core import (init_authenticator, MoulinetteError) logger = logging.getLogger('moulinette.interface') @@ -140,7 +139,7 @@ class BaseActionsMapParser(object): # Validate tid and namespace if not isinstance(tid, tuple) and \ (namespace is None or not hasattr(namespace, TO_RETURN_PROP)): - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('invalid_usage')) + raise MoulinetteError(errno.EINVAL, m18n.g('invalid_usage')) elif not tid: tid = GLOBAL_SECTION @@ -161,7 +160,7 @@ class BaseActionsMapParser(object): auth = msignals.authenticate(cls(), **auth_conf) if not auth.is_authenticated: raise MoulinetteError(errno.EACCES, - moulinette.m18n.g('authentication_required_long')) + m18n.g('authentication_required_long')) if self.get_conf(tid, 'argument_auth') and \ self.get_conf(tid, 'authenticate') == 'all': namespace.auth = auth @@ -265,7 +264,7 @@ class BaseActionsMapParser(object): else: logger.error("expecting 'all', 'False' or a list for " "configuration 'authenticate', got %r", ifaces) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) # -- 'authenticator' try: @@ -280,7 +279,7 @@ class BaseActionsMapParser(object): except KeyError: logger.error("requesting profile '%s' which is undefined in " "global configuration of 'authenticator'", auth) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) elif is_global and isinstance(auth, dict): if len(auth) == 0: logger.warning('no profile defined in global configuration ' @@ -303,7 +302,7 @@ class BaseActionsMapParser(object): else: logger.error("expecting a dict of profile(s) or a profile name " "for configuration 'authenticator', got %r", auth) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) # -- 'argument_auth' try: @@ -316,7 +315,7 @@ class BaseActionsMapParser(object): else: logger.error("expecting a boolean for configuration " "'argument_auth', got %r", arg_auth) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) # -- 'lock' try: @@ -329,7 +328,7 @@ class BaseActionsMapParser(object): else: logger.error("expecting a boolean for configuration 'lock', " "got %r", lock) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) return conf @@ -429,7 +428,7 @@ class _CallbackAction(argparse.Action): except: logger.exception("cannot get value from callback method " "'{0}'".format(self.callback_method)) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) else: if value: if self.callback_return: @@ -489,10 +488,10 @@ class _ExtendedSubParsersAction(argparse._SubParsersAction): else: # Warn the user about deprecated command if correct_name is None: - logger.warning(moulinette.m18n.g('deprecated_command', prog=parser.prog, + logger.warning(m18n.g('deprecated_command', prog=parser.prog, command=parser_name)) else: - logger.warning(moulinette.m18n.g('deprecated_command_alias', + logger.warning(m18n.g('deprecated_command_alias', old=parser_name, new=correct_name, prog=parser.prog)) values[0] = correct_name diff --git a/moulinette/interfaces/api.py b/moulinette/interfaces/api.py index 557e3759..71e4abb4 100644 --- a/moulinette/interfaces/api.py +++ b/moulinette/interfaces/api.py @@ -13,8 +13,7 @@ from geventwebsocket import WebSocketError from bottle import run, request, response, Bottle, HTTPResponse -import moulinette -from moulinette import msignals +from moulinette import msignals, m18n, pkg from moulinette.core import MoulinetteError, clean_session from moulinette.interfaces import ( BaseActionsMapParser, BaseInterface, ExtendedArgumentParser, @@ -310,7 +309,7 @@ class _ActionsMapPlugin(object): response.set_cookie('session.id', s_id, secure=True) response.set_cookie('session.hashes', s_hashes, secure=True, secret=s_secret) - return moulinette.m18n.g('logged_in') + return m18n.g('logged_in') def logout(self, profile=None): """Log out from an authenticator profile @@ -326,13 +325,13 @@ class _ActionsMapPlugin(object): try: del self.secrets[s_id] except KeyError: - raise HTTPUnauthorizedResponse(moulinette.m18n.g('not_logged_in')) + raise HTTPUnauthorizedResponse(m18n.g('not_logged_in')) else: # TODO: Clean the session for profile only # Delete cookie and clean the session response.set_cookie('session.hashes', '', max_age=-1) clean_session(s_id) - return moulinette.m18n.g('logged_out') + return m18n.g('logged_out') def messages(self): """Listen to the messages WebSocket stream @@ -352,7 +351,7 @@ class _ActionsMapPlugin(object): wsock = request.environ.get('wsgi.websocket') if not wsock: - raise HTTPErrorResponse(moulinette.m18n.g('websocket_request_expected')) + raise HTTPErrorResponse(m18n.g('websocket_request_expected')) while True: item = queue.get() @@ -415,9 +414,9 @@ class _ActionsMapPlugin(object): secret=s_secret)[authenticator.name] except KeyError: if authenticator.name == 'default': - msg = moulinette.m18n.g('authentication_required') + msg = m18n.g('authentication_required') else: - msg = moulinette.m18n.g('authentication_profile_required', + msg = m18n.g('authentication_profile_required', profile=authenticator.name) raise HTTPUnauthorizedResponse(msg) else: @@ -605,7 +604,7 @@ class ActionsMapParser(BaseActionsMapParser): tid, parser = self._parsers[route] except KeyError: logger.error("no argument parser found for route '%s'", route) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) ret = argparse.Namespace() if not self.get_conf(tid, 'lock'): @@ -621,7 +620,7 @@ class ActionsMapParser(BaseActionsMapParser): # TODO: Catch errors auth = msignals.authenticate(klass(), **auth_conf) if not auth.is_authenticated: - raise MoulinetteError(errno.EACCES, moulinette.m18n.g('authentication_required_long')) + raise MoulinetteError(errno.EACCES, m18n.g('authentication_required_long')) if self.get_conf(tid, 'argument_auth') and \ self.get_conf(tid, 'authenticate') == 'all': ret.auth = auth @@ -695,8 +694,8 @@ class Interface(BaseInterface): try: locale = request.params.pop('locale') except KeyError: - locale = moulinette.m18n.default_locale - moulinette.m18n.set_locale(locale) + locale = m18n.default_locale + m18n.set_locale(locale) return callback # Install plugins @@ -744,8 +743,8 @@ class Interface(BaseInterface): host, port) if e.args[0] == errno.EADDRINUSE: raise MoulinetteError(errno.EADDRINUSE, - moulinette.m18n.g('server_already_running')) - raise MoulinetteError(errno.EIO, moulinette.m18n.g('error_see_log')) + m18n.g('server_already_running')) + raise MoulinetteError(errno.EIO, m18n.g('error_see_log')) # Routes handlers @@ -758,11 +757,11 @@ class Interface(BaseInterface): """ if category is None: - with open('%s/../doc/resources.json' % moulinette.pkg.datadir) as f: + with open('%s/../doc/resources.json' % pkg.datadir) as f: return f.read() try: - with open('%s/../doc/%s.json' % (moulinette.pkg.datadir, category)) as f: + with open('%s/../doc/%s.json' % (pkg.datadir, category)) as f: return f.read() except IOError: return None diff --git a/moulinette/interfaces/cli.py b/moulinette/interfaces/cli.py index f9ad4986..b059c951 100644 --- a/moulinette/interfaces/cli.py +++ b/moulinette/interfaces/cli.py @@ -11,8 +11,7 @@ from collections import OrderedDict import argcomplete -import moulinette -from moulinette import msignals +from moulinette import msignals, m18n from moulinette.core import MoulinetteError from moulinette.interfaces import ( BaseActionsMapParser, BaseInterface, ExtendedArgumentParser, @@ -185,7 +184,7 @@ class TTYHandler(logging.StreamHandler): level = '%s ' % record.levelname elif record.levelname in ['SUCCESS', 'WARNING', 'ERROR']: # add translated level name before message - level = '%s ' % moulinette.m18n.g(record.levelname.lower()) + level = '%s ' % m18n.g(record.levelname.lower()) color = self.LEVELS_COLOR.get(record.levelno, 'white') msg = '{0}{1}{2}{3}'.format( colors_codes[color], level, END_CLI_COLOR, msg) @@ -299,7 +298,7 @@ class ActionsMapParser(BaseActionsMapParser): raise except: logger.exception("unable to parse arguments '%s'", ' '.join(args)) - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('error_see_log')) + raise MoulinetteError(errno.EINVAL, m18n.g('error_see_log')) else: self.prepare_action_namespace(getattr(ret, '_tid', None), ret) self._parser.dequeue_callbacks(ret) @@ -319,7 +318,7 @@ class Interface(BaseInterface): def __init__(self, actionsmap): # Set user locale - moulinette.m18n.set_locale(get_locale()) + m18n.set_locale(get_locale()) # Connect signals to handlers msignals.set_handler('display', self._do_display) @@ -346,7 +345,7 @@ class Interface(BaseInterface): """ if output_as and output_as not in ['json', 'plain', 'none']: - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('invalid_usage')) + raise MoulinetteError(errno.EINVAL, m18n.g('invalid_usage')) # auto-complete argcomplete.autocomplete(self.actionsmap.parser._parser) @@ -359,7 +358,7 @@ class Interface(BaseInterface): try: ret = self.actionsmap.process(args, timeout=timeout) except (KeyboardInterrupt, EOFError): - raise MoulinetteError(errno.EINTR, moulinette.m18n.g('operation_interrupted')) + raise MoulinetteError(errno.EINTR, m18n.g('operation_interrupted')) if ret is None or output_as == 'none': return @@ -386,7 +385,7 @@ class Interface(BaseInterface): """ # TODO: Allow token authentication? - msg = moulinette.m18n.n(help) if help else moulinette.m18n.g('password') + msg = m18n.n(help) if help else m18n.g('password') return authenticator(password=self._do_prompt(msg, True, False, color='yellow')) @@ -400,16 +399,16 @@ class Interface(BaseInterface): """ if is_password: - prompt = lambda m: getpass.getpass(colorize(moulinette.m18n.g('colon', m), + prompt = lambda m: getpass.getpass(colorize(m18n.g('colon', m), color)) else: - prompt = lambda m: raw_input(colorize(moulinette.m18n.g('colon', m), color)) + prompt = lambda m: raw_input(colorize(m18n.g('colon', m), color)) value = prompt(message) if confirm: m = message[0].lower() + message[1:] - if prompt(moulinette.m18n.g('confirm', prompt=m)) != value: - raise MoulinetteError(errno.EINVAL, moulinette.m18n.g('values_mismatch')) + if prompt(m18n.g('confirm', prompt=m)) != value: + raise MoulinetteError(errno.EINVAL, m18n.g('values_mismatch')) return value @@ -422,10 +421,10 @@ class Interface(BaseInterface): if isinstance(message, unicode): message = message.encode('utf-8') if style == 'success': - print('{} {}'.format(colorize(moulinette.m18n.g('success'), 'green'), message)) + print('{} {}'.format(colorize(m18n.g('success'), 'green'), message)) elif style == 'warning': - print('{} {}'.format(colorize(moulinette.m18n.g('warning'), 'yellow'), message)) + print('{} {}'.format(colorize(m18n.g('warning'), 'yellow'), message)) elif style == 'error': - print('{} {}'.format(colorize(moulinette.m18n.g('error'), 'red'), message)) + print('{} {}'.format(colorize(m18n.g('error'), 'red'), message)) else: print(message) diff --git a/moulinette/m18n.py b/moulinette/m18n.py new file mode 100644 index 00000000..e9cffafa --- /dev/null +++ b/moulinette/m18n.py @@ -0,0 +1,3 @@ +""" +Empty module used to gather m18n method to avoid to have a global magic variable +""" diff --git a/moulinette/pkg.py b/moulinette/pkg.py new file mode 100644 index 00000000..5c30da5d --- /dev/null +++ b/moulinette/pkg.py @@ -0,0 +1,3 @@ +""" +Empty module used to gather pkg method/attributes to avoid to have a global magic variable +""" diff --git a/moulinette/utils/filesystem.py b/moulinette/utils/filesystem.py index b0487df6..6cd5fbf2 100644 --- a/moulinette/utils/filesystem.py +++ b/moulinette/utils/filesystem.py @@ -5,7 +5,7 @@ import json import grp from pwd import getpwnam -import moulinette +from moulinette import m18n from moulinette.core import MoulinetteError # Files & directories -------------------------------------------------- @@ -23,7 +23,7 @@ def read_file(file_path): # Check file exists if not os.path.isfile(file_path): raise MoulinetteError(errno.ENOENT, - moulinette.m18n.g('file_not_exist', path=file_path)) + m18n.g('file_not_exist', path=file_path)) # Open file and read content try: @@ -31,11 +31,11 @@ def read_file(file_path): file_content = f.read() except IOError as e: raise MoulinetteError(errno.EACCES, - moulinette.m18n.g('cannot_open_file', + m18n.g('cannot_open_file', file=file_path, error=str(e))) except Exception as e: raise MoulinetteError(errno.EIO, - moulinette.m18n.g('error_reading_file', + m18n.g('error_reading_file', file=file_path, error=str(e))) return file_content @@ -57,7 +57,7 @@ def read_json(file_path): loaded_json = json.loads(file_content) except ValueError as e: raise MoulinetteError(errno.EINVAL, - moulinette.m18n.g('corrupted_json', + m18n.g('corrupted_json', ressource=file_path, error=str(e))) return loaded_json @@ -89,11 +89,11 @@ def write_to_file(file_path, data, file_mode="w"): f.write(data) except IOError as e: raise MoulinetteError(errno.EACCES, - moulinette.m18n.g('cannot_write_file', + m18n.g('cannot_write_file', file=file_path, error=str(e))) except Exception as e: raise MoulinetteError(errno.EIO, - moulinette.m18n.g('error_writing_file', + m18n.g('error_writing_file', file=file_path, error=str(e))) @@ -130,11 +130,11 @@ def write_to_json(file_path, data): json.dump(data, f) except IOError as e: raise MoulinetteError(errno.EACCES, - moulinette.m18n.g('cannot_write_file', + m18n.g('cannot_write_file', file=file_path, error=str(e))) except Exception as e: raise MoulinetteError(errno.EIO, - moulinette.m18n.g('_error_writing_file', + m18n.g('_error_writing_file', file=file_path, error=str(e))) @@ -155,7 +155,7 @@ def mkdir(path, mode=0777, parents=False, uid=None, gid=None, force=False): """ if os.path.exists(path) and not force: - raise OSError(errno.EEXIST, moulinette.m18n.g('folder_exists', path=path)) + raise OSError(errno.EEXIST, m18n.g('folder_exists', path=path)) if parents: # Create parents directories as needed @@ -195,7 +195,7 @@ def chown(path, uid=None, gid=None, recursive=False): uid = getpwnam(uid).pw_uid except KeyError: raise MoulinetteError(errno.EINVAL, - moulinette.m18n.g('unknown_user', user=uid)) + m18n.g('unknown_user', user=uid)) elif uid is None: uid = -1 if isinstance(gid, basestring): @@ -203,7 +203,7 @@ def chown(path, uid=None, gid=None, recursive=False): gid = grp.getgrnam(gid).gr_gid except KeyError: raise MoulinetteError(errno.EINVAL, - moulinette.m18n.g('unknown_group', group=gid)) + m18n.g('unknown_group', group=gid)) elif gid is None: gid = -1 @@ -217,7 +217,7 @@ def chown(path, uid=None, gid=None, recursive=False): os.chown(os.path.join(root, f), uid, gid) except Exception as e: raise MoulinetteError(errno.EIO, - moulinette.m18n.g('error_changing_file_permissions', + m18n.g('error_changing_file_permissions', path=path, error=str(e))) @@ -243,7 +243,7 @@ def chmod(path, mode, fmode=None, recursive=False): os.chmod(os.path.join(root, f), fmode) except Exception as e: raise MoulinetteError(errno.EIO, - moulinette.m18n.g('error_changing_file_permissions', + m18n.g('error_changing_file_permissions', path=path, error=str(e))) @@ -264,5 +264,5 @@ def rm(path, recursive=False, force=False): except OSError as e: if not force: raise MoulinetteError(errno.EIO, - moulinette.m18n.g('error_removing', + m18n.g('error_removing', path=path, error=str(e))) diff --git a/moulinette/utils/network.py b/moulinette/utils/network.py index 991eacc3..03051ca6 100644 --- a/moulinette/utils/network.py +++ b/moulinette/utils/network.py @@ -2,7 +2,7 @@ import errno import requests import json -import moulinette +from moulinette import m18n from moulinette.core import MoulinetteError @@ -24,24 +24,24 @@ def download_text(url, timeout=30): # Invalid URL except requests.exceptions.ConnectionError: raise MoulinetteError(errno.EBADE, - moulinette.m18n.g('invalid_url', url=url)) + m18n.g('invalid_url', url=url)) # SSL exceptions except requests.exceptions.SSLError: raise MoulinetteError(errno.EBADE, - moulinette.m18n.g('download_ssl_error', url=url)) + m18n.g('download_ssl_error', url=url)) # Timeout exceptions except requests.exceptions.Timeout: raise MoulinetteError(errno.ETIME, - moulinette.m18n.g('download_timeout', url=url)) + m18n.g('download_timeout', url=url)) # Unknown stuff except Exception as e: raise MoulinetteError(errno.ECONNRESET, - moulinette.m18n.g('download_unknown_error', + m18n.g('download_unknown_error', url=url, error=str(e))) # Assume error if status code is not 200 (OK) if r.status_code != 200: raise MoulinetteError(errno.EBADE, - moulinette.m18n.g('download_bad_status_code', + m18n.g('download_bad_status_code', url=url, code=str(r.status_code))) return r.text @@ -57,6 +57,6 @@ def download_json(url, timeout=30): loaded_json = json.loads(text) except ValueError: raise MoulinetteError(errno.EINVAL, - moulinette.m18n.g('corrupted_json', ressource=url)) + m18n.g('corrupted_json', ressource=url)) return loaded_json