Passed
Push — master ( ba6342...71f198 )
by P.R.
07:12
created

BaseCommand._handle_command()   A

Complexity

Conditions 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 8
Ratio 100 %

Importance

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