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
|
|
|
|