CrashDescriptionForm   A
last analyzed

Size/Duplication

Total Lines 4
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
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 not file:
56
            return
57
        if file.name.endswith('.tar') or file.name.endswith('.tar.gz'):
58
            try:
59
                t_file = BytesIO(file.read())
60
                t_file = tarfile.open(fileobj=t_file, mode='r')
61
                self.cleaned_data['archive_file'] = file
62
                dump_name = filter(lambda i: i.endswith('.dmp'), t_file.getnames())
63
                try:
64
                    file_name = next(dump_name)
65
                    file = t_file.extractfile(file_name)
66
                    file = SimpleUploadedFile(file_name, file.read())
67
                except StopIteration:
68
                    return None
69
            except tarfile.TarError as err:
70
                raise forms.ValidationError('The tar file is broken, error: {0}'.format(err.message))
71
        return file
72
73
    def clean_minidump_size(self):
74
        if 'upload_file_minidump' not in self.cleaned_data:
75
            raise forms.ValidationError('')
76
        _file = self.cleaned_data.get('upload_file_minidump')
77
        if isinstance(_file, UploadedFile):
78
            return _file.size
79
        return self.initial.get("minidump_size")
80
81
    def clean_archive_size(self):
82
        if 'archive_file' not in self.cleaned_data:
83
            return 0
84
        _file = self.cleaned_data.get('archive_file', 0)
85
        if isinstance(_file, UploadedFile):
86
            return _file.size
87
        return self.initial.get("archive_size", 0)
88
89
90
class CrashDescriptionForm(forms.ModelForm):
91
    class Meta:
92
        model = CrashDescription
93
        fields = ['summary', 'description']
94
95
96
class SymbolsFileInput(forms.ClearableFileInput):
97
    url_markup_template = '<a href="{0}">Link</a>'
98
99
100
class SymbolsFileField(forms.Field):
101
    widget = SymbolsFileInput
102
103
104
class SymbolsAdminForm(forms.ModelForm):
105
    file = SymbolsFileField()
106
107
    class Meta:
108
        model = Symbols
109
        exclude = []
110
        widgets = {
111
            'debug_id': widgets.TextInput(attrs=dict(disabled='disabled')),
112
            'debug_file': widgets.TextInput(attrs=dict(disabled='disabled')),
113
            'file_size': widgets.TextInput(attrs=dict(disabled='disabled')),
114
        }
115
116
    def clean_file(self):
117
        file = self.cleaned_data["file"]
118
        try:
119
            head = file.readline().rstrip()
120
            meta = parse_debug_meta_info(head, exception=forms.ValidationError)
121
            self.cleaned_data.update(meta)
122
        except:
123
            raise forms.ValidationError(u"The file contains invalid data.")
124
        return file
125
126
    def clean_file_size(self):
127
        if 'file' not in self.cleaned_data:
128
            raise forms.ValidationError('')
129
        _file = self.cleaned_data["file"]
130
        if isinstance(_file, UploadedFile):
131
            return _file.size
132
        return self.initial["file_size"]
133
134
class TextInputForm(forms.Form):
135
    def __init__(self, *args, **kwargs):
136
        field_name = kwargs.pop('field_name')
137
        super(TextInputForm, self).__init__(*args, **kwargs)
138
        self.fields[field_name] = forms.CharField(
139
            widget=TextInput(attrs={'placeholder': 'Filter by ID'}),
140
            label='',
141
            required=False)
142
143
    def is_valid(self):
144
        valid = super(TextInputForm, self).is_valid()
145
        if not valid:
146
            return valid
147
        _id = self.cleaned_data['id']
148
        if _id and not _id.isdigit():
149
            self.add_error('id', 'ID should be integer')
150
            return False
151
        return True
152