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 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.
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.
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:
[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 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.
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"
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.
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.
- 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
- taskwarrior
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
orpr
are defined, will set the created timesheet entry'sticket
andpr
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