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

get_platforms_by_appid()   A

Complexity

Conditions 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
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
from functools import wraps
22
import datetime
23
import calendar
24
25
from django.db.models import Q
26
27
from singledispatch import singledispatch
28
from django_redis import get_redis_connection
29
from redis.exceptions import WatchError
30
from django.utils import timezone
31
32
from omaha.settings import KEY_PREFIX, KEY_LAST_ID
33
from omaha.models import Platform
34
from sparkle.models import SparkleVersion
35
__all__ = ['get_sec_since_midnight', 'get_id']
36
37
redis = get_redis_connection('statistics')
38
39
40
def get_sec_since_midnight(date):
41
    """
42
    Return seconds since midnight
43
44
    >>> from datetime import datetime
45
    >>> get_sec_since_midnight(datetime(year=2014, month=1, day=1, second=42))
46
    42
47
    """
48
    midnight = date.replace(hour=0, minute=0, second=0, microsecond=0)
49
    delta = date - midnight
50
    return delta.seconds
51
52
53
def get_days_since_20070101(date):
54
    """
55
    Return days since 2007-01-01
56
57
    >>> from datetime import datetime
58
    >>> get_days_since_20070101(datetime(year=2016, month=3, day=4))
59
    3350
60
    """
61
    date_20070101 = datetime.datetime(year=2007, month=1, day=1, tzinfo=date.tzinfo)
62
    delta = date - date_20070101
63
    return delta.days
64
65
66
def get_id(uuid):
67
    """
68
    >>> get_id('{8C65E04C-0383-4AE2-893F-4EC7C58F70DC}')
69
    1
70
    >>> get_id('{8C65E04C-0383-4AE2-893F-4EC7C58F70DC}')
71
    1
72
    """
73
    id = redis.get('{}:{}'.format(KEY_PREFIX, uuid))
74
    if id is None:
75
        id = create_id(uuid)
76
    return int(id)
77
78
79
def create_id(uuid):
80
    """
81
    >>> create_id('{8C65E04C-0383-4AE2-893F-4EC7C58F70DC}')
82
    1
83
    """
84
    with redis.pipeline() as pipe:
85
        while True:
86
            try:
87
                pipe.watch(KEY_LAST_ID)
88
                current_id = pipe.get(KEY_LAST_ID) or 0
89
                next_id = int(current_id) + 1
90
                pipe.multi()
91
                pipe.set(KEY_LAST_ID, next_id)
92
                pipe.execute()
93
94
                redis.set('{}:{}'.format(KEY_PREFIX, uuid), next_id)
95
                return next_id
96
            except WatchError:
97
                continue
98
            except:
99
                raise
100
101
102
def valuedispatch(func):
103
    _func = singledispatch(func)
104
105
    @wraps(func)
106
    def wrapper(*args, **kwargs):
107
        return _func.registry.get(args[0], _func)(*args, **kwargs)
108
109
    wrapper.register = _func.register
110
    wrapper.dispatch = _func.dispatch
111
    wrapper.registry = _func.registry
112
    return wrapper
113
114
115
def make_piechart(id, data, unit='users'):
116
    xdata = [i[0] for i in data]
117
    ydata = [i[1] for i in data]
118
119
    extra_serie = {
120
        "tooltip": {"y_start": "", "y_end": " " + unit},
121
    }
122
    chartdata = {'x': xdata, 'y1': ydata, 'extra1': extra_serie}
123
    charttype = "pieChart"
124
    chartcontainer = 'chart_container_%s' % id  # container name
125
126
    data = {
127
        'charttype': charttype,
128
        'chartdata': chartdata,
129
        'chartcontainer': chartcontainer,
130
        'extra': {
131
            'x_is_date': False,
132
            'x_axis_format': '',
133
            'tag_script_js': True,
134
            'jquery_on_ready': False,
135
        }
136
    }
137
    return data
138
139
140
def get_month_range_from_dict(source):
141
    """
142
    :param source: dictionary with keys 'start' and 'end
143
    :return: a tuple of datatime objects in the form (start, end)
144
    """
145
    now = timezone.now()
146
    start = source.get('start')
147
148
    end = source.get('end', datetime.datetime(now.year, now.month, calendar.monthrange(now.year, now.month)[1]))
149
150
    if not start:
151
        start = datetime.datetime(end.year-1, end.month+1, 1) if end.month != 12 else datetime.datetime(end.year, 1, 1)
152
153
    return start, end
154
155
156
def is_new_install(appid, userid):
157
    event = "known_users:{}"
158
    return not redis.getbit(event.format(appid), userid)
159
160
161
def get_platforms_by_appid(app_id):
162
    filter_kwargs = Q(version__app=app_id)
163
    is_add_mac = SparkleVersion.objects.filter(app=app_id).exists()
164
    if is_add_mac:
165
        filter_kwargs |= Q(name='mac')
166
    return Platform.objects.filter(filter_kwargs).order_by('created').distinct()
167