Issues (84)

omaha_server/feedback/models.py (1 issue)

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
This code seems to be duplicated in your project.
Loading history...
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)