Пример #1
0
 def test_duration_string(self):
     duration = timezone.timedelta(hours=1, minutes=30, seconds=45)
     self.assertEqual(duration_string(duration),
                      '1 hour, 30 minutes, 45 seconds')
     self.assertEqual(duration_string(duration, 'm'), '1 hour, 30 minutes')
     self.assertEqual(duration_string(duration, 'h'), '1 hour')
     self.assertRaises(TypeError, lambda: duration_string('1 hour'))
Пример #2
0
 def test_duration_string(self):
     duration = timezone.timedelta(hours=1, minutes=30, seconds=45)
     self.assertEqual(utils.duration_string(duration),
                      "1 hour, 30 minutes, 45 seconds")
     self.assertEqual(utils.duration_string(duration, "m"),
                      "1 hour, 30 minutes")
     self.assertEqual(utils.duration_string(duration, "h"), "1 hour")
     self.assertRaises(TypeError, lambda: utils.duration_string("1 hour"))
Пример #3
0
 def get_paginated_response(self, data):
     return Response(
         OrderedDict([
             ('count', self.count), ('next', self.get_next_link()),
             ('previous', self.get_previous_link()),
             ('total_duration', duration_string(self.total_duration)),
             ('subtotal_duration', duration_string(self.subtotal_duration)),
             ('results', data)
         ]))
Пример #4
0
def _format_label(duration, start_time, end_time):
    """
    Formats a time block label.
    :param duration: Duration.
    :param start_time: Start time.
    :param end_time: End time.
    :return: Formatted string with duration, start, and end time.
    """
    return 'Asleep {} ({} to {})'.format(duration_string(duration),
                                         start_time.strftime('%I:%M %p'),
                                         end_time.strftime('%I:%M %p'))
Пример #5
0
def _format_label(duration, start_time, end_time):
    """
    Formats a time block label.
    :param duration: Duration.
    :param start_time: Start time.
    :param end_time: End time.
    :return: Formatted string with duration, start, and end time.
    """
    return 'Asleep {} ({} to {})'.format(
        duration_string(duration),
        formats.time_format(start_time, 'TIME_FORMAT'),
        formats.time_format(end_time, 'TIME_FORMAT'))
Пример #6
0
def duration_string(duration, precision="s"):
    """
    Format a duration (e.g. "2 hours, 3 minutes, 35 seconds").
    :param duration: a timedetla instance.
    :param precision: the level of precision to return (h for hours, m for
                      minutes, s for seconds)
    :returns: a string representation of the duration.
    """
    if not duration:
        return ""
    try:
        return utils.duration_string(duration, precision)
    except (ValueError, TypeError):
        return ""
Пример #7
0
def sleep_pattern(instances):
    """
    Create a graph showing blocked out periods of sleep during each day.
    :param instances: a QuerySet of Sleep instances.
    :returns: a tuple of the the graph's html and javascript.
    """
    # TODO: Simplify this using the bar charts "base" property.
    y_df = pd.DataFrame()
    text_df = pd.DataFrame()
    last_end_time = None
    adjustment = None
    df_index = 0
    for instance in instances:
        start_time = timezone.localtime(instance.start)
        end_time = timezone.localtime(instance.end)
        start_date = start_time.date().isoformat()
        duration = instance.duration

        # Check if the previous entry crossed midnight (see below).
        if adjustment:
            # Fake (0) entry to keep the color switching logic working.
            df_index = _add_sleep_entry(y_df, text_df, 0, adjustment['column'],
                                        0)
            # Real adjustment entry.
            df_index = _add_sleep_entry(
                y_df, text_df, df_index, adjustment['column'],
                adjustment['duration'].seconds / 60,
                'Asleep {} ({} to {})'.format(
                    duration_string(adjustment['duration']),
                    adjustment['start_time'].strftime('%I:%M %p'),
                    adjustment['end_time'].strftime('%I:%M %p')))
            last_end_time = timezone.localtime(adjustment['end_time'])
            adjustment = None

        # If the dates do not match, set up an adjustment for the next day.
        if end_time.date() != start_time.date():
            adj_start_time = end_time.replace(hour=0, minute=0, second=0)
            adjustment = {
                'column': end_time.date().isoformat(),
                'start_time': adj_start_time,
                'end_time': end_time,
                'duration': end_time - adj_start_time
            }

            # Adjust end_time for the current entry.
            end_time = end_time.replace(year=start_time.year,
                                        month=start_time.month,
                                        day=start_time.day,
                                        hour=23,
                                        minute=59,
                                        second=0)
            duration = end_time - start_time

        if start_date not in y_df:
            last_end_time = start_time.replace(hour=0, minute=0, second=0)

        # Awake time.
        df_index = _add_sleep_entry(y_df, text_df, df_index, start_date,
                                    (start_time - last_end_time).seconds / 60)

        # Asleep time.
        df_index = _add_sleep_entry(
            y_df, text_df, df_index, start_date, duration.seconds / 60,
            'Asleep {} ({} to {})'.format(duration_string(duration),
                                          start_time.strftime('%I:%M %p'),
                                          end_time.strftime('%I:%M %p')))

        # Update the previous entry duration if an offset change occurred.
        # This can happen when an entry crosses a daylight savings time change.
        if start_time.utcoffset() != end_time.utcoffset():
            diff = start_time.utcoffset() - end_time.utcoffset()
            duration -= timezone.timedelta(seconds=diff.seconds)
            y_df.set_value(df_index - 1, start_date, duration.seconds / 60)

        last_end_time = end_time

    dates = list(y_df)
    traces = []
    color = 'rgba(255, 255, 255, 0)'
    for index, row in y_df.iterrows():
        traces.append(
            go.Bar(
                x=dates,
                y=row,
                text=text_df.ix[index],
                hoverinfo='text',
                marker={'color': color},
                showlegend=False,
            ))
        if color == 'rgba(255, 255, 255, 0)':
            color = 'rgb(35, 110, 150)'
        else:
            color = 'rgba(255, 255, 255, 0)'

    layout_args = utils.default_graph_layout_options()
    layout_args['margin']['b'] = 100

    layout_args['barmode'] = 'stack'
    layout_args['hovermode'] = 'closest'
    layout_args['title'] = '<b>Sleep Pattern</b>'
    layout_args['height'] = 800

    layout_args['xaxis']['title'] = 'Date'
    layout_args['xaxis']['tickangle'] = -65
    layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()

    start = timezone.localtime().strptime('12:00 AM', '%I:%M %p')
    ticks = OrderedDict()
    ticks[0] = start.strftime('%I:%M %p')
    for i in range(30, 60 * 24, 30):
        ticks[i] = (start + timezone.timedelta(minutes=i)).strftime('%I:%M %p')

    layout_args['yaxis']['title'] = 'Time of day'
    layout_args['yaxis']['rangemode'] = 'tozero'
    layout_args['yaxis']['tickmode'] = 'array'
    layout_args['yaxis']['tickvals'] = list(ticks.keys())
    layout_args['yaxis']['ticktext'] = list(ticks.values())
    layout_args['yaxis']['tickfont'] = {'size': 10}

    fig = go.Figure({'data': traces, 'layout': go.Layout(**layout_args)})
    output = plotly.plot(fig, output_type='div', include_plotlyjs=False)
    return utils.split_graph_output(output)
Пример #8
0
def get_objects(child, date):
    """
    Create a time-sorted dictionary of all events for a child.
    :param child: an instance of a Child.
    :param date: a DateTime instance for the day to be summarized.
    :returns: a list of the day's events.
    """
    min_date = date
    max_date = date.replace(hour=23, minute=59, second=59)
    events = []

    instances = DiaperChange.objects.filter(child=child).filter(
        time__range=(min_date, max_date)).order_by('-time')
    for instance in instances:
        change_type = ''
        if instance.wet and instance.solid:
            change_type = 'wet and solid'
        elif instance.wet:
            change_type = 'wet'
        elif instance.solid:
            change_type = 'solid'

        events.append({
            'time': timezone.localtime(instance.time),
            'event': _('%(child)s had a diaper change.') % {
                'child': child.first_name,
                'change_type': change_type
            },
            'detail': _('%(change_type)s (%(color)s)') % {
                'change_type': change_type,
                'color': instance.color if instance.color else ''
            },
            'model_name': instance.model_name,
        })

    instances = Feeding.objects.filter(child=child).filter(
        start__range=(min_date, max_date)).order_by('-start')
    for instance in instances:
        feeding_type = ''
        if instance.type == 'breast milk':
            feeding_type = "{type} {method}".format(type=instance.type, method=instance.method)
        elif instance.type in ['formula', 'fortified breast milk']:
            if instance.amount:
                feeding_type = "{type} ({amount})".format(type=instance.type, amount=instance.amount)
            else:
                feeding_type = "{type}".format(type=instance.type)
        events.append({
            'time': timezone.localtime(instance.start),
            'event': _('%(child)s started feeding.') % {
                'child': instance.child.first_name
            },
            'detail': _('%(feeding_type)s') % {
                'feeding_type': feeding_type
            },
            'model_name': instance.model_name,
            'type': 'start'
        })
        events.append({
            'time': timezone.localtime(instance.end),
            'event': _('%(child)s finished feeding.') % {
                'child': instance.child.first_name
            },
            'detail': _('%(feeding_type)s') % {
                'feeding_type': feeding_type
            },
            'model_name': instance.model_name,
            'type': 'end'
        })

    instances = Sleep.objects.filter(child=child).filter(
        start__range=(min_date, max_date)).order_by('-start')
    for instance in instances:
        events.append({
            'time': timezone.localtime(instance.start),
            'event': _('%(child)s fell asleep.') % {
                'child': instance.child.first_name
            },
            'detail': _('%(duration)s') % {
                'duration': ''
            },
            'model_name': instance.model_name,
            'type': 'start'
        })
        events.append({
            'time': timezone.localtime(instance.end),
            'event': _('%(child)s woke up.') % {
                'child': instance.child.first_name
            },
            'detail': _('%(duration)s') % {
                'duration': duration_string(instance.duration)
            },
            'model_name': instance.model_name,
            'type': 'end'
        })

    instances = TummyTime.objects.filter(child=child).filter(
        start__range=(min_date, max_date)).order_by('-start')
    for instance in instances:
        events.append({
            'time': timezone.localtime(instance.start),
            'event': _('%(child)s started tummy time!') % {
                'child': instance.child.first_name
            },
            'detail': _('%(duration)s') % {
                'duration': ''
            },
            'model_name': instance.model_name,
            'type': 'start'
        })
        events.append({
            'time': timezone.localtime(instance.end),
            'event': _('%(child)s finished tummy time.') % {
                'child': instance.child.first_name
            },
            'detail': _('%(duration)s') % {
                'duration': duration_string(instance.duration)
            },
            'model_name': instance.model_name,
            'type': 'end'
        })

    events.sort(key=lambda x: x['time'], reverse=True)

    return events