ClientRuleService.update()   D
last analyzed

Complexity

Conditions 10

Size

Total Lines 51

Duplication

Lines 51
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
dl 51
loc 51
ccs 0
cts 21
cp 0
rs 4.2352
c 0
b 0
f 0
cc 10
crap 110

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 ClientRuleService.update() 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
from plugin.api.core.base import Service, expose
2
from plugin.managers.client import ClientManager
3
from plugin.managers.client_rule import ClientRuleManager
4
5
import logging
6
7
log = logging.getLogger(__name__)
8
9
10
class ClientService(Service):
11
    __key__ = 'session.client'
12
13
    @expose
14
    def list(self, full=False):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
15
        return [
16
            client.to_json(full=full)
17
            for client in ClientManager.get.all()
18
        ]
19
20
21 View Code Duplication
class ClientRuleService(Service):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
22
    __key__ = 'session.client.rule'
23
24
    @expose
25
    def list(self, full=False):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
26
        return [
27
            rule.to_json(full=full)
28
            for rule in ClientRuleManager.get.all()
29
        ]
30
31
    @expose
32
    def update(self, current, full=False):
0 ignored issues
show
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
33
        result = []
34
35
        # Build array of current ids
36
        current_ids = [
37
            r.get('id')
38
            for r in current
39
            if r.get('id') is not None
40
        ]
41
42
        # Delete rules
43
        deleted_rules = [
44
            rule
45
            for rule in ClientRuleManager.get.all()
46
            if rule.id not in current_ids
47
        ]
48
49
        for rule in deleted_rules:
50
            rule.delete_instance()
51
52
            log.debug('Deleted %r', rule)
53
54
        # Create/Update client rules
55
        for r in current:
56
            id = r.pop('id', None)
0 ignored issues
show
Bug Best Practice introduced by
This seems to re-define the built-in id.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
57
58
            if id is None:
59
                # Create new rule
60
                rule = ClientRuleManager.create(**r)
61
62
                log.debug('Created %r', rule)
63
                result.append(rule)
64
                continue
65
66
            # Retrieve existing rule
67
            rule = ClientRuleManager.get(id=id)
68
69
            # Update rule
70
            ClientRuleManager.update(rule, r)
71
72
            log.debug('Updated %r', rule)
73
            result.append(rule)
74
75
        # Ensure result is sorted by priority
76
        result = sorted(result, key=lambda item: item.priority)
77
78
        # Convert rules to serializable dictionaries
79
        return [
80
            r.to_json(full=full)
81
            for r in result
82
        ]
83