Skip to content

Commit

Permalink
Backup & restore media file 1 by 1
Browse files Browse the repository at this point in the history
  • Loading branch information
ZuluPro committed Jul 4, 2016
1 parent 8bd62c3 commit 1a91211
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 9 deletions.
22 changes: 19 additions & 3 deletions dbbackup/management/commands/mediabackup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"""
from __future__ import (absolute_import, division,
print_function, unicode_literals)
import sys
import os
import tarfile
from optparse import make_option

from django.core.management.base import CommandError
from django.conf import settings as dj_settings
from django.core.files.storage import get_storage_class

from ._base import BaseDbBackupCommand
from ... import utils
Expand Down Expand Up @@ -39,6 +39,7 @@ def handle(self, *args, **options):
self.compress = not options.get('no_compress')
self.servername = options.get('servername') or settings.HOSTNAME
try:
self.media_storage = get_storage_class()()
self.storage = BaseStorage.storage_factory()
self.backup_mediafiles()
if options.get('clean'):
Expand Down Expand Up @@ -67,12 +68,27 @@ def backup_mediafiles(self):
self.logger.info("Writing file to %s" % filename)
self.storage.write_file(outputfile, filename)

def _explore_storage(self):
"""Generator of a all files contained in media storage."""
path = ''
dirs = [path]
while dirs:
path = dirs.pop()
subdirs, files = self.media_storage.listdir(path)
for media_filename in files:
yield os.path.join(path, media_filename)
dirs.extend([os.path.join(path, subdir) for subdir in subdirs])

def _create_tar(self, name):
"""Create TAR file."""
fileobj = utils.create_spooled_temporary_file()
tar_file = tarfile.open(name=name, fileobj=fileobj, mode='w:gz') \
if self.compress \
else tarfile.open(name=name, fileobj=fileobj, mode='w')
tar_file.add(dj_settings.MEDIA_ROOT)
for media_filename in self._explore_storage():
tarinfo = tarfile.TarInfo(media_filename)
media_file = self.media_storage.open(media_filename)
tar_file.addfile(tarinfo, media_file)
# Close the TAR for writing
tar_file.close()
return fileobj
Expand Down
15 changes: 11 additions & 4 deletions dbbackup/management/commands/mediarestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@

from django.core.management.base import CommandError
from django.utils import six
from django.conf import settings
from django.core.files.storage import get_storage_class

from ._base import BaseDbBackupCommand
from ...storage.base import BaseStorage, StorageError
from ...storage.filesystem_storage import Storage as FileSystemStorage
from ... import utils

input = raw_input if six.PY2 else input # @ReservedAssignment
Expand Down Expand Up @@ -39,6 +38,7 @@ def handle(self, *args, **options):
self.passphrase = options.get('passphrase')
self.interactive = options.get('interactive')
self.storage = BaseStorage.storage_factory()
self.media_storage = get_storage_class()()
self._restore_backup()

def _get_backup_file(self):
Expand Down Expand Up @@ -83,5 +83,12 @@ def _restore_backup(self):
tar_file = tarfile.open(fileobj=input_file, mode='r:gz') \
if self.uncompress \
else tarfile.open(fileobj=input_file, mode='r:')
# tar_file.extractall(path=settings.MEDIA_ROOT)
tar_file.extractall(path='/')
# Restore file 1 by 1
for media_file_info in tar_file:
if media_file_info.path == 'media':
continue # Don't copy root directory
media_file = tar_file.extractfile(media_file_info)
if media_file is None:
continue # Skip directories
name = media_file_info.path.replace('media/', '')
self.media_storage.save(name, media_file)
2 changes: 2 additions & 0 deletions dbbackup/tests/test_mediabackup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
from mock import patch
from django.test import TestCase
from django.core.files.storage import get_storage_class
from dbbackup.management.commands.mediabackup import Command as DbbackupCommand
from dbbackup.tests.utils import (FakeStorage, DEV_NULL, HANDLED_FILES,
add_public_gpg)
Expand All @@ -17,6 +18,7 @@ def setUp(self):
self.command.stdout = DEV_NULL
self.command.compress = False
self.command.encrypt = False
self.command.media_storage = get_storage_class()()

def test_func(self):
self.command.backup_mediafiles()
Expand Down
4 changes: 2 additions & 2 deletions functional.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ test_db_results () {
}

make_media_test () {
touch ${MEDIA_ROOT}foo
echo foo > ${MEDIA_ROOT}foo
mkdir -p ${MEDIA_ROOT}bar
touch ${MEDIA_ROOT}bar/ham
echo ham > ${MEDIA_ROOT}bar/ham

$PYTHON runtests.py mediabackup --no-compress

Expand Down

0 comments on commit 1a91211

Please sign in to comment.