Completed
Push — master ( 726486...b38261 )
by Paolo
19s queued 14s
created

animals.tasks.BatchDeleteAnimals.on_failure()   A

Complexity

Conditions 1

Size

Total Lines 27
Code Lines 17

Duplication

Lines 27
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 17
dl 27
loc 27
rs 9.55
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
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
from celery.utils.log import get_task_logger
10
11
from django.db import transaction
12
13
from common.constants import NEED_REVISION
14
from common.tasks import BatchUpdateMixin, BatchFailurelMixin
15
from image.celery import app as celery_app, MyTask
16
from image_app.models import Submission, Animal, Name
17
from submissions.helpers import send_message
18
from validation.helpers import construct_validation_message
19
from validation.models import ValidationSummary
20
21
# Get an instance of a logger
22
logger = get_task_logger(__name__)
23
24
25
class BatchDeleteAnimals(BatchFailurelMixin, MyTask):
26
    name = "Batch delete animals"
27
    description = """Batch remove animals and associated samples"""
28
    batch_type = "delete"
29
    model_type = "animal"
30
    submission_cls = Submission
31
32
    def run(self, submission_id, animal_ids):
33
        """Function for batch update attribute in animals
34
        Args:
35
            submission_id (int): id of submission
36
            animal_ids (list): set with ids to delete
37
        """
38
39
        # get a submisision object
40
        submission_obj = Submission.objects.get(pk=submission_id)
41
42
        logger.info("Start batch delete for animals")
43
        success_ids = list()
44
        failed_ids = list()
45
46
        for animal_id in animal_ids:
47
            try:
48
                name = Name.objects.get(
49
                    name=animal_id, submission=submission_obj)
50
51
                animal_object = Animal.objects.get(name=name)
52
                samples = animal_object.sample_set.all()
53
54
                with transaction.atomic():
55
                    for sample in samples:
56
                        sample_name = sample.name
57
                        sample.delete()
58
                        sample_name.delete()
59
60
                    logger.debug("Clearing all childs from this animal")
61
                    name.mother_of.clear()
62
                    name.father_of.clear()
63
64
                    # delete this animal object
65
                    logger.debug(
66
                        "Deleting animal:%s and name:%s" % (
67
                            animal_object, name))
68
                    animal_object.delete()
69
                    name.delete()
70
71
                success_ids.append(animal_id)
72
73
            except Name.DoesNotExist:
74
                failed_ids.append(animal_id)
75
76
            except Animal.DoesNotExist:
77
                failed_ids.append(animal_id)
78
79
        # Update submission
80
        submission_obj.refresh_from_db()
81
        submission_obj.status = NEED_REVISION
82
83
        if len(failed_ids) != 0:
84
            submission_obj.message = f"You've removed {len(success_ids)} " \
85
                f"animals. It wasn't possible to find records with these " \
86
                f"ids: {', '.join(failed_ids)}. Rerun validation please!"
87
        else:
88
            submission_obj.message = f"You've removed {len(success_ids)} " \
89
                f"animals. Rerun validation please!"
90
91
        submission_obj.save()
92
93
        summary_obj, created = ValidationSummary.objects.get_or_create(
94
            submission=submission_obj, type='animal')
95
        summary_obj.reset()
96
97
        # after removing animal associated samples, we need to update also
98
        # sample all count
99
        summary_obj, created = ValidationSummary.objects.get_or_create(
100
            submission=submission_obj, type='sample')
101
        summary_obj.reset()
102
103
        # TODO: validation summary could be updated relying database, instead
104
        # doing validation. Define a method in validation.helpers to update
105
        # summary relying only on database
106
107
        send_message(
108
            submission_obj, construct_validation_message(submission_obj)
109
        )
110
111
        logger.info("batch delete for animals completed")
112
113
        return 'success'
114
115
116
class BatchUpdateAnimals(BatchFailurelMixin, BatchUpdateMixin, MyTask):
117
    name = "Batch update animals"
118
    description = """Batch update of field in animals"""
119
    batch_type = "update"
120
    model_type = "animal"
121
122
    # defined in common.tasks.BatchUpdateMixin
123
    item_cls = Animal
124
    submission_cls = Submission
125
126
    def run(self, submission_id, animal_ids, attribute):
127
        """Function for batch update attribute in animals
128
        Args:
129
            submission_id (int): id of submission
130
            animal_ids (dict): dict with id and values to update
131
            attribute (str): attribute to update
132
        """
133
134
        logger.info("Start batch update for animals")
135
        self.batch_update(submission_id, animal_ids, attribute)
136
        return 'success'
137
138
139
# register explicitly tasks
140
# https://github.com/celery/celery/issues/3744#issuecomment-271366923
141
celery_app.tasks.register(BatchDeleteAnimals)
142
celery_app.tasks.register(BatchUpdateAnimals)
143