timebook

A fork of timebook including several new features (many originally added for Parthenon Software Group).

Stars
29

.. -- restructuredtext --

Warning: This library is no longer maintained.

.. image:: https://travis-ci.org/coddingtonbear/timebook.png?branch=master

Timebook

Timebook is a small utility which aims to be a low-overhead way of tracking what you spend time on. It can be used to prepare annotated time logs of work for presentation to a client, or simply track how you spend your free time. Timebook is implemented as a python script which maintains its state in a sqlite3 database.

Concepts


Timebook maintains a list of *timesheets* -- distinct lists of timed
*periods*. Each period has a start and end time, with the exception of the
most recent period, which may have no end time set. This indicates that
this period is still running. Timesheets containing such periods are
considered *active*. It is possible to have multiple timesheets active
simultaneously, though a single time sheet may only have one period
running at once.

Interactions with timebook are performed through the ``t`` command on
the command line. ``t`` is followed by one of timebook's subcommands.
Often used subcommands include ``in``, ``out``, ``switch``, ``now``,
``list`` and ``display``. Commands may be abbreviated as long as they
are unambiguous: thus ``t switch foo`` and ``t s foo`` are identical.
With the default command set, no two commands share the first same
letter, thus it is only necessary to type the first letter of a command.
Likewise, commands which display timesheets accept abbreviated timesheet
names. ``t display f`` is thus equivalent to ``t display foo`` if
``foo`` is the only timesheet which begins with "f". Note that this does
not apply to ``t switch``, since this command also creates timesheets.
(Using the earlier example, if ``t switch f`` is entered, it would thus
be ambiguous whether a new timesheet ``f`` or switching to the existing
timesheet ``foo`` was desired).

Usage
~~~~~

The basic usage is as follows::

  $ t in 'document timebook'
  $ t change 'doing something else'
  $ t out

The first command, ``t in 'document timebook'`` creates a new period in
the current timesheet, and annotates it with the description "document
timebook". The second, ``t change 'doing something else'`` ends the first period
you created a moment ago, and starts a new period, annotating it with the 
description 'doing something else'.  Finally, ``t out`` records the current
time as the end time for the most recent period in the ``writing``
timesheet.

To display the current timesheet, invoke the ``t display`` command::

  $ t display
  Timesheet writing:
  Day            Start      End        Duration   Notes
  Mar 14, 2009   19:53:30 - 20:06:15   0:12:45    document timebook
                 20:07:02 -            0:00:01    write home about timebook
                                       0:12:46
  Total                                0:12:46

Each period in the timesheet is listed on a row. If the timesheet is
active, the final period in the timesheet will have no end time. After
each day, the total time tracked in the timesheet for that day is
listed. Note that this is computed by summing the durations of the
periods beginning in the day. In the last row, the total time tracked in
the timesheet is shown.

Parthenon-Related Usage

Annotating work-related projects can be somewhat more complicated due to having specific projects associated with billable or non-billable tickets, but timebook will help make this reasonably easy for you by allowing you to specify, in addition to a description, a ticket number that will be used when posting your timesheet (you can change 'in' to 'change' should you be switching tasks instead of starting a new one)::

$ t in --ticket=1038 "Working on my falafel recipe"

The above command will enter 'Working on my falafel recipe' into your timesheet, set the entry's ticket number to '1038' and mark the task as billable (the default). But, what if you want your ticket to be marked as non-billable? ::

$ t in --ticket=1038 --non-billable "Working on my falafel recipe"

Additionally, you can modify previous entries' ticket number and billable status (as well as any custom attributes) by using the alter command, optionally providing the ID number of an entry of which you'd like to change the properties. ::

$ t alter --id=208 --ticket=2408

At the end of the day, you can post your hours to our timesheet automatically by running::

$ t post

If you do not have your credentials saved in the configuration, you will be asked for your username and password, statistics will be gathered (if possible) for the entries you are posting, and your entries will be posted to your timesheet online.

Web Interface


A web interface for viewing timebook information is available in the project
``timebook_web``; head over to http://bitbucket.org/coddingtonbear/timebook_web/
for details.

Configuration

A configuration file lives in ~/.config/timebook/timebook.ini that you can use to configure various options in the timebook application including setting your ChiliProject username and password.

If you'd like to not be asked for your username and password when you're posting a timesheet and/or allow the web interface to gather information from ChiliProject directly, you can enter your username and password inside the above file in a format like::

[auth] username = MY USERNAME password = MY PASSWORD

Additionally, you can set sheet-specific reporting urls, hooks, etc by setting a configuration section using the name of the sheet for which you would like a pre, post, or reporting hook to be executed, and the name of the URL or application you would like executed like::

[default] post_hook = /path/to/some/application pre_hook = /path/to/some/other/application reporting_url = http://www.somedomain.com/reporting/

[some_other_client] post_out_hook = /path/to/application autocontinue =

Hooks

Hooks can be assigned a per-timesheet and per-timesheet-per-command basis by adding entries to your timesheet configuration like::

[timesheet] post_hook = /path/to/some/post_hook/application/ pre_out_hook = /path/to/some/pre_out_hook/application/

In the above example, the command /path/to/some/post_hook/application/ will be executed after every command; if the command exits with a non-zero status, an error will be displayed (but the entry will still be created successfully).

Additionally, the command /path/to/some/pre_out_hook/application/ will be executed before every execution of the out command (which is executed when one runs the t out command as well as the t change command). Should the hooked application execute with a non-zero status, an error will be displayed and the entry will not be created successfully.

Autocontinuation

Should you be working on a project with very-fine-grained tasks, you may consider enabling autocontinue by adding an entry to your timesheet configuration like::

[timesheet] autocontinue =

Autocontinuation will cause task details that you do not explicitly specify to be preserved from the previous timesheet entry to your current timesheet entry when you execute t change. For example::

t in --ticket=12308 "Helping Brian" // Entry is annotated with ticket# 12308 and a description of "Helping Brian" t change "Troubleshooting with Joseph" // Entry is still annotated with ticket# 12308 and a description of "Troubleshooting with Joesph"

Custom Metadata

You might have a peculiar use for storing some specific bit of metadata about individual ticket entries. You can use custom metadata attributes to provide this functionality.

To use custom metadata attributes, create a configuration section named custom_ticket_meta with the keys and values named after the name of the attribute and its help text, respectively::

[custom_ticket_meta] with=Who are you working with right now? category=What category is the work you're working on?

This will add two new parameters that are settable and modifiable during your t in, t change and t alter commands just like built-in attributes like an entry's associated ticket number and billable status.

Command Aliases

You will quickly notice that there are rather a lot of commands and that the connection between the command name and its action may be entirely unclear to you; in order to allow one to use the system in a way that suits their cognitive processes best, you are able to specify aliases for any command.

For example, if you would prefer to use the command to instead of change when changing tasks , you can create aliases in an aliases section in your Timebook configuration. ::

[aliases] to=change

You can also override built-in commands; so if you rarely use the built-in switch command and would rather have it behave as change already does, you can, of course, do that, too.

Commands


**alter**
  Inserts a note associated with the currently active period in the
  timesheet.

  *Also accepts custom ticket metadata parameters.*

  usage: ``t alter [--billable] [--non-billable] [--ticket=TICKETNUMBER] [--id=ID] NOTES...``

  hooks: ``post_alter_hook``, ``pre_alter_hook``

  aliases: *write*

**backend**
  Run an interactive database session on the timebook database. Requires
  the sqlite3 command.

  usage: ``t backend``

  hooks: ``post_backend_hook``, ``pre_backend_hook``

  aliases: *shell*

**change**
  Stop the timer for the current timesheet, and re-start the timer for the
  current timesheet with a new description.  Notes may be specified for this 
  period. This is roughly equivalent to ``t out; t in NOTES``, excepting that
  any metadata set for the previous timesheet entry will be preserved for the
  new timesheet entry.

  *Also accepts custom ticket metadata parameters.*

  usage: ``t change [--billable] [--non-billable] [--ticket=TICKETNUMBER] [NOTES...]``

  hooks: ``post_change_hook``, ``pre_change_hook``, ``pre_in__hook``, ``post_in__hook``, ``pre_out_hook``, ``post_out_hook``

**details**
  Displays details regarding tickets assigned to a specified ticket number.

  Information displayed includes the project name and ticket title, as well
  as the number of hours attributed to the specified ticket and the billable
  percentage.

  usage: ``t details TICKET_NUMBER``

  hooks: ``pre_details_hook``, ``post_details_hook``

**display**
  Display a given timesheet. If no timesheet is specified, show the
  current timesheet.

  Additionally allows one to display the ID#s for individual timesheet
  entries (for making modifications).

  *By default, shows only the last seven days of activity.*

  usage: ``t display [--show-ids] [--start=YYYY-MM-DD] [--end=YYYY-MM-DD] [TIMESHEET]``

  hooks: ``pre_display_hook``, ``post_display_hook``

  aliases: *show*

**hours**
  Calculates your timesheet's current balance for the current pay period
  given a 40-hour work week.

  Uses entries in additional tables named *unpaid*, *vacation*, and *holiday*
  to calculate whether a specific day counts as one during which you are
  expecting to reach eight hours.

  usage: ``t hours``

  hooks: ``pre_hours_hook``, ``post_hours_hook``

  aliases: *payperiod*, *pay*, *period*, *offset*

**in**
  Start the timer for the current timesheet. Must be called before out.
  Notes may be specified for this period. This is exactly equivalent to
  ``t in; t alter NOTES``

  *Also accepts custom ticket metadata parameters.*

  usage: ``t in [--billable] [--non-billable] [--ticket=TICKETNUMBER] [--switch TIMESHEET] [NOTES...]``

  hooks: ``pre_in__hook``, ``post_in__hook``

  aliases: *start*

**insert**
  Insert a new entry into the current timesheet.  Times must be in the 
  YYYY-MM-DD HH:MM format, and all parameters should be quoted.

  usage: ``t insert START END NOTE``

  hooks: ``pre_insert_hook``, ``post_insert_hook``

**kill**
  Delete a timesheet. If no timesheet is specified, delete the current
  timesheet and switch to the default timesheet.

  usage: ``t kill [TIMESHEET]``

  hooks: ``pre_kill_hook``, ``post_kill_hook``

  aliases: *delete*

**list**
  List the available timesheets.

  usage: ``t list [--summary]``

  hooks: ``pre_list_hook``, ``post_list_hook``

  aliases: *ls*


**modify**
  Provides a facility for one to modify a previously-entered timesheet entry.

  Requires the ID# of the timesheet entry; please see the command
  named *display* above.

  usage ``t modify ID``

  hooks: ``pre_modify_hook``, ``post_modify_hook``

**now**
  Print the current sheet, whether it's active, and if so, how long it
  has been active and what notes are associated with the current period.

  If a specific timesheet is given, display the same information for
  that timesheet instead.

  usage: ``t now [--simple] [TIMESHEET]``

  hooks: ``pre_now_hook``, ``post_now_hook``

  aliases: *info*

**out**
  Stop the timer for the current timesheet. Must be called after in.

  usage: ``t out [--verbose] [TIMESHEET]``

  hooks: ``pre_out_hook``, ``post_out_hook``

  aliases: *stop*

**post**
  Posts your current timesheet to our internal hours tracking system.

  The application will not require your input to post hours if you have stored
  your credentials in your configuration, but if you have not, your username
  and password will be requested.

  usage ``t post [--date=YYYY-MM-DD]``

  hooks: ``pre_post_hook``, ``post_post_hook``

**running**
  Print all active sheets and any messages associated with them.

  usage: ``t running``

  hooks: ``pre_running_hook``, ``post_running_hook``

  aliases: *active*

**stats**
  Print out billable hours and project time allocation details for the past
  seven days.

  Optionally you can specify the range of time for which you'd like statistics
  calculated.

  usage ``t stats [--start=YYYY-MM-DD] [--end=YYYY-MM-DD]``

  hooks: ``pre_stats_hook``, ``post_stats_hook``

**switch**
  Switch to a new timesheet. this causes all future operation (except
  switch) to operate on that timesheet. The default timesheet is called
  "default".

  usage: ``t switch TIMESHEET``

  hooks: ``pre_switch_hook``, ``post_switch_hook``