django-orchestra-test/orchestra/contrib/resources/aggregations.py

92 lines
2.5 KiB
Python
Raw Normal View History

import datetime
2015-04-01 15:49:21 +00:00
import decimal
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from orchestra import plugins
2015-04-08 14:41:09 +00:00
class Aggregation(plugins.Plugin, metaclass=plugins.PluginMount):
""" filters and computes dataset usage """
def filter(self, dataset):
""" Filter the dataset to get the relevant data according to the period """
raise NotImplementedError
def compute_usage(self, dataset):
""" given a dataset computes its usage according to the method (avg, sum, ...) """
raise NotImplementedError
2015-04-08 14:41:09 +00:00
class Last(Aggregation):
name = 'last'
2015-04-01 15:49:21 +00:00
verbose_name = _("Last value")
def filter(self, dataset):
try:
return dataset.order_by('object_id', '-id').distinct('object_id')
2015-04-04 17:44:07 +00:00
except dataset.model.DoesNotExist:
return dataset.none()
def compute_usage(self, dataset):
# FIXME Aggregation of 0s returns None! django bug?
# value = dataset.aggregate(models.Sum('value'))['value__sum']
values = dataset.values_list('value', flat=True)
if values:
return sum(values)
return None
class MonthlySum(Last):
name = 'monthly-sum'
verbose_name = _("Monthly Sum")
def filter(self, dataset):
today = timezone.now()
return dataset.filter(
created_at__year=today.year,
created_at__month=today.month
)
class MonthlyAvg(MonthlySum):
name = 'monthly-avg'
verbose_name = _("Monthly AVG")
def get_epoch(self):
today = timezone.now()
return datetime(
year=today.year,
month=today.month,
day=1,
tzinfo=timezone.utc
)
def compute_usage(self, dataset):
2015-04-03 10:14:45 +00:00
result = 0
try:
last = dataset.latest()
except dataset.model.DoesNotExist:
return result
epoch = self.get_epoch()
total = (last.created_at-epoch).total_seconds()
ini = epoch
for data in dataset:
slot = (data.created_at-ini).total_seconds()
2015-04-01 15:49:21 +00:00
result += data.value * decimal.Decimal(str(slot/total))
ini = data.created_at
return result
class Last10DaysAvg(MonthlyAvg):
name = 'last-10-days-avg'
verbose_name = _("Last 10 days AVG")
days = 10
def get_epoch(self):
today = timezone.now()
return today - datetime.timedelta(days=self.days)
def filter(self, dataset):
return dataset.filter(created_at__gt=self.get_epoch())