Source code for convert.universal

import importlib
import warnings

import convert.compress


class UnsupportedFileExtensionError(ValueError):
    """ The file extension is not supported. """

    def __init__(self, file, supported_file_extensions=None):
        self.file = file
        message = f'The file {file} has an unsupported file extension.'
        if supported_file_extensions is not None:
            self.supported_file_extensions = supported_file_extensions
            message += f' Only {supported_file_extensions} are supported.'
        self.message = message
        super().__init__(message)


class UnsupportedConversionError(ValueError):
    """ The file extension is not supported. """

    def __init__(self, file_from, file_to, supported_file_extension_combinations=None):
        self.file_from = file_from
        self.file_to = file_to
        message = f'The file {file_from} can not be converted to file {file_to}.'
        if supported_file_extension_combinations is not None:
            self.supported_file_extension_combinations = supported_file_extension_combinations
            message += (f' Only {supported_file_extension_combinations} as file extension'
                        f' conversions are supported.')
        self.message = message
        super().__init__(message)


SUPPORTED_MODULES = []
for module_string in ('convert.scipy', 'convert.numpy'):
    try:
        module = importlib.import_module(module_string)
    except ImportError:
        warnings.warn(f'Model {module_string} could not be imported. '
                      f'Thus the related functions are not available.',
                      category=ImportWarning)
    else:
        SUPPORTED_MODULES.append(module)

SUPPORTED_FILE_EXTENSIONS = [file_extension
                             for module in SUPPORTED_MODULES
                             for file_extension in module.FILE_EXTENSIONS]

SUPPORTED_FILE_EXTENSION_COMBINATIONS = [(file_extension_1, file_extension_2)
                                         for module in SUPPORTED_MODULES
                                         for file_extension_1 in module.FILE_EXTENSIONS
                                         for file_extension_2 in module.FILE_EXTENSIONS]


def _module_and_file_extension(file):
    file = str(file)
    for module in SUPPORTED_MODULES:
        for file_extension in module.FILE_EXTENSIONS:
            if file.endswith(file_extension):
                return module, file_extension
    raise UnsupportedFileExtensionError(file, supported_file_extensions=SUPPORTED_FILE_EXTENSIONS)


def _io_function(file, mode, module, file_extension):
    assert mode in ('r', 'w')

    # check if compress file extension
    try:
        compress_file_extension = convert.compress.compress_file_extension(file_extension)
    except UnsupportedFileExtensionError:
        compress_file_extension = None
    else:
        file_extension = file_extension[: len(file_extension) - len(compress_file_extension)]

    # apply binary or text mode
    binary_mode = module.BINARY_MODE_DICT[file_extension]
    if binary_mode:
        mode += 'b'
    else:
        mode += 't'

    # open function
    if compress_file_extension is None:
        def open_function():
            return open(file, mode=mode)
    else:
        def open_function():
            return convert.compress.compress_file_object(file, mode=mode)

    #
    if mode.startswith('r'):
        def io_function():
            with open_function() as file_object:
                return module.load(file_object, file_extension)
    else:
        def io_function(value):
            with open_function() as file_object:
                return module.save(file_object, file_extension, value)

    # return
    return io_function


def _load(file, module, file_extension):
    io_function = _io_function(file, 'r', module, file_extension)
    return io_function()


[docs]def load(file): """ Loads a value. Parameters ---------- file : str or pathlib.Path The file that should be loaded. Returns ------- object The value stored in `file`. """ module, file_extension = _module_and_file_extension(file) return _load(file, module, file_extension)
def _save(file, module, file_extension, value): io_function = _io_function(file, 'w', module, file_extension) return io_function(value)
[docs]def save(file, value): """ Saves a value. Parameters ---------- file : str or pathlib.Path The file where `value` should be saved. value : object The value that should be saved. """ module, file_extension = _module_and_file_extension(file) return _save(file, module, file_extension, value)
[docs]def convert_file(file_from, file_to): """ Converts a file into another file. Parameters ---------- file_from : str or pathlib.Path The file that should be converted. file_to : str or pathlib.Path The file to which `file_from` should be converted. """ if file_from != file_to: module_from, file_extension_from = _module_and_file_extension(file_from) module_to, file_extension_to = _module_and_file_extension(file_to) if (file_extension_from, file_extension_to) not in SUPPORTED_FILE_EXTENSION_COMBINATIONS: raise UnsupportedConversionError( file_from, file_to, supported_file_extension_combinations=SUPPORTED_FILE_EXTENSION_COMBINATIONS) array = _load(file_from, module_from, file_extension_from) _save(file_to, module_to, file_extension_to, array) return file_to
[docs]def convert_file_extension(file, file_extension): """ Converts a file into another file. Parameters ---------- file : str or pathlib.Path The file that should be converted. file_extension : str The new file extension that the converted file should have. The new file has the same filename as `file` only its file extension is replaced by `file_extension`. """ file = str(file) _, old_file_extension = _module_and_file_extension(file) file_to = file[: len(file) - len(old_file_extension)] + file_extension convert_file(file, file_to) return file_to