Add further methods and refine backup classes
This commit is contained in:
@@ -1,39 +1,72 @@
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext
|
||||
from django.core.management.commands.dumpdata import Command
|
||||
from django.db import router, DEFAULT_DB_ALIAS
|
||||
|
||||
|
||||
class BackupManagerBase(object):
|
||||
class ElementBackupBase(object):
|
||||
"""
|
||||
Sub classes must provide at least:
|
||||
info()
|
||||
backup()
|
||||
restore()
|
||||
"""
|
||||
|
||||
label = _(u'Base backup manager')
|
||||
#def __init__(self, name, label):
|
||||
# self.label = label
|
||||
# self.name = name
|
||||
|
||||
def info(self):
|
||||
"""
|
||||
Must return at least None
|
||||
"""
|
||||
return None
|
||||
|
||||
def link(self, app_backup):
|
||||
self.app_backup = app_backup
|
||||
return self
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.__class__.label)
|
||||
|
||||
|
||||
class ModelFixtures(BackupManagerBase):
|
||||
class ElementBackupModel(ElementBackupBase):
|
||||
label = _(u'Model fixtures')
|
||||
|
||||
def __init__(self, models=None):
|
||||
self.model_list = models or []
|
||||
|
||||
def info(self):
|
||||
return u', '.join(self.model_list) or _(u'All')
|
||||
return _(u'models: %s') % (u', '.join(self.model_list) if self.model_list else _(u'All'))
|
||||
|
||||
def backup(self):
|
||||
"""
|
||||
TODO: turn into a generator maybe?
|
||||
"""
|
||||
command = Command()
|
||||
if not self.model_list:
|
||||
result = [self.app_backup.name]
|
||||
else:
|
||||
result = [u'%s.%s' (self.app_backup.name, model) for model in self.model_list]
|
||||
result = command.handle(u' '.join(result), format='json', indent=4, using=DEFAULT_DB_ALIAS, exclude=[], user_base_manager=False, use_natural_keys=False)
|
||||
return result
|
||||
|
||||
|
||||
class DirectoryCopy(BackupManagerBase):
|
||||
label = _(u'Directory copy')
|
||||
class ElementBackupFile(ElementBackupBase):
|
||||
label = _(u'File copy')
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
def __init__(self, storage_class, filepath):
|
||||
self.storage_class = storage_class
|
||||
self.filepath = filepath
|
||||
|
||||
def info(self):
|
||||
return self.path
|
||||
return _(u'%s from %s') % (self.filepath, self.storage_class)
|
||||
|
||||
def backup(self):
|
||||
"""
|
||||
Fetch a file specified by filepath from the Django storage class
|
||||
and return a file like object
|
||||
"""
|
||||
return None
|
||||
|
||||
|
||||
class AppBackup(object):
|
||||
_registry = {}
|
||||
@@ -59,25 +92,27 @@ class AppBackup(object):
|
||||
def __init__(self, name, label, backup_managers):
|
||||
self.label = label
|
||||
self.name = name
|
||||
self.backup_managers = backup_managers
|
||||
self.backup_managers = [manager.link(self) for manager in backup_managers]
|
||||
self.state = self.__class__.STATE_IDLE
|
||||
self.__class__._registry[name] = self
|
||||
|
||||
@property
|
||||
def info(self):
|
||||
results = []
|
||||
for manager in self.backup_managers:
|
||||
results.append(u'%s - %s' % (manager, manager.info() or _(u'Nothing')))
|
||||
return u', '.join(results)
|
||||
|
||||
def backup(self, storage_module=None):
|
||||
def backup(self, storage_module, *args, **kwargs):
|
||||
self.state = self.__class__.STATE_BACKING_UP
|
||||
# call storage_module
|
||||
for manager in self.backup_managers:
|
||||
result = manager.backup()
|
||||
storage_module.backup(result)
|
||||
self.state = self.__class__.STATE_IDLE
|
||||
|
||||
def restore(self, storage_module=None):
|
||||
self.state = self.__class__.STATE_RESTORING
|
||||
# call storage_module
|
||||
for manager in self.backup_managers:
|
||||
manager.restore(storage_module.restore())
|
||||
self.state = self.__class__.STATE_IDLE
|
||||
|
||||
def __unicode__(self):
|
||||
@@ -85,15 +120,55 @@ class AppBackup(object):
|
||||
|
||||
|
||||
class StorageModuleBase(object):
|
||||
_registry = {}
|
||||
#_registry = {}
|
||||
_registry = []
|
||||
|
||||
REALM_LOCAL = 'local'
|
||||
REALM_REMOTE = 'remote'
|
||||
|
||||
REALM_CHOICES = (
|
||||
(REALM_LOCAL, _(u'local')),
|
||||
(REALM_REMOTE, _(u'remote')),
|
||||
)
|
||||
|
||||
# TODO: register subclasses of StorageModuleBase
|
||||
# do not register instances
|
||||
#def __new__(cls, *args, **kwargs):
|
||||
# print "NEW"
|
||||
|
||||
def __init__(self, name, label):
|
||||
self.label = label
|
||||
self.name = name
|
||||
self.__class__._registry[name] = self
|
||||
|
||||
def backup(self, *args, **kwargs):
|
||||
@classmethod
|
||||
def register(cls, klass):
|
||||
cls._registry.append(klass)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def backup(self, data):
|
||||
raise NotImplemented
|
||||
|
||||
def restore(self, *args, **kwargs):
|
||||
def restore(self):
|
||||
"""
|
||||
Must return data or a file like object
|
||||
"""
|
||||
raise NotImplemented
|
||||
|
||||
|
||||
class TestStorageModule(StorageModuleBase):
|
||||
label = _(u'Test storage module')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.backup_path = kwargs.pop('backup_path', None)
|
||||
self.restore_path = kwargs.pop('restore_path', None)
|
||||
return super(TestStorageModule, self).__init__(*args, **kwargs)
|
||||
|
||||
def backup(self, data):
|
||||
print '***** received data'
|
||||
print data
|
||||
print '***** saving to path: %s' % self.backup_path
|
||||
|
||||
def restore(self):-
|
||||
print 'restore from path: %s' % self.restore_path
|
||||
return 'sample_data'
|
||||
|
||||
# TODO: get rid of register and try to register on subclassing
|
||||
StorageModuleBase.register(TestStorageModule)
|
||||
|
||||
Reference in New Issue
Block a user