diff --git a/kfet/statistic.py b/kfet/statistic.py index 4ae17959..fe948f73 100644 --- a/kfet/statistic.py +++ b/kfet/statistic.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -import ast from datetime import date, datetime, time, timedelta from dateutil.relativedelta import relativedelta +from dateutil.parser import parse as dateutil_parse from django.utils import timezone from django.db.models import Sum @@ -114,25 +114,29 @@ class MonthScale(Scale): return to_kfet_day(dt).replace(day=1) -def stat_manifest(scales_def=None, scale_args=None, **url_params): +def stat_manifest(scales_def=None, scale_args=None, scale_prefix=None, + **other_url_params): + if scale_prefix is None: + scale_prefix = 'scale_' if scales_def is None: scales_def = [] if scale_args is None: scale_args = {} - return [ - dict( + manifest = [] + for label, cls in scales_def: + url_params = {scale_prefix+'name': cls.name} + url_params.update({scale_prefix+key: value + for key, value in scale_args.items()}) + url_params.update(other_url_params) + manifest.append(dict( label=label, - url_params=dict( - scale=cls.name, - scale_args=scale_args, - **url_params, - ), - ) - for label, cls in scales_def - ] + url_params=url_params, + )) + return manifest -def last_stats_manifest(scales_def=None, scale_args=None, **url_params): +def last_stats_manifest(scales_def=None, scale_args=None, scale_prefix=None, + **url_params): scales_def = [ ('Derniers mois', MonthScale, ), ('Dernières semaines', WeekScale, ), @@ -145,7 +149,7 @@ def last_stats_manifest(scales_def=None, scale_args=None, **url_params): n_steps=7, )) return stat_manifest(scales_def=scales_def, scale_args=scale_args, - **url_params) + scale_prefix=scale_prefix, **url_params) # Étant donné un queryset d'operations @@ -156,20 +160,61 @@ def tot_ventes(queryset): class ScaleMixin(object): + scale_args_prefix = 'scale_' + + def get_scale_args(self, params=None, prefix=None): + """Retrieve scale args from params. + + Should search the same args of Scale constructor. + + Args: + params (dict, optional): Scale args are searched in this. + Default to GET params of request. + prefix (str, optional): Appended at the begin of scale args names. + Default to `self.scale_args_prefix`. + + """ + if params is None: + params = self.request.GET + if prefix is None: + prefix = self.scale_args_prefix + + scale_args = {} + + name = params.get(prefix+'name', None) + if name is not None: + scale_args['name'] = name + + n_steps = params.get(prefix+'n_steps', None) + if n_steps is not None: + scale_args['n_steps'] = int(n_steps) + + begin = params.get(prefix+'begin', None) + if begin is not None: + scale_args['begin'] = dateutil_parse(begin) + + end = params.get(prefix+'send', None) + if end is not None: + scale_args['end'] = dateutil_parse(end) + + last = params.get(prefix+'last', None) + if last is not None: + scale_args['last'] = ( + last in ['true', 'True', '1'] and True or False) + + return scale_args def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) - scale_name = self.request.GET.get('scale', None) + scale_args = self.get_scale_args() + scale_name = scale_args.pop('name', None) + scale_cls = Scale.by_name(scale_name) - cls = Scale.by_name(scale_name) - if cls is None: + if scale_cls is None: scale = self.get_default_scale() else: - scale_args = self.request.GET.get('scale_args', {}) - if isinstance(scale_args, str): - scale_args = ast.literal_eval(scale_args) - scale = cls(**scale_args) + scale = scale_cls(**scale_args) self.scale = scale context['labels'] = scale.get_labels() diff --git a/requirements.txt b/requirements.txt index 06f6c46e..ce081588 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,3 +20,4 @@ django-widget-tweaks==1.4.1 git+https://git.eleves.ens.fr/cof-geek/django_custommail.git#egg=django_custommail ldap3 git+https://github.com/Aureplop/channels.git#egg=channels +python-dateutil