Ejemplo n.º 1
0
def reflect(request):
    """ Respond to the "/reflect" URL.

        This is the main view for the "reflect" mode.
    """
    # Calculate a summary of the tasks worked on over the past 7 days.

    started_at = utils.start_of_day() - datetime.timedelta(days=7)
    ended_at   = utils.current_datetime()

    weekly_summary = activities.calc_task_summary(started_at, ended_at)

    # Now calculate a summary for each day of the week, grouping the results by
    # day and storing the results in a format which makes it easy for us to
    # generate the final table.

    day_start = started_at
    day_end   = started_at + datetime.timedelta(days=1) \
              - datetime.timedelta(seconds=1)

    daily_task_times = [] # List of times spent on the various tasks each day.
                          # For each day, the list item will be a dictionary
                          # with the following entries:
                          #
                          #     'day_label'
                          #
                          #         The label to use to identify this day.
                          #
                          #     'task_times'
                          #
                          #         A dictionary mapping each Task record ID to
                          #         the time spent on that task, as an integer
                          #         number of seconds.

    start_of_today = utils.start_of_day()
    while day_start <= start_of_today:
        weekday = day_start.date().weekday()
        day_label = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
                     "Saturday", "Sunday"][weekday]

        daily_summary = activities.calc_task_summary(day_start, day_end)

        def _add_task_times(daily_summary, task_times):
            """ Recursively add 'daily_summary' to the 'task_times' dictionary.
            """
            for node in daily_summary:
                task_times[node['task'].id] = node['time_spent']
                _add_task_times(node['children'], task_times)

        task_times = {}
        _add_task_times(daily_summary['summary'], task_times)

        daily_task_times.append({'day_label'  : day_label,
                                 'task_times' : task_times})

        day_start = day_start + datetime.timedelta(days=1)
        day_end   = day_end   + datetime.timedelta(days=1)

    daily_task_times.reverse() # Show newest day first.

    # Process the weekly task summary, building a master list of all tasks
    # worked on during the week.

    tasks = [] # List of tasks worked on during the week.  Each list item is a
               # dictionary with the following entries:
               #
               #     'task'
               #
               #         The Task object to work on.
               #
               #     'label'
               #
               #         The (possibly indented) label to use for this task.
               #
               #     'time_spent'
               #
               #         The total amount of time spent on this task over the
               #         last week, as an integer number of seconds.

    def _add_tree(tree, task, indent=0):
        """ Recursively add a summary tree to the list of tasks.
        """
        for node in tree:
            label = "&nbsp;" * indent * 8 + node['task'].label
            tasks.append({'task'       : node['task'],
                          'label'      : label,
                          'time_spent' : node['time_spent']})

            _add_tree(node['children'], tasks, indent=indent+1)

    _add_tree(weekly_summary['summary'], tasks)

    # Calculate the totals to display at the bottom of the table.

    weekly_total = 0 # Total time spent for the week, in seconds.
    for task in tasks:
        weekly_total = weekly_total + task['time_spent']

    daily_totals = [] # Total time spent per day, in seconds.
    for day in daily_task_times:
        daily_total = 0
        for task_time in day['task_times'].values():
            daily_total = daily_total + task_time
        daily_totals.append(daily_total)

    # Using the calculated information, build a single large table representing
    # the entire summary.

    summary_table = [] # List of [col][row] entries.  Each list item is a
                       # dictionary with the following entries:
                       #
                       #    'text'
                       #
                       #        The text to be displayed.
                       #
                       #    'style'
                       #
                       #        The CSS style to apply to this table item.

    # Add the heading row to the top of the table.

    row = []
    row.append({'text'  : "&nbsp;",
                'style' : "heading"})
    row.append({'text'  : "Last 7 Days",
                'style' : "heading border-b"})
    row.append({'text'  : "&nbsp;",
                'style' : "heading"})

    for day in daily_task_times:
        row.append({'text'  : day['day_label'],
                    'style' : "heading border-b"})

    summary_table.append(row)

    # Add each task in turn.

    for task in tasks:
        row = []
        row.append({'text'  : task['label'] + "&nbsp;&nbsp;",
                    'style' : "heading left"})
        row.append({'text'  : utils.seconds_to_hms(task['time_spent']),
                    'style' : "body border-lrb"})
        row.append({'text'  : "&nbsp;",
                    'style' : "body"})

        task_id = task['task'].id
        for day in daily_task_times:
            if task_id in day['task_times']:
                task_time = utils.seconds_to_hms(day['task_times'][task_id])
            else:
                task_time = "&nbsp;"

            row.append({'text'  : task_time,
                        'style' : "body border-lrb"})

        summary_table.append(row)

    # Add the total times to the bottom of the table.

    row = []
    row.append({'text'  : "&nbsp;",
                'style' : "heading right"})
    row.append({'text'  : utils.seconds_to_hms(weekly_total),
                'style' : "body border-t"})
    row.append({'text'  : "&nbsp;",
                'style' : "body"})

    for daily_total in daily_totals:
        row.append({'text'  : utils.seconds_to_hms(daily_total),
                    'style' : "body border-t"})

    summary_table.append(row)

    # Finally, display the table to the user.

    return render(request, "reflect.html",
                  {'table' : summary_table})
Ejemplo n.º 2
0
def suggest(request):
    """ Select a task and suggest that the user works on it.

        This is the main view for the "do" mode.
    """
    # Get the details of the most recently worked-on task, if any.

    activity = activities.latest_activity()
    if activity['task'] == None:
        recent_task = None
    else:
        age = utils.current_datetime() - activity['ended_at']
        if age > datetime.timedelta(hours=1):
            recent_task = None
        else:
            time_spent = \
                utils.format_seconds_for_display(activity['time_spent'])

            did_minimum = (activity['time_spent'] > activity['task'].min_time)

            recent_task = {'label'       : activity['task'].label,
                           'time_spent'  : time_spent,
                           'did_minimum' : did_minimum}

    # Calculate the summary of the tasks worked on so far today.

    started_at = utils.start_of_day() #.replace(day=17)
    ended_at   = utils.current_datetime()

    summary = activities.calc_task_summary(started_at, ended_at)

    # Convert the task tree into a "table" of nested activities.

    task_table = []

    def _add_tree(tree, task_table, indent=0):
        """ Recursively add the tree to the task table.
        """
        for node in tree:
            time_spent = utils.format_seconds_for_display(node['time_spent'])
            indent_str = "&nbsp;" * 8
            task_table.append({'task'       : node['task'],
                               'time_spent' : time_spent,
                               'prefix'     : indent_str * indent})
            _add_tree(node['children'], task_table, indent=indent+1)

    _add_tree(summary['summary'], task_table)

    # Choose the suggested task to work on next.

    suggested_task = chooser.choose_next_task()
    if suggested_task != None:
        start_url = "/do/" + str(suggested_task.id)
    else:
        start_url = None

    # Finally, display the suggested task to the user.

    total_time   = utils.format_seconds_for_display(summary['tot_time'])
    finished_url = "/"

    return render(request, "suggest.html",
                  {'recent_task'    : recent_task,
                   'task_table'     : task_table,
                   'total_time'     : total_time,
                   'suggested_task' : suggested_task,
                   'start_url'      : start_url,
                   'finished_url'   : finished_url})