Source code for AutoArchive._services.archiver._tar_archiver_provider_base

# tar_archiver_provider_base.py
#
# Project: AutoArchive
# License: GNU GPLv3
#
# Copyright (C) 2003 - 2015 Róbert Čerňanský



""":class:`_TarArchiverProviderBase` class."""



__all__ = ["_TarArchiverProviderBase", "_BACKUP_TYPES_TO_EXTENSIONS"]



# {{{ INCLUDES

from abc import *
import os

from ..._py_additions import *
from ..._archiving import *

# }}} INCLUDES



# {{{ CONSTANTS

_BACKUP_TYPES_TO_EXTENSIONS = {BackupTypes.Tar: "tar",
                               BackupTypes.TarGz: "tar.gz",
                               BackupTypes.TarBz2: "tar.bz2",
                               BackupTypes.TarXz: "tar.xz"}

# }}} CONSTANTS



# {{{ CLASSES

[docs]class _TarArchiverProviderBase(IArchiver): """Base class for tar archiver service providers. Abstract constructor of this class, should be called from derived constructors. It initializes the :attr:`workDir_` property. :param workDir: Path to a writable directory. The service will use it as persistent storage. :type workDir: ``str``""" __PARTIAL_FILE_SUFFIX = "._partial" @abstractmethod def __init__(self, workDir): self.__workDir = workDir # {{{ IArchiver members @event def fileAdd(filesystemObjectName): "See: :meth:`.IArchiver.fileAdd`." @event def backupOperationError(operation, error, filesystemObjectName = None, unknownErrorString = None): "See: :meth:`.IArchiver.backupOperationError`."
[docs] @abstractmethod def backupFiles(self, backupDefinition, compressionStrength = None): """Performs basic checks before the backup creation. .. note:: Derived classes should call this base method on the beginning of the overridden method. See also: :meth:`.IArchiver.backupFiles()`.""" self.raiseIfUnsupportedBackupType_(backupDefinition.backupType) self.raiseIfUnsupportedFeature_(backupDefinition.backupType, compressionStrength) self.__raiseIfEmptyIncludeFiles(backupDefinition.includeFiles)
[docs] @abstractmethod def backupFilesIncrementally(self, backupDefinition, compressionStrength = None, level = None): """Performs basic checks before the incremental backup creation. .. note:: Derived classes should call this base method on the beginning of the overridden method. See also: :meth:`.IArchiver.backupFilesIncrementally()`.""" self.raiseIfUnsupportedBackupType_(backupDefinition.backupType) self.raiseIfUnsupportedFeature_(backupDefinition.backupType, compressionStrength, 99) self.__raiseIfEmptyIncludeFiles(backupDefinition.includeFiles)
[docs] def removeBackup(self, backupDefinition): "See: :meth:`.IArchiver.removeBackup()`." self.raiseIfUnsupportedBackupType_(backupDefinition.backupType) os.remove(self.getBackupFilePath_( backupDefinition.backupId, backupDefinition.backupType, backupDefinition.destination))
[docs] def removeBackupIncrements(self, backupDefinition, level = None): "See: :meth:`.IArchiver.removeBackupIncrements()`." raise NotImplementedError("Not supported.")
[docs] @classmethod def getSupportedFeatures(cls, backupType = None): "See: :meth:`.IArchiver.getSupportedFeatures()`." return frozenset()
[docs] def getMaxBackupLevel(self, backupId): "See: :meth:`.IArchiver.getMaxBackupLevel()`." raise NotImplementedError("Not supported.")
[docs] def getStoredBackupIds(self): "See: :meth:`.IArchiver.getMaxBackupLevel()`." return ()
[docs] def purgeStoredBackupData(self, backupId): "See: :meth:`.IArchiver.purgeStoredBackupData()`." pass
# }}} IArchiver members @property def workDir_(self): """Gets path to the working directory. :rtype: ``str``""" return self.__workDir
[docs] @staticmethod def getBackupFilePath_(backupId, backupType, destination, level = None): """Assembles the backup file name and returns a path to it. :param backupId: ID of the backup for which the path shall be returned. :type backupId: ``str`` :param backupType: Type of the backup. :type backupType: :data:`BackupTypes` :param destination: Path to the directory where the to the backup shall be created. :type destination: ``str`` :param level: Backup level. :type level: ``int`` :return: Path to the backup file. :rtype: ``str``""" levelToken = "." + str(level) if level else "" return os.path.join(destination, backupId + levelToken + "." + _BACKUP_TYPES_TO_EXTENSIONS[backupType])
[docs] @classmethod def getWorkingPath_(cls, properPath): return properPath + cls.__PARTIAL_FILE_SUFFIX
[docs] @classmethod def raiseIfUnsupportedBackupType_(cls, backupType): """Raises an exception if the passed ``backupType`` is not supported by the implementation. See also: :attr:`.IArchiver.supportedBackupTypes`. :param backupType: The backup type that shall be checked. :type backupType: :data:`.BackupTypes` :raise ValueError: If the passed ``backupType`` is not supported by the concrete implementation.""" if backupType not in cls.supportedBackupTypes: raise ValueError(str.format("Unsupported backup type: {}", str(backupType)))
[docs] @classmethod def raiseIfUnsupportedFeature_(cls, backupType, compressionStrength = None, level = None): for feature in cls.__parametersToFeatures(compressionStrength, level): if feature not in cls.getSupportedFeatures(backupType): raise RuntimeError(str.format("Feature {} is not supported be the backup type {}.", str(feature), str(backupType)))
@classmethod def __raiseIfEmptyIncludeFiles(cls, includeFiles): if not includeFiles: raise RuntimeError("Nothing to backup.") @staticmethod def __parametersToFeatures(compressionStrength = None, level = None): features = set() if compressionStrength is not None: features.add(ArchiverFeatures.CompressionStrength) if level is not None: features.add(ArchiverFeatures.Incremental) return features
# }}} CLASSES