about summary refs log tree commit diff stats
path: root/modules/home.legacy/conf/taskwarrior/hooks/scripts/on-modify_track-timewarrior.py
blob: b482af6a207531a8bf7b27e6f0a3d0edaab1f2b8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (C) 2016-present Arctic Ice Studio <development@arcticicestudio.com>
# Copyright (C) 2016-present Sven Greb <development@svengreb.de>

# Project:    igloo
# Repository: https://github.com/arcticicestudio/igloo
# License:    MIT
# References:
#   https://taskwarrior.org/docs
#   https://taskwarrior.org/docs/timewarrior
#   timew(1)
#   task(1)

"""A Taskwarrior hook to track the time of a active task with Taskwarrior.

This hook will extract all of the following for use as Timewarrior tags:

* UUID
* Project
* Tags
* Description
* UDAs

Note:
    This hook requires Python 3 and is only compatible with Taskwarrior version greater or equal to 2.4!

This hook is a fork from the `official on-modify.timewarrior hook`_.

.. _`official on-modify.timewarrior hook`:
   https://github.com/GothenburgBitFactory/timewarrior/blob/dev/ext/on-modify.timewarrior
"""

import subprocess
import sys
from json import loads, dumps
from os import system
from sys import stdin
from taskw import TaskWarrior

# Make no changes to the task, simply observe.
old = loads(stdin.readline())
new = loads(stdin.readline())
print(dumps(new))


w = TaskWarrior(config_filename=sys.argv[4].replace("rc:", ""))
config = w.load_config(config_filename=sys.argv[4].replace("rc:", ""))
if "max_active_tasks" in config:
    MAX_ACTIVE = int(config["max_active_tasks"])
else:
    MAX_ACTIVE = 1


# Extract attributes for use as tags.
tags = [new["description"]]

if "project" in new:
    project = new["project"]
    tags.append(project)
    if "." in project:
        tags.extend([tag for tag in project.split(".")])

if "tags" in new:
    tags.extend(new["tags"])

combined = " ".join(["'%s'" % tag for tag in tags]).encode("utf-8").strip()

# Task has been started.
if "start" in new and "start" not in old:
    # Prevent this task from starting if "task +ACTIVE count" is greater than "MAX_ACTIVE".
    p = subprocess.Popen(
        ["task", "+ACTIVE", "status:pending", "count", "rc.verbose:off"],
        stdout=subprocess.PIPE,
    )
    out, err = p.communicate()
    count = int(out.rstrip())
    if count >= MAX_ACTIVE:
        print(
            "Only %d task(s) can be active at a time. "
            "See 'max_active_tasks' in .taskrc." % MAX_ACTIVE
        )
        sys.exit(1)

    system("timew start " + combined.decode() + " :yes")

# Task has been stopped.
elif "start" not in new and "start" in old:
    system("timew stop " + combined.decode() + " :yes")

# Any task that is active, with a non-pending status should not be tracked.
elif "start" in new and new["status"] != "pending":
    system("timew stop " + combined.decode() + " :yes")