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

samples.tasks   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 173
Duplicated Lines 26.01 %

Importance

Changes 0
Metric Value
wmc 9
eloc 86
dl 45
loc 173
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
B BatchDeleteSamples.run() 0 57 6
A BatchDeleteSamples.on_failure() 0 27 1
A BatchUpdateSamples.on_failure() 19 19 1
A BatchUpdateSamples.run() 12 12 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
#!/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 ERROR, NEED_REVISION
14
from common.tasks import BatchUpdateMixin
15
from image.celery import app as celery_app, MyTask
16
from image_app.models import Submission, Sample, 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 BatchDeleteSamples(MyTask):
26
    name = "Batch delete samples"
27
    description = """Batch remove samples"""
28
29
    # Ovverride default on failure method
30
    # This is not a failed validation for a wrong value, this is an
31
    # error in task that mean an error in coding
32
    def on_failure(self, exc, task_id, args, kwargs, einfo):
33
        logger.error('{0!r} failed: {1!r}'.format(task_id, exc))
34
35
        submission_id, sample_ids = args[0], args[1]
36
37
        logger.error(
38
            ("BatchDeleteAnimals called with submission_id: %s and "
39
             "sample_ids: %s" % (submission_id, sample_ids))
40
        )
41
42
        # get submission object
43
        submission_obj = Submission.objects.get(pk=submission_id)
44
45
        # mark submission with ERROR
46
        submission_obj.status = ERROR
47
        submission_obj.message = (
48
            "Error in sample batch delete: %s" % (str(exc)))
49
        submission_obj.save()
50
51
        send_message(submission_obj)
52
53
        # send a mail to the user with the stacktrace (einfo)
54
        submission_obj.owner.email_user(
55
            "Error in sample batch delete for submission: %s" % (
56
                submission_obj.id),
57
            ("Something goes wrong in batch delete for samples. Please report "
58
             "this to InjectTool team\n\n %s" % str(einfo)),
59
        )
60
61
        # TODO: submit mail to admin
62
63
    def run(self, submission_id, sample_ids):
64
        """Function for batch update attribute in animals
65
        Args:
66
            submission_id (int): id of submission
67
            sample_ids (list): set with ids to delete
68
        """
69
70
        # get a submisision object
71
        submission_obj = Submission.objects.get(pk=submission_id)
72
73
        logger.info("Start batch delete for samples")
74
        success_ids = list()
75
        failed_ids = list()
76
77
        for sample_id in sample_ids:
78
            try:
79
                name = Name.objects.get(
80
                    name=sample_id, submission=submission_obj)
81
82
                sample_obj = Sample.objects.get(name=name)
83
84
                with transaction.atomic():
85
                    sample_obj.delete()
86
                    name.delete()
87
                success_ids.append(sample_id)
88
89
            except Name.DoesNotExist:
90
                failed_ids.append(sample_id)
91
92
            except Sample.DoesNotExist:
93
                failed_ids.append(sample_id)
94
95
        # Update submission
96
        submission_obj.refresh_from_db()
97
        submission_obj.status = NEED_REVISION
98
99
        if len(failed_ids) != 0:
100
            submission_obj.message = f"You've removed {len(success_ids)} " \
101
                f"samples. It wasn't possible to find records with these " \
102
                f"ids: {', '.join(failed_ids)}. Rerun validation please!"
103
        else:
104
            submission_obj.message = f"You've removed {len(success_ids)} " \
105
                f"samples. Rerun validation please!"
106
107
        submission_obj.save()
108
109
        summary_obj, created = ValidationSummary.objects.get_or_create(
110
            submission=submission_obj, type='sample')
111
        summary_obj.reset_all_count()
112
113
        send_message(
114
            submission_obj, construct_validation_message(submission_obj)
115
        )
116
117
        logger.info("batch delete for samples completed")
118
119
        return 'success'
120
121
122 View Code Duplication
class BatchUpdateSamples(MyTask, BatchUpdateMixin):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
123
    name = "Batch update samples"
124
    description = """Batch update of field in samples"""
125
126
    item_cls = Sample
127
    submission_cls = Submission
128
129
    # Ovverride default on failure method
130
    # This is not a failed validation for a wrong value, this is an
131
    # error in task that mean an error in coding
132
    def on_failure(self, exc, task_id, args, kwargs, einfo):
133
        logger.error('{0!r} failed: {1!r}'.format(task_id, exc))
134
135
        # get submission object
136
        submission_obj = Submission.objects.get(pk=args[0])
137
138
        # mark submission with ERROR
139
        submission_obj.status = ERROR
140
        submission_obj.message = ("Error in batch update for samples: %s"
141
                                  % (str(exc)))
142
        submission_obj.save()
143
144
        send_message(submission_obj)
145
146
        # send a mail to the user with the stacktrace (einfo)
147
        submission_obj.owner.email_user(
148
            "Error in batch update for samples: %s" % (args[0]),
149
            ("Something goes wrong in batch update for samples. Please report "
150
             "this to InjectTool team\n\n %s" % str(einfo)),
151
        )
152
153
        # TODO: submit mail to admin
154
155
    def run(self, submission_id, sample_ids, attribute):
156
        """Function for batch update attribute in samples
157
        Args:
158
            submission_id (int): id of submission
159
            sample_ids (dict): dict with id and values to update
160
            attribute (str): attribute to update
161
        """
162
163
        logger.info("Start batch update for samples")
164
        super(BatchUpdateSamples, self).batch_update(submission_id, sample_ids,
165
                                                     attribute)
166
        return 'success'
167
168
169
# register explicitly tasks
170
# https://github.com/celery/celery/issues/3744#issuecomment-271366923
171
celery_app.tasks.register(BatchDeleteSamples)
172
celery_app.tasks.register(BatchUpdateSamples)
173