towards version 0.2
diff --git a/crashreports/admin.py b/crashreports/admin.py
index 0697de1..1894034 100644
--- a/crashreports/admin.py
+++ b/crashreports/admin.py
@@ -1,8 +1,6 @@
from django.contrib import admin
-from models import Crashreport
-# Register your models here.
+from crashreports.models import Crashreport
@admin.register(Crashreport)
class CrashreportAdmin(admin.ModelAdmin):
- list_display = ['report_type', 'build_fingerprint', 'boot_reason', 'power_on_reason', 'power_off_reason', 'aux_data', 'date', 'uuid', 'crashreport_file_link']
pass
diff --git a/crashreports/forms.py b/crashreports/forms.py
index 14917bc..9c4b8ee 100644
--- a/crashreports/forms.py
+++ b/crashreports/forms.py
@@ -1,15 +1,15 @@
# -*- coding: utf-8 -*-
from django import forms
-
-class CrashreportForm(forms.Form):
- uuid = forms.CharField()
- uptime = forms.CharField()
- build_fingerprint = forms.CharField()
- boot_reason = forms.CharField()
- power_on_reason = forms.CharField()
- power_off_reason = forms.CharField()
- aux_data = forms.CharField()
- crashreport = forms.FileField(required=False)
- date = forms.DateTimeField()
- report_type = forms.CharField(required=False)
- app_version = forms.IntegerField(required=False)
+#
+# class CrashreportForm(forms.Form):
+# uuid = forms.CharField()
+# uptime = forms.CharField()
+# build_fingerprint = forms.CharField()
+# boot_reason = forms.CharField()
+# power_on_reason = forms.CharField()
+# power_off_reason = forms.CharField()
+# aux_data = forms.CharField()
+# crashreport = forms.FileField(required=False)
+# date = forms.DateTimeField()
+# report_type = forms.CharField(required=False)
+# app_version = forms.IntegerField(required=False)
diff --git a/crashreports/migrations/0001_initial.py b/crashreports/migrations/0001_initial.py
index d882a9b..203f616 100644
--- a/crashreports/migrations/0001_initial.py
+++ b/crashreports/migrations/0001_initial.py
@@ -1,9 +1,13 @@
# -*- coding: utf-8 -*-
-# Generated by Django 1.9.7 on 2016-08-23 08:51
+# Generated by Django 1.10.2 on 2016-10-11 14:04
from __future__ import unicode_literals
-from django.db import migrations, models
import crashreports.models
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import taggit.managers
+import uuid
class Migration(migrations.Migration):
@@ -11,6 +15,8 @@
initial = True
dependencies = [
+ ('taggit', '0002_auto_20150616_2121'),
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
@@ -18,15 +24,57 @@
name='Crashreport',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('uuid', models.CharField(max_length=200)),
+ ('is_fake_report', models.BooleanField(default=False)),
+ ('app_version', models.IntegerField()),
('uptime', models.CharField(max_length=200)),
('build_fingerprint', models.CharField(max_length=200)),
('boot_reason', models.CharField(max_length=200)),
('power_on_reason', models.CharField(max_length=200)),
('power_off_reason', models.CharField(max_length=200)),
- ('aux_data', models.CharField(max_length=200)),
('date', models.DateTimeField()),
- ('crashreport_file', models.FileField(blank=True, null=True, upload_to=crashreports.models.crashreport_file_name)),
],
),
+ migrations.CreateModel(
+ name='Device',
+ fields=[
+ ('uuid', models.CharField(default=uuid.uuid4, editable=False, max_length=32, primary_key=True, serialize=False)),
+ ('iemi', models.CharField(blank=True, max_length=32, null=True)),
+ ('board_date', models.DateTimeField(blank=True, null=True)),
+ ('last_heartbeat', models.DateTimeField(blank=True, null=True)),
+ ('token', models.CharField(blank=True, max_length=200, null=True)),
+ ('tags', taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')),
+ ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='Hiccup_Device', to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='HeartBeat',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('app_version', models.IntegerField()),
+ ('uptime', models.CharField(max_length=200)),
+ ('build_fingerprint', models.CharField(max_length=200)),
+ ('date', models.DateTimeField()),
+ ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='crashreports.Device')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='LogFile',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('logfile_type', models.TextField(max_length=36)),
+ ('crashreport_file', models.FileField(upload_to=crashreports.models.crashreport_file_name)),
+ ('crashreport', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='crashreports.Crashreport')),
+ ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='crashreports.Device')),
+ ],
+ ),
+ migrations.AddField(
+ model_name='crashreport',
+ name='device',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='crashreports.Device'),
+ ),
+ migrations.AddField(
+ model_name='crashreport',
+ name='tags',
+ field=taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
+ ),
]
diff --git a/crashreports/models.py b/crashreports/models.py
index 38d86ff..ebf9c4b 100644
--- a/crashreports/models.py
+++ b/crashreports/models.py
@@ -1,29 +1,55 @@
# -*- coding: utf-8 -*-
from django.db import models
import datetime
+from django.contrib.auth.models import User
+from taggit.managers import TaggableManager
+import uuid
+
+class Device(models.Model):
+ # for every device there is a django user
+ uuid = models.CharField(max_length=64, unique=True, default=uuid.uuid4, editable=False)
+ user = models.OneToOneField(User, related_name='Hiccup_Device', on_delete=models.CASCADE, unique=True)
+ imei = models.CharField(max_length=32, null=True, blank=True)
+ board_date = models.DateTimeField(null=True, blank= True)
+ chipset = models.CharField(max_length=200, null=True, blank= True)
+ tags = TaggableManager(blank=True)
+ last_heartbeat = models.DateTimeField(null=True, blank=True)
+ token = models.CharField(max_length=200, null=True, blank=True)
def crashreport_file_name(instance, filename):
- return '/'.join(["crashreport_uploads", instance.uuid, str(datetime.date.today().year), str(datetime.date.today().month), str(datetime.date.today().day), filename])
-
+ return '/'.join([
+ "crashreport_uploads",
+ instance.device.uuid,
+ instance.crashreport.id,
+ str(instance.crashreport.date),
+ filename])
class Crashreport(models.Model):
- uuid = models.CharField(max_length=200)
- report_type = models.CharField(max_length=200)
+ device = models.ForeignKey(Device, on_delete=models.CASCADE)
+ is_fake_report = models.BooleanField(default=False)
+ app_version = models.IntegerField()
+ uptime = models.CharField(max_length=200)
+ build_fingerprint = models.CharField(max_length=200)
+ boot_reason = models.CharField(max_length=200)
+ power_on_reason = models.CharField(max_length=200)
+ power_off_reason = models.CharField(max_length=200)
+ date = models.DateTimeField()
+ tags = TaggableManager(blank=True)
+ def _get_uuid(self):
+ "Returns the person's full name."
+ return self.device.uuid
+ uuid = property(_get_uuid)
+
+
+class LogFile(models.Model):
+ logfile_type = models.TextField(max_length=36)
+ device = models.ForeignKey(Device, on_delete=models.CASCADE)
+ crashreport = models.ForeignKey(Crashreport, on_delete=models.CASCADE)
+ crashreport_file = models.FileField(upload_to=crashreport_file_name)
+
+class HeartBeat(models.Model):
+ device = models.ForeignKey(Device, on_delete=models.CASCADE)
app_version = models.IntegerField()
uptime = models.CharField(max_length=200)
build_fingerprint = models.CharField(max_length=200)
- boot_reason = models.CharField(max_length=200)
- power_on_reason = models.CharField(max_length=200)
- power_off_reason = models.CharField(max_length=200)
- aux_data = models.CharField(max_length=200)
date = models.DateTimeField()
- crashreport_file = models.FileField(upload_to=crashreport_file_name, null=True, blank=True)
-
- def crashreport_file_link(self):
- if self.crashreport_file:
- return '<a href="/hiccup/' + str(self.crashreport_file.url) + '">' + 'Logfile' + '</a>'
- else:
- return '<a href="''"></a>'
-
- crashreport_file_link.allow_tags = True
- crashreport_file_link.short_description = "File Link"
diff --git a/crashreports/rest_api_crashreports.py b/crashreports/rest_api_crashreports.py
new file mode 100644
index 0000000..83b94e4
--- /dev/null
+++ b/crashreports/rest_api_crashreports.py
@@ -0,0 +1,38 @@
+from rest_framework import filters
+from rest_framework import generics
+from rest_framework.response import Response
+
+from rest_framework.decorators import api_view
+from rest_framework.decorators import permission_classes
+
+from rest_framework.permissions import AllowAny
+
+from rest_framework.permissions import IsAdminUser
+from rest_framework.permissions import IsAuthenticated
+from rest_framework.permissions import AllowAny
+
+
+from rest_framework.permissions import BasePermission
+
+from rest_framework.authtoken.models import Token
+
+from crashreports.models import Crashreport
+from crashreports.serializers import CrashReportSerializer
+
+# class IsCreationAndHasCreationRights(BasePermission):
+# def has_permission(self, request, view):
+# if not request.user.is_authenticated():
+# if view.action == 'create':
+# if request.user.has_permission(""):
+# return True
+# return False
+# else:
+# return True
+#
+
+class ListCreateCrashReport(generics.ListCreateAPIView):
+ queryset = Crashreport.objects.all()
+ paginate_by = 20
+ permission_classes = (IsAuthenticated, )
+ serializer_class = CrashReportSerializer
+ pass
diff --git a/crashreports/rest_api_devices.py b/crashreports/rest_api_devices.py
new file mode 100644
index 0000000..0c4d6b1
--- /dev/null
+++ b/crashreports/rest_api_devices.py
@@ -0,0 +1,52 @@
+from rest_framework import filters
+from rest_framework import generics
+from rest_framework.response import Response
+
+from rest_framework.decorators import api_view
+from rest_framework.decorators import permission_classes
+
+from rest_framework.permissions import AllowAny
+
+from rest_framework.permissions import IsAdminUser
+from rest_framework.permissions import IsAuthenticated
+
+from rest_framework.permissions import BasePermission
+from rest_framework.authtoken.models import Token
+
+from django.contrib.auth.models import Permission
+
+from crashreports.models import Device
+from crashreports.models import User
+
+from crashreports.serializers import DeviceSerializer
+
+class ListCreateDevices(generics.ListCreateAPIView):
+ queryset = Device.objects.all()
+ paginate_by = 20
+ permission_classes = (IsAuthenticated, )
+ serializer_class = DeviceSerializer
+ pass
+
+class RetrieveUpdateDestroyDevice(generics.RetrieveUpdateDestroyAPIView):
+ queryset = Device.objects.all()
+ permission_classes = (IsAuthenticated, )
+ serializer_class = DeviceSerializer
+ lookup_field = 'uuid'
+ pass
+
+@api_view(http_method_names=['POST'], )
+@permission_classes((AllowAny,))
+def register_device(request):
+ """ Register a new device. This endpoint will generate a django user for the
+ new device. The device is identified by a uuid, and authenticated with a token.
+ We generate the uuid here as this makes it easier to deal with collisions.
+ """
+ device = Device()
+ user = User.objects.create_user("device_"+str(device.uuid), '', None)
+ permission = Permission.objects.get(name='Can add crashreport')
+ user.user_permissions.add(permission)
+ user.save()
+ device.user = user
+ device.token = Token.objects.create(user=user).key
+ device.save()
+ return Response({'uuid':device.uuid, 'token': device.token})
diff --git a/crashreports/serializers.py b/crashreports/serializers.py
index 783c0d7..5ccf3b8 100644
--- a/crashreports/serializers.py
+++ b/crashreports/serializers.py
@@ -1,10 +1,33 @@
from rest_framework import serializers
-from models import Crashreport
+from rest_framework.serializers import PrimaryKeyRelatedField
+from rest_framework.serializers import CharField
+from rest_framework.serializers import ObjectDoesNotExist
+from rest_framework.exceptions import NotFound
+from crashreports.models import Crashreport
+from crashreports.models import Device
from rest_framework import permissions
+
class CrashReportSerializer(serializers.ModelSerializer):
- permission_classes = (permissions.IsAuthenticated)
+ permission_classes = (permissions.AllowAny,)
+ uuid = serializers.CharField(max_length=64)
class Meta:
model = Crashreport
- fields = ('pk','uuid', 'uptime', 'build_fingerprint', 'boot_reason',
- 'power_on_reason', 'power_off_reason', 'aux_data', 'date','app_version', 'report_type')
+ exclude = ('device',)
+
+ def create(self, validated_data):
+ try:
+ device = Device.objects.get(uuid=validated_data['uuid'])
+ except:
+ raise NotFound(detail="uuid does not exist")
+ validated_data.pop('uuid', None)
+ report = Crashreport(**validated_data)
+ report.device=device
+ report.save()
+ return report
+
+
+class DeviceSerializer(serializers.ModelSerializer):
+ permission_classes = (permissions.IsAdminUser,)
+ class Meta:
+ model = Device
diff --git a/crashreports/tests.py b/crashreports/tests.py
index 7ce503c..3eb6854 100644
--- a/crashreports/tests.py
+++ b/crashreports/tests.py
@@ -1,3 +1,142 @@
from django.test import TestCase
+from rest_framework.test import APITestCase
+from rest_framework.test import APIClient
+from django.contrib.auth.models import User
+from rest_framework.test import force_authenticate
# Create your tests here.
+
+
+class DeviceTestCase(APITestCase):
+
+ def setUp(self):
+ pass
+
+ def test(self):
+ request = self.client.post("/hiccup/api/v1/devices/register/", {})
+ self.assertTrue("token" in request.data)
+ self.assertTrue("uuid" in request.data)
+ self.assertEqual(request.status_code, 200)
+
+# Create your tests here.
+
+
+class ListDevicesTestCase(APITestCase):
+
+ def setUp(self):
+ self.password = "test"
+ self.admin = User.objects.create_superuser(
+ 'myuser', 'myemail@test.com', self.password)
+ self.client.post("/hiccup/api/v1/devices/register/", {})
+ request = self.client.post("/hiccup/api/v1/devices/register/", {})
+ self.uuid_to_retrieve = request.data['uuid']
+ self.token_to_retrieve = request.data['token']
+ request = self.client.post("/hiccup/api/v1/devices/register/", {})
+ self.uuid_to_delete = request.data['uuid']
+ self.token_to_delete = request.data['token']
+
+ def test_device_list(self):
+ client = APIClient()
+ client.login(username='myuser', password='test')
+ request = client.get("/hiccup/api/v1/devices/", {})
+ self.assertTrue("uuid" in request.data[1])
+ self.assertTrue(len(request.data) >= 3)
+ self.assertEqual(request.status_code, 200)
+ client.logout()
+
+ def test_device_list_unauth(self):
+ client = APIClient()
+ request = client.get("/hiccup/api/v1/devices/", {})
+ self.assertEqual(request.status_code, 401)
+
+ def test_retrieve_device_auth(self):
+ client = APIClient()
+ client.login(username='myuser', password='test')
+ request = client.get(
+ "/hiccup/api/v1/devices/{}/".format(self.uuid_to_retrieve), {})
+ self.assertEqual(request.status_code, 200)
+ self.assertEqual(request.data['uuid'], str(self.uuid_to_retrieve))
+ self.assertEqual(request.data['token'], self.token_to_retrieve)
+ client.logout()
+
+ def test_retrieve_device_unauth(self):
+ client = APIClient()
+ request = client.get(
+ "/hiccup/api/v1/devices/{}/".format(self.uuid_to_retrieve), {})
+ self.assertEqual(request.status_code, 401)
+
+ def test_delete_device_auth(self):
+ client = APIClient()
+ client.login(username='myuser', password='test')
+ url = "/hiccup/api/v1/devices/{}/".format(self.uuid_to_delete)
+ request = client.delete(url, {})
+ # self.assertEqual(request.status_code, 204)
+ # request = client.delete("/hiccup/api/v1/devices/{}/".format(self.uuid_to_delete),{})
+ # self.assertEqual(request.status_code, 404)
+ client.logout()
+
+import datetime
+
+
+def create_dummy_crash_report(uuid="not set"):
+ return {
+ 'uuid': uuid,
+ 'is_fake_report': 0,
+ 'app_version': 2,
+ 'uptime': "2 Hours",
+ 'build_fingerprint': "models.CharField(max_length=200)",
+ 'boot_reason': "models.CharField(max_length=200)",
+ 'power_on_reason': "models.CharField(max_length=200)",
+ 'power_off_reason': "models.CharField(max_length=200)",
+ 'date': str(datetime.datetime(year=2016, month=1, day=1))
+ }
+
+from crashreports.models import Crashreport
+
+class CreateCrashreportTestCase(APITestCase):
+
+ def setUp(self):
+ self.password = "test"
+ self.admin = User.objects.create_superuser(
+ 'myuser', 'myemail@test.com', self.password)
+ # we need a device
+ request = self.client.post("/hiccup/api/v1/devices/register/", {})
+ self.uuid = request.data['uuid']
+ self.token = request.data['token']
+ request = self.client.post("/hiccup/api/v1/devices/register/", {})
+ self.other_uuid = request.data['uuid']
+ self.other_token = request.data['token']
+ self.crashreport = create_dummy_crash_report(self.uuid)
+
+ def test_create_crashreport_no_auth(self):
+ client = APIClient()
+ request = client.post("/hiccup/api/v1/crashreports/", self.crashreport)
+ self.assertEqual(request.status_code, 401)
+
+ def test_create_crashreport_as_admin(self):
+ client = APIClient()
+ client.login(username='myuser', password='test')
+ request = client.post("/hiccup/api/v1/crashreports/", self.crashreport)
+ self.assertEqual(request.status_code, 201)
+ client.logout()
+
+ def test_create_crashreport_as_admin_not_existing_device(self):
+ client = APIClient()
+ client.login(username='myuser', password='test')
+ request = client.post("/hiccup/api/v1/crashreports/", create_dummy_crash_report())
+ self.assertEqual(request.status_code, 404)
+ client.logout()
+
+ def test_create_crashreport_as_uuid_owner(self):
+ client = APIClient()
+ client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
+ request = client.post("/hiccup/api/v1/crashreports/", create_dummy_crash_report(self.uuid))
+ self.assertEqual(request.status_code, 201)
+ client.credentials()
+
+ def test_create_crashreport_as_uuid_not_owner(self):
+ client = APIClient()
+ client.credentials(HTTP_AUTHORIZATION='Token ' + self.token)
+ request = client.post("/hiccup/api/v1/crashreports/", create_dummy_crash_report(self.other_uuid))
+ self.assertEqual(request.status_code, 403)
+ client.credentials()
diff --git a/crashreports/urls.py b/crashreports/urls.py
index 6f47ff8..a81f242 100644
--- a/crashreports/urls.py
+++ b/crashreports/urls.py
@@ -1,17 +1,21 @@
from django.conf.urls import url, include
from . import views
-from rest_framework import routers
-from rest_framework import filters
+from . import rest_api_devices
+from . import rest_api_crashreports
-router = routers.DefaultRouter()
-router.register(r'crashreports', views.CrashreportViewSet)
urlpatterns = [
- url(r'^crashreport/', views.index, name='index'),
- url(r'^crashreports/hiccup_stats/(?P<version>[0-9]+)/', views.hiccup_stats, name='home'),
- url(r'^crashreports/hiccup_stats/', views.hiccup_stats, name='home'),
- url(r'^crashreport_uploads/(?P<path>.*)$', views.serve_saved_crashreport, name='serve_saved_crashreport'),
- url(r'^crashreports_per_day/', views.CrashReportPerDayView.as_view(), name='reports_per_day'),
- url(r'^', include(router.urls)),
+
+ url(r'^api/v1/crashreports/$', rest_api_crashreports.ListCreateCrashReport.as_view(), name='api_v1_crashreports'),
+ # url(r'^api/v1/crashreports/(?P<pk>[0-9]+)/$', views.index, name='api_v1_crashreports_single'),
+ # url(r'^api/v1/crashreports/(?P<pk>[0-9]+)/logfiles/$', views.index, name='api_v1_crashreports_single_logfiles'),
+ # url(r'^api/v1/crashreports/(?P<pk>[0-9]+)/logfiles/(?P<pk>[0-9]+)/$', views.index, name='api_v1_crashreports_single_logfiles_single'),
+ #
+ # url(r'^api/v1//logfiles/$',views.index, name='api_v1_logfiles'),
+ # url(r'^api/v1//logfiles/(?P<pk>[0-9]+)/$',views.index, name='api_v1_logfiles_single')
+
+ url(r'^api/v1/devices/$', rest_api_devices.ListCreateDevices.as_view(), name='api_v1_list_devices'),
+ url(r'^api/v1/devices/(?P<uuid>[a-f0-9-]+)/$', rest_api_devices.RetrieveUpdateDestroyDevice.as_view(), name='api_v1_retrieve_device'),
+ url(r'^api/v1/devices/register/$', rest_api_devices.register_device, name='api_v1_register_device'),
]
diff --git a/crashreports/views.py b/crashreports/views.py
index 3b09e4f..a25b071 100644
--- a/crashreports/views.py
+++ b/crashreports/views.py
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
-
import datetime
import django_filters
import os
@@ -22,80 +21,25 @@
from rest_framework import filters
from rest_framework import generics
-from rest_framework import viewsets
from rest_framework.permissions import BasePermission
+from rest_framework import viewsets
-from crashreports.forms import CrashreportForm
+import rest_framework
+
from crashreports.models import Crashreport
-from serializers import CrashReportSerializer
+from crashreports.serializers import CrashReportSerializer
-@ratelimit( key='ip', rate='100/h')
-@csrf_exempt
-def index(request):
- # Handle file upload`
- if request.method == 'POST':
- form = CrashreportForm(request.POST, request.FILES)
- if form.is_valid():
- # DEAL with the old version of the app:
- if 'app_version' not in request.POST:
- app_version = 0
- boot_reason=form.cleaned_data['boot_reason']
- report_type = "FAKE_REPORT" if boot_reason == "FAKECRASH" else "CRASH_REPORT"
- else:
- app_version = form.cleaned_data['app_version']
- boot_reason = form.cleaned_data['boot_reason']
- report_type = form.cleaned_data["report_type"]
-
- new_cr = Crashreport(uuid=form.cleaned_data['uuid'],
- aux_data=form.cleaned_data['aux_data'],
- uptime=form.cleaned_data['uptime'],
- boot_reason=boot_reason,
- power_on_reason=form.cleaned_data['power_on_reason'],
- power_off_reason=form.cleaned_data['power_off_reason'],
- build_fingerprint=form.cleaned_data['build_fingerprint'],
- date=form.cleaned_data['date'],
- app_version = app_version,
- report_type = report_type)
-
- try:
- new_cr.crashreport_file = request.FILES['crashreport']
- except:
- new_cr.crashreport_file = None
-
- new_cr.save()
- # Redirect to the document list after POST
- return HttpResponse(status=204)
- else:
- return HttpResponse(status=400)
- else:
- return HttpResponse(status=400)
-
-
-
-@login_required
-def hiccup_stats(request,version=2):
- version = int(version)
- templates = {
- 1 : 'crashreports/hiccup_stats.html',
- 2 : 'crashreports/hiccup_stats2.html',
- }
- if version not in templates:
- version = 2
- template = loader.get_template(templates[version])
- return HttpResponse(template.render({}, request))
-
-
-@login_required
-def serve_saved_crashreport (request, path):
- if settings.DEBUG == False:
- response = HttpResponse()
- response["Content-Disposition"] = "attachment; filename={0}".format(
- os.path.basename(path))
- response['X-Accel-Redirect'] = "/hiccup/protected/{0}".format(path)
- return response
- else:
- return serve(request, os.path.basename(path), os.path.dirname(settings.BASE_DIR + "/crashreport_uploads/" + path))
+# @login_required
+# def serve_saved_crashreport (request, path):
+# if settings.DEBUG == False:
+# response = HttpResponse()
+# response["Content-Disposition"] = "attachment; filename={0}".format(
+# os.path.basename(path))
+# response['X-Accel-Redirect'] = "/hiccup/protected/{0}".format(path)
+# return response
+# else:
+# return serve(request, os.path.basename(path), os.path.dirname(settings.BASE_DIR + "/crashreport_uploads/" + path))
class IsCreationOrIsAuthenticated(BasePermission):
@@ -108,18 +52,21 @@
else:
return True
+
+
class ListFilter(django_filters.Filter):
def filter(self, qs, value):
value_list = value.split(u',')
return super(ListFilter, self).filter(qs, django_filters.fields.Lookup(value_list, 'in'))
+
class CrashreportFilter(filters.FilterSet):
start_date = django_filters.DateTimeFilter(name="date", lookup_expr='gte')
end_date = django_filters.DateTimeFilter(name="date", lookup_expr='lte')
boot_reason = ListFilter(name='boot_reason')
class Meta:
model = Crashreport
- fields = ['build_fingerprint','boot_reason', 'power_on_reason', 'power_off_reason', 'report_type']
+ fields = ['build_fingerprint','boot_reason', 'power_on_reason', 'power_off_reason']
class CrashreportViewSet(viewsets.ModelViewSet):
queryset = Crashreport.objects.all()
@@ -127,15 +74,3 @@
permission_classes = [IsCreationOrIsAuthenticated]
filter_backends = (filters.DjangoFilterBackend,)
filter_class = CrashreportFilter
-
-from rest_framework.views import APIView
-from rest_framework.response import Response
-
-class CrashReportPerDayView(APIView):
- permission_classes = [IsCreationOrIsAuthenticated]
- def get(self, request, format=None):
- """
- Return a list of all users.
- """
- result = Crashreport.objects.filter(date__gt="2016-01-01").extra({'date':"date(date)"}).values('date').annotate(count=Count('id'))
- return Response(result)