diff --git a/generators/pdk_app_event.py b/generators/pdk_app_event.py index 7ef86d4..7e5c8f9 100644 --- a/generators/pdk_app_event.py +++ b/generators/pdk_app_event.py @@ -1,10 +1,19 @@ +# pylint: disable=line-too-long, no-member + import calendar import csv +import datetime import json import tempfile +from django.template.loader import render_to_string +from django.utils import timezone + from ..models import DataPoint, install_supports_jsonfield +def generator_name(identifier): # pylint: disable=unused-argument + return 'App Events' + def extract_secondary_identifier(properties): if 'event_name' in properties: return properties['event_name'] @@ -54,3 +63,15 @@ def compile_report(generator, sources): index += 5000 return filename + +def data_table(source, generator): + context = {} + context['source'] = source + context['generator_identifier'] = generator + + end = timezone.now() + start = end - datetime.timedelta(days=30) + + context['values'] = DataPoint.objects.filter(source=source.identifier, generator_identifier=generator, created__gt=start, created__lte=end).order_by('created') + + return render_to_string('pdk_app_event_table_template.html', context) diff --git a/generators/pdk_withings_device.py b/generators/pdk_withings_device.py index dca963c..95b36d5 100644 --- a/generators/pdk_withings_device.py +++ b/generators/pdk_withings_device.py @@ -1,3 +1,5 @@ +# pylint: disable=line-too-long, no-member + import calendar import csv import datetime @@ -117,7 +119,7 @@ def compile_report(generator, sources): # pylint: disable=too-many-locals export_file.write(secondary_filename, secondary_filename.split('/')[-1]) return filename - + def data_table(source, generator): context = {} context['source'] = source @@ -128,8 +130,7 @@ def data_table(source, generator): context['activity_values'] = DataPoint.objects.filter(source=source.identifier, generator_identifier=generator, secondary_identifier=SECONDARY_IDENTIFIER_ACTIVITY, created__gt=start, created__lte=end).order_by('created') context['intraday_values'] = DataPoint.objects.filter(source=source.identifier, generator_identifier=generator, secondary_identifier=SECONDARY_IDENTIFIER_INTRADAY, created__gt=start, created__lte=end).order_by('created') - context['sleep_values'] = DataPoint.objects.filter(source=source.identifier, generator_identifier=generator, secondary_identifier=SECONDARY_IDENTIFIER_SLEEP, created__lte=end).order_by('created') # created__gt=start, + context['sleep_values'] = DataPoint.objects.filter(source=source.identifier, generator_identifier=generator, secondary_identifier=SECONDARY_IDENTIFIER_SLEEP, created__lte=end).order_by('created') # created__gt=start, context['body_values'] = DataPoint.objects.filter(source=source.identifier, generator_identifier=generator, secondary_identifier=SECONDARY_IDENTIFIER_BODY, created__lte=end).order_by('created') return render_to_string('pdk_wearable_withings_device_table_template.html', context) - diff --git a/management/commands/pdk_status_withings_device_check_last_upload.py b/management/commands/pdk_status_check_withings_device_check_last_upload.py similarity index 96% rename from management/commands/pdk_status_withings_device_check_last_upload.py rename to management/commands/pdk_status_check_withings_device_check_last_upload.py index 20fd152..e7f9485 100644 --- a/management/commands/pdk_status_withings_device_check_last_upload.py +++ b/management/commands/pdk_status_check_withings_device_check_last_upload.py @@ -17,7 +17,7 @@ class Command(BaseCommand): @handle_lock def handle(self, *args, **options): # pylint: disable=too-many-branches, too-many-statements now = timezone.now() - + for source in DataSource.objects.all(): last_alert = DataSourceAlert.objects.filter(data_source=source, generator_identifier=GENERATOR, active=True).order_by('-created').first() @@ -26,20 +26,20 @@ def handle(self, *args, **options): # pylint: disable=too-many-branches, too-man alert_name = None alert_details = {} alert_level = 'info' - + delta = now - last_upload.created - - if last_upload is not None: - if delta.days >= CRITICAL_DAYS: - alert_name = 'Withings upload is critically overdue' - alert_details['message'] = 'Latest Withings upload was ' + str(delta.days) + ' days ago.' - alert_level = 'critical' - elif delta.days >= WARNING_DAYS: + if last_upload is not None: + if delta.days >= WARNING_DAYS: alert_name = 'Withings upload is overdue' alert_details['message'] = 'Latest Withings upload was 1 day ago.' alert_level = 'warning' + elif delta.days >= CRITICAL_DAYS: + alert_name = 'Withings upload is critically overdue' + alert_details['message'] = 'Latest Withings upload was ' + str(delta.days) + ' days ago.' + alert_level = 'critical' + if alert_name is not None: if last_alert is None or last_alert.alert_name != alert_name or last_alert.alert_level != alert_level: if last_alert is not None: diff --git a/pdk_api.py b/pdk_api.py index 8a44b00..090903e 100644 --- a/pdk_api.py +++ b/pdk_api.py @@ -6,6 +6,7 @@ import json import tempfile +from django.conf import settings from django.template.loader import render_to_string from .models import DataPoint @@ -53,17 +54,18 @@ def visualization(source, generator): return render_to_string('pdk_generic_viz_template.html', context) def data_table(source, generator): - try: - generator_module = importlib.import_module('.generators.' + generator.replace('-', '_'), package='passive_data_kit') - - output = generator_module.data_table(source, generator) - - if output is not None: - return output - except ImportError: - pass - except AttributeError: - pass + for app in settings.INSTALLED_APPS: + try: + generator_module = importlib.import_module('.generators.' + generator.replace('-', '_'), package=app) + + output = generator_module.data_table(source, generator) + + if output is not None: + return output + except ImportError: + pass + except AttributeError: + pass context = {} context['source'] = source diff --git a/templates/pdk_app_event_table_template.html b/templates/pdk_app_event_table_template.html new file mode 100644 index 0000000..0f48311 --- /dev/null +++ b/templates/pdk_app_event_table_template.html @@ -0,0 +1,29 @@ + + + + + + + + + {% for row in values %} + {% with props=row.fetch_properties %} + + + + + {% endwith %} + {% endfor %} + + + + diff --git a/templatetags/passive_data_kit.py b/templatetags/passive_data_kit.py index 7fc052f..0464dc5 100644 --- a/templatetags/passive_data_kit.py +++ b/templatetags/passive_data_kit.py @@ -1,10 +1,14 @@ # pylint: disable=line-too-long, no-member +import datetime import importlib +import traceback + import arrow from django import template +from django.conf import settings from django.template.loader import render_to_string from django.utils import timezone @@ -387,20 +391,42 @@ def __init__(self, generator): def render(self, context): generator = self.generator.resolve(context) - try: - generator_module = importlib.import_module('.generators.' + generator.replace('-', '_'), package='passive_data_kit') + for app in settings.INSTALLED_APPS: + try: + generator_module = importlib.import_module('.generators.' + generator.replace('-', '_'), package=app) - output = generator_module.generator_name(generator) + output = generator_module.generator_name(generator) - if output is not None: - return output - except ImportError: - pass - except AttributeError: - pass + if output is not None: + return output + except ImportError: + traceback.print_exc() + except AttributeError: + traceback.print_exc() return generator @register.filter("to_datetime") def to_datetime(value): - return arrow.get(value).datetime + return arrow.get(value).datetime + +@register.tag(name="hour_minute_to_time") +def hour_minute_to_time(parser, token): # pylint: disable=unused-argument + try: + tag_name, hour, minute = token.split_contents() # pylint: disable=unused-variable + except ValueError: + raise template.TemplateSyntaxError("%r tag requires a single argument" % \ + token.contents.split()[0]) + + return HourMinuteTimeNode(hour, minute) + +class HourMinuteTimeNode(template.Node): + def __init__(self, hour, minute): + self.hour = template.Variable(hour) + self.minute = template.Variable(minute) + + def render(self, context): + hour = int(self.hour.resolve(context)) + minute = int(self.minute.resolve(context)) + + return datetime.time(hour, minute, 0, 0)