def __init__(self, config_filename): """ Model to store the software configuration It contains main information about the software version and parses and serves the software configuration path (pw.ini) @raise os.error """ self.app_version = '0.3' self.app_name = 'Packet Weaver' self.app_name_abbrev = 'pw' self.app_prompt_l1 = 'pw> ' self.app_prompt_l2 = 'pw ({})> ' self.app_slogan = 'A Python framework for ' \ 'script filing and task sequencing' self.framework_path = os.getcwd() self._config_file = path_ha.get_abs_path(config_filename) self._load_config() self.hist_file_default_path = '.pwhistory' self.err_header_pkg = 'Config. file ({}) | Packages:\n'.format( self._config_file) self.err_header_dep = 'Config. file ({}) | Dependencies:\n'.format( self._config_file) self.err_header_editor = 'Config. file ({}) | Tools:\n'.format( self._config_file) self.err_header_hist = 'Config. file ({})| Internals:\n'.format( self._config_file)
def get_hist_file_path(self): """ Return a path to the file where is store the interactive CLI command history The path to this file is taken from the framework configuration file. :raises: ConfHistFileNotAccessible :returns: str containing the path to the file """ hist_file_path = None try: hist_file_path = self.get_config('Internals', 'HistFile') except config_parser.NoSectionError: pass if hist_file_path is None: hist_file_path = self.hist_file_default_path hist_file_path = path_ha.get_abs_path(hist_file_path) # make sure the file exists (or create it) try: if not os.path.isfile(hist_file_path): open(hist_file_path, "w").close() except IOError: raise ex.ConfHistFileNotAccessible( '{} history file at [{}]' ' is not accessible or is not a file'.format( self.err_header_hist, hist_file_path)) return hist_file_path
def get_pkg_abs_path(self): """ Return the absolute path of the current PacketWeaver package The package base folder is defined as the parent directory of the 'abilities' folder. :return: the absolute path of the package """ abs_abl_path = path_ha.get_abs_path(self._module.get_module_path()) return os.path.dirname(abs_abl_path)
def _refresh_module_list(self, limit=None): """ Build the list of available modules :param limit: (future) limit the refresh to a specific path :return: list of modules, (key is the relative path) """ searched_path = [limit] if limit is not None else self._paths for pkg_path in searched_path: m = module_factory.ModuleFactory.get_module( path_hand.get_abs_path(pkg_path), self._view) self._module_list[pkg_path] = m.get_standalone_abilities()
def do_save(self, filename): """ Saves the current ability configuration into a file, which can be loaded back with the "load" command Example: save /tmp/my_abl """ filename = path_ha.get_abs_path(filename, self.get_pkg_abs_path()) if not os.access(filename, os.F_OK): try: open(filename, 'w').close() except IOError: self._view.error('File "{}" cannot be created.'.format( filename) ) return cp = config_parser.ConfigParser() options = {} else: if not os.access(filename, os.W_OK): self._view.error('File "{}" is not writable.'.format(filename)) return cp = config_parser.ConfigParser() try: cp.read_file(open(filename, 'r')) except Exception: self._view.error( 'Invalid configuration file: {}'.format( filename) ) return try: options = dict(cp.items('Configuration')) except config_parser.NoSectionError: options = {} for opt_name in type(self._module_inst).get_option_list(): options[opt_name] = self._module_inst.get_opt(opt_name, interpreted=False) try: cp.add_section('Configuration') except config_parser.DuplicateSectionError: pass for key, val in options.items(): cp.set('Configuration', str(key), str(val)) cp.write(open(filename, 'w')) self._view.info('Current option values have been saved to {}.'.format( filename) )
def get_module_by_name(self, name): """ Retrieves a module by its name This is mostly use in case of ability packages, where the name is the one defined in the configuration file. The path is always returned in its absolute form. :param name: name of the ability package """ if isinstance(self._app_model, type(None)): return None pkg_path = path_ha.get_abs_path( self._app_model.get_config('Packages', name), self._app_model.framework_path) if isinstance(pkg_path, type(None)): return None return self.get_module(pkg_path, self._view)
def get_packages(self, absolute=True): """ Return all the pw packages path specified in the framework configuration file Tests are performed on the package paths to enforce the following properties: - this path must exists - it must be a folder The corresponding exception are raised when one of these conditions is not met. :raises: ConfPkgAbl, ConfPkgNotExists, ConfPkgNotDir, ConfPkgNone :returns: list of the package paths """ try: l_pkg_path = [] for p in self._config.options('Packages'): path = path_ha.get_abs_path(self._config.get( 'Packages', p)) if absolute else p pkg = path[:-1] if path.endswith('/') else path if not os.path.exists(pkg): raise ex.ConfPkgNotExists( '{} - specified [{}] path does not exists'.format( self.err_header_pkg, pkg)) if not os.path.isdir(pkg): raise ex.ConfPkgNotDir( '{} - specified [{}] must be a directory'.format( self.err_header_pkg, pkg)) l_pkg_path.append(path) if len(l_pkg_path) == 0: raise ex.ConfPkgNone( '{} - no packages are activated, you will not find ' 'any ability.'.format(self.err_header_pkg)) return l_pkg_path except config_parser.NoSectionError: raise ex.ConfPkgNone('{} - no packages are activated and ' 'the "Packages" section does not exist, ' 'you will not find any ability.'.format( self.err_header_pkg))
def do_load(self, filename): """ Loads options for the current ability from a specified configuration file. Any incorrect values in the option file is simply ignored. Relative file name will start from the current ability package path. Example: load /tmp/my_abl """ filename = path_ha.get_abs_path(filename, self.get_pkg_abs_path()) if not os.access(filename, os.R_OK): self._view.error('Unreadable file: {}'.format(filename)) return cp = config_parser.ConfigParser() try: cp.read_file(open(filename, 'r')) except config_parser.ParsingError: self._view.error('Invalid configuration file: {}'.format(filename)) return try: options = dict(cp.items('Configuration')) except config_parser.NoSectionError: self._view.error( 'Invalid configuration file: {}'.format(filename) ) return for opt_name, opt_value in options.items(): try: self._module_inst.set_opt(opt_name, opt_value) except AssertionError: pass