Module geode.lib.utils

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.
# ------------------------------------------------------------------------------

# Filesystem
from pathlib import Path

# Regex
from re import sub

# System
from os import environ


# ------------------------------------------------------------------------------
#   Methods
# ------------------------------------------------------------------------------

def get_data(*args, egg="geode"):
    """ Provides easy access to data in a python egg or local folder

    This function search a path in a specific python egg or in local folder.
    The local folder is check before egg to allow quick debugging.

    Thanks Deluge :)

    Parameters
    ----------
    args : list
        File path as strings list
    egg : str, optional
        Python egg name (Default: geode)

    Returns
    -------
    pathlib.Path
        File path instance
    """

    path = Path(*args).expanduser()

    try:
        # Only available for Python >= 3.7
        from importlib.resources import path as resource_filename

        # Generate a module name based on egg name and file resource path
        module_name = '.'.join([egg, *args[:-1]])

        # Open resource to retrieve Path instance
        with resource_filename(module_name, args[-1]) as filepath:
            data = filepath.expanduser()

    except ImportError:
        from pkg_resources import resource_filename

        data = Path(resource_filename(egg, str(path))).expanduser()

    except Exception:
        data = path

    if data.exists():
        return data

    return path


def get_binary_path(binary):
    """ Get a list of available binary paths from $PATH variable

    This function get all the path from $PATH variable which match binary
    request.

    Parameters
    ----------
    binary : str
        Binary name or path

    Returns
    -------
    list
        List of available path

    Examples
    --------
    >>> get_binary_path('ls')
    ['/bin/ls']
    """

    available = list()

    if binary is None or not str(binary):
        return available

    binary = Path(binary).expanduser()

    if binary.exists():
        available.append(binary.name)

    for path in set(environ["PATH"].split(':')):
        binary_path = Path(path, binary)

        try:
            if not binary_path.exists():
                continue

        except PermissionError:
            continue

        if binary_path.name not in available:
            available.append(str(binary_path))

    return available


def generate_identifier(path):
    """ Generate an identifier from a path

    Parameters
    ----------
    path : pathlib.Path or str
        Path to parse into indentifier

    Returns
    -------
    str
        Identifier string

    Examples
    --------
    >>> generate_identifier('Double Dragon (Europe).nes')
    'double-dragon-europe-nes-25953832'
    """

    inode = int()

    if isinstance(path, str):
        path = Path(path).expanduser()

    if path.exists():
        # Retrieve file inode number
        inode = path.stat().st_ino

    # Retrieve file basename
    path = path.name

    # Retrieve only alphanumeric element from filename
    name = sub(r"[^\w\d]+", ' ', path.lower())
    # Remove useless spaces and replace the others with a dash
    name = sub(r"[\s|_]+", '-', name.strip())

    if inode > 0:
        name = f"{name}-{inode}"

    return name


def generate_extension(extension):
    """ Generate a regex pattern to check lower and upper case extensions

    Thanks to https://stackoverflow.com/a/10148272

    Parameters
    ----------
    extension : str
        Extension to parse without the first dot

    Returns
    -------
    str
        Regex pattern

    Examples
    --------
    >>> generate_extensions('nes')
    '[nN][eE][sS]'
    """

    pattern = str()

    for character in extension:
        if not character == '.':
            pattern += f"[{character.lower()}{character.upper()}]"

        else:
            pattern += '.'

    return pattern


def escape_request(*args, separator=',', **kwargs):
    """ Retrieve an escaped string which can be used for sqlite request

    Parameters
    ----------
    separator : str, optional
        Arguments separator in result string (Default: ',')

    Returns
    -------
    str
        Escaped string

    Examples
    --------
    >>> escape_request('name', 'type')
    '"name","type"'
    >>> escape_request(name='test')
    '"name"="test"'
    """

    request = list()

    if args:
        request.extend([f"\"{element}\"" for element in args])

    if kwargs:
        request.extend([
            f"\"{key}\"=\"{value}\"" for key, value in kwargs.items()])

    return separator.join(request)

Functions

def escape_request(*args, separator=',', **kwargs)

Retrieve an escaped string which can be used for sqlite request

Parameters

separator : str, optional
Arguments separator in result string (Default: ',')

Returns

str
Escaped string

Examples

>>> escape_request('name', 'type')
'"name","type"'
>>> escape_request(name='test')
'"name"="test"'
Expand source code
def escape_request(*args, separator=',', **kwargs):
    """ Retrieve an escaped string which can be used for sqlite request

    Parameters
    ----------
    separator : str, optional
        Arguments separator in result string (Default: ',')

    Returns
    -------
    str
        Escaped string

    Examples
    --------
    >>> escape_request('name', 'type')
    '"name","type"'
    >>> escape_request(name='test')
    '"name"="test"'
    """

    request = list()

    if args:
        request.extend([f"\"{element}\"" for element in args])

    if kwargs:
        request.extend([
            f"\"{key}\"=\"{value}\"" for key, value in kwargs.items()])

    return separator.join(request)
def generate_extension(extension)

Generate a regex pattern to check lower and upper case extensions

Thanks to https://stackoverflow.com/a/10148272

Parameters

extension : str
Extension to parse without the first dot

Returns

str
Regex pattern

Examples

>>> generate_extensions('nes')
'[nN][eE][sS]'
Expand source code
def generate_extension(extension):
    """ Generate a regex pattern to check lower and upper case extensions

    Thanks to https://stackoverflow.com/a/10148272

    Parameters
    ----------
    extension : str
        Extension to parse without the first dot

    Returns
    -------
    str
        Regex pattern

    Examples
    --------
    >>> generate_extensions('nes')
    '[nN][eE][sS]'
    """

    pattern = str()

    for character in extension:
        if not character == '.':
            pattern += f"[{character.lower()}{character.upper()}]"

        else:
            pattern += '.'

    return pattern
def generate_identifier(path)

Generate an identifier from a path

Parameters

path : pathlib.Path or str
Path to parse into indentifier

Returns

str
Identifier string

Examples

>>> generate_identifier('Double Dragon (Europe).nes')
'double-dragon-europe-nes-25953832'
Expand source code
def generate_identifier(path):
    """ Generate an identifier from a path

    Parameters
    ----------
    path : pathlib.Path or str
        Path to parse into indentifier

    Returns
    -------
    str
        Identifier string

    Examples
    --------
    >>> generate_identifier('Double Dragon (Europe).nes')
    'double-dragon-europe-nes-25953832'
    """

    inode = int()

    if isinstance(path, str):
        path = Path(path).expanduser()

    if path.exists():
        # Retrieve file inode number
        inode = path.stat().st_ino

    # Retrieve file basename
    path = path.name

    # Retrieve only alphanumeric element from filename
    name = sub(r"[^\w\d]+", ' ', path.lower())
    # Remove useless spaces and replace the others with a dash
    name = sub(r"[\s|_]+", '-', name.strip())

    if inode > 0:
        name = f"{name}-{inode}"

    return name
def get_binary_path(binary)

Get a list of available binary paths from $PATH variable

This function get all the path from $PATH variable which match binary request.

Parameters

binary : str
Binary name or path

Returns

list
List of available path

Examples

>>> get_binary_path('ls')
['/bin/ls']
Expand source code
def get_binary_path(binary):
    """ Get a list of available binary paths from $PATH variable

    This function get all the path from $PATH variable which match binary
    request.

    Parameters
    ----------
    binary : str
        Binary name or path

    Returns
    -------
    list
        List of available path

    Examples
    --------
    >>> get_binary_path('ls')
    ['/bin/ls']
    """

    available = list()

    if binary is None or not str(binary):
        return available

    binary = Path(binary).expanduser()

    if binary.exists():
        available.append(binary.name)

    for path in set(environ["PATH"].split(':')):
        binary_path = Path(path, binary)

        try:
            if not binary_path.exists():
                continue

        except PermissionError:
            continue

        if binary_path.name not in available:
            available.append(str(binary_path))

    return available
def get_data(*args, egg='geode')

Provides easy access to data in a python egg or local folder

This function search a path in a specific python egg or in local folder. The local folder is check before egg to allow quick debugging.

Thanks Deluge :)

Parameters

args : list
File path as strings list
egg : str, optional
Python egg name (Default: geode)

Returns

pathlib.Path
File path instance
Expand source code
def get_data(*args, egg="geode"):
    """ Provides easy access to data in a python egg or local folder

    This function search a path in a specific python egg or in local folder.
    The local folder is check before egg to allow quick debugging.

    Thanks Deluge :)

    Parameters
    ----------
    args : list
        File path as strings list
    egg : str, optional
        Python egg name (Default: geode)

    Returns
    -------
    pathlib.Path
        File path instance
    """

    path = Path(*args).expanduser()

    try:
        # Only available for Python >= 3.7
        from importlib.resources import path as resource_filename

        # Generate a module name based on egg name and file resource path
        module_name = '.'.join([egg, *args[:-1]])

        # Open resource to retrieve Path instance
        with resource_filename(module_name, args[-1]) as filepath:
            data = filepath.expanduser()

    except ImportError:
        from pkg_resources import resource_filename

        data = Path(resource_filename(egg, str(path))).expanduser()

    except Exception:
        data = path

    if data.exists():
        return data

    return path