1. Adam Coddington
  2. timebook


timebook /

Filename Size Date modified Message
71 B
507 B
133 B
384 B
14.8 KB
881 B
84 B


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.


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).


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
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.

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.


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:

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:

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

post_out_hook = /path/to/application
autocontinue =


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

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.


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:

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:

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.


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.



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


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


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


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 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


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


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 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


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 the available timesheets.

usage: t list

hooks: pre_list_hook, post_list_hook

aliases: ls


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


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


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


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


Print all active sheets and any messages associated with them.

usage: t running

hooks: pre_running_hook, post_running_hook

aliases: active


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 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


Watch taskwarrior for active tasks. As the currently active task changes, create new timesheet entries matching the currently-active task. This command runs forever until exited using CTRL``+``C.

If UDAs named ticket or pr are defined, will set the created timesheet entry's ticket and pr fields to match those of the ticket UDA values.

usage: t taskwarrior

hooks: pre_watch_tasks_hook, post_watch_tasks_hook

aliases: watch_tasks, task