Coverage for src/rsnapshot_docker_compose_backup/config/default_config.py: 42%

65 statements  

« prev     ^ index     » next       coverage.py v7.5.4, created at 2024-07-07 01:03 +0200

1import configparser 

2from importlib import resources 

3import os 

4from pathlib import Path 

5import re 

6from typing import Dict, Optional 

7 

8from rsnapshot_docker_compose_backup import global_values 

9from rsnapshot_docker_compose_backup.config.abstract_config import AbstractConfig 

10from rsnapshot_docker_compose_backup.utils.regex import CaseInsensitiveRe 

11 

12 

13class DefaultConfig(AbstractConfig): 

14 __instance: Optional["DefaultConfig"] = None 

15 defaultConfig = "default_config" 

16 defaultConfigName = "backup.ini" 

17 settingsSection = "settings" 

18 actionSection = "actions" 

19 

20 # Settings 

21 settings = { 

22 "logTime": True, 

23 "onlyRunning": True, 

24 } 

25 

26 actions: Dict[str, Dict[str, str]] = {} 

27 

28 @staticmethod 

29 def get_instance() -> "DefaultConfig": 

30 # print(f"Get Default Config, {DefaultConfig.__instance}") 

31 if DefaultConfig.__instance is None: 

32 DefaultConfig.__instance = DefaultConfig() 

33 return DefaultConfig.__instance 

34 

35 @staticmethod 

36 def reset() -> None: 

37 DefaultConfig.__instance = None 

38 

39 def __init__(self) -> None: 

40 if DefaultConfig.__instance is not None: 

41 raise Exception("This class is a singleton!") 

42 if global_values.config_file is not None: 

43 self.filename: Path = global_values.config_file 

44 else: 

45 self.filename = global_values.folder / Path( 

46 self.defaultConfigName, 

47 ) 

48 if not os.path.isfile(self.filename): 

49 self._create_default_config() 

50 super().__init__(self.filename, self.defaultConfig) 

51 self._load_actions() 

52 self._load_settings() 

53 

54 def _create_default_config(self) -> None: 

55 with resources.open_text( 

56 "rsnapshot_docker_compose_backup.config", "backup.ini" 

57 ) as default_backup_ini: 

58 default_config = default_backup_ini.read().format( 

59 default_config=self.defaultConfig, 

60 default_config_actions=self.actions_name(self.defaultConfig), 

61 default_config_vars=self.vars_name(self.defaultConfig), 

62 actions=self.actionSection, 

63 default_config_settings=self.settingsSection, 

64 ) 

65 

66 with open(self.filename, "w", encoding="UTF-8") as config_file: 

67 config_file.write(default_config) 

68 

69 def get_step(self, step: str) -> str: 

70 return self.backup_steps.get(step, "") 

71 

72 def _load_actions(self) -> None: 

73 config_file = configparser.ConfigParser(allow_no_value=True) 

74 config_file.SECTCRE = CaseInsensitiveRe( 

75 re.compile(r"\[ *(?P<header>[^]]+?) *]") 

76 ) # type: ignore 

77 config_file.read(self.filename) 

78 for section in config_file.sections(): 

79 if section.startswith(self.actionSection): 

80 action_name = section[len(self.actionSection + ".") :] 

81 commands = {} 

82 for step in self.backup_steps: 

83 if config_file.has_option(section.lower(), step): 

84 commands[step] = config_file.get(section, step).strip() + "\n" 

85 if commands: 

86 self.actions[action_name] = commands 

87 

88 def _load_settings(self) -> None: 

89 config_file = configparser.ConfigParser(allow_no_value=True) 

90 config_file.SECTCRE = CaseInsensitiveRe( 

91 re.compile(r"\[ *(?P<header>[^]]+?) *]") 

92 ) # type: ignore 

93 config_file.read(self.filename) 

94 # print(f"filename {self.filename}") 

95 for setting in self.settings: 

96 if config_file.has_option(self.settingsSection, setting): 

97 self.settings[setting] = config_file.getboolean( 

98 self.settingsSection, setting 

99 ) 

100 # print(f"{setting} is set to {self.settings[setting]}") 

101 

102 def get_action(self, name: str) -> Dict[str, str]: 

103 return self.actions[name]