mybuddy/core/timeline.py

183 lines
6.4 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
from django.urls import reverse
2021-07-09 20:45:07 +00:00
from django.utils import timezone, timesince
from django.utils.translation import gettext as _
2021-11-20 17:41:15 +00:00
from core.models import DiaperChange, Feeding, Note, Sleep, TummyTime
from datetime import timedelta
2021-08-29 20:50:22 +00:00
def get_objects(date, child=None):
"""
Create a time-sorted dictionary of all events for a child.
:param date: a DateTime instance for the day to be summarized.
2021-08-29 20:50:22 +00:00
:param child: Child instance to filter results for (no filter if `None`).
:returns: a list of the day's events.
"""
min_date = date
max_date = date.replace(hour=23, minute=59, second=59)
events = []
2021-08-29 20:50:22 +00:00
_add_diaper_changes(min_date, max_date, events, child)
_add_feedings(min_date, max_date, events, child)
_add_sleeps(min_date, max_date, events, child)
_add_tummy_times(min_date, max_date, events, child)
2021-11-20 17:41:15 +00:00
_add_notes(min_date, max_date, events, child)
2021-08-05 21:06:23 +00:00
events.sort(key=lambda x: x['time'], reverse=True)
return events
2021-08-29 20:50:22 +00:00
def _add_tummy_times(min_date, max_date, events, child=None):
instances = TummyTime.objects.filter(
start__range=(min_date, max_date)).order_by('-start')
2021-08-29 20:50:22 +00:00
if child:
instances = instances.filter(child=child)
for instance in instances:
details = []
if instance.milestone:
details.append(instance.milestone)
2021-08-05 21:06:23 +00:00
edit_link = reverse('core:tummytime-update', args=[instance.id])
events.append({
'time': timezone.localtime(instance.start),
2021-08-05 21:06:23 +00:00
'event': _('%(child)s started tummy time!') % {
'child': instance.child.first_name
},
'details': details,
'edit_link': edit_link,
'model_name': instance.model_name,
'type': 'start'
})
events.append({
'time': timezone.localtime(instance.end),
2021-08-05 21:06:23 +00:00
'event': _('%(child)s finished tummy time.') % {
'child': instance.child.first_name
},
'details': details,
'edit_link': edit_link,
2021-07-09 20:45:07 +00:00
'duration': timesince.timesince(instance.start, now=instance.end),
'model_name': instance.model_name,
'type': 'end'
})
2021-08-05 21:06:23 +00:00
2021-08-29 20:50:22 +00:00
def _add_sleeps(min_date, max_date, events, child=None):
instances = Sleep.objects.filter(
start__range=(min_date, max_date)).order_by('-start')
2021-08-29 20:50:22 +00:00
if child:
instances = instances.filter(child=child)
for instance in instances:
details = []
if instance.notes:
details.append(instance.notes)
edit_link = reverse('core:sleep-update', args=[instance.id])
events.append({
'time': timezone.localtime(instance.start),
'event': _('%(child)s fell asleep.') % {
'child': instance.child.first_name
},
'details': details,
'edit_link': edit_link,
'model_name': instance.model_name,
'type': 'start'
})
events.append({
'time': timezone.localtime(instance.end),
'event': _('%(child)s woke up.') % {
'child': instance.child.first_name
},
'details': details,
'edit_link': edit_link,
2021-07-09 20:45:07 +00:00
'duration': timesince.timesince(instance.start, now=instance.end),
'model_name': instance.model_name,
'type': 'end'
})
2021-08-05 21:06:23 +00:00
2021-08-29 20:50:22 +00:00
def _add_feedings(min_date, max_date, events, child=None):
# Ensure first feeding has a previous.
yesterday = min_date - timedelta(days=1)
prev_start = None
2021-08-29 20:50:22 +00:00
instances = Feeding.objects.filter(
start__range=(yesterday, max_date)).order_by('start')
2021-08-29 20:50:22 +00:00
if child:
instances = instances.filter(child=child)
for instance in instances:
details = []
if instance.notes:
details.append(instance.notes)
time_since_prev = None
if prev_start:
time_since_prev = \
timesince.timesince(prev_start, now=instance.start)
prev_start = instance.start
if instance.start < min_date:
continue
2021-08-05 21:06:23 +00:00
edit_link = reverse('core:feeding-update', args=[instance.id])
if instance.amount:
details.append(_('Amount: %(amount).0f') % {
2021-08-05 21:06:23 +00:00
'amount': instance.amount,
})
events.append({
'time': timezone.localtime(instance.start),
2021-08-05 21:06:23 +00:00
'event': _('%(child)s started feeding.') % {
'child': instance.child.first_name
},
2021-08-05 21:06:23 +00:00
'details': details,
'edit_link': edit_link,
'time_since_prev': time_since_prev,
'model_name': instance.model_name,
'type': 'start'
})
events.append({
'time': timezone.localtime(instance.end),
2021-08-05 21:06:23 +00:00
'event': _('%(child)s finished feeding.') % {
'child': instance.child.first_name
},
2021-08-05 21:06:23 +00:00
'details': details,
'edit_link': edit_link,
2021-07-09 20:45:07 +00:00
'duration': timesince.timesince(instance.start, now=instance.end),
'model_name': instance.model_name,
'type': 'end'
})
2021-08-29 20:50:22 +00:00
def _add_diaper_changes(min_date, max_date, events, child):
instances = DiaperChange.objects.filter(
2021-08-05 21:06:23 +00:00
time__range=(min_date, max_date)).order_by('-time')
2021-08-29 20:50:22 +00:00
if child:
instances = instances.filter(child=child)
2021-08-05 21:06:23 +00:00
for instance in instances:
contents = []
if instance.wet:
contents.append('💧')
2021-08-05 21:06:23 +00:00
if instance.solid:
contents.append('💩')
2021-08-05 21:06:23 +00:00
events.append({
'time': timezone.localtime(instance.time),
'event': _('%(child)s had a %(type)s diaper change.') % {
'child': instance.child.first_name,
'type': ''.join(contents),
2021-08-05 21:06:23 +00:00
},
'edit_link': reverse('core:diaperchange-update',
args=[instance.id]),
'model_name': instance.model_name
})
2021-11-20 17:41:15 +00:00
def _add_notes(min_date, max_date, events, child):
instances = Note.objects.filter(
time__range=(min_date, max_date)).order_by('-time')
if child:
instances = instances.filter(child=child)
for instance in instances:
events.append({
'time': timezone.localtime(instance.time),
'details': [instance.note],
'edit_link': reverse('core:note-update',
args=[instance.id]),
'model_name': instance.model_name
})