Issues (23)

backuppc_clone/command/BaseCommand.py (1 issue)

1
import abc
2
import configparser
3
import os
4
from typing import Optional
5
6
from cleo import Command
7
8
from backuppc_clone.Config import Config
9
from backuppc_clone.DataLayer import DataLayer
10
from backuppc_clone.exception.BackupPcCloneException import BackupPcCloneException
11
from backuppc_clone.style.BackupPcCloneStyle import BackupPcCloneStyle
12
13
14 View Code Duplication
class BaseCommand(Command, metaclass=abc.ABCMeta):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
15
    """
16
    Abstract parent command for (almost) all BackupPC Clone commands.
17
    """
18
19
    # ------------------------------------------------------------------------------------------------------------------
20
    def __init__(self, name: Optional[str] = None) -> None:
21
        """
22
        Object constructor.
23
        """
24
        Command.__init__(self, name)
25
26
        self._io: Optional[BackupPcCloneStyle] = None
27
        """
28
        The output style.
29
        """
30
31
    # ------------------------------------------------------------------------------------------------------------------
32
    def __validate_user(self) -> None:
33
        """
34
        Validates that this command is not run under root.
35
        """
36
        self._io.log_very_verbose('testing user')
37
38
        if os.getuid() == 0:
39
            raise BackupPcCloneException('Will not run this command under root')
40
41
    # ------------------------------------------------------------------------------------------------------------------
42
    def __validate_config(self) -> None:
43
        """
44
        Validates the configuration files.
45
        """
46
        if self.input.has_argument('clone.cfg'):
47
            self._io.log_very_verbose('validation configuration')
48
49
            config_filename_clone = self.input.get_argument('clone.cfg')
50
            config_clone = configparser.ConfigParser()
51
            config_clone.read(config_filename_clone)
52
53
            config_original = configparser.ConfigParser()
54
            config_original.read(config_clone['Original']['config'])
55
56
            if config_clone['Original']['name'] != config_original['BackupPC Clone']['name']:
57
                raise BackupPcCloneException(
58
                        'Clone {} is not a clone of original {}'.format(config_clone['Original']['name'],
59
                                                                        config_original['BackupPC Clone']['name']))
60
61
    # ------------------------------------------------------------------------------------------------------------------
62
    def ask(self, question: str, default: Optional[str] = None) -> Optional[str]:
63
        """
64
        Prompt the user for input.
65
66
        @param str question: The question to ask
67
        @param str|None default: The default value
68
69
        :rtype: str|None
70
        """
71
        if default is not None:
72
            question = question + ' [' + default + ']'
73
74
        answer = self._io.ask(question, default)
75
        if answer is None:
76
            answer = default
77
78
        return answer
79
80
    # ------------------------------------------------------------------------------------------------------------------
81
    def _init_singletons(self) -> None:
82
        """
83
        Initializes the singleton objects.
84
        """
85
        Config(self.argument('clone.cfg'))
86
        DataLayer(os.path.join(Config.instance.top_dir_clone, 'clone.db'))
87
88
    # ------------------------------------------------------------------------------------------------------------------
89
    @abc.abstractmethod
90
    def _handle_command(self) -> int:
91
        """
92
        Executes the command.
93
94
        :rtype: int
95
        """
96
        raise NotImplementedError()
97
98
    # ------------------------------------------------------------------------------------------------------------------
99
    def handle(self) -> int:
100
        """
101
        Executes the command.
102
        """
103
        try:
104
            self._io = BackupPcCloneStyle(self.input, self.output)
105
106
            self.__validate_user()
107
            self.__validate_config()
108
            self._init_singletons()
109
110
            return self._handle_command()
111
112
        except BackupPcCloneException as error:
113
            self._io.error(str(error))
114
            return -1
115
116
# ----------------------------------------------------------------------------------------------------------------------
117