Completed
Push — master ( 6a4ed1...7ae2ee )
by
unknown
44s
created

PartialUpdateViewSet   A

Complexity

Total Complexity 0

Size/Duplication

Total Lines 3
Duplicated Lines 0 %

Importance

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