blob: 6378d013681187f114f0f0ca640e841c92c511e2 [file] [log] [blame]
Dirk Vogt62ff7f22017-05-04 16:07:21 +02001from rest_framework import generics
2from rest_framework import serializers
3from rest_framework.response import Response
4from rest_framework.views import APIView
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +02005from crashreports.permissions import (
6 HasRightsOrIsDeviceOwnerDeviceCreation, HasStatsAccess)
Dirk Vogt62ff7f22017-05-04 16:07:21 +02007from django.db import connection
8from . import raw_querys
Dirk Vogt1accb672017-05-10 14:07:42 +02009from crashreport_stats.models import *
Dirk Vogt62ff7f22017-05-04 16:07:21 +020010import zipfile
11from crashreports.models import *
Dirk Vogt1accb672017-05-10 14:07:42 +020012from django.db.models.expressions import F
13import django_filters
14from rest_framework import filters
Dirk Vogt62ff7f22017-05-04 16:07:21 +020015
16def dictfetchall(cursor):
17 "Returns all rows from a cursor as a dict"
18 desc = cursor.description
19 return [
20 dict(zip([col[0] for col in desc], row))
21 for row in cursor.fetchall()
22 ]
23
24class DeviceUpdateHistory(APIView):
25 permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
26 def get(self, request, uuid, format=None):
27 cursor = connection.cursor()
28 raw_querys.execute_device_update_history_query(
29 cursor,
30 {
31 'uuid': uuid
32 })
33 res = dictfetchall(cursor)
34 return Response(res)
35
36class DeviceReportHistory(APIView):
37 permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
38 def get(self, request, uuid, format=None):
39 cursor = connection.cursor()
40 raw_querys.execute_device_report_history(
41 cursor,
42 {
43 'uuid': uuid
44 })
45 res = dictfetchall(cursor)
46 return Response(res)
47
Dirk Vogt571168c2017-12-08 16:54:12 +010048class Status(APIView):
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +020049 permission_classes = (HasStatsAccess,)
Dirk Vogt571168c2017-12-08 16:54:12 +010050 def get(self, request, format=None, ):
51 num_devices = Device.objects.count()
52 num_crashreports = Crashreport.objects.count()
53 num_heartbeats = HeartBeat.objects.count()
54 return Response( {
55 'devices': num_devices,
56 'crashreports': num_crashreports,
57 'heartbeats': num_heartbeats
58 })
59
Dirk Vogt62ff7f22017-05-04 16:07:21 +020060class DeviceStat(APIView):
61 permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
62 def get(self, request, uuid, format=None, ):
63 device = Device.objects.filter(uuid=uuid)
64 last_active = HeartBeat.objects.filter(device=device).order_by('-date')[0].date
65 heartbeats = HeartBeat.objects.filter(device=device).count()
Franz-Xaver Geiger0b3a48e2018-04-16 15:00:14 +020066 crashreports = Crashreport.objects.filter(device=device).filter(boot_reason__in=Crashreport.CRASH_BOOT_REASONS).count()
Dirk Vogt62ff7f22017-05-04 16:07:21 +020067 crashes_per_day = crashreports*1.0/heartbeats if heartbeats > 0 else 0
Franz-Xaver Geiger0b3a48e2018-04-16 15:00:14 +020068 smpls = Crashreport.objects.filter(device=device).filter(boot_reason__in=Crashreport.SMPL_BOOT_REASONS).count()
Dirk Vogt62ff7f22017-05-04 16:07:21 +020069 smpl_per_day = smpls*1.0/heartbeats if heartbeats > 0 else 0
70 return Response(
71 {
72 'uuid' : uuid,
73 'last_active' : last_active,
74 'heartbeats' : heartbeats,
75 'crashreports' : crashreports,
76 'crashes_per_day' : crashes_per_day,
77 'smpls' : smpls,
Dirk Vogt7439ee72017-12-05 15:51:17 +010078 'smpl_per_day' : smpl_per_day,
79 'board_date' : device[0].board_date,
Dirk Vogt62ff7f22017-05-04 16:07:21 +020080 })
81
82class LogFileDownload(APIView):
83 permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
84 def get(self, request, id, format=None):
85 try:
86 logfile = LogFile.objects.get(id=id)
87 except:
88 raise NotFound(detail="Logfile does not exist.")
89 zf = zipfile.ZipFile(logfile.logfile.path)
90 ret = {}
91 for f in zf.filelist:
92 fo = zf.open(f)
93 ret[f.filename] = fo.read()
94 return Response(ret)
Dirk Vogt1accb672017-05-10 14:07:42 +020095
Borjan Tchakaloff227b4312018-02-23 17:02:16 +040096
97class _VersionStatsFilter(filters.FilterSet):
Dirk Vogt1accb672017-05-10 14:07:42 +020098 first_seen_before = django_filters.DateFilter(name="first_seen_on", lookup_expr='lte')
Borjan Tchakaloff227b4312018-02-23 17:02:16 +040099 first_seen_after = django_filters.DateFilter(name="first_seen_on", lookup_expr='gte')
Dirk Vogt1accb672017-05-10 14:07:42 +0200100 released_before = django_filters.DateFilter(name="released_on", lookup_expr='lte')
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400101 released_after = django_filters.DateFilter(name="released_on", lookup_expr='gte')
Dirk Vogt1accb672017-05-10 14:07:42 +0200102
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400103class _VersionStatsSerializer(serializers.ModelSerializer):
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +0200104 permission_classes = (HasStatsAccess,)
Dirk Vogt1accb672017-05-10 14:07:42 +0200105
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400106class _VersionStatsListView(generics.ListAPIView):
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +0200107 permission_classes = (HasStatsAccess,)
Dirk Vogt1accb672017-05-10 14:07:42 +0200108 filter_backends = (filters.DjangoFilterBackend,)
Dirk Vogt1accb672017-05-10 14:07:42 +0200109
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400110class _DailyVersionStatsFilter(filters.FilterSet):
Dirk Vogt1accb672017-05-10 14:07:42 +0200111 date_start = django_filters.DateFilter(name="date", lookup_expr='gte')
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400112 date_end = django_filters.DateFilter(name="date", lookup_expr='lte')
113
114class _DailyVersionStatsSerializer(serializers.ModelSerializer):
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +0200115 permission_classes = (HasStatsAccess,)
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400116
117class _DailyVersionStatsListView(generics.ListAPIView):
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +0200118 permission_classes = (HasStatsAccess,)
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400119 filter_backends = (filters.DjangoFilterBackend,)
120
121
122class VersionSerializer(_VersionStatsSerializer):
123 class Meta:
124 model = Version
125 fields = '__all__'
126
127class VersionFilter(_VersionStatsFilter):
128 class Meta:
129 model = Version
130 fields = '__all__'
131
132class VersionListView(_VersionStatsListView):
133 queryset = Version.objects.all().order_by('-heartbeats')
134 filter_class = VersionFilter
135 serializer_class = VersionSerializer
136
137class VersionDailyFilter(_DailyVersionStatsFilter):
Dirk Vogt1accb672017-05-10 14:07:42 +0200138 version__build_fingerprint = django_filters.CharFilter()
139 version__is_official_release = django_filters.BooleanFilter()
140 version__is_beta_release = django_filters.BooleanFilter()
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400141
Dirk Vogt1accb672017-05-10 14:07:42 +0200142 class Meta:
143 model = VersionDaily
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400144 fields = '__all__'
Dirk Vogt1accb672017-05-10 14:07:42 +0200145
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400146class VersionDailySerializer(_DailyVersionStatsSerializer):
147 build_fingerprint = serializers.CharField()
148
Dirk Vogt1accb672017-05-10 14:07:42 +0200149 class Meta:
150 model = VersionDaily
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400151 fields = '__all__'
Dirk Vogt1accb672017-05-10 14:07:42 +0200152
Borjan Tchakaloff227b4312018-02-23 17:02:16 +0400153class VersionDailyListView(_DailyVersionStatsListView):
154 queryset = (
155 VersionDaily.objects
156 .annotate(build_fingerprint=F('version__build_fingerprint'))
157 .all()
158 .order_by('date')
159 )
160 filter_class = VersionDailyFilter
161 filter_fields = (
162 'version__build_fingerprint',
163 'version__is_official_release',
164 'version__is_beta_release',
165 )
Dirk Vogt1accb672017-05-10 14:07:42 +0200166 serializer_class = VersionDailySerializer
Borjan Tchakaloff1db45c72018-02-23 17:03:49 +0400167
168
169class RadioVersionSerializer(_VersionStatsSerializer):
170 class Meta:
171 model = RadioVersion
172 fields = '__all__'
173
174class RadioVersionFilter(_VersionStatsFilter):
175 class Meta:
176 model = RadioVersion
177 fields = '__all__'
178
179class RadioVersionListView(_VersionStatsListView):
180 queryset = RadioVersion.objects.all().order_by('-heartbeats')
181 serializer_class = RadioVersionSerializer
182 filter_class = RadioVersionFilter
183
184class RadioVersionDailyFilter(_DailyVersionStatsFilter):
185 version__radio_version = django_filters.CharFilter()
186 version__is_official_release = django_filters.BooleanFilter()
187 version__is_beta_release = django_filters.BooleanFilter()
188
189 class Meta:
190 model = RadioVersionDaily
191 fields = '__all__'
192
193class RadioVersionDailySerializer(_DailyVersionStatsSerializer):
194 radio_version = serializers.CharField()
195
196 class Meta:
197 model = RadioVersionDaily
198 fields = '__all__'
199
200class RadioVersionDailyListView(_DailyVersionStatsListView):
201 queryset = (
202 RadioVersionDaily.objects
203 .annotate(radio_version=F('version__radio_version'))
204 .all()
205 .order_by('date')
206 )
207 filter_class = RadioVersionDailyFilter
208 filter_fields = (
209 'version__radio_version',
210 'version__is_official_release',
211 'version__is_beta_release',
212 )
213 serializer_class = RadioVersionDailySerializer