File: _base.py

package info (click to toggle)
django-dbbackup 4.2.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 512 kB
  • sloc: python: 3,767; makefile: 7
file content (145 lines) | stat: -rw-r--r-- 4,558 bytes parent folder | download | duplicates (2)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
"""
Abstract Command.
"""

import logging
import sys
from optparse import make_option as optparse_make_option
from shutil import copyfileobj

import django
from django.core.management.base import BaseCommand, CommandError

from ...storage import StorageError

USELESS_ARGS = ("callback", "callback_args", "callback_kwargs", "metavar")
TYPES = {
    "string": str,
    "int": int,
    "long": int,
    "float": float,
    "complex": complex,
    "choice": list,
}
LOGGING_VERBOSITY = {
    0: logging.WARN,
    1: logging.INFO,
    2: logging.DEBUG,
    3: logging.DEBUG,
}


def make_option(*args, **kwargs):
    return args, kwargs


class BaseDbBackupCommand(BaseCommand):
    """
    Base command class used for create all dbbackup command.
    """

    base_option_list = (
        make_option(
            "--noinput",
            action="store_false",
            dest="interactive",
            default=True,
            help="Tells Django to NOT prompt the user for input of any kind.",
        ),
        make_option(
            "-q",
            "--quiet",
            action="store_true",
            default=False,
            help="Tells Django to NOT output other text than errors.",
        ),
    )
    option_list = ()

    verbosity = 1
    quiet = False
    logger = logging.getLogger("dbbackup.command")

    def __init__(self, *args, **kwargs):
        self.option_list = self.base_option_list + self.option_list
        if django.VERSION < (1, 10):
            options = tuple(
                optparse_make_option(*_args, **_kwargs)
                for _args, _kwargs in self.option_list
            )

            self.option_list = options + BaseCommand.option_list
        super().__init__(*args, **kwargs)

    def add_arguments(self, parser):
        for args, kwargs in self.option_list:
            kwargs = {
                k: v
                for k, v in kwargs.items()
                if not k.startswith("_") and k not in USELESS_ARGS
            }
            parser.add_argument(*args, **kwargs)

    def _set_logger_level(self):
        level = 60 if self.quiet else LOGGING_VERBOSITY[int(self.verbosity)]
        self.logger.setLevel(level)

    def _ask_confirmation(self):
        answer = input("Are you sure you want to continue? [Y/n] ")
        if answer.lower().startswith("n"):
            self.logger.info("Quitting")
            sys.exit(0)

    def read_from_storage(self, path):
        return self.storage.read_file(path)

    def write_to_storage(self, file, path):
        self.logger.info("Writing file to %s", path)
        self.storage.write_file(file, path)

    def read_local_file(self, path):
        """Open file in read mode on local filesystem."""
        return open(path, "rb")

    def write_local_file(self, outputfile, path):
        """Write file to the desired path."""
        self.logger.info("Writing file to %s", path)
        outputfile.seek(0)
        with open(path, "wb") as fd:
            copyfileobj(outputfile, fd)

    def _get_backup_file(self, database=None, servername=None):
        if self.path:
            input_filename = self.path
            input_file = self.read_local_file(self.path)
        else:
            if self.filename:
                input_filename = self.filename
            # Fetch the latest backup if filepath not specified
            else:
                self.logger.info("Finding latest backup")
                try:
                    input_filename = self.storage.get_latest_backup(
                        encrypted=self.decrypt,
                        compressed=self.uncompress,
                        content_type=self.content_type,
                        database=database,
                        servername=servername,
                    )
                except StorageError as err:
                    raise CommandError(err.args[0]) from err
            input_file = self.read_from_storage(input_filename)
        return input_filename, input_file

    def _cleanup_old_backups(self, database=None, servername=None):
        """
        Cleanup old backups, keeping the number of backups specified by
        DBBACKUP_CLEANUP_KEEP.
        """
        self.storage.clean_old_backups(
            encrypted=self.encrypt,
            compressed=self.compress,
            content_type=self.content_type,
            database=database,
            servername=servername,
        )