Completed
Pull Request — master (#41)
by Paolo
06:52
created

animals.tasks.BatchUpdateAnimals.on_failure()   A

Complexity

Conditions 1

Size

Total Lines 19
Code Lines 12

Duplication

Lines 19
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 12
dl 19
loc 19
rs 9.8
c 0
b 0
f 0
cc 1
nop 6
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Wed Feb 27 16:38:37 2019
5
@author: Paolo Cozzi <[email protected]>
6
"""
7
8
from celery.utils.log import get_task_logger
9
10
from django.db import transaction
11
12
from common.constants import ERROR, NEED_REVISION
13
from common.tasks import BatchUpdateMixin
14
from image.celery import app as celery_app, MyTask
15
from image_app.models import Submission, Animal, Name
16
from submissions.helpers import send_message
17
from validation.helpers import construct_validation_message
18
from validation.models import ValidationSummary
19
20
# Get an instance of a logger
21
logger = get_task_logger(__name__)
22
23
24
class BatchDeleteAnimals(MyTask):
25
    name = "Batch delete animals"
26
    description = """Batch remove animals and associated samples"""
27
28
    # Ovverride default on failure method
29
    # This is not a failed validation for a wrong value, this is an
30
    # error in task that mean an error in coding
31
    def on_failure(self, exc, task_id, args, kwargs, einfo):
32
        logger.error('{0!r} failed: {1!r}'.format(task_id, exc))
33
34
        submission_id, animal_ids = args[0], args[1]
35
36
        logger.error(
37
            ("BatchDeleteAnimals called with submission_id: %s and "
38
             "animal_ids: %s" % (submission_id, animal_ids))
39
        )
40
41
        # get submission object
42
        submission_obj = Submission.objects.get(pk=submission_id)
43
44
        # mark submission with ERROR
45
        submission_obj.status = ERROR
46
        submission_obj.message = (
47
            "Error in animal batch delete: %s" % (str(exc)))
48
        submission_obj.save()
49
50
        send_message(submission_obj)
51
52
        # send a mail to the user with the stacktrace (einfo)
53
        submission_obj.owner.email_user(
54
            "Error in animal batch delete for submission: %s" % (
55
                submission_obj.id),
56
            ("Something goes wrong in batch delete for animals. Please report "
57
             "this to InjectTool team\n\n %s" % str(einfo)),
58
        )
59
60
        # TODO: submit mail to admin
61
62
    def run(self, submission_id, animal_ids):
63
        """Function for batch update attribute in animals
64
        Args:
65
            submission_id (int): id of submission
66
            animal_ids (list): set with ids to delete
67
        """
68
69
        # get a submisision object
70
        submission_obj = Submission.objects.get(pk=submission_id)
71
72
        logger.info("Start batch delete for animals")
73
        success_ids = list()
74
        failed_ids = list()
75
76
        for animal_id in animal_ids:
77
            try:
78
                name = Name.objects.get(
79
                    name=animal_id, submission=submission_obj)
80
81
                animal_object = Animal.objects.get(name=name)
82
                samples = animal_object.sample_set.all()
83
84
                with transaction.atomic():
85
                    for sample in samples:
86
                        sample_name = sample.name
87
                        sample.delete()
88
                        sample_name.delete()
89
90
                    logger.debug("Clearing all childs from this animal")
91
                    name.mother_of.clear()
92
                    name.father_of.clear()
93
94
                    # delete this animal object
95
                    logger.debug(
96
                        "Deleting animal:%s and name:%s" % (
97
                            animal_object, name))
98
                    animal_object.delete()
99
                    name.delete()
100
101
                success_ids.append(animal_id)
102
103
            except Name.DoesNotExist:
104
                failed_ids.append(animal_id)
105
106
            except Animal.DoesNotExist:
107
                failed_ids.append(animal_id)
108
109
        # Update submission
110
        submission_obj.refresh_from_db()
111
        submission_obj.status = NEED_REVISION
112
113
        if len(failed_ids) != 0:
114
            submission_obj.message = f"You've removed {len(success_ids)} " \
115
                f"animals. It wasn't possible to find records with these " \
116
                f"ids: {', '.join(failed_ids)}. Rerun validation please!"
117
        else:
118
            submission_obj.message = f"You've removed {len(success_ids)} " \
119
                f"animals. Rerun validation please!"
120
121
        submission_obj.save()
122
123
        summary_obj, created = ValidationSummary.objects.get_or_create(
124
            submission=submission_obj, type='animal')
125
        summary_obj.reset_all_count()
126
127
        send_message(
128
            submission_obj, construct_validation_message(submission_obj)
129
        )
130
131
        logger.info("batch delete for animals completed")
132
133
        return 'success'
134
135
136 View Code Duplication
class BatchUpdateAnimals(MyTask, BatchUpdateMixin):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
137
    name = "Batch update animals"
138
    description = """Batch update of field in animals"""
139
140
    item_cls = Animal
141
    submission_cls = Submission
142
143
    # Ovverride default on failure method
144
    # This is not a failed validation for a wrong value, this is an
145
    # error in task that mean an error in coding
146
    def on_failure(self, exc, task_id, args, kwargs, einfo):
147
        logger.error('{0!r} failed: {1!r}'.format(task_id, exc))
148
149
        # get submission object
150
        submission_obj = Submission.objects.get(pk=args[0])
151
152
        # mark submission with ERROR
153
        submission_obj.status = ERROR
154
        submission_obj.message = ("Error in batch update for animals: %s"
155
                                  % (str(exc)))
156
        submission_obj.save()
157
158
        send_message(submission_obj)
159
160
        # send a mail to the user with the stacktrace (einfo)
161
        submission_obj.owner.email_user(
162
            "Error in batch update for animals: %s" % (args[0]),
163
            ("Something goes wrong  in batch update for animals. Please report "
164
             "this to InjectTool team\n\n %s" % str(einfo)),
165
        )
166
167
        # TODO: submit mail to admin
168
169
    def run(self, submission_id, animal_ids, attribute):
170
        """Function for batch update attribute in animals
171
        Args:
172
            submission_id (int): id of submission
173
            animal_ids (dict): dict with id and values to update
174
            attribute (str): attribute to update
175
        """
176
177
        logger.info("Start batch update for animals")
178
        super(BatchUpdateAnimals, self).batch_update(submission_id, animal_ids,
179
                                                     attribute)
180
        return 'success'
181
182
183
# register explicitly tasks
184
# https://github.com/celery/celery/issues/3744#issuecomment-271366923
185
celery_app.tasks.register(BatchDeleteAnimals)
186
celery_app.tasks.register(BatchUpdateAnimals)
187