From fce247b7c066806693552efff44566a0721e4ce0 Mon Sep 17 00:00:00 2001 From: xianfuxing Date: Mon, 13 Aug 2018 20:22:20 +0800 Subject: [PATCH] # up mosq task --- apps/mosquito/tasks.py | 74 +++++++++++++++++++++++++++++++++++++----- mosqkiller/settings.py | 4 +-- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/apps/mosquito/tasks.py b/apps/mosquito/tasks.py index 5d80caf..11dded8 100644 --- a/apps/mosquito/tasks.py +++ b/apps/mosquito/tasks.py @@ -1,22 +1,80 @@ import pytz -from datetime import datetime, time +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(): - 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') - + # 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: - ret = [] + tz = pytz.timezone("UTC") + ret = {} for q in queryset: - entry = DeviceCount.objects.get(device_id=q.device_id, data_time=q.data_time) - ret.append((entry.data_time, entry.device_id, entry.count)) + 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(): diff --git a/mosqkiller/settings.py b/mosqkiller/settings.py index c40839a..2c173c6 100644 --- a/mosqkiller/settings.py +++ b/mosqkiller/settings.py @@ -208,11 +208,11 @@ CELERY_TASK_SERIALIZER = 'json' CELERY_TIMEZONE = 'Asia/Shanghai' CELERY_BEAT_SCHEDULE = { 'update-daily-statistic': { - 'task': 'counter.tasks.update_daily_statistic', + 'task': 'mosquito.tasks.update_daily_statistic', 'schedule': crontab(minute='*/1'), }, 'update-latest-statistic': { - 'task': 'counter.tasks.update_latest_statistic', + 'task': 'mosquito.tasks.update_latest_statistic', 'schedule': crontab(minute='*/1'), }, } \ No newline at end of file