Passed
Pull Request — master (#40)
by Paolo
01:48
created

submissions.forms   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 11
eloc 60
dl 0
loc 109
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
B SubmissionFormMixin.clean() 0 13 6
A SubmissionFormMixin.check_crbanim_columns() 0 19 2
A SubmissionFormMixin.check_file_encoding() 0 16 3
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Tue Jul 24 15:51:05 2018
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
import magic
10
11
from django import forms
12
13
from common.forms import RequestFormMixin
14
from common.constants import CRB_ANIM_TYPE, TEMPLATE_TYPE
15
from image_app.models import Submission
16
from crbanim.helpers import CRBAnimReader
17
18
19
class SubmissionFormMixin():
20
    def clean(self):
21
        # I can call this method without providing a 'uploaded file'
22
        # (for instance, when omitting uploaded file)
23
        if "uploaded_file" in self.cleaned_data:
24
            # avoid file type for excel types (is not an text file)
25
            if ("datasource_type" in self.cleaned_data and
26
                    self.cleaned_data["datasource_type"] != TEMPLATE_TYPE):
27
                self.check_file_encoding()
28
29
            # same applies for datasource type
30
            if ("datasource_type" in self.cleaned_data and
31
                    self.cleaned_data["datasource_type"] == CRB_ANIM_TYPE):
32
                self.check_crbanim_columns()
33
34
    def check_file_encoding(self):
35
        uploaded_file = self.cleaned_data['uploaded_file']
36
37
        # read one chunk of such file
38
        chunk = next(uploaded_file.chunks())
39
        magic_line = magic.from_buffer(chunk)
40
        file_type = magic_line.split(",")[0]
41
42
        if "UTF-8" not in file_type and "ASCII" not in file_type:
43
            # create message and add error
44
            msg = (
45
                "Error: file not in UTF-8 nor ASCII format: "
46
                "format was %s" % file_type)
47
48
            # raising an exception:
49
            raise forms.ValidationError(msg, code='invalid')
50
51
    def check_crbanim_columns(self):
52
        """Check if a CRBanim file has mandatory columns"""
53
54
        uploaded_file = self.cleaned_data['uploaded_file']
55
56
        # read one chunk of such file
57
        chunk = next(uploaded_file.chunks())
58
59
        # now determine if CRBanim file is valid. chunk is in binary format
60
        # neet to convert to a string, fortunately I've already check that
61
        # file is in UTF-8
62
        check, not_found = CRBAnimReader.is_valid(chunk.decode("utf-8"))
63
64
        if check is False:
65
            msg = "Error: file lacks of CRBanim mandatory columns: %s" % (
66
                not_found)
67
68
            # raising an exception:
69
            raise forms.ValidationError(msg, code='invalid')
70
71
72
class SubmissionForm(SubmissionFormMixin, RequestFormMixin, forms.ModelForm):
73
    class Meta:
74
        model = Submission
75
        fields = (
76
            'title',
77
            'description',
78
            'gene_bank_name',
79
            'gene_bank_country',
80
            'organization',
81
            'datasource_type',
82
            'datasource_version',
83
            'uploaded_file'
84
        )
85
86
        help_texts = {
87
            'uploaded_file': 'Need to be in UTF-8 or ASCII format',
88
        }
89
90
91
# I use forms.Form since I need to pass primary key as a field,
92
# and I can't use it with a modelform
93
class ReloadForm(SubmissionFormMixin, RequestFormMixin, forms.ModelForm):
94
    # custom attributes
95
    agree_reload = forms.BooleanField(
96
        label="That's fine. Replace my submission data with this file",
97
        help_text="You have to check this box to reload your data")
98
99
    class Meta:
100
        model = Submission
101
        fields = (
102
            'datasource_type',
103
            'datasource_version',
104
            'uploaded_file',
105
        )
106
107
        help_texts = {
108
            'uploaded_file': 'Need to be in UTF-8 or ASCII format',
109
        }
110