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

backuppc_clone.helper.PoolScanner   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 127
Duplicated Lines 90.55 %

Importance

Changes 0
Metric Value
eloc 48
dl 115
loc 127
rs 10
c 0
b 0
f 0
wmc 15

6 Methods

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