tiempo-rs/docs/source/index.rst

1118 lines
32 KiB
ReStructuredText

Tiempo
======
Synopsys
--------
``t -h|--help``
``t help SUBCOMMAND``
``t SUBCOMMAND -h|--help``
``t SUBCOMMAND [OPTIONS]``
Subcommands
-----------
Bellow you can see the full list of subcommands. All of them can be abbreviated
to their first letter, so for example ``t backend`` can also be typed ``t b``.
+--------------------+---------------------------------------------------------+
| Command | Description |
+====================+=========================================================+
| :ref:`t-archive` | Archive entries to a hidden timesheet. |
+--------------------+---------------------------------------------------------+
| :ref:`t-backend` | Open an sqlite shell to the database |
+--------------------+---------------------------------------------------------+
| :ref:`t-configure` | Configure tiempo in-place or get path to config file. |
+--------------------+---------------------------------------------------------+
| :ref:`t-display` | Display all entries in the current sheet. |
+--------------------+---------------------------------------------------------+
| :ref:`t-edit` | Edit an entry. |
+--------------------+---------------------------------------------------------+
| :ref:`t-in` | Start an entry in the current timesheet. |
+--------------------+---------------------------------------------------------+
| :ref:`t-kill` | Delete an entry or an entire timesheet. |
+--------------------+---------------------------------------------------------+
| :ref:`t-list` | List existing sheets. |
+--------------------+---------------------------------------------------------+
| :ref:`t-month` | Display entries starting this month. |
+--------------------+---------------------------------------------------------+
| :ref:`t-now` | Show all running entries. |
+--------------------+---------------------------------------------------------+
| :ref:`t-out` | End the active entry in the current timesheet. |
+--------------------+---------------------------------------------------------+
| :ref:`t-resume` | Restart the timer for an entry. |
+--------------------+---------------------------------------------------------+
| :ref:`t-sheet` | Switch to a new or existing timesheet. |
+--------------------+---------------------------------------------------------+
| :ref:`t-today` | Display entries that started today. |
+--------------------+---------------------------------------------------------+
| :ref:`t-week` | Display entries starting last monday or later. |
+--------------------+---------------------------------------------------------+
| :ref:`t-yesterday` | Display entries that started yesterday. |
+--------------------+---------------------------------------------------------+
Description
-----------
Tiempo is a command-line time tracker. Register the start and end times of your
activities and get results by day, week, month or custom periods of time in
different formats, including custom ones.
Entries are optionally organized in timesheets which you can use to represent
projects, clients etc. Most commands (notably the ones that display entries)
work on the *current* or *active* timesheet.
The entries are stored in a local Sqlite3 database whose location you can learn
by looking at your config file (whose location you can learn running ``t c``).
**tiempo** stores entries as UTC and then converts to the local timezone for
displaying and querying. This means that even if you change timezones your
recorded times will be correct, although their displayed results might vary if
grouping by day for example.
This tool is compatible with a previous one with the same purpose called
``timetrap``. The most notable difference being that timetrap stores times as
local timezone times, which makes it messy if you switch timezones. Another
difference is that in timetrap you used the internal ruby API to add custom
display formats and in ``tiempo`` you'll use standard input/output and
command-line arguments in any language of your choice.
Tutorial
--------
.. _life-cycle:
Life Cycle
..........
Most of the time you'll be using these commands:
#. ``t in`` starts time tracking for an activity.
#. ``t out`` ends time tracking for the current activity.
#. ``t resume`` resumes time tracking for a previous activity.
#. ``t edit`` allows to quickly edit an entry's details.
#. ``t archive`` archives entries without deleting them from the database.
#. ``t kill`` permanently deletes entries.
You can see the state of your activities using:
* ``t list`` shows time tracking summary for all timesheets.
* ``t now`` shows running entries for all timesheets.
* ``t display`` shows more detailed information about activities in the current
timesheet. Variants of this subcommand include ``t today``, ``t yesterday``,
``t week`` and ``t month``.
To begin, let's start a task with:
.. code-block:: shell-session
$ t in 'task 1'
Checked into sheet "default".
At any time see what's happening with:
.. code-block:: shell-session
$ t display
Timesheet: default
Day Start End Duration Notes
Sun Oct 30, 2022 11:24:18 - 0:00:03 first task
0:00:03
----------------------------------------------------------------
Total 0:00:03
After some time of hard work you can stop tracking with:
.. code:: shell-session
$ t out
Checked out of sheet "default".
If later (say, after lunch) you decide to continue with this activity you may do
so with:
.. code:: shell-session
$ t resume
Resuming "task1"
Checked into sheet "default".
Which by default resumes the last task of the timesheet.
After some time (days, weeks, months...) of activities being recorded and
queried you might want to archive some of them. For that use:
.. code:: shell-session
$ t archive
A total of 2 entries accounting for 9m 38s will be archived.
Proceed? [y/N] y
If you do ``list`` or ``display``, no activities are going to be active. If you
want to see archived activities, you can do it with:
.. code:: shell-session
$ t display full
Timesheet: _default
Day Start End Duration Notes
Mon Oct 24, 2022 18:57:03 - 19:01:25 0:04:21 task1
19:06:49 - 19:12:05 0:05:16 task1
0:09:38
-----------------------------------------------------------
Total 0:09:38
Using sheets
............
Usually you need to track activities for different projects or clients. That's
what timesheets are for.
To switch (and create if necessary) to a new timesheet use:
.. code:: shell-session
$ t sheet 'My Amazing Project'
Switching to sheet 'My Amazing Project'
Then, start a new activity in the new timesheet with:
.. code:: shell-session
$ t in 'An Amazing Activity'
Checked into sheet "My Amazing Project".
Just like before you can use ``t display`` to see your progress. To see a
summary of all of your timesheets use:
.. code:: shell-session
$ t list
Timesheet Running Today Total Time
* My Amazing Project 0:00:00 0:00:00 0:00:00
- default 0:00:00 0:00:05 0:00:05
-----------------------------------------------------
0:00:00 0:00:05 0:00:05
You can switch timesheets with:
.. code:: shell-session
$ t sheet default
Switching to sheet 'default'
If you switch very often between two timesheets pass ``-`` to switch to the
previously active timesheet.
Next steps
..........
See the list of subcommands and their options bellow to really take advantage of
tiempo. Learn about the different settings (see :ref:`settings`) and how to use
the different formatters (see :ref:`default-formatters`) that are shipped by
default or learn how to make your own (see :ref:`custom-formatters`).
Happy time tracking!
Subcommands
-----------
.. _t-archive:
t archive
.........
``t a|archive [OPTIONS] [SHEET]``
To archive means to move entries from the current or specified timesheet to a
different "hidden" sheet so that when you query the current sheet you don't see
them but they are kept in the database. Archived entries are stored in a sheet
with the same name of the original with an underscore as prefix. Use
:ref:`t-list` to see archived sheets.
By default this command will ask for you confirmation, then archive ALL entries
in the current timesheet. Pass ``--fake`` to only display the entries using the
``text`` formatter (useful if you want to make sure that the archived
time/entries are correct).
Using ``--start`` and ``--end`` you can further limit the period of time that
will be archived (See :ref:`specifying-times` section of the docs on the
accepted formats). You can use ``--grep`` to only archive certain entries that
match the given regular expression.
If what you need is to archive a specific elapsed time, for example only 15
hours out of however many the timesheet has use ``--time`` with the amount of
hours you want to archive.
**Options**
-f, --fake
Don't actually archive the entries, just display them
-e, --end <TIME>
Include entries that start on this date or earlier
-g, --grep <REGEXP>
Include entries where the note matches this regexp.
-s, --start <TIME>
Include entries that start on this date or later
-t, --time <HOURS>
Time in hours to archive. Archived time will be equal or less than this.
``SHEET``
Archive entries from this timesheet instead of the current one.
.. _t-backend:
t backend
.........
``t b|backend``
Open a sqlite3 shell into the database. Sqlite3 must be installed and in the
``PATH`` variable for this command to work.
.. _t-configure:
t configure
...........
``t c|configure [OPTIONS]``
If called without arguments ``t c`` will print the absoulte path to the config
file. If you pass arguments they'll be used to edit your config file in place.
.. warning::
This will erase any comments you might have added to your toml or yaml file.
It is better to edit the config file manually with your preferred text
editor:
.. code:: shell-session
vim $(t c)
**Options**
--auto-checkout
Checkout of current running entry when starting a new one. **Not
implemented**.
--no-auto-checkout
Starting a new entry fails if one is running (default).
--no-require-note
Entries can be created without a note.
--require-note
Prompt for a note if one isn't provided when checking in (default).
--append-notes-delimiter <DELIMITER>
delimiter used when appending notes via t edit --append. Default: ' '
(space).
--database-file <PATH>
Set the absoulte path to the sqlite database. A new database will be created
at this location if one does not exist.
--default-formatter <FORMATTER>
The format to use when display commands are invoked without a ``--format``
option. Defaults to ``'text'``. See :ref:`settings` section of the docs for
per-command default formatter.
``--formatter-search-paths <PATH>[,<PATH>...]``
comma separated paths to search for user defined fomatters. See
:ref:`custom-formatters` section for more info on this.
--interactive-entries <N>
How many unique previous notes to show when selecting interactively. An
example of an interactive command is ``t resume -i``.
--note-editor <EDITOR>
Specify a custom command used to edit an entry's note. Default: $EDITOR
--round-in-seconds <SECONDS>
The duration of time to use for rounding with the -r flag. Default: 900 (15
m). **Not implemented**.
--week-start <DAY>
The day of the week to use as the start of the week for t week. Default:
monday [possible values: monday, tuesday, wednesday, thursday, friday,
saturday, sunday]
.. _t-display:
t display
.........
``t d|display [OPTIONS] [SHEET|all|full]``
Display all entries in the current timesheet using the specified formatter (by
default this is ``text``). For more information on formatters see
:ref:`default-formatters`. For information on custom formatters see
:ref:`custom-formatters`.
It is worh noting that **BOTH** the ``--start`` and ``--end`` arguments act on
the start time of the entry.
**Options**
-v, --ids
Print database ids (for use with edit).
-e, --end <TIME>
Include entries that start on this date or earlier.
-f, --format <FORMAT>
The output format. Valid built-in formats are chart, text, ical, csv, json
and ids. See :ref:`default-formatters` for more info. See
:ref:`custom-formatters` to learn how to make your own.
-g, --grep <REGEXP>
Only display entries whose notes match this regular expression.
-s, --start <TIME>
Include entries that start on this date or later.
``<SHEET>``
The sheet to display. Pass 'all' to see entries from all sheets or 'full' to
see hidden entries.
.. _t-edit:
t edit
......
``t e|edit [OPTIONS] [NOTE]``
If run without arguments this command will launch a text editor with the text of
the current timesheet's last entry's note. Upon saving and exiting the new text
will be set. If a string is given as command-line argument it will be used as
the new note and no editor will be launched. If used with ``--append`` the
new text will be appended to the previous one using whatever string is set as
:ref:`append_notes_delimiter` in the settings file.
The last entry is defined as the one that was started last, not necessarily the
one with the highest ID in the current timesheet.
You can also leave the note untouched and edit other parts of the entry like its
start and end times using ``--start`` and ``--end`` respectively, see
:ref:`specifying-times`. Or you can move an entry that was created in the wrong
timesheet by using ``--move``.
**Options**
-z, --append
Append the new text to the current note instead of replacing it.
-e, --end <TIME>
Set this as the end time.
--id <ID>
Edit entry with this ID instead of the last one in the current sheet.
-m, --move <SHEET>
Move entry to another sheet.
-s, --start <TIME>
Set this as the start time.
``<NOTE>``
Set this as the entry's note. It will replace the previous one unless
``--append`` is given.
t help
......
``t help SUBCOMMAND``
Get help on the specified subcommand. It is equivalent to passing ``-h`` to any
subcommand.
.. _t-in:
t in
....
``t i|in [--at TIME] [NOTE]``
Start an entry in the current timesheet. If used without arguments and
:ref:`require_note` is set to ``true`` in the settings then it will launch a
text editor for you to write a note. Pass ``--at`` to set a specific time of
start instead of now, like in case you forgot to start an activity five minutes
ago:
.. code:: shell-session
t i --at '5 min ago' 'writing the codez'
.. _t-kill:
t kill
......
``t k|kill (--id ID|--last|SHEET)``
Use this to completely delete entries. Pass a timesheet name to delete all
entries from it or use ``--id`` to delete an entry by its ID. IDs from entries
can be shown passing ``-v`` to 'display' subcommand and variants. To delete only
the last entry from the sheet pass ``--last`` as single argument.
This command will ask for confirmation before touching the database.
If you'd prefer to keep record of entries but have them out of the way use
:ref:`t-archive`.
**Options**
-l, --last
Delete the last entry of the current sheet
--id <ID>
Delete entry with this ID instead of sheet
``<SHEET>``
Delete an entire sheet by its name
.. _t-list:
t list
......
``t l|list [-a|--all] [-f|--flat]``
Lists existing timesheets. Pass ``--all`` to also list hidden (archived) ones.
The output includes 4 columns: the name of the timesheet, the elapsed time of
the running entry, the accumulated time for the day and the total time (sum of
all entries per timesheet).
.. code:: text
Timesheet Running Today Total Time
default 0:00:00 0:00:00 2:39:38
- foo 0:00:00 0:30:01 0:30:01
* pink 0:00:00 0:05:04 0:05:04
--------------------------------------------
0:00:00 0:35:06 3:14:44
An asterisk (*) at the left will indicate the current timesheet and a dash (-)
indicates the previously used one. This is relevant for :ref:`t-sheet` where you
can use - as the timesheet name to just switch to the previous one.
**New in 1.5.3**
Pass ``--flat`` to only display timesheet names one per line. Useful for passing
the list to other commands (it is used for the different completion scripts).
.. code:: shell-session
$ t l --flat
default
foo
pink
.. _t-month:
t month
.......
``t m|month [OPTIONS] [SHEET|all|full]``
Like :ref:`t-display` but only display entries that started this month in the
current timezone. Pass ``--month MONTH`` to display entries of different months.
Just like ``t-display`` this accepts ``--grep``, ``--ids``, and ``--format``.
.. _t-now:
t now
.....
``t n|now``
Show only timesheets with running entries. Since every timesheet can only have
one running entry at a time this command displays its note.
.. code:: text
Timesheet Running Activity
* default 0:00:01 reading
- pink 0:00:21 gardening
Just like :ref:`t-list` it displays an asterisk for the current timesheet and a
dash for the previous one.
.. _t-out:
t out
.....
``t o|out [--at TIME]``
End the active entry in the current timesheet, if any. End time is set as the
current time unless ``--at`` is passed, case in which the specified time is set
as end time for the entry. See :ref:`specifying-times` to learn the accepted
formats.
.. _t-resume:
t resume
........
``t r|resume [OPTIONS]``
If called without arguments this command will start a new entry with the same
note as the last started entry in the current sheet. It is an easy way of
continuing with a task that was suspended.
To restart an entry with one of the last 10 unique notes pass ``--interactive``
which will show an UI like this:
.. code:: text
Latest entries of sheet 'dafault':
# Note Total time Last started
5 try to find a pair for this sock 11:35:35 1 week ago
4 pensar en la inmortalidad del cangrejo 1:31:09 1 week ago
3 cook fried rice 0:50:03 4 days ago
2 investigate quantum mechanics 10:59:17 11 hours ago
1 turn lead into gold 1:24:14 10 hours ago
enter number or q to cancel
>>
The number of unique entries shown is configurable with the
:ref:`interactive_entries` setting. To proceed pass any of the shown numbers of
the left column and press intro or enter q or Ctrl+D to exit.
To restart an entry whose ID you know pass ``--id ID``.
**Options**
-i, --interactive
Select one of the latest unique entries interactively
--id ID
Resume entry by its ID
.. _t-sheet:
t sheet
.......
``t s|sheet [SHEET]``
Switch to a timesheet with name ``SHEET``, creating it if it doesn't exist. If
used without arguments this command is an alias to :ref:`t-list` so you can see
what timesheets you have.
``tiempo`` remembers the last sheet you used (unless it doesn't exist anymore),
so you can switch quickly between the current and the previous one passing ``-``
(a dash) as the sheet name.
.. _t-today:
t today
.......
``t t|today [OPTIONS] [SHEET|all|full]``
Like :ref:`t-display` but only display entries that started today in the current
timezone. Pass ``--end`` to further filter entries that started earlier than the
given time.
Just like ``t-display`` this accepts ``--grep``, ``--ids``, and ``--format``.
.. _t-week:
t week
......
``t w|week [OPTIONS] [SHEET|all|full]``
Like :ref:`t-display` but only display entries that started this week in the
computer's timezone. The first day of the week by default is ``monday`` but this
is configurable. See :ref:`settings` and :ref:`t-configure`.
Just like ``t-display`` this accepts ``--grep``, ``--ids``, and ``--format``.
.. _t-yesterday:
t yesterday
...........
``t y|yesterday [OPTIONS] [SHEET|all|full]``
Like :ref:`t-display` but only display entries that started yesterday in the
computer's current timezone.
Just like ``t-display`` this accepts ``--grep``, ``--ids``, and ``--format``.
.. _settings:
Settings
--------
Tiempo settings are kept in a single ``TOML`` file. You can learn its location
by running ``t c``. Here is the full list with descriptions.
.. _append_notes_delimiter:
append_notes_delimiter
......................
**Type**: string **Default**: ``" "``
String used to concatenate text when ``--append`` is passed to :ref:`t-edit`.
auto_checkout
.............
**Type**: bool **Default**: false
Not implemented. Kept for compatibility with ``timetrap``. Tracking issue
https://gitlab.com/categulario/tiempo-rs/-/issues/11
auto_sheet
..........
**Type**: string **Default**: ``"dotfiles"``
Not implemented. Kept for compatibility with ``timetrap``. Tracking issue:
https://gitlab.com/categulario/tiempo-rs/-/issues/9
auto_sheet_search_paths
.......................
**Type**: [string] **Default** Depends on OS, irrelevant anyways
Not implemented. Kept for compatibility with ``timetrap``. Tracking issue:
https://gitlab.com/categulario/tiempo-rs/-/issues/9
.. _commands:
commands
........
``tiempo`` allows having per-command configuration. For now it limits to
per-command default formatters introduced in ``1.4.0``. To set a default
formatter other than the default ``text`` use something like this in your
settings file:
**In toml**
.. code:: toml
[commands.week]
default_formatter = "chart"
**In yaml**
.. code:: yaml
commands:
week:
default_formatter: chart
To set a default formatter for every command use :ref:`default_formatter`.
database_file
.............
**Type**: string **Default**: Depends on OS
Absolute path to the database file.
default_command
...............
**Type**: string|null **Default**: null
Not implemented. Kept for compatibility with ``timetrap``. Implementation
planned. Tracking issue: https://gitlab.com/categulario/tiempo-rs/-/issues/10
.. _default_formatter:
default_formatter
.................
**Type**: string **Default**: ``"text"``
Formatter used for :ref:`t-display` subcommand and variants when no ``--format``
argument is passed. Included formatters are explained in the
:ref:`default-formatters` section, they are: chart, text, ical, csv, json, ids.
To set a default formatter for only one command see the :ref:`commands` config
above.
.. _formatter_search_paths:
formatter_search_paths
......................
**Type**: [string] **Default**: Depends on OS, but not empty
Array of paths to search for custom formatters. See :ref:`custom-formatters` to
learn how to write them. Custom formatters must be executable files.
.. _formatters:
formatters
..........
The :ref:`chart` formatter introduced in ``1.4.0`` has a few settings. It is
also possible to store settings for your custom formatters in this variable.
Take a look at the following example:
.. code:: toml
[formatters.earnings]
currency = "USD"
hourly_rate = 400
[formatters.chart]
daily_goal_hours = 4
weekly_goal_hours = 20
character_equals_minutes = 30
.. code:: yaml
formatters:
earnings:
currency: MXN
hourly_rate: 280
chart:
daily_goal_hours: 4
weekly_goal_hours: 20
character_equals_minutes: 30
Check :ref:`custom-formatters` to learn how to read this settings in your
formatters.
Available settings for the :ref:`chart` formatter are:
* ``daily_goal_hours`` (integer, default: 0) Number of hours you set as your
daily goal. Will display a uniform gray bar at the set hours that will turn
green as you make progress.
* ``weekly_goal_hours`` (integer, default: 0) Number of hours you expect to work
in a week. Controls wether the weekly hour count displays in green color.
* ``character_equals_minutes`` (integer, default: 30). Controls how many minutes
each character of the chart represents. Set lower for wider charts. Set to 0
to make tiempo crash.
.. _interactive_entries:
interactive_entries
...................
**Type**: integer **Default** 10
Number of unique entries to show when interactive commands like :ref:`t-resume`
are invoked.
.. _note_editor:
note_editor
...........
**Type**: string|null **Default** ``null``
Specify an editor to use when starting an entry without a note and when
:ref:`require_note` is true. By default ``tiempo`` respects the ``$EDITOR``
variable so you can leave this setting as ``null`` most of the time.
.. _require_note:
require_note
............
**Type**: bool **Default** true
Wether or not entries require a note to be recorded. If true then running
:ref:`t-in` without arguments will launch the text editor configured in
:ref:`note_editor`
round_in_seconds
................
**Type**: integer **Default**: 900 (15 min)
Not implemented, kept for compatibility with timetrap. Tracking issue:
https://gitlab.com/categulario/tiempo-rs/-/issues/6
week_start
..........
**Type**: string **Default** ``"monday"``
Day of the week that should be considered as the start for :ref:`t-week`.
Options are ``"monday"``, ``"tuesday"``, ``"wednesday"``, ``"thursday"``,
``"friday"``, ``"saturday"``, ``"sunday"``.
Files, paths and the environment
--------------------------------
Tiempo uses the same directory to store the database and configuration. It's
location depends on the operative system, but it's likely one of these options:
**On Linux**
tiempo respects ``XDG`` variables. So most likely the config directory is
``$HOME/.config/tiempo``.
**On windows**
``{FOLDERID_RoamingAppData}``
**On mac**
``$HOME/Library/Application Support``
To be 100% sure run ``t c``.
Inside the config directory you'll find two files: ``config.toml`` and
``database.sqlite3`` which are your settings file and database respectively.
Tiempo also recognises traditional ``timetrap`` config and directories, which in
all platforms should be: ``$HOME/.timetrap.yml`` for the config file and
``$HOME/.timetrap.db`` for the database.
You can set the config file to a different location by setting the
``TIMETRAP_CONFIG_FILE`` envornment variable to an absolute path that includes
the filename like so:
``TIMETRAP_CONFIG_FILE=/path/to/my_config.toml``
From within the config file you can set the paths to the database and custom
formatters as explained in the :ref:`settings`.
.. _specifying-times:
Specifying times
----------------
Some arguments accept a time as value, like ``t in``'s ``--at`` or ``t d
--start``. These are the accepted formats:
**Something similar to ISO format** will be parsed as a time in the computer's
timezone.
* ``2021-01-13`` a date
* ``2019-05-03 11:13`` a date with portions of a time
**ISO format with offset or UTC** will be parsed as a time in the specified
timezone. Use ``Z`` for ``UTC`` and an offset for everything else
* ``2021-01-13Z``
* ``2005-10-14 19:20:35+05:00``
**something that looks like an hour** will be parsed as a time in the current
day in the computer's timezone. Add ``Z`` or an offset to specify the timezone.
* ``11:30``
* ``23:50:45`` (with seconds)
**some human times**, for now restricted to time ago:
* ``an hour ago``
* ``a minute ago``
* ``50 min ago``
* ``1h30m ago``
* ``two hours thirty minutes ago``
.. _default-formatters:
Default formatters
------------------
Tiempo comes with a handful of formatters that display your entries in different
ways. Here's the full list.
.. _chart:
chart
.....
(New in 1.4.0) Displays a nice chart of the weekly progress:
.. code:: text
Date Day Chart Hours
Sep 5 Mon ####### 3.8
6 Tue #### 2.3
7 Wed ####### 3.9
8 Thu 0.0
9 Fri ######### 4.5
10 Sat ######### 4.7
11 Sun 0.0
Week 19.3/20.0
Timesheet: default
This formatter comes with a few settings. See :ref:`formatters` for more.
text
....
Displays nicely the entries grouped by sheet and day. This is the default
formatter. Pass ``-v`` to also reveal each entry's id:
.. code:: text
Timesheet: foo
Day Start End Duration Notes
Tue Sep 20, 2022 09:09:58 - 09:40:13 0:30:15 write tiempo's docs
09:41:01 - 10:11:20 0:30:18 work on pizarra.categulario.xyz
1:00:34
-------------------------------------------------------------------------------------
Total 1:00:34
ical
....
This formatter's output can be redirected to a file and then uploaded to a
calendar app:
.. code:: text
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
METHOD:PUBLISH
PRODID:tiempo-rs
VERSION:2.0
BEGIN:VEVENT
DESCRIPTION:write tiempo's docs
DTEND:20220920T134013Z
DTSTAMP:20220920T130958Z
DTSTART:20220920T130958Z
SEQUENCE:0
SUMMARY:write tiempo's docs
UID:tiempo-10@abraham-lenovo-t470s
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:work on pizarra.categulario.xyz
DTEND:20220920T141120Z
DTSTAMP:20220920T134101Z
DTSTART:20220920T134101Z
SEQUENCE:0
SUMMARY:work on pizarra.categulario.xyz
UID:tiempo-11@abraham-lenovo-t470s
END:VEVENT
END:VCALENDAR
csv
...
Dump the entries as CSV to stdout. Useful for passing entries to a different
tool. Pass ``-v`` to add an ``id`` column.
.. code:: text
start,end,note,sheet
2022-09-20T13:09:58.805280Z,2022-09-20T13:40:13.837994Z,write tiempo's docs,foo
2022-09-20T13:41:01.478854Z,2022-09-20T14:11:20.461322Z,work on pizarra.categulario.xyz,foo
json
....
Dump the entries in JSON format:
.. code:: json
[{"id":10,"note":"write tiempo's docs","start":"2022-09-20T13:09:58.805280283Z","end":"2022-09-20T13:40:13.837994932Z","sheet":"foo"},{"id":11,"note":"work on pizarra.categulario.xyz","start":"2022-09-20T13:41:01.478854071Z","end":"2022-09-20T14:11:20.461322041Z","sheet":"foo"}]
ids
...
Dump only the ids in a single line:
.. code:: text
2196 2197 2198 2199 2200 2201
.. _custom-formatters:
Custom formatters
-----------------
You can implement your own formatters for all subcommands that display entries
(like ``t display``, ``t week`` etc.). It is as easy as creating an executable
file written in any programming language (interpreted or compiled) and placing
it in a path listed in the config value for ``formatter_search_paths``.
This executable will be given as standard input a csv stream with each row
representing a time entry with the same structure as the ``csv`` formatter
output. It will also be given a command line argument representing user settings
for this formatter stored in the config file and formatted as JSON.
Example
.......
Let's create a simple ``earnings`` formatter. It is as easy as creating the
following python script under the name ``earnings`` (no extension) inside one of
the paths listed in your :ref:`formatter_search_paths` setting and marking it as
executable (``chmod +x earnings``):
.. code:: python
#!/usr/bin/env python3
import sys, json, csv
from datetime import datetime, timezone, timedelta
from math import ceil
# Settings for this formatter are passed as the first argument
config = json.loads(sys.argv[1])
reader = csv.DictReader(
sys.stdin, # entries are received from stdin
fieldnames=['id', 'start', 'end', 'note', 'sheet'],
)
total = timedelta(seconds=0)
for line in reader:
# times are formatted as ISO format
start = datetime.strptime(line['start'], '%Y-%m-%dT%H:%M:%S.%fZ')
# entries that are still running don't have a value in the 'end' column
if not line['end']:
end = datetime.utcnow()
else:
end = datetime.strptime(line['end'], '%Y-%m-%dT%H:%M:%S.%fZ')
total += end - start
hours = total.total_seconds() / 3600
# use the settings
earnings = hours * config['hourly_rate']
currency = config['currency']
print(f'You have earned: ${earnings:.2f} {currency}')
You'll also need to add these settings to your config file:
.. code:: toml
[formatters.earnings]
hourly_rate = 300
currency = "USD"
Now if you run ``t display -f earnings`` you will get something like:
.. code:: text
You have earned: 2400 USD