Module geode.lib.common

Expand source code
# ------------------------------------------------------------------------------
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
# ------------------------------------------------------------------------------

# Configuration
from configparser import ConfigParser

# Filesystem
from os import access, R_OK, W_OK
from pathlib import Path

# Geode
from geode.lib.utils import generate_identifier


# ------------------------------------------------------------------------------
#   Class
# ------------------------------------------------------------------------------

class CommonPath():

    def __init__(self, path='.', *paths):
        """ Constructor

        Parameters
        ----------
        path : str or pathlib.Path, optional
            Path on current filesystem (Default: current directory).
        paths : tuple, optional
            Optional paths to join on the first path parameter.
        """

        self.set_path(path, *paths)

    def exists(self):
        """ Check if element path exists on filesystem

        Returns
        -------
        bool
            True if element exists, False otherwise
        """

        if self.path is None:
            return False

        try:
            return self.path.exists()

        except PermissionError:
            return False

    @property
    def path(self):
        """ Retrieve element path

        Returns
        -------
        pathlib.Path
            Element path as file object
        """

        return self.__path

    def set_path(self, path, *paths):
        """ Set a new path for element

        Parameters
        ----------
        path : pathlib.Path or str
            New path on current filesystem.
        paths : tuple, optional
            Optional paths to join on the first path parameter.

        Raises
        ------
        ValueError
            when path parameter is an empty string
        """

        if path is None:
            self.__path = None

        elif None in paths:
            raise TypeError(f"Cannot join '{path}' with a None value")

        else:
            self.__path = Path(path, *paths).resolve()


class CommonObject(CommonPath):

    def __init__(self, *paths, **kwargs):
        """ Constructor

        Parameters
        ----------
        paths : list of str or pathlib.Path
            Object folder path
        name : str, optional
            Object name (Default: Folder name)
        environ: dict, optional
            Specific environment variables storage (Default: None)
        """

        CommonPath.__init__(self, *paths)

        self.name = kwargs.get("name")
        self.environ = kwargs.get("environ")

    @property
    def environ(self):
        """ Retrieve object environment variables

        Returns
        -------
        dict
            Object environment variables
        """

        return self.__environment

    @environ.setter
    def environ(self, environment):
        """ Set a new environment variables structure

        Set None as parameter allow to clear the environment variables storage

        Parameters
        ----------
        environment : dict or None
            Environment variables structure

        Raises
        ------
        TypeError
            when environment parameter is not a dict
        """

        if environment is None:
            environment = dict()

        if not isinstance(environment, dict):
            raise TypeError("Wrong type for environment, expected dict")

        self.__environment = environment

    @property
    def id(self):
        """ Retrieve object identifier based on his folder

        Returns
        -------
        str
            Folder identifier
        """

        return generate_identifier(self.path)

    @property
    def name(self):
        """ Retrieve object name

        Returns
        -------
        str
            Object name
        """

        return self.__name

    @name.setter
    def name(self, name):
        """ Set a new name for object

        Set None as parameter allow to reset name as folder name

        Parameters
        ----------
        name : str of None
            New object name

        Raises
        ------
        TypeError
            when name is None and object path is None
        ValueError
            when specified name is empty
        """

        if name is None:

            if self.path is not None:
                name = self.path.stem

            else:
                raise TypeError("Cannot set a name from null value")

        if not name:
            raise ValueError("Cannot set an empty string as name")

        self.__name = name

    def clear_environ(self):
        """ Remove any environment variables from storage
        """

        self.__environment.clear()

    def get_environ_value(self, key):
        """ Retrieve a specific environment variable from storage

        Key parameter is case-sensistive, causing VAR != var

        Parameters
        ----------
        key : str
            Environment variable key

        Returns
        -------
        str or None
            Environment variable value if found, None otherwise
        """

        return self.__environment.get(key)

    def set_environ_value(self, key, value):
        """ Set a new value to a specific environment variable key

        Parameters
        ----------
        key : str
            Environment variable key
        value : str
            Environment variable value

        Raises
        ------
        ValueError
            when key parameter is empty
        """

        if not key:
            raise ValueError("Cannot set an empty string as key")

        self.__environment[key] = value


class CommonConfiguration(CommonPath, ConfigParser):

    def __init__(self, *paths, **kwargs):
        """ Constructor

        Raises
        ------
        IsADirectoryError
            When the specified file path is a directory.
        PermissionError
            When the file path is not readable.
        """

        CommonPath.__init__(self, *paths)
        ConfigParser.__init__(self, **kwargs)

        if self.exists():
            if self.path.is_dir():
                raise IsADirectoryError(
                    f"Specified path '{self.path}' is a directory")

            if not access(self.path, R_OK):
                raise PermissionError(f"Cannot read file '{self.path.name}' "
                                      f"in '{self.path.parent}' directory")

            self.read(self.path)

    def write(self):
        """ Write configuration parser content to filesystem

        Raises
        ------
        IsADirectoryError
            When the specified file path is a directory.
        PermissionError
            When the file parent directory is not writable.
        """

        if self.exists() and self.path.is_dir():
            raise IsADirectoryError(
                f"Specified path '{self.path}' is a directory")

        if not access(self.path.parent, W_OK):
            raise PermissionError(f"Cannot write file '{self.path.name}' in "
                                  f"'{self.path.parent}' directory")

        with self.path.open('w') as pipe:
            ConfigParser.write(self, pipe)

Classes

class CommonConfiguration (*paths, **kwargs)

ConfigParser implementing interpolation.

Constructor

Raises

IsADirectoryError
When the specified file path is a directory.
PermissionError
When the file path is not readable.
Expand source code
class CommonConfiguration(CommonPath, ConfigParser):

    def __init__(self, *paths, **kwargs):
        """ Constructor

        Raises
        ------
        IsADirectoryError
            When the specified file path is a directory.
        PermissionError
            When the file path is not readable.
        """

        CommonPath.__init__(self, *paths)
        ConfigParser.__init__(self, **kwargs)

        if self.exists():
            if self.path.is_dir():
                raise IsADirectoryError(
                    f"Specified path '{self.path}' is a directory")

            if not access(self.path, R_OK):
                raise PermissionError(f"Cannot read file '{self.path.name}' "
                                      f"in '{self.path.parent}' directory")

            self.read(self.path)

    def write(self):
        """ Write configuration parser content to filesystem

        Raises
        ------
        IsADirectoryError
            When the specified file path is a directory.
        PermissionError
            When the file parent directory is not writable.
        """

        if self.exists() and self.path.is_dir():
            raise IsADirectoryError(
                f"Specified path '{self.path}' is a directory")

        if not access(self.path.parent, W_OK):
            raise PermissionError(f"Cannot write file '{self.path.name}' in "
                                  f"'{self.path.parent}' directory")

        with self.path.open('w') as pipe:
            ConfigParser.write(self, pipe)

Ancestors

  • CommonPath
  • configparser.ConfigParser
  • configparser.RawConfigParser
  • collections.abc.MutableMapping
  • collections.abc.Mapping
  • collections.abc.Collection
  • collections.abc.Sized
  • collections.abc.Iterable
  • collections.abc.Container

Methods

def write(self)

Write configuration parser content to filesystem

Raises

IsADirectoryError
When the specified file path is a directory.
PermissionError
When the file parent directory is not writable.
Expand source code
def write(self):
    """ Write configuration parser content to filesystem

    Raises
    ------
    IsADirectoryError
        When the specified file path is a directory.
    PermissionError
        When the file parent directory is not writable.
    """

    if self.exists() and self.path.is_dir():
        raise IsADirectoryError(
            f"Specified path '{self.path}' is a directory")

    if not access(self.path.parent, W_OK):
        raise PermissionError(f"Cannot write file '{self.path.name}' in "
                              f"'{self.path.parent}' directory")

    with self.path.open('w') as pipe:
        ConfigParser.write(self, pipe)

Inherited members

class CommonObject (*paths, **kwargs)

Constructor

Parameters

paths : list of str or pathlib.Path
Object folder path
name : str, optional
Object name (Default: Folder name)
environ : dict, optional
Specific environment variables storage (Default: None)
Expand source code
class CommonObject(CommonPath):

    def __init__(self, *paths, **kwargs):
        """ Constructor

        Parameters
        ----------
        paths : list of str or pathlib.Path
            Object folder path
        name : str, optional
            Object name (Default: Folder name)
        environ: dict, optional
            Specific environment variables storage (Default: None)
        """

        CommonPath.__init__(self, *paths)

        self.name = kwargs.get("name")
        self.environ = kwargs.get("environ")

    @property
    def environ(self):
        """ Retrieve object environment variables

        Returns
        -------
        dict
            Object environment variables
        """

        return self.__environment

    @environ.setter
    def environ(self, environment):
        """ Set a new environment variables structure

        Set None as parameter allow to clear the environment variables storage

        Parameters
        ----------
        environment : dict or None
            Environment variables structure

        Raises
        ------
        TypeError
            when environment parameter is not a dict
        """

        if environment is None:
            environment = dict()

        if not isinstance(environment, dict):
            raise TypeError("Wrong type for environment, expected dict")

        self.__environment = environment

    @property
    def id(self):
        """ Retrieve object identifier based on his folder

        Returns
        -------
        str
            Folder identifier
        """

        return generate_identifier(self.path)

    @property
    def name(self):
        """ Retrieve object name

        Returns
        -------
        str
            Object name
        """

        return self.__name

    @name.setter
    def name(self, name):
        """ Set a new name for object

        Set None as parameter allow to reset name as folder name

        Parameters
        ----------
        name : str of None
            New object name

        Raises
        ------
        TypeError
            when name is None and object path is None
        ValueError
            when specified name is empty
        """

        if name is None:

            if self.path is not None:
                name = self.path.stem

            else:
                raise TypeError("Cannot set a name from null value")

        if not name:
            raise ValueError("Cannot set an empty string as name")

        self.__name = name

    def clear_environ(self):
        """ Remove any environment variables from storage
        """

        self.__environment.clear()

    def get_environ_value(self, key):
        """ Retrieve a specific environment variable from storage

        Key parameter is case-sensistive, causing VAR != var

        Parameters
        ----------
        key : str
            Environment variable key

        Returns
        -------
        str or None
            Environment variable value if found, None otherwise
        """

        return self.__environment.get(key)

    def set_environ_value(self, key, value):
        """ Set a new value to a specific environment variable key

        Parameters
        ----------
        key : str
            Environment variable key
        value : str
            Environment variable value

        Raises
        ------
        ValueError
            when key parameter is empty
        """

        if not key:
            raise ValueError("Cannot set an empty string as key")

        self.__environment[key] = value

Ancestors

Subclasses

Instance variables

var environ

Retrieve object environment variables

Returns

dict
Object environment variables
Expand source code
@property
def environ(self):
    """ Retrieve object environment variables

    Returns
    -------
    dict
        Object environment variables
    """

    return self.__environment
var id

Retrieve object identifier based on his folder

Returns

str
Folder identifier
Expand source code
@property
def id(self):
    """ Retrieve object identifier based on his folder

    Returns
    -------
    str
        Folder identifier
    """

    return generate_identifier(self.path)
var name

Retrieve object name

Returns

str
Object name
Expand source code
@property
def name(self):
    """ Retrieve object name

    Returns
    -------
    str
        Object name
    """

    return self.__name

Methods

def clear_environ(self)

Remove any environment variables from storage

Expand source code
def clear_environ(self):
    """ Remove any environment variables from storage
    """

    self.__environment.clear()
def get_environ_value(self, key)

Retrieve a specific environment variable from storage

Key parameter is case-sensistive, causing VAR != var

Parameters

key : str
Environment variable key

Returns

str or None
Environment variable value if found, None otherwise
Expand source code
def get_environ_value(self, key):
    """ Retrieve a specific environment variable from storage

    Key parameter is case-sensistive, causing VAR != var

    Parameters
    ----------
    key : str
        Environment variable key

    Returns
    -------
    str or None
        Environment variable value if found, None otherwise
    """

    return self.__environment.get(key)
def set_environ_value(self, key, value)

Set a new value to a specific environment variable key

Parameters

key : str
Environment variable key
value : str
Environment variable value

Raises

ValueError
when key parameter is empty
Expand source code
def set_environ_value(self, key, value):
    """ Set a new value to a specific environment variable key

    Parameters
    ----------
    key : str
        Environment variable key
    value : str
        Environment variable value

    Raises
    ------
    ValueError
        when key parameter is empty
    """

    if not key:
        raise ValueError("Cannot set an empty string as key")

    self.__environment[key] = value

Inherited members

class CommonPath (path='.', *paths)

Constructor

Parameters

path : str or pathlib.Path, optional
Path on current filesystem (Default: current directory).
paths : tuple, optional
Optional paths to join on the first path parameter.
Expand source code
class CommonPath():

    def __init__(self, path='.', *paths):
        """ Constructor

        Parameters
        ----------
        path : str or pathlib.Path, optional
            Path on current filesystem (Default: current directory).
        paths : tuple, optional
            Optional paths to join on the first path parameter.
        """

        self.set_path(path, *paths)

    def exists(self):
        """ Check if element path exists on filesystem

        Returns
        -------
        bool
            True if element exists, False otherwise
        """

        if self.path is None:
            return False

        try:
            return self.path.exists()

        except PermissionError:
            return False

    @property
    def path(self):
        """ Retrieve element path

        Returns
        -------
        pathlib.Path
            Element path as file object
        """

        return self.__path

    def set_path(self, path, *paths):
        """ Set a new path for element

        Parameters
        ----------
        path : pathlib.Path or str
            New path on current filesystem.
        paths : tuple, optional
            Optional paths to join on the first path parameter.

        Raises
        ------
        ValueError
            when path parameter is an empty string
        """

        if path is None:
            self.__path = None

        elif None in paths:
            raise TypeError(f"Cannot join '{path}' with a None value")

        else:
            self.__path = Path(path, *paths).resolve()

Subclasses

Instance variables

var path

Retrieve element path

Returns

pathlib.Path
Element path as file object
Expand source code
@property
def path(self):
    """ Retrieve element path

    Returns
    -------
    pathlib.Path
        Element path as file object
    """

    return self.__path

Methods

def exists(self)

Check if element path exists on filesystem

Returns

bool
True if element exists, False otherwise
Expand source code
def exists(self):
    """ Check if element path exists on filesystem

    Returns
    -------
    bool
        True if element exists, False otherwise
    """

    if self.path is None:
        return False

    try:
        return self.path.exists()

    except PermissionError:
        return False
def set_path(self, path, *paths)

Set a new path for element

Parameters

path : pathlib.Path or str
New path on current filesystem.
paths : tuple, optional
Optional paths to join on the first path parameter.

Raises

ValueError
when path parameter is an empty string
Expand source code
def set_path(self, path, *paths):
    """ Set a new path for element

    Parameters
    ----------
    path : pathlib.Path or str
        New path on current filesystem.
    paths : tuple, optional
        Optional paths to join on the first path parameter.

    Raises
    ------
    ValueError
        when path parameter is an empty string
    """

    if path is None:
        self.__path = None

    elif None in paths:
        raise TypeError(f"Cannot join '{path}' with a None value")

    else:
        self.__path = Path(path, *paths).resolve()