Completed
Push — master ( 824653...e6f560 )
by Egor
01:03
created

StatisticsMonthsDetailView.get()   F

Complexity

Conditions 9

Size

Total Lines 27

Duplication

Lines 9
Ratio 33.33 %

Importance

Changes 0
Metric Value
cc 9
c 0
b 0
f 0
dl 9
loc 27
rs 3
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 datetime
22
23
from django.http import Http404
24
from django.conf import settings
25
from django.utils import timezone
26
27
from rest_framework import viewsets
28
from rest_framework import mixins
29
from rest_framework import pagination
30
from rest_framework.views import APIView
31
from rest_framework.response import Response
32
33
import pytz
34
35
from omaha.statistics import (
36
    get_users_statistics_months,
37
    get_users_versions,
38
    get_channel_statistics,
39
    get_users_live_versions
40
)
41
from omaha.serializers import (
42
    AppSerializer,
43
    DataSerializer,
44
    PlatformSerializer,
45
    ChannelSerializer,
46
    VersionSerializer,
47
    ActionSerializer,
48
    StatisticsMonthsSerializer,
49
    MonthRangeSerializer,
50
    MonthInputSerializer,
51
    ServerVersionSerializer,
52
    LiveStatisticsInputSerializer,
53
)
54
from omaha.models import (
55
    Application,
56
    Data,
57
    Platform,
58
    Channel,
59
    Version,
60
    Action,
61
)
62
from omaha.utils import get_month_range_from_dict
63
64
65
class BaseView(mixins.ListModelMixin, mixins.CreateModelMixin,
66
               mixins.DestroyModelMixin, mixins.RetrieveModelMixin,
67
               viewsets.GenericViewSet):
68
    pass
69
70
71
class StandardResultsSetPagination(pagination.PageNumberPagination):
72
    page_size = 10
73
    page_size_query_param = 'page_size'
74
    max_page_size = 100
75
76
77
class AppViewSet(viewsets.ModelViewSet):
78
    """
79
    API endpoint that allows applications to be viewed.
80
81
    ## Applications Collection
82
83
    ### List all Applications [GET]
84
85
    URL: `http://example.com/api/app/`
86
87
    Response:
88
89
        [
90
            {
91
                "id": "{8A76FC95-0086-4BCE-9517-DC09DDB5652F}",
92
                "name": "Chromium"
93
            },
94
            {
95
                "id": "{430FD4D0-B729-4F61-AA34-91526481799D}",
96
                "name": "Potato"
97
            }
98
        ]
99
100
101
    ### Create a Application [POST]
102
103
    URL: `http://example.com/api/app/`
104
105
    Headers:
106
107
        Content-Type: application/json
108
109
    Body:
110
111
        {
112
            "id": "{8A76FC95-0086-4BCE-9517-DC09DDB5652F}",
113
            "name": "Chromium",
114
        }
115
116
    Response:
117
118
        HTTP 201 CREATED
119
        Content-Type: application/json
120
121
        {
122
            "id": "{8A76FC95-0086-4BCE-9517-DC09DDB5652F}",
123
            "name": "Chromium",
124
        }
125
126
    ## Application
127
128
    ### Retrieve a Application [GET]
129
130
    URL: `http://example.com/api/app/[app_id]`
131
132
    Response:
133
134
        HTTP 201 CREATED
135
        Content-Type: application/json
136
137
        {
138
            "id": "{8A76FC95-0086-4BCE-9517-DC09DDB5652F}",
139
            "name": "Chromium",
140
        }
141
142
    ### Remove a Application [DELETE]
143
144
    URL: `http://example.com/api/app/[app_id]`
145
146
    Response:
147
148
        HTTP 204 NO CONTENT
149
        Content-Type: application/json
150
    """
151
    queryset = Application.objects.all().order_by('-id')
152
    serializer_class = AppSerializer
153
154
155
class DataViewSet(viewsets.ModelViewSet):
156
    queryset = Data.objects.all().order_by('-id')
157
    serializer_class = DataSerializer
158
159
160
class PlatformViewSet(viewsets.ModelViewSet):
161
    queryset = Platform.objects.all().order_by('-id')
162
    serializer_class = PlatformSerializer
163
164
165
class ChannelViewSet(viewsets.ModelViewSet):
166
    queryset = Channel.objects.all().order_by('-id')
167
    serializer_class = ChannelSerializer
168
169
170
class VersionViewSet(viewsets.ModelViewSet):
171
    queryset = Version.objects.all().order_by('-id')
172
    serializer_class = VersionSerializer
173
174
175
class ActionViewSet(viewsets.ModelViewSet):
176
    queryset = Action.objects.all().order_by('-id')
177
    serializer_class = ActionSerializer
178
179
180
class StatisticsMonthsDetailView(APIView):
181
    MAC_KEYS = ['new', 'updates']
182
    OMAHA_KEYS = MAC_KEYS + ['uninstalls']
183
184
    def get_object(self, name):
185
        try:
186
            return Application.objects.get(name=name)
187
        except Application.DoesNotExist:
188
            raise Http404
189
190
    def get(self, request, app_name, format=None):
191
        app = self.get_object(app_name)
192
        dates = MonthRangeSerializer(data=request.GET)
193
        dates.is_valid()
194
195
        start, end = get_month_range_from_dict(dates.validated_data)
196
197
        diapasons = [((start.month if year == start.year else 1, end.month if year == end.year else 12), year)
198
                     for year in range(start.year, end.year+1)]
199
200
        data = {}
201
        platforms = Platform.objects.values_list('name', flat=True)
202
        for platform in platforms:
203
            if platform == 'mac':
204
                platform_keys = self.MAC_KEYS
205
            else:
206
                platform_keys = self.OMAHA_KEYS
207
            platform_data = {key: [] for key in platform_keys}
208 View Code Duplication
            for diapason in diapasons:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
209
                step = get_users_statistics_months(app_id=app.id, platform=platform, year=diapason[1],
210
                                                   start=diapason[0][0], end=diapason[0][1])
211
                for key in platform_data:
212
                    platform_data[key] += step[key]
213
            data.update({platform: platform_data})
214
215
        serializer = StatisticsMonthsSerializer(dict(data=data))
216
        return Response(serializer.data)
217
218
class StatisticsVersionsView(APIView):
219
    def get_object(self, name):
220
        try:
221
            return Application.objects.get(name=name)
222
        except Application.DoesNotExist:
223
            raise Http404
224
225
    def get(self, request, app_name, format=None):
226
        now = timezone.now()
227
        app = self.get_object(app_name)
228
229
        date = MonthInputSerializer(data=request.GET)
230
        date.is_valid()
231
        date = date.validated_data.get('date', now)
232
233
        data = get_users_versions(app.id, date=date)
234
        serializer = StatisticsMonthsSerializer(dict(data=dict(data)))
235
        return Response(serializer.data)
236
237
238
class StatisticsVersionsLiveView(APIView):
239
    def get_object(self, name):
240
        try:
241
            return Application.objects.get(name=name)
242
        except Application.DoesNotExist:
243
            raise Http404
244
245
    def get(self, request, app_name, format=None):
246
        import logging
247
        logging.info('Starting working in view')
248
        app = self.get_object(app_name)
249
250 View Code Duplication
        now = timezone.now()
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
251
        data = LiveStatisticsInputSerializer(data=request.GET)
252
        data.is_valid()
253
254
        end = data.validated_data.get('end', now)
255
        start = data.validated_data.get('start', end - datetime.timedelta(hours=24))
256
        channel = data.validated_data.get('channel')
257
258
        data = get_users_live_versions(app.id, start, end, channel, tz=request.session.get('django_timezone', 'UTC'))
259
        logging.info('Getting data is finished')
260
        serializer = StatisticsMonthsSerializer(dict(data=dict(data)))
261
        return Response(serializer.data)
262
263
264
class StatisticsChannelsView(APIView):
265
    def get_object(self, name):
266
        try:
267
            return Application.objects.get(name=name)
268
        except Application.DoesNotExist:
269
            raise Http404
270
271
    def get(self, request, app_name, format=None):
272
        now = timezone.now()
273
        app = self.get_object(app_name)
274
275
        date = MonthInputSerializer(data=request.GET)
276
        date.is_valid()
277
        date = date.validated_data.get('date', now)
278
279
        data = get_channel_statistics(app.id, date=date)
280
        serializer = StatisticsMonthsSerializer(dict(data=dict(data)))
281
        return Response(serializer.data)
282
283
284
class ServerVersionView(APIView):
285
    def get(self, request, format=None):
286
        version = settings.APP_VERSION
287
        serializer = ServerVersionSerializer(dict(version=version))
288
        return Response(serializer.data)