Skip to content

Instantly share code, notes, and snippets.

@wbsch
Last active November 10, 2021 21:17
Show Gist options
  • Select an option

  • Save wbsch/d977b0ac29aa1dfa4437 to your computer and use it in GitHub Desktop.

Select an option

Save wbsch/d977b0ac29aa1dfa4437 to your computer and use it in GitHub Desktop.

Revisions

  1. wbsch revised this gist Jan 12, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion on-modify.timetrack.py
    Original file line number Diff line number Diff line change
    @@ -110,6 +110,6 @@ def dt_to_tw(d):
    entry += " uuid: " + new['uuid']
    entry += "\n\n"
    with open(LEDGERFILE, "a") as ledger:
    ledger.write(entry)
    ledger.write(entry.encode("utf-8"))

    print(json.dumps(new))
  2. wbsch revised this gist Mar 23, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions on-modify.timetrack.py
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #!/usr/bin/env python
    #
    # Writes task start/stop times to a timelog formatted file.
    # You need to adjust LEDGERFILE, or set the TIMELOG environment variable.
    # You might need to adjust LEDGERFILE, or set the TIMELOG environment variable.
    #
    # Example reports, after using start/stop on a task:
    # ledger -f /path/to/timelog.ledger print
    @@ -36,7 +36,7 @@
    from datetime import timedelta


    LEDGERFILE = '/home/bf/.task/hooks/timetrack.ledger'
    LEDGERFILE = "%s/.task/hooks/timetrack.ledger" % os.getenv('HOME')

    if 'TIMELOG' in os.environ:
    LEDGERFILE = os.environ['TIMELOG']
  3. wbsch revised this gist Mar 5, 2015. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions on-modify.timetrack.py
    Original file line number Diff line number Diff line change
    @@ -19,6 +19,10 @@
    # file to be backdated. Note that this is not properly displayed in
    # Taskwarrior itself, but only in your timelog file.
    #
    # Note: This will only work on Taskwarrior 2.4.2+ due to a bug in
    # earlier versions. The basic time tracking functionality will
    # work on 2.4.1+.
    #
    #
    # May the Holy Python forgive me for this mess.
    #
  4. wbsch revised this gist Mar 5, 2015. 1 changed file with 84 additions and 5 deletions.
    89 changes: 84 additions & 5 deletions on-modify.timetrack.py
    Original file line number Diff line number Diff line change
    @@ -1,32 +1,111 @@
    #!/usr/bin/env python
    #
    # Writes task start/stop times to a timelog formatted file.
    # You need to adjust LEDGERFILE, or set the TIMELOG environment variable.
    #
    # Example reports, after using start/stop on a task:
    # ledger -f /path/to/timelog.ledger print
    # ledger -f /path/to/timelog.ledger register
    #
    # Projects, tags, and UUIDs are fully supported and queryable from ledger.
    #
    #
    # 2015-03-05 wbsch
    # - Now with "I forgot to start/stop this task!" convenience features:
    # "task $id start $x"
    # "task $id stop $x"
    # "task $id done $x"
    # Where $x is the time in minutes you want the entry in your timelog
    # file to be backdated. Note that this is not properly displayed in
    # Taskwarrior itself, but only in your timelog file.
    #
    #
    # May the Holy Python forgive me for this mess.
    #

    import calendar
    import json
    import os
    import re
    import sys
    from datetime import datetime
    from datetime import timedelta


    LEDGERFILE = '/home/bf/.task/hooks/timetrack.ledger'

    if 'TIMELOG' in os.environ:
    LEDGERFILE = os.environ['TIMELOG']


    def adjust_date(d, adjust_by):
    if not isinstance(d, datetime):
    d = tw_to_dt(d)
    d -= timedelta(minutes=int(adjust_by))
    return d

    def tw_to_dt(s):
    """ Taskwarrior JSON date ---> datetime object. """
    return datetime.strptime(s, "%Y%m%dT%H%M%SZ")

    def dt_to_tw(d):
    """ datetime object ---> Taskwarrior JSON date. """
    return d.strftime("%Y%m%dT%H%M%SZ")


    old = json.loads(sys.stdin.readline())
    new = json.loads(sys.stdin.readline())

    annotation_added = ('annotations' in new and not 'annotations' in old) \
    or \
    ('annotations' in new and 'annotations' in old and \
    len(new['annotations']) > len(old['annotations']))


    # task started
    if ('start' in new and not 'start' in old) and annotation_added:
    new['annotations'].sort(key=lambda anno: anno['entry'])
    m = re.match('^[0-9]+$', new['annotations'][-1]['description'])
    if m:
    new['start'] = dt_to_tw(adjust_date(new['start'], int(m.group(0))))
    new['annotations'] = new['annotations'][:-1]
    if not new['annotations']:
    del new['annotations']
    print("Timelog: Started task %s minutes ago." % m.group(0))

    if tw_to_dt(new['start']) < tw_to_dt(new['entry']):
    new['entry'] = new['start']

    # task stopped
    if 'start' in old and not 'start' in new:
    started = datetime.strptime(old['start'], "%Y%m%dT%H%M%SZ")
    started_ts = calendar.timegm(started.timetuple())
    entry = "i " + datetime.fromtimestamp(started_ts).strftime("%Y/%m/%d %H:%M:%S")
    started_utc = tw_to_dt(old['start'])
    started_ts = calendar.timegm(started_utc.timetuple())
    started = datetime.fromtimestamp(started_ts)
    stopped = datetime.now()

    if annotation_added:
    new['annotations'].sort(key=lambda anno: anno['entry'])
    m = re.match('^[0-9]+$', new['annotations'][-1]['description'])
    if m:
    new['annotations'] = new['annotations'][:-1]
    if not new['annotations']:
    del new['annotations']
    stopped = adjust_date(stopped, m.group(0))
    if stopped < started:
    print("ERROR: Stop date -%s minutes would be before the start date!" % m.group(0))
    sys.exit(1)
    print("Timelog: Stopped task %s minutes ago." % m.group(0))

    entry = "i " + started.strftime("%Y/%m/%d %H:%M:%S")
    entry += " "
    entry += new['project'].replace('.', ':') if 'project' in new else "no project"
    entry += " " + new['description'] + "\n"
    entry += "o " + datetime.now().strftime("%Y/%m/%d %H:%M:%S")
    entry += "o " + stopped.strftime("%Y/%m/%d %H:%M:%S")
    entry += " ;"
    entry += " :" + ":".join(new['tags']) + ":" if 'tags' in new else ""
    entry += " uuid: " + new['uuid']
    entry += "\n\n"
    with open(LEDGERFILE, "a") as ledger:
    ledger.write(entry)

    print(json.dumps(new))
  5. wbsch revised this gist Feb 24, 2015. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions on-modify.timetrack.py
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,16 @@
    #!/usr/bin/env python
    import calendar
    import json
    import os
    import sys
    from datetime import datetime

    LEDGERFILE = '/home/bf/.task/hooks/timetrack.ledger'

    if 'TIMELOG' in os.environ:
    LEDGERFILE = os.environ['TIMELOG']


    old = json.loads(sys.stdin.readline())
    new = json.loads(sys.stdin.readline())

  6. wbsch revised this gist Feb 24, 2015. 1 changed file with 9 additions and 6 deletions.
    15 changes: 9 additions & 6 deletions on-modify.timetrack.py
    Original file line number Diff line number Diff line change
    @@ -12,12 +12,15 @@
    if 'start' in old and not 'start' in new:
    started = datetime.strptime(old['start'], "%Y%m%dT%H%M%SZ")
    started_ts = calendar.timegm(started.timetuple())
    entry = "; " + new['uuid']
    entry += " " + " ".join(("+" + t for t in new['tags'])) + "\n" if 'tags' in new else "\n"
    entry += "i " + datetime.fromtimestamp(started_ts).strftime("%Y/%m/%d %H:%M:%S")
    entry += " " + new['project'] + " " if 'project' in new else " "
    entry += "[" + new['description'] + "]\n"
    entry += "o " + datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "\n\n"
    entry = "i " + datetime.fromtimestamp(started_ts).strftime("%Y/%m/%d %H:%M:%S")
    entry += " "
    entry += new['project'].replace('.', ':') if 'project' in new else "no project"
    entry += " " + new['description'] + "\n"
    entry += "o " + datetime.now().strftime("%Y/%m/%d %H:%M:%S")
    entry += " ;"
    entry += " :" + ":".join(new['tags']) + ":" if 'tags' in new else ""
    entry += " uuid: " + new['uuid']
    entry += "\n\n"
    with open(LEDGERFILE, "a") as ledger:
    ledger.write(entry)

  7. wbsch revised this gist Feb 24, 2015. 1 changed file with 5 additions and 3 deletions.
    8 changes: 5 additions & 3 deletions on-modify.timetrack.py
    Original file line number Diff line number Diff line change
    @@ -12,11 +12,13 @@
    if 'start' in old and not 'start' in new:
    started = datetime.strptime(old['start'], "%Y%m%dT%H%M%SZ")
    started_ts = calendar.timegm(started.timetuple())
    entry = "i " + datetime.fromtimestamp(started_ts).strftime("%Y/%m/%d %H:%M:%S")
    entry = "; " + new['uuid']
    entry += " " + " ".join(("+" + t for t in new['tags'])) + "\n" if 'tags' in new else "\n"
    entry += "i " + datetime.fromtimestamp(started_ts).strftime("%Y/%m/%d %H:%M:%S")
    entry += " " + new['project'] + " " if 'project' in new else " "
    entry += "[" + new['description'] + "]\n"
    entry += "o " + datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "\n\n"
    with open(LEDGERFILE, "a") as ledger:
    ledger.write(entry)

    print(json.dumps(new))
    print(json.dumps(new))
  8. wbsch revised this gist Feb 23, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions on-modify.timetrack.py
    Original file line number Diff line number Diff line change
    @@ -9,11 +9,11 @@
    old = json.loads(sys.stdin.readline())
    new = json.loads(sys.stdin.readline())

    if old.has_key('start') and not new.has_key('start'):
    if 'start' in old and not 'start' in new:
    started = datetime.strptime(old['start'], "%Y%m%dT%H%M%SZ")
    started_ts = calendar.timegm(started.timetuple())
    entry = "i " + datetime.fromtimestamp(started_ts).strftime("%Y/%m/%d %H:%M:%S")
    entry += " " + new['project'] + " " if new.has_key('project') else " "
    entry += " " + new['project'] + " " if 'project' in new else " "
    entry += "[" + new['description'] + "]\n"
    entry += "o " + datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "\n\n"
    with open(LEDGERFILE, "a") as ledger:
  9. wbsch created this gist Feb 23, 2015.
    22 changes: 22 additions & 0 deletions on-modify.timetrack.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    #!/usr/bin/env python
    import calendar
    import json
    import sys
    from datetime import datetime

    LEDGERFILE = '/home/bf/.task/hooks/timetrack.ledger'

    old = json.loads(sys.stdin.readline())
    new = json.loads(sys.stdin.readline())

    if old.has_key('start') and not new.has_key('start'):
    started = datetime.strptime(old['start'], "%Y%m%dT%H%M%SZ")
    started_ts = calendar.timegm(started.timetuple())
    entry = "i " + datetime.fromtimestamp(started_ts).strftime("%Y/%m/%d %H:%M:%S")
    entry += " " + new['project'] + " " if new.has_key('project') else " "
    entry += "[" + new['description'] + "]\n"
    entry += "o " + datetime.now().strftime("%Y/%m/%d %H:%M:%S") + "\n\n"
    with open(LEDGERFILE, "a") as ledger:
    ledger.write(entry)

    print(json.dumps(new))