1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
"""
Restore media files.
"""
import tarfile
from ... import utils
from ...storage import get_storage, get_storage_class
from ._base import BaseDbBackupCommand, make_option
class Command(BaseDbBackupCommand):
help = """Restore a media backup from storage, encrypted and/or
compressed."""
content_type = "media"
option_list = (
make_option(
"-i",
"--input-filename",
action="store",
help="Specify filename to backup from",
),
make_option(
"-I", "--input-path", help="Specify path on local filesystem to backup from"
),
make_option(
"-s",
"--servername",
help="If backup file is not specified, filter the existing ones with the "
"given servername",
),
make_option(
"-e",
"--decrypt",
default=False,
action="store_true",
help="Decrypt data before restoring",
),
make_option(
"-p", "--passphrase", default=None, help="Passphrase for decrypt file"
),
make_option(
"-z",
"--uncompress",
action="store_true",
help="Uncompress gzip data before restoring",
),
make_option(
"-r", "--replace", help="Replace existing files", action="store_true"
),
)
def handle(self, *args, **options):
"""Django command handler."""
self.verbosity = int(options.get("verbosity"))
self.quiet = options.get("quiet")
self._set_logger_level()
self.servername = options.get("servername")
self.decrypt = options.get("decrypt")
self.uncompress = options.get("uncompress")
self.filename = options.get("input_filename")
self.path = options.get("input_path")
self.replace = options.get("replace")
self.passphrase = options.get("passphrase")
self.interactive = options.get("interactive")
self.storage = get_storage()
self.media_storage = get_storage_class()()
self._restore_backup()
def _upload_file(self, name, media_file):
if self.media_storage.exists(name):
if not self.replace:
return
self.media_storage.delete(name)
self.logger.info("%s deleted", name)
self.media_storage.save(name, media_file)
self.logger.info("%s uploaded", name)
def _restore_backup(self):
self.logger.info("Restoring backup for media files")
input_filename, input_file = self._get_backup_file(servername=self.servername)
self.logger.info("Restoring: %s", input_filename)
if self.decrypt:
unencrypted_file, input_filename = utils.unencrypt_file(
input_file, input_filename, self.passphrase
)
input_file.close()
input_file = unencrypted_file
self.logger.debug("Backup size: %s", utils.handle_size(input_file))
if self.interactive:
self._ask_confirmation()
input_file.seek(0)
tar_file = (
tarfile.open(fileobj=input_file, mode="r:gz")
if self.uncompress
else tarfile.open(fileobj=input_file, mode="r:")
)
# 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._upload_file(name, media_file)
|