Test Failed
Push — master ( 8192fe...83ef1f )
by Steffen
02:25
created

saucenao.files.filter.Filter.apply()   F

Complexity

Conditions 19

Size

Total Lines 60
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 60
rs 3.1212
c 0
b 0
f 0
cc 19
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like saucenao.files.filter.Filter.apply() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#!/usr/bin/python
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
2
# -*- coding: utf-8 -*-
3
import datetime
4
import os
5
import re
6
from pathlib import Path
7
from stat import ST_CTIME, ST_MTIME, ST_SIZE
8
from typing import Generator
0 ignored issues
show
introduced by
Unable to import 'typing'
Loading history...
Unused Code introduced by
Unused Generator imported from typing
Loading history...
9
10
from saucenao.files.constraint import Constraint
0 ignored issues
show
Unused Code introduced by
Unused Constraint imported from saucenao.files.constraint
Loading history...
11
12
13
class Filter:
0 ignored issues
show
Unused Code introduced by
The variable __class__ seems to be unused.
Loading history...
14
    """
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
15
    Filter to apply constraints for multiple metadata entries of the files.
16
    Obviously the files have to exist or they'll automatically get removed.
17
    Returns a generator object
18
    """
19
20
    def __init__(self, assert_is_folder=False, assert_is_file=False, creation_date=None, modified_date=None, name=None,
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (119/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
best-practice introduced by
Too many arguments (8/5)
Loading history...
21
                 file_type=None, size=None):
22
        """Initializing function
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
23
24
        :type assert_is_folder: bool
25
        :type assert_is_file: bool
26
        :type creation_date: Constraint
27
        :type modified_date: Constraint
28
        :type name: Constraint
29
        :type file_type: Constraint
30
        :type size: Constraint
31
        """
32
        self.filter_assert_is_folder = assert_is_folder
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
33
        self.filter_assert_is_file = assert_is_file
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
34
        self.filter_creation_date = creation_date
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
35
        self.filter_modified_date = modified_date
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
36
        self.filter_name = name
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
37
        self.filter_file_type = file_type
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
38
        self.filter_file_size = size
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
39
40
    @staticmethod
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
41
    def _get_timestamp_from_datestring(date_string):
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
42
        """Convert the given date string to timestamp
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
43
44
        :param date_string:
45
        :return:
46
        """
47
        if re.match('\d+.\d+.\d+ \d+:\d+:\d+', date_string):
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
Bug introduced by
A suspicious escape sequence \d was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
48
            return datetime.datetime.strptime(date_string, "%d.%m.%Y %H:%M:%S").timestamp()
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (91/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
49
        elif re.match('\d+.\d+.\d+ \d+:\d+', date_string):
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
Bug introduced by
A suspicious escape sequence \d was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
50
            return datetime.datetime.strptime(date_string, "%d.%m.%Y %H:%M").timestamp()
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (88/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
51
        elif re.match('\d+.\d+.\d+', date_string):
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
Bug introduced by
A suspicious escape sequence \d was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
52
            return datetime.datetime.strptime(date_string, "%d.%m.%Y").timestamp()
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
53
        else:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
54
            raise AttributeError("The date doesn't fit the format: d.m.Y[ H:M[:S]]")
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (84/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
55
56
    def apply(self, directory='', file_system_objects=None):
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
57
        """Apply the filter values to the given FSOs(File System Objects)
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
58
59
        :type directory: str
60
        :type file_system_objects: list|tuple|Generator
61
        :return:
62
        """
63
        if file_system_objects is None:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
64
            if directory:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
65
                file_system_objects = os.listdir(directory)
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
66
            else:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
67
                file_system_objects = []
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
68
69
        for file_system_object in file_system_objects:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
70
            abs_path = os.path.join(directory, file_system_object)
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
71
72
            # check if the FSO exists, else we can't access the metadata
73
            if not os.path.exists(abs_path):
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
74
                continue
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
75
76
            # check if the FSO is a file
77
            if self.filter_assert_is_file and not os.path.isfile(abs_path):
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
78
                continue
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
79
80
            # check if the FSO is a folder
81
            if self.filter_assert_is_folder and not os.path.isdir(abs_path):
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
82
                continue
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
83
84
            file_stats = os.stat(abs_path)
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
85
86
            # check if the FSO creation date matches the constraint
87
            if self.filter_creation_date:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
88
                creation_time = file_stats[ST_CTIME]
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
89
                expected_creation_time = self._get_timestamp_from_datestring(self.filter_creation_date.value)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (109/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
90
                if not self.filter_creation_date.cmp_func(creation_time, expected_creation_time):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (97/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
91
                    continue
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
92
93
            # check if the FSO modification date matches the constraint
94
            if self.filter_modified_date:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
95
                modified_time = file_stats[ST_MTIME]
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
96
                expected_modified_time = self._get_timestamp_from_datestring(self.filter_modified_date.value)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (109/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
97
                if not self.filter_modified_date.cmp_func(modified_time, expected_modified_time):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (97/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
98
                    continue
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
99
100
            # check if the FSO name matches the constraint
101
            if self.filter_name:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
102
                if not self.filter_name.cmp_func(file_system_object, self.filter_name.value):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (93/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
103
                    continue
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
104
105
            # check if the FSO suffix matches the constraint
106
            if self.filter_file_type:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
107
                if not self.filter_file_type.cmp_func(Path(abs_path).suffix, self.filter_file_type.value):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
108
                    continue
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
109
110
            # check if the FSO size matches the constraint
111
            if self.filter_file_size:
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
112
                if not self.filter_file_size.cmp_func(file_stats[ST_SIZE], self.filter_file_size.value):
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (104/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
113
                    continue
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
114
115
            yield file_system_object
0 ignored issues
show
Coding Style introduced by
Found indentation with spaces instead of tabs
Loading history...
116