Completed
Pull Request — master (#45)
by Paolo
06:12
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
@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 image.celery import app as celery_app, MyTask
14
from image_app.models import Submission, Animal, Name
15
from submissions.helpers import send_message
16
from validation.helpers import construct_validation_message
17
from validation.models import ValidationSummary
18
19
# Get an instance of a logger
20
logger = get_task_logger(__name__)
21
22
23
class BatchDeleteAnimals(MyTask):
24
    name = "Batch delete animals"
25
    description = """Batch remove animals and associated samples"""
26
27
    # Ovverride default on failure method
28
    # This is not a failed validation for a wrong value, this is an
29
    # error in task that mean an error in coding
30 View Code Duplication
    def on_failure(self, exc, task_id, args, kwargs, einfo):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
31
        logger.error('{0!r} failed: {1!r}'.format(task_id, exc))
32
33
        submission_id, animal_ids = args[0], args[1]
34
35
        logger.error(
36
            ("BatchDeleteAnimals called with submission_id: %s and "
37
             "animal_ids: %s" % (submission_id, animal_ids))
38
        )
39
40
        # get submission object
41
        submission_obj = Submission.objects.get(pk=submission_id)
42
43
        # mark submission with ERROR
44
        submission_obj.status = ERROR
45
        submission_obj.message = (
46
            "Error in animal batch delete: %s" % (str(exc)))
47
        submission_obj.save()
48
49
        send_message(submission_obj)
50
51
        # send a mail to the user with the stacktrace (einfo)
52
        submission_obj.owner.email_user(
53
            "Error in animal batch delete for submission: %s" % (
54
                submission_obj.id),
55
            ("Something goes wrong in batch delete for animals. Please report "
56
             "this to InjectTool team\n\n %s" % str(einfo)),
57
        )
58
59
        # TODO: submit mail to admin
60
61
    def run(self, submission_id, animal_ids):
62
        """Function for batch update attribute in animals
63
        Args:
64
            submission_id (int): id of submission
65
            animal_ids (list): set with ids to delete
66
        """
67
68
        # get a submisision object
69
        submission_obj = Submission.objects.get(pk=submission_id)
70
71
        logger.info("Start batch delete for animals")
72
        success_ids = list()
73
        failed_ids = list()
74
75
        for animal_id in animal_ids:
76
            try:
77
                name = Name.objects.get(
78
                    name=animal_id, submission=submission_obj)
79
80
                animal_object = Animal.objects.get(name=name)
81
                samples = animal_object.sample_set.all()
82
83
                with transaction.atomic():
84
                    for sample in samples:
85
                        sample_name = sample.name
86
                        sample.delete()
87
                        sample_name.delete()
88
89
                    logger.debug("Clearing all childs from this animal")
90
                    name.mother_of.clear()
91
                    name.father_of.clear()
92
93
                    # delete this animal object
94
                    logger.debug(
95
                        "Deleting animal:%s and name:%s" % (
96
                            animal_object, name))
97
                    animal_object.delete()
98
                    name.delete()
99
100
                success_ids.append(animal_id)
101
102
            except Name.DoesNotExist:
103
                failed_ids.append(animal_id)
104
105
            except Animal.DoesNotExist:
106
                failed_ids.append(animal_id)
107
108
        # Update submission
109
        submission_obj.refresh_from_db()
110
        submission_obj.status = NEED_REVISION
111
112
        if len(failed_ids) != 0:
113
            submission_obj.message = f"You've removed {len(success_ids)} " \
114
                f"animals. It wasn't possible to find records with these " \
115
                f"ids: {', '.join(failed_ids)}. Rerun validation please!"
116
        else:
117
            submission_obj.message = f"You've removed {len(success_ids)} " \
118
                f"animals. Rerun validation please!"
119
120
        submission_obj.save()
121
122
        summary_obj, created = ValidationSummary.objects.get_or_create(
123
            submission=submission_obj, type='animal')
124
        summary_obj.reset_all_count()
125
126
        send_message(
127
            submission_obj, construct_validation_message(submission_obj)
128
        )
129
130
        logger.info("batch delete for animals completed")
131
132
        return 'success'
133
134
135
# register explicitly tasks
136
# https://github.com/celery/celery/issues/3744#issuecomment-271366923
137
celery_app.tasks.register(BatchDeleteAnimals)
138