tiempo-rs/README.md

467 lines
13 KiB
Markdown
Raw Normal View History

2021-06-27 23:20:37 -05:00
# Tiempo
2021-06-27 23:22:50 -05:00
A [timetrap](https://github.com/samg/timetrap/) compatible command line time
tracking application.
2021-06-27 23:20:37 -05:00
2021-08-14 18:47:58 -05:00
## Installation
2022-07-22 06:20:47 -05:00
### For Archlinux (and derivatives) users
There are a binary and a source package in the AUR:
* [tiempo-bin](https://aur.archlinux.org/packages/tiempo-bin)
* [tiempo-git](https://aur.archlinux.org/packages/tiempo-git)
### For every other linux users
Go to [gitlab releases page](https://gitlab.com/categulario/tiempo-rs/-/releases)
and grab the latest binary for your linux. There is a `.deb` file for Debian and
Ubuntu as well as a binary for any `x86_64` Linux.
### For Rust developers
You have `cargo`! you can run:
2021-08-14 18:47:58 -05:00
cargo install tiempo
2022-07-22 06:20:47 -05:00
### For everyone else
You need to compile `tiempo` by yourself. But don't worry! It is not that hard.
Just clone [the repository](https://gitlab.com/categulario/tiempo-rs), make sure
you have [rust installed](https://rustup.rs) and run:
cargo build --release
inside the repository. The binary will be named `t` (or `t.exe` if you use
windows) and it is located inside the `target/release` directory that was
created during compilation.
2021-08-14 18:47:58 -05:00
2021-07-03 16:44:31 -05:00
## Tutorial
2021-07-03 17:05:53 -05:00
First of all, you can abbreviate all commands to their first letter, so `t in`
and `t i` are equivalent.
2021-07-03 16:44:31 -05:00
### Managing entries
Register the start of an activity in the default timesheet with:
t in 'Doing some coding'
which sets the activity's start time to the current time. Later when you're done
use
t out
2021-07-03 17:05:53 -05:00
to mark it as finished. If you forgot to start the activity before you can do so
with:
2021-07-03 16:44:31 -05:00
t i --at '20 min ago'
the same applies for `t out`.
Edit an entry with
t edit [options]
where the options are
-i, --id <id:i> Alter entry with id <id> instead of the running entry
-s, --start <time:qs> Change the start time to <time>
-e, --end <time:qs> Change the end time to <time>
-a, --append Append to the current note instead of replacing it
the delimiter between appended notes is
configurable (see configure)
-m, --move <sheet> Move to another sheet
2021-07-03 17:02:34 -05:00
You can remove an entry with
t kill --id 123
or an entire timesheet with
t kill somesheet
check bellow to see how to get the ids.
2021-07-03 16:44:31 -05:00
### Displaying entries
2021-07-03 17:02:34 -05:00
At any point in time you can check your time spent in the current or other
timesheet with:
2021-07-03 16:44:31 -05:00
t display [options] [SHEET | all | full]
the available options are
-v, --ids Print database ids (for use with edit)
-s, --start <date:qs> Include entries that start on this date or later
-e, --end <date:qs> Include entries that start on this date or earlier
-f, --format <format> The output format. Valid built-in formats are
chart, text (default), ical, csv, json and ids.
2021-07-03 17:04:19 -05:00
Check the docs on defining custom formats bellow.
2021-07-03 16:44:31 -05:00
-g, --grep <regexp> Include entries where the note matches this regexp
Some shortcuts available are:
2021-07-06 22:51:36 -05:00
`today` - Display entries that started today
2021-07-03 16:44:31 -05:00
t today [--ids] [--format FMT] [SHEET | all]
2021-07-06 22:51:36 -05:00
`yesterday` - Display entries that started yesterday
2021-07-03 16:44:31 -05:00
t yesterday [--ids] [--format FMT] [SHEET | all]
2021-07-03 16:48:51 -05:00
`week` - Entries of this week so far. The default start of the week is Monday
2021-07-03 16:44:31 -05:00
(configurable).
t week [--ids] [--end DATE] [--format FMT] [SHEET | all]
2021-07-06 22:51:36 -05:00
`month` - Entries of this month or a specified one.
2021-07-03 16:44:31 -05:00
t month [--ids] [--start MONTH] [--format FMT] [SHEET | all]
#### Per command default formatters
**New in 1.4.0**
It might be the case that you want to use one default formatter for when you use
`t week` and a different one for `t month` or `t today`. That's what per-command
default formatters are for. To use them just add a `commands` section to your
config file and set `default_formatter` on some formatters. This is what it
would look like:
**In toml**
```toml
[commands.week]
default_formatter = "chart"
[commands.month]
default_formatter = "ical"
```
**In yaml**
```yaml
commands:
week:
default_formatter: chart
month:
default_formatter: ical
```
2021-07-03 16:44:31 -05:00
### Using different timesheets
You can organize your activities in different timesheets by first switching to
an existing one, then starting an activity:
t sheet somename
t in 'some activity'
which will also create the timesheet if it doesn't exist.
2021-07-03 17:02:34 -05:00
List all existing timesheets using
t list [all]
(defaults to not showing archive timesheets with names preceded by an
underscore)
2021-07-03 16:44:31 -05:00
### Advanced management
2021-07-03 17:02:34 -05:00
You can archive entries from a timesheet using:
t archive [OPTIONS] [SHEET]
2021-07-03 17:02:34 -05:00
which defaults to archiving all entries in the current sheet, or you can be more
specific using these options:
-s, --start <date:qs> Include entries that start on this date or later.
-e, --end <date:qs> Include entries that start on this date or earlier.
2021-07-03 17:02:34 -05:00
-g, --grep <regexp> Include entries where the note matches this regexp.
-t, --time <hours> Only archive up to `hours` hours.
2021-07-03 17:02:34 -05:00
This subcommand will move the selected entries to a hidden timesheet named
`_[SHEET]` (the name of the timesheet preceded by an underscore).
2021-07-03 16:44:31 -05:00
2021-07-03 17:02:34 -05:00
It is possible to access directly the sqlite database using
2021-07-03 16:44:31 -05:00
2021-07-03 17:02:34 -05:00
t backend
2021-07-03 16:44:31 -05:00
2021-08-14 11:30:20 -05:00
### Configuration
`tiempo` keeps a config file, whose location you can learn usign `t configure`.
It is also possible to edit the config file in-place passing arguments to
`t configure` like this:
t c --append-notes-delimiter ';'
it will print the resulting config file. Beware that it wont keep comments added
to the file.
2021-07-03 16:44:31 -05:00
## Specifying times
Some arguments accept a time as value, like `t in`'s `--at` or `t d --start`.
These are the accepted formats:
2021-07-03 16:44:31 -05:00
**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`
2022-08-31 07:44:55 -05:00
## Default formatters
Tiempo comes with a handful of formatters that display your entries in different
ways. Here's the full list.
### chart
(New in 1.4.0) Displays a nice chart of the weekly progress.
**Settings**
By default this formatter will only display a nice chart of the progress divided
by week and respecting the `week_start` setting. However you may specify a daily
goal and a weekly goal to customize the chart, as well as how many minutes each
character represents:
In toml:
```toml
[formatters.chart]
daily_goal_hours = 4
weekly_goal_hours = 20
character_equals_minutes = 30
```
In yaml:
```yaml
formatters:
chart:
daily_goal_hours: 4
weekly_goal_hours: 20
character_equals_minutes: 30
```
### text
Displays nicely the entries grouped by sheet and day.
### ical
This formatter's output can be redirected to a file and then uploaded to a
calendar app.
### csv
Basically dump the entries as CSV to stdout. Useful for passing entries to a
different tool.
### json
Dump the entries in JSON format.
### ids
Dump only the ids in a single line
2021-09-07 22:48:35 -05:00
## 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.
2021-09-07 22:57:21 -05:00
It will also be given a command line argument representing user settings for
this formatter stored in the config file and formatted as JSON.
2021-09-07 22:48:35 -05:00
### Example
Suppose we have this config file:
```toml
2021-09-07 22:57:21 -05:00
database_file = "/home/user/.config/tiempo/database.sqlite3"
2021-09-07 22:48:35 -05:00
round_in_seconds = 900
append_notes_delimiter = " "
formatter_search_paths = ["/home/user/.config/tiempo/formatters"]
default_formatter = "text"
auto_sheet = "dotfiles"
auto_sheet_search_paths = ["/home/user/.config/tiempo/auto_sheets"]
auto_checkout = false
require_note = true
week_start = "Monday"
[formatters.earnings]
hourly_rate = 300
currency = "USD"
```
then we can create the `earnings` formatter by placing the following file in
`/home/user/.config/tiempo/formatters/earnings`:
```python
#!/usr/bin/env python3
import sys
import json
import csv
from datetime import datetime, timezone
from datetime import timedelta
from math import ceil
config = json.loads(sys.argv[1])
reader = csv.DictReader(
sys.stdin,
fieldnames=['id', 'start', 'end', 'note', 'sheet'],
)
total = timedelta(seconds=0)
for line in reader:
start = datetime.strptime(line['start'], '%Y-%m-%dT%H:%M:%S.%fZ')
2021-09-08 10:06:36 -05:00
if not line['end']:
end = datetime.utcnow()
else:
end = datetime.strptime(line['end'], '%Y-%m-%dT%H:%M:%S.%fZ')
2021-09-07 22:48:35 -05:00
total += end - start
2021-09-08 10:06:36 -05:00
hours = total.total_seconds() / 3600
2021-09-07 22:48:35 -05:00
earnings = hours * config['hourly_rate']
currency = config['currency']
2021-09-08 10:06:36 -05:00
print(f'You have earned: ${earnings:.2f} {currency}')
2021-09-07 22:48:35 -05:00
```
Now if you run `t display -f earnings` you will get something like:
```
You have earned: 2400 USD
```
## Why did you write this instead of improving timetrap?
2021-08-14 11:30:45 -05:00
* timetrap is [hard to install](https://github.com/samg/timetrap/issues/176),
hard to keep [updated](https://github.com/samg/timetrap/issues/174) (because
2022-08-03 08:53:52 -05:00
of ruby). With tiempo you can get (or build) a binary, put it somewhere in
your `PATH`, and it will just work forever in that machine. I'm bundling
sqlite.
* timetrap is slow (no way around it, because of ruby), some commands take up to
a second. Tiempo always feels snappy.
* needed major refactor to fix the timezone problem (in a language I'm not
proficient with). I was aware of this problem and designed tiempo to store
timestamps in UTC while at the same time being able to work with a database
2021-08-14 11:30:45 -05:00
made by timetrap without messing up. And there are a lot of tests backing this
assertions.
### Other advantages
2021-08-14 11:30:45 -05:00
* Columns in the output are always aligned.
* Fixed some input inconsistencies.
2022-08-03 08:53:52 -05:00
* CLI interface is easier to discover (ask -h for any sub-command)
* End times are printed with +1d to indicate that the activity ended the next
2021-08-14 11:30:45 -05:00
day in the 'text' formatter.
2022-08-03 08:53:52 -05:00
* Solved some old issues in timetrap.
* Added new features!
2021-07-03 16:44:31 -05:00
## How to build
2021-06-27 23:20:37 -05:00
You need [rust](https://rustup.rs), then clone the repo and simply run
cargo test
to check that everything is working, and then
cargo build --release
2021-07-03 16:44:31 -05:00
to have a binary at `target/release/t` that you can then move to a
directory in your `PATH` or use it by its absoulte or relative paths.
2021-06-27 23:20:37 -05:00
Run
2021-07-03 16:44:31 -05:00
t --help
2021-06-27 23:20:37 -05:00
to see the options.
2021-07-21 19:07:05 -05:00
### Development database
When developing I prefer not to mess with my own database, so I use this `.env`
file:
export TIMETRAP_CONFIG_FILE=/absolute/path/to/repo/dev_config.toml
PS1="$ "
and when I want to test some commands against such config file I just source it:
source .env
cargo run -- in 'hola'
### Documentation
The docs are written using [sphinx](https://www.sphinx-doc.org/en/master/), so
first you need to install it somehow. Two options I can offer are:
* using your computer's package manager. Install a package with a name similar
to `python-sphinx`.
* using [pipenv](https://duckduckgo.com/?t=ffab&q=pipenv&ia=web). Just ensure
you have python 3.9 on your computer, enter the `docs` directory and do
`pipenv install`.
To build the docs just enter the `docs` directory and some of the language
directories (currently `es` or `en`) and run:
make html
for the html version (output located at `docs/<lang>/build/html`), or
make man
for the man page (output located at `docs/<lang>/build/man/tiempo.1`). If you
are using pipenv just prefix the commands with `pipenv run` or run `pipenv
shell` before running any command.
2021-10-26 20:32:59 -05:00
The contents of the docs are located in `docs/<lang>/source/index.rst`,
formatted as
[reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html).
2021-07-21 19:07:05 -05:00
## Special Thanks
To [timetrap](https://github.com/samg/timetrap) for existing, to
[samg](https://github.com/samg) for creating it. It is the tool I was looking
for and whose design I took as reference, keeping compatibility when possible.
2022-08-03 08:53:52 -05:00
## Release checklist
(mostly to remind myself)
* [ ] Ensure tests pass and that clippy doesn't complain
* [ ] Add documentation to the readme on the new features
* [ ] Create an entry in `CHANGELOG.md` with the target version, stage it but
don't commit
2022-08-03 08:53:52 -05:00
* [ ] run `vbump`
* [ ] git push && git push --tags && cargo publish && cargo build --release && cp target/release/t ~/.local/bin/t