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 | import os |
||
22 | import uuid |
||
23 | |||
24 | from django.db import models |
||
25 | from django.db.models.signals import pre_delete, pre_save |
||
26 | from django.dispatch import receiver |
||
27 | from django.utils import timezone |
||
28 | |||
29 | from jsonfield import JSONField |
||
30 | |||
31 | from omaha.models import BaseModel |
||
32 | from feedback.managers import FeedbackManager |
||
33 | |||
34 | |||
35 | View Code Duplication | def upload_to(directory, obj, filename): |
|
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
36 | now = timezone.now() |
||
37 | max_length = 100 |
||
38 | path = os.path.join(*map(str, [directory, now.year, now.month, |
||
39 | now.day, uuid.uuid4(), filename])) |
||
40 | if len(path) > max_length: |
||
41 | name, ext = os.path.splitext(path) |
||
42 | ext_length = len(ext) |
||
43 | path = name[:max_length-ext_length] + ext |
||
44 | return path |
||
45 | |||
46 | |||
47 | def screenshot_upload_to(obj, filename): |
||
48 | return upload_to('screenshot', obj, filename) |
||
49 | |||
50 | |||
51 | def blackbox_upload_to(obj, filename): |
||
52 | return upload_to('blackbox', obj, filename) |
||
53 | |||
54 | |||
55 | def logs_upload_to(obj, filename): |
||
56 | return upload_to('system_logs', obj, filename) |
||
57 | |||
58 | |||
59 | def attach_upload_to(obj, filename): |
||
60 | return upload_to('feedback_attach', obj, filename) |
||
61 | |||
62 | |||
63 | class Feedback(BaseModel): |
||
64 | description = models.TextField() |
||
65 | email = models.CharField(max_length=500, null=True, blank=True) |
||
66 | page_url = models.CharField(max_length=2048, null=True, blank=True) |
||
67 | screenshot = models.ImageField(upload_to=screenshot_upload_to, blank=True, null=True) |
||
68 | screenshot_size = models.PositiveIntegerField(null=True, blank=True) |
||
69 | blackbox = models.FileField(upload_to=blackbox_upload_to, blank=True, null=True) |
||
70 | blackbox_size = models.PositiveIntegerField(null=True, blank=True) |
||
71 | system_logs = models.FileField(upload_to=logs_upload_to, blank=True, null=True) |
||
72 | system_logs_size = models.PositiveIntegerField(null=True, blank=True) |
||
73 | attached_file = models.FileField(upload_to=attach_upload_to, blank=True, null=True) |
||
74 | attached_file_size = models.PositiveIntegerField(null=True, blank=True) |
||
75 | feedback_data = JSONField(verbose_name='Feedback data', help_text='JSON format', null=True, blank=True) |
||
76 | ip = models.GenericIPAddressField(blank=True, null=True) |
||
77 | |||
78 | created_at = models.DateTimeField(auto_now_add=True, db_index=True) |
||
79 | updated_at = models.DateTimeField(auto_now=True) |
||
80 | |||
81 | objects = FeedbackManager() |
||
82 | |||
83 | @property |
||
84 | def size(self): |
||
85 | return self.screenshot_size + self.blackbox_size + self.system_logs_size + self.attached_file_size |
||
86 | |||
87 | |||
88 | class FeedbackDescription(Feedback): |
||
89 | class Meta: |
||
90 | proxy = True |
||
91 | |||
92 | |||
93 | def pre_feedback_save(sender, instance, **kwargs): |
||
94 | if instance.pk: |
||
95 | old = sender.objects.get(pk=instance.pk) |
||
96 | if old.screenshot != instance.screenshot: |
||
97 | old.screenshot.delete(save=False) |
||
98 | old.screenshot_size = 0 |
||
99 | if old.blackbox != instance.blackbox: |
||
100 | old.blackbox.delete(save=False) |
||
101 | old.blackbox_size = 0 |
||
102 | if old.system_logs != instance.system_logs: |
||
103 | old.system_logs.delete(save=False) |
||
104 | old.system_logs_size = 0 |
||
105 | if old.attached_file != instance.attached_file: |
||
106 | old.attached_file.delete(save=False) |
||
107 | old.attached_file_size = 0 |
||
108 | |||
109 | |||
110 | def pre_feedback_delete(sender, instance, **kwargs): |
||
111 | file_fields = [instance.screenshot, instance.blackbox, instance.system_logs, instance.attached_file] |
||
112 | for field in file_fields: |
||
113 | storage, name = field.storage, field.name |
||
114 | if name: |
||
115 | storage.delete(name) |
||
116 | |||
117 | |||
118 | def get_subclasses(cls): |
||
119 | result = [cls] |
||
120 | classes_to_inspect = [cls] |
||
121 | while classes_to_inspect: |
||
122 | class_to_inspect = classes_to_inspect.pop() |
||
123 | for subclass in class_to_inspect.__subclasses__(): |
||
124 | if subclass not in result: |
||
125 | result.append(subclass) |
||
126 | classes_to_inspect.append(subclass) |
||
127 | return result |
||
128 | |||
129 | for subclass in get_subclasses(Feedback): |
||
130 | pre_delete.connect(pre_feedback_delete, subclass) |
||
131 | pre_save.connect(pre_feedback_save, subclass) |