Completed
Push — master ( 74c045...3a5649 )
by
unknown
01:24
created

FeedbackFormView   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 73
rs 10
c 0
b 0
f 0
wmc 12

5 Methods

Rating   Name   Duplication   Size   Complexity  
C get_form_kwargs() 0 45 7
A dispatch() 0 3 1
A handle_file_extension() 0 10 2
A form_invalid() 0 4 1
A form_valid() 0 3 1
1
# coding: utf8
2
3
"""
4
This software is licensed under the Apache 2 license, quoted below.
5
6
Copyright 2015 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 copy import copy
22
import StringIO
23
24
25
from django.core.files.uploadedfile import SimpleUploadedFile
26
from django.views.generic import FormView
27
from django.views.decorators.csrf import csrf_exempt
28
from django.http import HttpResponse, HttpResponseBadRequest
29
from django.conf import settings
30
31
from google.protobuf.descriptor import FieldDescriptor
32
from protobuf_to_dict import protobuf_to_dict, TYPE_CALLABLE_MAP
33
from raven import Client
34
35
from feedback.forms import FeedbackForm
36
from feedback.proto_gen.extension_pb2 import ExtensionSubmit
37
from omaha_server.utils import get_client_ip
38
from utils import get_file_extension
39
40
dsn = getattr(settings, 'RAVEN_CONFIG', None)
41
if dsn:
42
    dsn = dsn['dsn']
43
raven = Client(
44
    dsn,
45
    name=getattr(settings, 'HOST_NAME', None),
46
    release=getattr(settings, 'APP_VERSION', None)
47
)
48
49
50
class FeedbackFormView(FormView):
51
    http_method_names = ('post',)
52
    form_class = FeedbackForm
53
54
    @csrf_exempt
55
    def dispatch(self, *args, **kwargs):
56
        return super(FeedbackFormView, self).dispatch(*args, **kwargs)
57
58
    def get_form_kwargs(self):
59
        kwargs = {
60
            'initial': self.get_initial(),
61
            'prefix': self.get_prefix(),
62
        }
63
        submit = ExtensionSubmit()
64
        submit.ParseFromString(self.request.body)
65
66
        type_callable_map = copy(TYPE_CALLABLE_MAP)
67
        type_callable_map[FieldDescriptor.TYPE_BYTES] = lambda x: '[binary content]'
68
        pb_dict = protobuf_to_dict(
69
            submit,
70
            type_callable_map=type_callable_map,
71
            use_enum_labels=True
72
        )
73
74
        data = dict(
75
            description=submit.common_data.description,
76
            email=submit.common_data.user_email,
77
            page_url=submit.web_data.url,
78
            feedback_data=pb_dict,
79
            ip=get_client_ip(self.request)
80
        )
81
        files = dict()
82
        if submit.screenshot.binary_content:
83
            files['screenshot'] = SimpleUploadedFile(
84
                'screenshot.png',
85
                submit.screenshot.binary_content
86
            )
87
        if submit.blackbox.data:
88
            blackbox_name = self.handle_file_extension(
89
                StringIO.StringIO(submit.blackbox.data).read(1024)
90
            )
91
            files['blackbox'] = SimpleUploadedFile(
92
                blackbox_name, submit.blackbox.data
93
            )
94
        for attach in submit.product_specific_binary_data:
95
            key = 'attached_file'
96
            logs_key = 'system_logs'
97
            if attach.name == u'system_logs.zip' and logs_key not in files:
98
                key = logs_key
99
            files[key] = SimpleUploadedFile(attach.name, attach.data)
100
101
        kwargs.update(dict(data=data, files=files))
102
        return kwargs
103
104
    def handle_file_extension(self, file_header):
105
        file_description = get_file_extension(file_header)
106
        blackbox_name = 'blackbox'
107
        if file_description['file_extension']:
108
            blackbox_name += '.%s' % file_description['file_extension']
109
        else:
110
            raven.captureMessage(
111
                'This is file type not supported, mime type: %s' % file_description['mime_type']
112
            )
113
        return blackbox_name
114
115
    def form_valid(self, form):
116
        obj = form.save()
117
        return HttpResponse(obj.pk, status=200)
118
119
    def form_invalid(self, form):
120
        message = 'Invalid feedback form: ' + form.errors.as_json()
121
        raven.captureMessage(message=message, extra=form.cleaned_data)
122
        return HttpResponseBadRequest(message)
123