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
Duplication
introduced
by
![]() |
|||
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 |