Completed
Push — master ( 4f7ee6...646424 )
by Paolo
08:30 queued 06:53
created

uid.helpers.update_or_create_obj()   B

Complexity

Conditions 5

Size

Total Lines 37
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 37
rs 8.9332
c 0
b 0
f 0
cc 5
nop 2
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Tue Feb  6 12:41:05 2018
5
6
@author: Paolo Cozzi <[email protected]>
7
8
Common functions in uid
9
10
"""
11
12
import re
13
import logging
14
15
from language.helpers import check_species_synonyms
16
17
from .models import Animal, Sample, DictSpecie
18
19
# Get an instance of a logger
20
logger = logging.getLogger(__name__)
21
22
# a pattern to correctly parse aliases
23
ALIAS_PATTERN = re.compile(r"IMAGE([AS])([0-9]+)")
24
25
26
def parse_image_alias(alias):
27
    """Parse alias and return table and pk"""
28
29
    match = re.search(ALIAS_PATTERN, alias)
30
31
    if not match:
32
        raise Exception("Cannot deal with '%s'" % (alias))
33
34
    letter, padded_pk = match.groups()
35
    table, pk = None, None
36
37
    if letter == "A":
38
        table = "Animal"
39
40
    elif letter == "S":
41
        table = "Sample"
42
43
    pk = int(padded_pk)
44
45
    return table, pk
46
47
48
def get_model_object(table, pk):
49
    """Get a model object relying on table name (Sample/Alias) and pk"""
50
51
    # get sample object
52
    if table == "Animal":
53
        sample_obj = Animal.objects.get(pk=pk)
54
55
    elif table == "Sample":
56
        sample_obj = Sample.objects.get(pk=pk)
57
58
    else:
59
        raise Exception("Unknown table '%s'" % (table))
60
61
    return sample_obj
62
63
64
class FileDataSourceMixin():
65
    """A class to deal with common operation between Template and CRBanim
66
    files"""
67
68
    def check_items(self, item_set, model, column):
69
        """General check of DataSource items into database"""
70
71
        # a list of not found terms and a status to see if something is missing
72
        # or not
73
        not_found = []
74
        result = True
75
76
        for item in item_set:
77
            # check for species in database
78
            if not model.objects.filter(label=item).exists():
79
                not_found.append(item)
80
81
        if len(not_found) != 0:
82
            result = False
83
            logger.warning(
84
                "Those %s are not present in UID database:" % (column))
85
            logger.warning(not_found)
86
87
        return result, not_found
88
89
    def check_species(self, column, item_set, country, create=False):
90
        """Check if all species are defined in UID DictSpecies. Create
91
        dictionary term if create is True and species is not found"""
92
93
        check, not_found = self.check_items(
94
            item_set, DictSpecie, column)
95
96
        if check is False:
97
            # try to check in dictionary table
98
            logger.info("Searching for %s in dictionary tables" % (not_found))
99
100
            # if this function return True, I found all synonyms
101
            if check_species_synonyms(not_found, country, create) is True:
102
                logger.info("Found %s in dictionary tables" % not_found)
103
104
                # return True and an empty list for check and not found items
105
                return True, []
106
107
            else:
108
                # if I arrive here, there are species that I couldn't find
109
                logger.error(
110
                    "Couldnt' find those species in dictionary tables:")
111
                logger.error(not_found)
112
113
        return check, not_found
114
115
116
def get_or_create_obj(model, **kwargs):
117
    """Generic method to create or getting a model object"""
118
119
    instance, created = model.objects.get_or_create(**kwargs)
120
121
    if created:
122
        logger.info("Created '%s'" % instance)
123
124
    else:
125
        logger.debug("Found '%s'" % instance)
126
127
    return instance
128
129
130
def update_or_create_obj(model, **kwargs):
131
    """Generic method to create or getting a model object"""
132
133
    if 'submission' in kwargs:
134
        # ok, try to remove submission from kwargs and test if this objects
135
        # is already in database
136
        new_kwargs = kwargs.copy()
137
        submission = new_kwargs.pop('submission')
138
        new_kwargs.pop('defaults')
139
140
        logger.debug("Test if %s is already in database" % (new_kwargs))
141
        instance = model.objects.filter(**new_kwargs).first()
142
143
        if instance:
144
            logger.debug("Found %s in database" % (instance))
145
146
            # test if instance is in a different submission
147
            if submission != instance.submission:
148
                message = (
149
                    "Ignoring: %s - Already in database with submission %s"
150
                    % (kwargs, submission)
151
                )
152
                logger.warning(message)
153
                return instance
154
155
    # if I arrive here, or I don't have the submission key or
156
    # I see this object for the first time or I just see this
157
    # object in this submission
158
    instance, created = model.objects.update_or_create(**kwargs)
159
160
    if created:
161
        logger.debug("Created '%s'" % instance)
162
163
    else:
164
        logger.debug("Updating '%s'" % instance)
165
166
    return instance
167