Source code for foundations.rotatingBackup

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
**rotatingbackup.py**

**Platform:**
	Windows, Linux, Mac Os X.

**Description:**
	This module defines the :class:`RotatingBackup` class.

**Others:**
	Code extracted from rotatingbackup.py written by leo.ss.pku@gmail.com
"""

#**********************************************************************************************************************
#***	External imports.
#**********************************************************************************************************************
import os

#**********************************************************************************************************************
#***	Internal imports.
#**********************************************************************************************************************
import foundations.common
import foundations.exceptions
import foundations.io
import foundations.verbose

#**********************************************************************************************************************
#***	Module attributes.
#**********************************************************************************************************************
__author__ = "Thomas Mansencal"
__copyright__ = "Copyright (C) 2008 - 2013 - Thomas Mansencal"
__license__ = "GPL V3.0 - http://www.gnu.org/licenses/"
__maintainer__ = "Thomas Mansencal"
__email__ = "thomas.mansencal@gmail.com"
__status__ = "Production"

__all__ = ["LOGGER", "RotatingBackup"]

LOGGER = foundations.verbose.installLogger()

#**********************************************************************************************************************
#***	Module classes and definitions.
#**********************************************************************************************************************
[docs]class RotatingBackup(object): """ This class provides a rotating backup system. """ def __init__(self, source=None, destination=None, count=3): """ .. Sphinx: Statements updated for auto-documentation purpose. .. warning:: Backups destination folder should not be the same than the folder containing the source to be backuped! Usage:: >>> file = "File.txt" >>> destination = "backup" >>> backup = RotatingBackup(file, destination) >>> backup.backup() True >>> for i in range(3): ... backup.backup() ... True True True >>> import os >>> os.listdir(destination) ['File.txt', 'File.txt.1', 'File.txt.2', 'File.txt.3'] :param source: Backup source. ( String ) :param destination: Backup destination. ( String ) :param count: Backups count. ( Integer ) """ LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__)) # --- Setting class attributes. --- self.__source = None self.__source = source self.__destination = None self.__destination = destination self.__count = None self.__count = count #****************************************************************************************************************** #*** Attributes properties. #****************************************************************************************************************** @property def source(self): """ This method is the property for **self.__source** attribute. :return: self.__source. ( String ) """ return self.__source @source.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(AssertionError) def source(self, value): """ This method is the setter method for **self.__source** attribute. :param value: Attribute value. ( String ) """ if value is not None: assert type(value) in (str, unicode), "'{0}' attribute: '{1}' type is not 'str' or 'unicode'!".format( "source", value) assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("source", value) self.__source = value @source.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def source(self): """ This method is the deleter method for **self.__source** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "source"))
@property def destination(self): """ This method is the property for **self.__destination** attribute. :return: self.__destination. ( String ) """ return self.__destination @destination.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(AssertionError) def destination(self, value): """ This method is the setter method for **self.__destination** attribute. :param value: Attribute value. ( String ) """ if value is not None: assert type(value) in (str, unicode), "'{0}' attribute: '{1}' type is not 'str' or 'unicode'!".format( "destination", value) self.__destination = value @destination.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def destination(self): """ This method is the deleter method for **self.__destination** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "destination"))
@property def count(self): """ This method is the property for **self.__count** attribute. :return: self.__count. ( Integer ) """ return self.__count @count.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(AssertionError) def count(self, value): """ This method is the setter method for **self.__count** attribute. :param value: Attribute value. ( Integer ) """ if value is not None: assert type(value) is int, "'{0}' attribute: '{1}' type is not 'int'!".format( "count", value) assert value > 0, "'{0}' attribute: '{1}' need to be exactly positive!".format("count", value) self.__count = value @count.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def count(self): """ This method is the deleter method for **self.__count** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "count")) #****************************************************************************************************************** #*** Class methods. #******************************************************************************************************************
[docs] def backup(self): """ This method does the rotating backup. :return: Method success. ( Boolean ) """ LOGGER.debug("> Storing '{0}' file backup.".format(self.__source)) foundations.common.pathExists(self.__destination) or foundations.io.setDirectory(self.__destination) destination = os.path.join(self.__destination, os.path.basename(self.__source)) for i in range(self.__count - 1, 0, -1): sfn = "{0}.{1}".format(destination, i) dfn = "{0}.{1}".format(destination, i + 1) if foundations.common.pathExists(sfn): if foundations.common.pathExists(dfn): foundations.io.remove(dfn) os.renames(sfn, dfn) foundations.common.pathExists(destination) and os.rename(destination, destination + ".1") foundations.io.copy(self.__source, destination) return True