From d5b9c785fb1ff59c1fa28641fc968fb9ff039dff Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Thu, 23 Aug 2018 13:05:34 -0400 Subject: [PATCH] Improve statistics subclassing. Split class module into classes and renderers. Signed-off-by: Roberto Rosario --- HISTORY.rst | 2 + mayan/apps/documents/statistics.py | 14 ++-- mayan/apps/mayan_statistics/__init__.py | 2 + mayan/apps/mayan_statistics/apps.py | 10 +-- mayan/apps/mayan_statistics/classes.py | 83 ++++--------------- mayan/apps/mayan_statistics/renderers.py | 75 +++++++++++++++++ .../{backends => renderers}/chartjs/line.html | 0 7 files changed, 105 insertions(+), 81 deletions(-) create mode 100644 mayan/apps/mayan_statistics/renderers.py rename mayan/apps/mayan_statistics/templates/statistics/{backends => renderers}/chartjs/line.html (100%) diff --git a/HISTORY.rst b/HISTORY.rst index c99b4eff93..a10dc066fc 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -106,6 +106,8 @@ - After queuing a chart for update, the view will now redirect to the same chart. - The multiple document action dropdown is now sorted alphabetically. +- Improve statistics subclassing. Split class module into classes + and renderers. 3.0.3 (2018-08-17) ================== diff --git a/mayan/apps/documents/statistics.py b/mayan/apps/documents/statistics.py index 548e4badb9..8ba196867f 100644 --- a/mayan/apps/documents/statistics.py +++ b/mayan/apps/documents/statistics.py @@ -8,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _ import qsstats -from mayan_statistics.classes import StatisticNamespace, CharJSLine +from mayan_statistics import StatisticLineChart, StatisticNamespace from .permissions import permission_document_view @@ -230,44 +230,44 @@ def total_document_page_per_month(): namespace = StatisticNamespace(slug='documents', label=_('Documents')) namespace.add_statistic( + klass=StatisticLineChart, slug='new-documents-per-month', label=_('New documents per month'), func=new_documents_per_month, - renderer=CharJSLine, minute='0' ) namespace.add_statistic( + klass=StatisticLineChart, slug='new-document-versions-per-month', label=_('New document versions per month'), func=new_document_versions_per_month, - renderer=CharJSLine, minute='0' ) namespace.add_statistic( + klass=StatisticLineChart, slug='new-document-pages-per-month', label=_('New document pages per month'), func=new_document_pages_per_month, - renderer=CharJSLine, minute='0' ) namespace.add_statistic( + klass=StatisticLineChart, slug='total-documents-at-each-month', label=_('Total documents at each month'), func=total_document_per_month, - renderer=CharJSLine, minute='0' ) namespace.add_statistic( + klass=StatisticLineChart, slug='total-document-versions-at-each-month', label=_('Total document versions at each month'), func=total_document_version_per_month, - renderer=CharJSLine, minute='0' ) namespace.add_statistic( + klass=StatisticLineChart, slug='total-document-pages-at-each-month', label=_('Total document pages at each month'), func=total_document_page_per_month, - renderer=CharJSLine, minute='0' ) diff --git a/mayan/apps/mayan_statistics/__init__.py b/mayan/apps/mayan_statistics/__init__.py index 1bf03c670e..59c4ee052b 100644 --- a/mayan/apps/mayan_statistics/__init__.py +++ b/mayan/apps/mayan_statistics/__init__.py @@ -1,3 +1,5 @@ from __future__ import unicode_literals +from .classes import StatisticLineChart, StatisticNamespace + default_app_config = 'mayan_statistics.apps.StatisticsApp' diff --git a/mayan/apps/mayan_statistics/apps.py b/mayan/apps/mayan_statistics/apps.py index f1284a1ba6..acf76212b9 100644 --- a/mayan/apps/mayan_statistics/apps.py +++ b/mayan/apps/mayan_statistics/apps.py @@ -9,7 +9,7 @@ from common import MayanAppConfig, menu_object, menu_secondary, menu_tools from navigation import SourceColumn -from .classes import Statistic, StatisticNamespace +from .classes import Statistic, StatisticLineChart, StatisticNamespace from .links import ( link_execute, link_namespace_details, link_namespace_list, link_statistics, link_view @@ -29,9 +29,9 @@ class StatisticsApp(MayanAppConfig): super(StatisticsApp, self).ready() SourceColumn( - source=Statistic, - # Translators: Schedule here is a verb, the 'schedule' at which the - # statistic will be updated + source=StatisticLineChart, + # Translators: Schedule here is a verb, the 'schedule' at + # which the statistic will be updated label=_('Schedule'), attribute='schedule', ) @@ -54,7 +54,7 @@ class StatisticsApp(MayanAppConfig): ) menu_object.bind_links( - links=(link_execute, link_view), sources=(Statistic,) + links=(link_execute, link_view), sources=(StatisticLineChart,) ) menu_object.bind_links( links=(link_namespace_details,), sources=(StatisticNamespace,) diff --git a/mayan/apps/mayan_statistics/classes.py b/mayan/apps/mayan_statistics/classes.py index 4432a6634d..a1b877b0a9 100644 --- a/mayan/apps/mayan_statistics/classes.py +++ b/mayan/apps/mayan_statistics/classes.py @@ -9,6 +9,8 @@ from celery.schedules import crontab from mayan.celery import app +from .renderers import ChartJSLine + @python_2_unicode_compatible class StatisticNamespace(object): @@ -31,8 +33,8 @@ class StatisticNamespace(object): def __str__(self): return force_text(self.label) - def add_statistic(self, *args, **kwargs): - statistic = Statistic(*args, **kwargs) + def add_statistic(self, klass, *args, **kwargs): + statistic = klass(*args, **kwargs) statistic.namespace = self self._statistics.append(statistic) @@ -44,6 +46,7 @@ class StatisticNamespace(object): @python_2_unicode_compatible class Statistic(object): _registry = {} + renderer = None @staticmethod def purge_schedules(): @@ -82,11 +85,10 @@ class Statistic(object): def get_task_names(cls): return [task.get_task_name() for task in cls.get_all()] - def __init__(self, slug, label, func, renderer, minute='*', hour='*', day_of_week='*', day_of_month='*', month_of_year='*'): + def __init__(self, slug, label, func, minute='*', hour='*', day_of_week='*', day_of_month='*', month_of_year='*'): self.slug = slug self.label = label self.func = func - self.renderer = renderer self.schedule = crontab( minute=minute, hour=hour, day_of_week=day_of_week, @@ -123,7 +125,9 @@ class Statistic(object): return 'mayan_statistics.task_execute_statistic_{}'.format(self.slug) def store_results(self, results): - from .models import StatisticResult + StatisticResult = apps.get_model( + app_label='mayan_statistics', model_name='StatisticResult' + ) StatisticResult.objects.filter(slug=self.slug).delete() @@ -133,7 +137,9 @@ class Statistic(object): statistic_result.store_data(data=results) def get_results(self): - from .models import StatisticResult + StatisticResult = apps.get_model( + app_label='mayan_statistics', model_name='StatisticResult' + ) try: return StatisticResult.objects.get(slug=self.slug).get_data() @@ -144,66 +150,5 @@ class Statistic(object): return self.renderer(data=self.get_results()).get_chart_data() -class ChartRenderer(object): - def __init__(self, data): - self.data = data - - def get_chart_data(self): - raise NotImplementedError - - -class CharJSLine(ChartRenderer): - template_name = 'statistics/backends/chartjs/line.html' - - dataset_palette = ( - { - 'fillColor': "rgba(220,220,220,0.2)", - 'strokeColor': "rgba(220,220,220,1)", - 'pointColor': "rgba(220,220,220,1)", - 'pointStrokeColor': "#fff", - 'pointHighlightFill': "#fff", - 'pointHighlightStroke': "rgba(220,220,220,1)", - }, - { - 'fillColor': "rgba(151,187,205,0.2)", - 'strokeColor': "rgba(151,187,205,1)", - 'pointColor': "rgba(151,187,205,1)", - 'pointStrokeColor': "#fff", - 'pointHighlightFill': "#fff", - 'pointHighlightStroke': "rgba(151,187,205,1)", - }, - ) - - def get_chart_data(self): - labels = [] - datasets = [] - - for count, serie in enumerate(self.data['series'].items()): - series_name, series_data = serie - dataset_labels = [] - dataset_values = [] - - for data_point in series_data: - dataset_labels.extend(data_point.keys()) - dataset_values.extend(data_point.values()) - - labels = dataset_labels - dataset = { - 'label': series_name, - 'data': dataset_values, - } - dataset.update( - CharJSLine.dataset_palette[ - count % len(CharJSLine.dataset_palette) - ] - ) - - datasets.append(dataset) - - data = { - 'labels': labels, - 'datasets': datasets, - - } - - return json.dumps(data) +class StatisticLineChart(Statistic): + renderer = ChartJSLine diff --git a/mayan/apps/mayan_statistics/renderers.py b/mayan/apps/mayan_statistics/renderers.py new file mode 100644 index 0000000000..4ca67aee36 --- /dev/null +++ b/mayan/apps/mayan_statistics/renderers.py @@ -0,0 +1,75 @@ +from __future__ import unicode_literals + +import json + +from django.apps import apps +from django.utils.encoding import force_text, python_2_unicode_compatible + +from celery.schedules import crontab + +from mayan.celery import app + + +class ChartRenderer(object): + def __init__(self, data): + self.data = data + + def get_chart_data(self): + raise NotImplementedError + + +class ChartJSLine(ChartRenderer): + template_name = 'statistics/renderers/chartjs/line.html' + + dataset_palette = ( + { + 'fillColor': "rgba(220,220,220,0.2)", + 'strokeColor': "rgba(220,220,220,1)", + 'pointColor': "rgba(220,220,220,1)", + 'pointStrokeColor': "#fff", + 'pointHighlightFill': "#fff", + 'pointHighlightStroke': "rgba(220,220,220,1)", + }, + { + 'fillColor': "rgba(151,187,205,0.2)", + 'strokeColor': "rgba(151,187,205,1)", + 'pointColor': "rgba(151,187,205,1)", + 'pointStrokeColor': "#fff", + 'pointHighlightFill': "#fff", + 'pointHighlightStroke': "rgba(151,187,205,1)", + }, + ) + + def get_chart_data(self): + labels = [] + datasets = [] + + for count, serie in enumerate(self.data['series'].items()): + series_name, series_data = serie + dataset_labels = [] + dataset_values = [] + + for data_point in series_data: + dataset_labels.extend(data_point.keys()) + dataset_values.extend(data_point.values()) + + labels = dataset_labels + dataset = { + 'label': series_name, + 'data': dataset_values, + } + dataset.update( + ChartJSLine.dataset_palette[ + count % len(ChartJSLine.dataset_palette) + ] + ) + + datasets.append(dataset) + + data = { + 'labels': labels, + 'datasets': datasets, + + } + + return json.dumps(data) diff --git a/mayan/apps/mayan_statistics/templates/statistics/backends/chartjs/line.html b/mayan/apps/mayan_statistics/templates/statistics/renderers/chartjs/line.html similarity index 100% rename from mayan/apps/mayan_statistics/templates/statistics/backends/chartjs/line.html rename to mayan/apps/mayan_statistics/templates/statistics/renderers/chartjs/line.html