Completed
Push — master ( 37bb4c...2160b9 )
by Egor
01:33
created

SymbolsAdminForm.clean_file_size()   A

Complexity

Conditions 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 3
dl 0
loc 7
rs 9.4285
1
# coding: utf8
2
3
"""
4
This software is licensed under the Apache 2 license, quoted below.
5
6
Copyright 2014 Crystalnix Limited
7
8
Licensed under the Apache License, Version 2.0 (the "License"); you may not
9
use this file except in compliance with the License. You may obtain a copy of
10
the License at
11
12
    http://www.apache.org/licenses/LICENSE-2.0
13
14
Unless required by applicable law or agreed to in writing, software
15
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17
License for the specific language governing permissions and limitations under
18
the License.
19
"""
20
21
from builtins import filter
22
23
import tarfile
24
from io import BytesIO
25
26
from django import forms
27
from django.core.files.uploadedfile import SimpleUploadedFile
28
from django.forms import widgets
29
from django.forms.widgets import TextInput
30
from django.core.files.uploadedfile import UploadedFile
31
32
from django_ace import AceWidget
33
from crash.models import Symbols, Crash, CrashDescription
34
from crash.utils import parse_debug_meta_info
35
36
37
class CrashFrom(forms.ModelForm):
38
    class Meta:
39
        model = Crash
40
        exclude = []
41
        widgets = {
42
            'stacktrace_json': AceWidget(mode='json', theme='monokai', width='600px', height='300px'),
43
            'stacktrace': AceWidget(theme='monokai', width='600px', height='300px'),
44
            'meta': AceWidget(mode='json', theme='monokai', width='600px', height='300px'),
45
            'archive_size': widgets.TextInput(attrs=dict(disabled='disabled')),
46
            'minidump_size': widgets.TextInput(attrs=dict(disabled='disabled')),
47
        }
48
49
    def clean_archive(self):
50
        return self.cleaned_data.get('archive_file')
51
52
    def clean_upload_file_minidump(self):
53
        file = self.cleaned_data["upload_file_minidump"]
54
55
        if file.name.endswith('.tar'):
56
            t_file = BytesIO(file.read())
57
            t_file = tarfile.open(fileobj=t_file, mode='r')
58
            self.cleaned_data['archive_file'] = file
59
            dump_name = filter(lambda i: i.endswith('.dmp'), t_file.getnames())
60
            try:
61
                file_name = next(dump_name)
62
                file = t_file.extractfile(file_name)
63
                file = SimpleUploadedFile(file_name, file.read())
64
            except StopIteration:
65
                return None
66
        return file
67
68
    def clean_minidump_size(self):
69
        if 'upload_file_minidump' not in self.cleaned_data:
70
            raise forms.ValidationError('')
71
        _file = self.cleaned_data.get('upload_file_minidump')
72
        if isinstance(_file, UploadedFile):
73
            return _file.size
74
        return self.initial.get("minidump_size")
75
76
    def clean_archive_size(self):
77
        if 'archive_file' not in self.cleaned_data:
78
            return 0
79
        _file = self.cleaned_data.get('archive_file', 0)
80
        if isinstance(_file, UploadedFile):
81
            return _file.size
82
        return self.initial.get("archive_size", 0)
83
84
85
class CrashDescriptionForm(forms.ModelForm):
86
    class Meta:
87
        model = CrashDescription
88
        fields = ['summary', 'description']
89
90
91
class SymbolsFileInput(forms.ClearableFileInput):
92
    url_markup_template = '<a href="{0}">Link</a>'
93
94
95
class SymbolsFileField(forms.Field):
96
    widget = SymbolsFileInput
97
98
99
class SymbolsAdminForm(forms.ModelForm):
100
    file = SymbolsFileField()
101
102
    class Meta:
103
        model = Symbols
104
        exclude = []
105
        widgets = {
106
            'debug_id': widgets.TextInput(attrs=dict(disabled='disabled')),
107
            'debug_file': widgets.TextInput(attrs=dict(disabled='disabled')),
108
            'file_size': widgets.TextInput(attrs=dict(disabled='disabled')),
109
        }
110
111
    def clean_file(self):
112
        file = self.cleaned_data["file"]
113
        try:
114
            head = file.readline().rstrip()
115
            meta = parse_debug_meta_info(head, exception=forms.ValidationError)
116
            self.cleaned_data.update(meta)
117
        except:
118
            raise forms.ValidationError(u"The file contains invalid data.")
119
        return file
120
121
    def clean_file_size(self):
122
        if 'file' not in self.cleaned_data:
123
            raise forms.ValidationError('')
124
        _file = self.cleaned_data["file"]
125
        if isinstance(_file, UploadedFile):
126
            return _file.size
127
        return self.initial["file_size"]
128
129
class TextInputForm(forms.Form):
130
    def __init__(self, *args, **kwargs):
131
        field_name = kwargs.pop('field_name')
132
        super(TextInputForm, self).__init__(*args, **kwargs)
133
        self.fields[field_name] = forms.CharField(
134
            widget=TextInput(attrs={'placeholder': 'Filter by ID'}),
135
            label='',
136
            required=False)
137
138
    def is_valid(self):
139
        valid = super(TextInputForm, self).is_valid()
140
        if not valid:
141
            return valid
142
        _id = self.cleaned_data['id']
143
        if _id and not _id.isdigit():
144
            self.add_error('id', 'ID should be integer')
145
            return False
146
        return True
147