/src/yppy/config.py
Python | 230 lines | 228 code | 0 blank | 2 comment | 0 complexity | 2dc3b6e0b1bb954eee4c9626d548bc5a MD5 | raw file
Possible License(s): BSD-3-Clause
- '''Yppy configuration facilities.
- This module exposes a global variable, "Config", encapsulating the set of all
- global settings for the current Yppy process. Other modules are encouraged to
- import and access this variable as needed and at any time.
- '''
- # ....................{ IMPORTS }....................
- from yppy import core
- from yppy.classmap import ClassMaps
- from yppy.exception import YppyException
- from yppy.util.file import filesystem
- import os
- # ....................{ CLASSES }....................
- class YppyConfig(object):
- '''Yppy configuration.
-
- This class encapsulates the set of all globally accessible "settings" for
- this Yppy process.
-
- Attributes
- ----------
- _graph_library_name : string
- Name of the graph library to be used.
- is_overwriting_output_paths : boolean
- True if overwriting existing output files and directories.
- '''
- # ..................{ CLASS ATTRIBUTES }..................
- # Frozen set of all graph library names (i.e., the set of all external graph
- # libraries installed on the current system).
- GRAPH_LIBRARY_NAMES = ClassMaps.GRAPH_LIBRARY_NAME_TO_FACTORY_CLASS.keys()
-
- # Default graph library name (i.e., the "factory"-recommended external graph
- # library to be used on the current system).
- GRAPH_LIBRARY_NAME_DEFAULT =\
- ClassMaps.GRAPH_LIBRARY_NAME_TO_FACTORY_CLASS.default_key
-
- # ..................{ INITIALIZATION }..................
- # Do not use "@core.assign_parameters_to_self()" here, as that confuses
- # common IDE editors. (Eclipse, I'm squinting at you.)
- def __init__(self,
- graph_library_name=None,
- is_overwriting_output_paths=False):
- '''Initialize this configuration.
-
- Arguments
- ----------
- _graph_library_name : string, optional
- Name of the graph library to be used. This must necessarily be a key
- in the "ClassMaps.GRAPH_LIBRARY_NAME_TO_FACTORY_CLASS" classmap.
- Defaults to None, in which case the optimally efficient graph
- library available on the current system is used.
- _is_overwriting_output_paths : boolean, optional
- True if overwriting existing output files and directories. If False,
- then classes elsewhere raise exceptions when attempting to overwrite
- such files. Defaults to False for safety.
- '''
- # Technically, this should be:
- #
- # if not graph_library_name:
- # graph_library_name =\
- # ClassMaps.GRAPH_LIBRARY_NAME_TO_FACTORY_CLASS.default_key
- #
- # However, that induces a circular dependency issue. So, just do this!
- if graph_library_name:
- self.graph_library_name = graph_library_name
- else:
- self._graph_library_name = None
-
- # Copy the passed parameters to object attributes.
- self.is_overwriting_output_paths = is_overwriting_output_paths
-
- # Make user-specific Yppy directories, if not already.
- filesystem.make_dir_if_not_found(self.dot_dirname)
- filesystem.make_dir_if_not_found(self.temporary_dirname)
-
- # Set this object as the new singleton configuration.
- global Config
- Config = self
-
- # ..................{ PROPERTIES ~ immutable }..................
- #FIXME: This technically works under Windows, but may refer to an unexpected
- #location. Sadly, although there has been some recent discusson on Python
- #forums concerning a standardization of the dot directory concept under
- #Windows, there appears to be no broad consensus as of yet.
- @property
- def dot_dirname(self):
- '''Get the absolute path to the user-specific Yppy dot directory.
-
- This is the platform-dependent directory to which Yppy records user-
- specific logs, history, et al., as follows:
-
- * Under *nix (e.g., Linux), "~/.yppy".
- * Under Windows, ...?
- '''
- return os.path.join(
- filesystem.get_user_home_dir(),
- '.' + core.get_program_executable_name())
-
- @property
- def temporary_dirname(self):
- '''Get the absolute path to the user-specific Yppy temporary directory.
- '''
- return os.path.join(self.dot_dirname, 'tmp')
-
- @property
- def log_filename(self):
- '''Get the absolute path to the user-specific Yppy log filename.
- '''
- return os.path.join(self.dot_dirname, 'log')
- # ..................{ PROPERTIES ~ mutable }..................
- @property
- def graph_library_name(self):
- '''Get the currently configured graph library name.
- '''
- return self._graph_library_name
-
- @graph_library_name.setter
- def graph_library_name(self, graph_library_name):
- '''Set the currently configured graph library name.
-
- Parameters
- ----------
- graph_library_name : string
- Key in the "GRAPH_LIBRARY_NAME_TO_FACTORY_CLASS" classmap.
- '''
- if graph_library_name not in self.GRAPH_LIBRARY_NAMES:
- raise YppyException(graph_library_name,
- 'not available on this system; expected one of: ' +\
- core.to_human_readable_string(self.GRAPH_LIBRARY_NAMES))
- self._graph_library_name = graph_library_name
-
- # ..................{ FILENAMES }..................
- def get_temporary_filename(self, *args, **kwargs):
- '''Get the absolute path to a unique temporary file.
-
- Caveats
- ----------
- This function guarantees that at the time of return this file does not
- exist, but no guarantees past that time. Inevitably, this *COULD* lead
- to subtle race conditions; as in Latin, "Caveat emptor."
-
- Parameters
- ----------
- This method passes all passed parameters to the
- filesystem.get_temporary_filename() function.
- '''
- return filesystem.get_temporary_filename(
- dirname=self.temporary_dirname, *args, **kwargs)
- # ....................{ GLOBALS }....................
- # Singleton configuration for the current Yppy process.
- #
- # Technically, this should be None. Instead, set this to the above base class to
- # reduce IDE errors (e.g., as from Eclipse).
- Config = YppyConfig()
- #FIXME: Obsolete.
- # # ..................{ PUBLIC }..................
- # def make_graph(self, *args, **kwargs):
- # '''Make a new graph object for the currently configured graph library.
- #
- # Parameters
- # ----------
- # This method delegates to the YppyGraphObjectFactory.make() method; see
- # that method for parameter details.
- #
- # Returns
- # ----------
- # object
- # Empty graph object.
- # '''
- # return ClassMaps.GRAPH_LIBRARY_NAME_TO_FACTORY_CLASS[
- # self._graph_library_name].make(*args, **kwargs)
- #Defaults to None,
- # requiring callers to call the init() function before accessing this global.
- # ....................{ FUNCTIONS }....................
- #def init(*args, **kwargs):
- # '''Initialize the singleton configuration for the current Yppy process.
- #
- # This function should be called once and only once, per Yppy process:
- # typically by the instance of the "YppyConfigBase" base class itself.
- # '''
- # # Initialize a new configuration given the passed parameters.
- # new_config = YppyConfig(*args, **kwargs)
- #
- # # If a singleton Config has already been set, raise an exception.
- # global Config
- # if Config:
- # raise YppyException(Config, 'already initialized, so cannot overwrite '\
- # 'with new configuration "%s"' % new_config)
- #
- # # Set us up the config bomb.
- # Config = new_config
- # --------------------( COPYRIGHT AND LICENSE )--------------------
- # The information below applies to everything in this distribution,
- # except where noted.
- #
- # Copyright 2010-2011, Cecil Curry <leycec@gmail.com {*} http://raiazome.com>.
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are met:
- #
- # 1. Redistributions of source code must retain the above copyright notice,
- # this list of conditions and the following disclaimer.
- # 2. Redistributions in binary form must reproduce the above copyright
- # notice, this list of conditions and the following disclaimer in the
- # documentation and/or other materials provided with the distribution.
- # 3. Neither the name of the <ORGANIZATION> nor the names of its
- # contributors may be used to endorse or promote products derived from
- # this software without specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- #
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- # POSSIBILITY OF SUCH DAMAGE.