Completed
Push — master ( 37bb4c...2160b9 )
by Egor
01:33
created

symbols_upload_to()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 4
rs 10
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
import os
22
import uuid
23
24
from django.db import models
25
from django.db.models.signals import post_save, pre_delete
26
from django.dispatch import receiver
27
from django.utils import timezone
28
29
from celery import signature
30
from jsonfield import JSONField
31
32
from omaha.models import BaseModel
33
from crash.managers import CrashManager, SymbolsManager
34
35
36
def crash_upload_to(obj, filename):
37
    now = timezone.now()
38
    return os.path.join(*map(str, ['minidump', now.year, now.month,
39
                                   now.day, uuid.uuid4(), filename]))
40
41
42
def crash_archive_upload_to(obj, filename):
43
    now = timezone.now()
44
    return os.path.join(*map(str, ['minidump_archive', now.year, now.month,
45
                                   now.day, uuid.uuid4(), filename]))
46
47
48
class Crash(BaseModel):
49
    upload_file_minidump = models.FileField(upload_to=crash_upload_to, blank=True, null=True, max_length=255)
50
    minidump_size = models.PositiveIntegerField(null=True, blank=True)
51
    archive = models.FileField(upload_to=crash_archive_upload_to, blank=True, null=True, max_length=255)
52
    archive_size = models.PositiveIntegerField(null=True, blank=True)
53
    appid = models.CharField(max_length=38, null=True, blank=True)
54
    userid = models.CharField(max_length=38, null=True, blank=True)
55
    meta = JSONField(verbose_name='Meta-information', help_text='JSON format', null=True, blank=True)
56
    stacktrace = models.TextField(null=True, blank=True)
57
    stacktrace_json = JSONField(null=True, blank=True)
58
    signature = models.CharField(max_length=255, db_index=True, null=True, blank=True)
59
    ip = models.GenericIPAddressField(blank=True, null=True, protocol="ipv4")
60
    groupid = models.CharField(max_length=38, null=True, blank=True)
61
    eventid = models.CharField(max_length=38, null=True, blank=True)
62
63
    objects = CrashManager()
64
65
    class Meta(BaseModel.Meta):
66
        verbose_name_plural = 'Crashes'
67
68
    @property
69
    def size(self):
70
         return self.archive_size + self.minidump_size
71
72
class CrashDescription(BaseModel):
73
    crash = models.OneToOneField(Crash, related_name='crash_description')
74
    summary = models.CharField(max_length=500)
75
    description = models.TextField(null=True, blank=True)
76
77
def symbols_upload_to(obj, filename):
78
    sym_filename = os.path.splitext(os.path.basename(obj.debug_file))[0]
79
    sym_filename = '%s.sym' % sym_filename
80
    return os.path.join('symbols', obj.debug_file, obj.debug_id, sym_filename)
81
82
83
class Symbols(BaseModel):
84
    debug_id = models.CharField(verbose_name='Debug ID', max_length=255, db_index=True, null=True, blank=True)
85
    debug_file = models.CharField(verbose_name='Debug file name', max_length=140, null=True, blank=True)
86
    file = models.FileField(upload_to=symbols_upload_to, null=True)
87
    file_size = models.PositiveIntegerField(null=True, blank=True)
88
89
    objects = SymbolsManager()
90
91
    class Meta:
92
        verbose_name_plural = 'Symbols'
93
        unique_together = (
94
            ('debug_id', 'debug_file'),
95
        )
96
97
    @property
98
    def size(self):
99
         return self.file_size
100
101
@receiver(post_save, sender=Crash)
102
def crash_post_save(sender, instance, created, *args, **kwargs):
103
    if created and instance.upload_file_minidump:
104
        signature("tasks.processing_crash_dump", args=(instance.pk,)).apply_async(queue='private', countdown=1)
105
106
107
@receiver(pre_delete, sender=Crash)
108
def pre_crash_delete(sender, instance, **kwargs):
109
    file_fields = [instance.archive, instance.upload_file_minidump]
110
    for field in file_fields:
111
        storage, name = field.storage, field.name
112
        if name:
113
            storage.delete(name)
114
115
116
@receiver(pre_delete, sender=Symbols)
117
def pre_symbol_delete(sender, instance, **kwargs):
118
    storage, name = instance.file.storage, instance.file.name
119
    if name:
120
        storage.delete(name)
121