ore.models.node_group   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 134
Duplicated Lines 40.3 %

Importance

Changes 0
Metric Value
wmc 18
eloc 92
dl 54
loc 134
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A NodeGroup.to_dict() 0 12 2
A NodeGroup.same_as() 0 14 5
B NodeGroup.get_property() 32 32 5
A NodeGroup.set_attr() 22 22 2
A NodeGroup.set_attrs() 0 9 2
A NodeGroup.to_json() 0 2 1

1 Function

Rating   Name   Duplication   Size   Complexity  
A graph_modify() 0 8 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 json
2
import datetime
3
import sys
4
import logging
5
6
from django.dispatch import receiver
7
from django.db.models.signals import post_save, pre_delete
8
from django.db import models
9
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
10
11
from ore.models import Node, Graph
12
from .notations import notations
13
14
logger = logging.getLogger('ore')
15
16
17
class NodeGroup(models.Model):
18
19
    class Meta:
20
        app_label = 'ore'
21
22
    client_id = models.BigIntegerField(default=-sys.maxsize)
23
    graph = models.ForeignKey(Graph, null=False, related_name='groups')
24
    nodes = models.ManyToManyField(Node)
25
    deleted = models.BooleanField(default=False)
26
27
    def to_dict(self, use_value_dict=False):
28
        if use_value_dict:
29
            prop_values = {prop.key: {'value': prop.value}
30
                           for prop in self.properties.filter(deleted=False)}
31
        else:
32
            prop_values = {
33
                prop.key: prop.value for prop in self.properties.filter(
34
                    deleted=False)}
35
36
        return {'id': self.client_id,
37
                'nodeIds': [node.client_id for node in self.nodes.all()],
38
                'properties': prop_values,
39
                }
40
41
    def to_json(self, use_value_dict=False):
42
        return json.dumps(self.to_dict(use_value_dict))
43
44 View Code Duplication
    def get_property(self, key, default=None):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
45
        try:
46
            return self.properties.get(key=key).get_value()
47
        except ObjectDoesNotExist:
48
            node_kind = self.nodes.all()[0].kind
49
            logger.debug(
50
                "Assuming node kind %s for node group properties" %
51
                node_kind)
52
            try:
53
                prop = notations.by_kind[
54
                    self.graph.kind]['nodes'][node_kind]['properties'][key]
55
                if prop is None:
56
                    logger.warning(
57
                        'Notation configuration has empty default for node property ' +
58
                        key)
59
                    result = default
60
                else:
61
                    result = prop['default']
62
                logger.debug(
63
                    'Node has no property "%s", using default "%s"' %
64
                    (key, str(result)))
65
                return result
66
            except KeyError:
67
                logger.debug(
68
                    'No default given in notation, using given default "%s" instead' %
69
                    default)
70
                return default
71
        except MultipleObjectsReturned:
72
            logger.error(
73
                "ERROR: Property %s in node group %u exists in multiple instances" %
74
                (key, self.pk))
75
            raise MultipleObjectsReturned()
76
77 View Code Duplication
    def set_attr(self, key, value):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
78
        """
79
        Method: set_attr
80
81
        Use this method to set a group's attribute. It looks in the group object and its related properties for an
82
        attribute with the given name and changes it. If non exist, a new property is added saving this attribute.
83
84
        Parameters:
85
            {string} key - The name of the attribute.
86
            {attr} value - The new value that should be stored.
87
88
        TODO: Deprecate this method, set_attrs() should only be used to have an efficient modification signal handling.
89
        """
90
        assert(self.pk)
91
        if hasattr(self, key):
92
            # Native NodeGroup attribute, such as client_id
93
            setattr(self, key, value)
94
        else:
95
            prop, created = self.properties.get_or_create(
96
                key=key, defaults={
97
                    'node_group': self})
98
            prop.save_value(value)
99
100
    def set_attrs(self, d):
101
        '''
102
            Set groups attributes according to the provided dictionary.
103
104
            TODO: Replace by true bulk insert implementation.
105
        '''
106
        for key, value in d.iteritems():
107
            self.set_attr(key, value)
108
        post_save.send(sender=self.__class__, instance=self)
109
110
    def same_as(self, group):
111
        '''
112
            Checks if this group is equal to the given group in terms of nodes and attributes.
113
            This is a very expensive operation that is only intended for testing purposes.
114
        '''
115
        for my_node in self.nodes.all().filter(deleted=False):
116
            found_match = False
117
            for their_node in group.nodes.all().filter(deleted=False):
118
                if my_node.same_as(their_node):
119
                    found_match = True
120
                    break
121
            if not found_match:
122
                return False
123
        return True
124
125
126
@receiver(post_save, sender=NodeGroup)
127
@receiver(pre_delete, sender=NodeGroup)
128
def graph_modify(sender, instance, **kwargs):
129
    instance.graph.modified = datetime.datetime.now()
130
    instance.graph.save()
131
    # updating project modification date
132
    instance.graph.project.modified = instance.graph.modified
133
    instance.graph.project.save()
134