backuppc_clone.helper.PoolScanner   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 122
Duplicated Lines 92.62 %

Importance

Changes 0
Metric Value
eloc 48
dl 113
loc 122
rs 10
c 0
b 0
f 0
wmc 15

6 Methods

Rating   Name   Duplication   Size   Complexity  
A PoolScanner.scan_directory() 17 17 4
A PoolScanner.__get_number_of_pool_dirs() 14 14 3
A PoolScanner.__scan_directory_helper1() 20 20 1
A PoolScanner.count() 6 6 1
A PoolScanner.__scan_directory_helper2() 21 21 5
A PoolScanner.__init__() 18 18 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
import csv
2
import os
3
from typing import List, Optional
4
5
from backuppc_clone.ProgressBar import ProgressBar
6
from backuppc_clone.style.BackupPcCloneStyle import BackupPcCloneStyle
7
8
9 View Code Duplication
class PoolScanner:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
10
    """
11
    Helper class for scanning pool and backup directories.
12
    """
13
    # ------------------------------------------------------------------------------------------------------------------
14
    def __init__(self, io: BackupPcCloneStyle):
15
        """
16
        Object constructor.
17
18
        @param BackupPcCloneStyle io: The output style.
19
        """
20
        self.__io: BackupPcCloneStyle = io
21
        """
22
        The output style.
23
        """
24
25
        self.__count: int = 0
26
        """
27
        The file count.
28
        """
29
30
        self.__progress: Optional[ProgressBar] = None
31
        """
32
        The progress bar.
33
        """
34
35
    # ------------------------------------------------------------------------------------------------------------------
36
    @property
37
    def count(self) -> int:
38
        """
39
        Returns the number of found files.
40
        """
41
        return self.__count
42
43
    # ------------------------------------------------------------------------------------------------------------------
44
    @staticmethod
45
    def __get_number_of_pool_dirs(dir_name: str) -> int:
46
        """
47
        Returns the (estimate) number of directories in a pool.
48
49
        @param str dir_name: The name of the directory.
50
51
        :rtype: int
52
        """
53
        if os.path.isdir(os.path.join(dir_name, '0')) and \
54
                os.path.isdir(os.path.join(dir_name, 'f')):
55
            return 1 + 16 + 16 * 16 + 16 * 16 * 16
56
57
        return 1
58
59
    # ------------------------------------------------------------------------------------------------------------------
60
    def __scan_directory_helper2(self, parent_dir: str, dir_name: str, csv_writer: csv.writer) -> None:
61
        """
62
        Scans recursively a list of directories and stores filenames and directories in CSV format.
63
64
        @param str parent_dir: The name of the parent directory.
65
        @param str dir_name: The name of the directory.
66
        @param csv.writer csv_writer: The CSV writer.
67
        """
68
        sub_dir_names = []
69
        for entry in os.scandir(os.path.join(parent_dir, dir_name)):
70
            if entry.is_file():
71
                self.__count += 1
72
                csv_writer.writerow((entry.inode(), dir_name, entry.name))
73
74
            elif entry.is_dir():
75
                sub_dir_names.append(entry.name)
76
77
        for sub_dir_name in sub_dir_names:
78
            self.__scan_directory_helper2(parent_dir, os.path.join(dir_name, sub_dir_name), csv_writer)
79
80
        self.__progress.advance()
81
82
    # ------------------------------------------------------------------------------------------------------------------
83
    def __scan_directory_helper1(self, parent_dir: str, dir_name: str, csv_writer: csv.writer) -> None:
84
        """
85
        Scans recursively a list of directories and stores filenames and directories in CSV format.
86
87
        @param str parent_dir: The name of the parent directory.
88
        @param str dir_name: The name of the directory.
89
        @param csv.writer csv_writer: The CSV writer.
90
        """
91
        dir_target = os.path.join(parent_dir, dir_name)
92
93
        self.__io.writeln(' Scanning <fso>{}</fso>'.format(dir_target))
94
        self.__io.writeln('')
95
96
        dir_count = self.__get_number_of_pool_dirs(dir_target)
97
        self.__progress = ProgressBar(self.__io, dir_count)
98
99
        self.__scan_directory_helper2(parent_dir, dir_name, csv_writer)
100
101
        self.__progress.finish()
102
        self.__io.writeln('')
103
104
    # ------------------------------------------------------------------------------------------------------------------
105
    def scan_directory(self, parent_dir: str, dir_names: List[str], csv_filename: str) -> None:
106
        """
107
        Scans recursively a list of directories and stores filenames and directories in CSV format.
108
109
        @param str parent_dir: The name of the parent dir.
110
        @param list[str] dir_names: The list of directories to scan.
111
        @param str csv_filename: The filename of the CSV file.
112
        """
113
        self.__count = 0
114
115
        with open(csv_filename, 'w') as csv_file:
116
            csv_writer = csv.writer(csv_file)
117
            if not dir_names:
118
                self.__scan_directory_helper1(parent_dir, '', csv_writer)
119
            else:
120
                for dir_name in dir_names:
121
                    self.__scan_directory_helper1(parent_dir, dir_name, csv_writer)
122
123
# ----------------------------------------------------------------------------------------------------------------------
124