0.0
No release in over 3 years
There's a lot of open issues
The gem formerly known as gpuzzletime is now ptimelog
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

pTimeLog

small tooling to transfer timelog-entries from gtimelog's timelog.txt or the tasks of an Obsidian vault to the PuzzleTime time-tracking web-application.

Approach

  • read timelog.txt
    • from known location
    • later: configure location?
    • later: auto-detect location?
  • parse out last day
    • especially start/end-times for each entry
    • date - ticket - description
    • later: parse out specific day
  • open N browser instances with the time entry data
    • without selected account
  • infer time-account from ticket-format
    • support user-supplied ticket-parsers
    • get ticket-parser from tags
  • merge equal adjacent entries into one
  • caculate, show and upload durations
  • complete login/entry automation
  • avoid duplicate entries
    • start/end time as indicator?
  • offer rounding times to the next 5, 10 or 15 minutes
  • [-] allow to add entries from the command-line (removed in 0.13.0)
  • handle time-account and billable better
    • import time-accounts from ptime (https://time.puzzle.ch/work_items/search.json?q=search%20terms)
      • with a dedicated cli?
      • from a REST-Endpoint of PTime?
    • automatically prefill billable
      • from time-accounts
      • from *-notation
    • allow to have a list of "favourite" time-accounts
    • select best-matching time-account according to tags, possibly limited to the favourites
    • combine billable and account-lookup into one script
  • add cli-help
    • use commander cmd_parse for CLI
  • support Obsidian as datasource
    • with explicit config
    • with reading the config from the Obsidian Vault
    • time-entries from the sessions Operon tracked on its tasks
    • time-account/billable/metadata lookup from a note
    • support show-command: output the entries of a day
    • support upload-command: send the entries of a day to ptime
    • support "last"-day for obsidian
  • filter the entries by tag

Installation

Install it with:

$ gem install ptimelog

Usage

$ ptimelog ACTION DATE

Maybe it's best to explore the commands with ptimelog help and going from there.

Actions

Currently supported actions are

  • show
  • upload
  • confirm
  • edit
  • version
  • help
  • info

Date-Identifier

To handle a specific date, the format YYYY-MM-DD is expected, e.g. 2017-12-25. Please note that you should not work on that day, unless you bring presents or release a new version of Ruby.

For reusability in a shell-history the following keywords are supported:

  • today
  • yesterday
  • all

Currently, you need to pass a day. The previously exisiting "last" worked fine to timelog.txt, but not for Obsidian.

Edit-Identifier

When the action is "edit", the next argument is treated as script that should be edited.

If nothing is passed, the main timelog.txt is loaded. :warn: The Obsidian-Datasource has no single file, because an entry can come from any note of the vault. Without an argument, this command only edits an inferer-script, which is the thing that can still be edited.

Otherwise, a script to determine the time-account is loaded.

Filtering by Tag

All actions that list entries (currently: show, upload and confirm) take a -t/--tag parameter to limit the entries to those tagged with it.

$ ptimelog show today -t hit

It can be repeated to filter more intensely. All mentioned tags must apply.

$ ptimelog show today -t hit -t mail

A day without a single matching entry is skipped instead of being printed as empty, which keeps ptimelog show all -t hit readable.

Adding entries (removed)

Up to 0.12.0 there was an add-action that appended an entry to the timelog.txt:

$ ptimelog add 'ticket 1337: Implement requirements -- client coding'

It is gone since 0.13.0. It had been broken for a while: no datasource implemented the write it called, so every invocation ended in a NoMethodError. With Obsidian as datasource it cannot come back in that shape at all — tracked time belongs to a task in Operon, and only Operon may write it. This is a self-imposed limitation, of course.

Patches are welcome, but be warned that this is not a small job. See docs/add-command.md: section 9 describes what a rebuild for the timelog.txt backend needs, sections 1 to 8 why the Obsidian side is hard. Tracking time in Operon needs a task with correct tracking attributes. Adding those is not impossible, but to cumbersome for now, for me.

It might come back to support automating events like closing or opening the laptop (via a lidswitch-script) and locking or unlocking the screen (via a hook in your screen-locker). But this requires some thought and careful planning. Currently, I am happy enough using drag&drop in Operon.

Showing the Version

I got tired of asking rubygems which version I installed, so I took on the herculean task of letting ptimelog show its own version. With the switch to a cmd_parse-based CLI, this has been partially offloaded to cmd_parse. You can imagine the weight that has been lifted off my shoulders.

Formatting the Output

In order to format the output of the show-action into a table, a hopefully convienient field-marker has been chosen. After 0.10.0, I switched from '∴' to '|', which is much more widely used, but also much easier to find on keyboard. This removes one need to copy an unusual separator, maybe even using the mouse... Anyway, you can pipe the output into column:

ptimelog show today | column -t -s'|'

Helper-Scripts

ptimelog can prefill the account-number and billable-state of an entry.

The tags are used to determine a script that helps infer the time-account. These scripts should be located in ~/.config/ptimelog/inferers/ and be named like the first tag used. The script gets the ticket, the description and all remaining tags passed as arguments.

Only the first tag picks the script. --tag does not care about that order and matches a tag at any position.

The output of the script should be the ID of the time-account and the billable-state as "true" or "false". Both items need to be separated by whitespace, so you can output those two on the same line or on different lines.

Since these scripts are called a lot, it is better to write them in a compiled language. If you only like ruby, take a look at crystal. For such simple scripts, the code is almost identical and "just" needs to be compiled.

Operon

With obsidian: true, entries are read from the time-sessions Operon tracked on the tasks of your vault. Operon stores them on the task itself, so one entry comes from one session, not from one task:

{{trackers:: 2026-10-07T11:00:00/2026-10-07T12:00:00; 2026-10-07T14:00:00/2026-10-07T15:00:00}}

Only tracked time is read. A running timer and a planned block (datetimeStart/datetimeEnd) are no time yet, so they are skipped. A session counts on the day it started on. Notes below archive/ and Operons own documentation are skipped.

Ticket and account-tags come from two custom keys, which you can create in Settings → Operon → Core → Custom Keys:

- [ ] HIT-12345: Zeug machen {{operonId:: …}} {{ticket:: HIT-12345}} {{ptimelog:: hit sac mv}}

ticket is the text puzzletime is asked for. ptimelog is a single, space-separated string of tags, identical to what the dayplanner-entries used to carry after their --. The first tag selects the inferer-script, the rest are passed to it. A task without that key is still listed, but has no account.

If your vault already uses other names for these keys, map them with operon_custom_keys. A key you leave out keeps its default:

operon_custom_keys:
  ticket: issue
  inferer: account

Configuration

A config-file is read from $HOME/.config/ptimelog/config. It is expected to be a YAML-file. Currently, it supports the following keys:

  • rounding: [integer or false, default 15]
  • base_url: [url to your puzzletime-installation, default https://time.puzzle.ch]
  • obsidian: [boolean, default false, read from an Obsidian vault instead of timelog.txt]
  • obsidian_vault: [path to that vault, default ~/path/to/obsidian-vault]
  • operon_custom_keys: [hash, default { ticket: ticket, inferer: ptimelog }, names of the keys Operon stores ticket and tags in]

If the default path of obsidian_vault works for you, I really want to talk to you :-)

Operons tracked time is stored to the second, so set rounding: false to keep it exact.

It might still work with the timelog.txt-config. I do not use it anymore, but I do not want to break things needlessly. So I left it in.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment. Run bundle exec ptimelog to use the gem in this directory, ignoring other installed copies of this gem.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/kronn/ptimelog.

License

The gem is available as open source under the terms of the MIT License.