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

BackupInfoScanner.__scan_for_backups()   B

Complexity

Conditions 6

Size

Total Lines 25
Code Lines 17

Duplication

Lines 25
Ratio 100 %

Importance

Changes 0
Metric Value
cc 6
eloc 17
nop 1
dl 25
loc 25
rs 8.6166
c 0
b 0
f 0
1
"""
2
BackupPC Clone
3
"""
4
import os
5
import re
6
from typing import Optional, Dict, List
7
8
from backuppc_clone.Config import Config
9
from backuppc_clone.DataLayer import DataLayer
10
from backuppc_clone.style.BackupPcCloneStyle import BackupPcCloneStyle
11
12
13 View Code Duplication
class BackupInfoScanner:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
14
    """
15
    Class for retrieving information about backups.
16
    """
17
18
    # ------------------------------------------------------------------------------------------------------------------
19
    def __init__(self, io: BackupPcCloneStyle):
20
        """
21
        Object constructor.
22
23
        :param BackupPcCloneStyle io: The output style.
24
        """
25
26
        self.__io: BackupPcCloneStyle = io
27
        """
28
        The output style.
29
        """
30
31
    # ------------------------------------------------------------------------------------------------------------------
32
    @staticmethod
33
    def get_backup_info(backup_dir: str, param_name: str) -> Optional[str]:
34
        """
35
        Extracts info about a backup from file backupInfo.
36
37
        :param str backup_dir: The path to the host backup.
38
        :param str param_name: The name of the info parameter.
39
40
        :rtype: str|None
41
        """
42
        ret = None
43
44
        path = os.path.join(backup_dir, 'backupInfo')
45
        if os.path.isfile(path):
46
            with open(path) as file:
47
                content = file.read()
48
                result = re.search(r"'{}' => '(.*?)'".format(param_name), content)
49
                if result:
50
                    ret = result.group(1)
51
52
        if not ret:
53
            ret = None
54
55
        return ret
56
57
    # ------------------------------------------------------------------------------------------------------------------
58
    def __scan_for_backups(self) -> List[Dict]:
59
        """
60
        Scans for host backups and returns the metadata of the host backups.
61
62
        :rtype: list[dict]
63
        """
64
        pc_dir_original = Config.instance.pc_dir_original
65
66
        self.__io.writeln(' Scanning <fso>{}</fso>'.format(pc_dir_original))
67
68
        backups = []
69
        for host in os.scandir(pc_dir_original):
70
            if host.is_dir():
71
                host_dir = os.path.join(Config.instance.pc_dir_original, host.name)
72
                for backup in os.scandir(host_dir):
73
                    if backup.is_dir() and re.match(r'^\d+$', backup.name):
74
                        backup_dir = os.path.join(host_dir, backup.name)
75
                        backups.append({'bob_host':     host.name,
76
                                        'bob_number':   int(backup.name),
77
                                        'bob_end_time': self.get_backup_info(backup_dir, 'endTime'),
78
                                        'bob_version':  self.get_backup_info(backup_dir, 'version'),
79
                                        'bob_level':    self.get_backup_info(backup_dir, 'level'),
80
                                        'bob_type':     self.get_backup_info(backup_dir, 'type')})
81
82
        return backups
83
84
    # ------------------------------------------------------------------------------------------------------------------
85
    def __import_backups(self, backups: List[Dict]) -> None:
86
        """
87
        Imports the original host backups info into the SQLite database.
88
89
        :param list[dict] backups: The metadata of the original backups.
90
        """
91
        DataLayer.instance.original_backup_truncate()
92
93
        for backup in backups:
94
            DataLayer.instance.original_backup_insert(backup['bob_host'],
95
                                                      backup['bob_number'],
96
                                                      backup['bob_end_time'],
97
                                                      backup['bob_version'],
98
                                                      backup['bob_level'],
99
                                                      backup['bob_type'])
100
101
        stats = DataLayer.instance.original_backup_get_stats()
102
103
        self.__io.writeln('')
104
        self.__io.writeln(' Found {} hosts and {} backups'.format(stats['#hosts'], stats['#backups']))
105
        self.__io.writeln('')
106
107
    # ------------------------------------------------------------------------------------------------------------------
108
    def scan(self) -> None:
109
        """
110
        Scans information about backups.
111
        """
112
        backups = self.__scan_for_backups()
113
        self.__import_backups(backups)
114
115
# ----------------------------------------------------------------------------------------------------------------------
116