81 lines
3.2 KiB
Python
81 lines
3.2 KiB
Python
import pytz
|
|
from functools import reduce
|
|
# from collections import OrderedDict
|
|
from datetime import datetime, time, timedelta
|
|
from django.db.models import Max
|
|
from celery import task
|
|
from counter.models import DeviceCount
|
|
from mosquito.models import MosqPostStatistic
|
|
|
|
|
|
def max_count(x, y):
|
|
if x.count > y.count:
|
|
return x
|
|
return y
|
|
|
|
|
|
def shortest_date(date, date_list):
|
|
distance_list = [(date - _date).days for _date in date_list]
|
|
shortest_distance = min(filter(lambda x: x > 0, distance_list))
|
|
return shortest_distance
|
|
|
|
|
|
@task()
|
|
def update_daily_statistic():
|
|
# calc_ret = {}
|
|
# queryset = DeviceCount.objects.raw(
|
|
# 'select id, device_id, max(data_time) as max_date '
|
|
# 'from device_count group by device_id, date(data_time) order by max_date')
|
|
#
|
|
# if queryset:
|
|
# ret = []
|
|
# for q in queryset:
|
|
# entry = DeviceCount.objects.filter(device_id=q.device_id, data_time=q.max_date)
|
|
# entry = reduce(max_count, entry) if len(entry) > 1 else entry[0]
|
|
# ret.append((entry.data_time.date(), int(entry.count)))
|
|
# if ret:
|
|
# for item in ret:
|
|
# key, value = item[0], item[1]
|
|
# try:
|
|
# calc_ret[key] += value
|
|
# except KeyError:
|
|
# calc_ret[key] = value
|
|
queryset = DeviceCount.objects.raw('select id, date(data_time) as date from device_count group by date')
|
|
if queryset:
|
|
tz = pytz.timezone("UTC")
|
|
ret = {}
|
|
for q in queryset:
|
|
midnight = tz.localize(datetime.combine(q.date, time(23, 59)), is_dst=None)
|
|
daily_queryset = [DeviceCount.objects.filter(device_id=x['device_id'], data_time=x['max_time'])
|
|
for x in DeviceCount.objects.filter(data_time__lte=midnight).values(
|
|
'device_id').annotate(max_time=Max('data_time'))]
|
|
if daily_queryset:
|
|
daily_queryset = [reduce(max_count, entry) if len(entry) > 1 else entry[0] for entry in daily_queryset]
|
|
calc_result = sum(map(lambda x: int(x.count), daily_queryset))
|
|
date = q.date
|
|
ret[date] = calc_result
|
|
date_list = [k for k in ret]
|
|
min_date = min(date_list)
|
|
max_date = max(date_list)
|
|
days = (max_date - min_date).days
|
|
for d in range(1, days+1):
|
|
date_ahead = min_date + timedelta(days=d)
|
|
if date_ahead not in ret:
|
|
distance = shortest_date(date_ahead, date_list)
|
|
ret[date_ahead] = ret[date_ahead - timedelta(days=distance)]
|
|
|
|
# Update statistic to MosqPostStatistic
|
|
_date_list = [k for k in ret]
|
|
_date_list.sort()
|
|
is_first = True
|
|
for d in _date_list:
|
|
if is_first:
|
|
history, created = MosqPostStatistic.objects.update_or_create(date=d, total=ret[d], increment=ret[d])
|
|
else:
|
|
increment = ret[d] - ret[d-timedelta(days=1)]
|
|
history, created = MosqPostStatistic.objects.update_or_create(date=d, total=ret[d], increment=increment)
|
|
is_first = False
|
|
|
|
@task()
|
|
def update_latest_statistic():
|
|
pass |