Initial Commit
This commit is contained in:
110
taskwarrior_daily_timetracking_hook/__init__.py
Normal file
110
taskwarrior_daily_timetracking_hook/__init__.py
Normal file
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python
|
||||
import datetime
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
from taskw import TaskWarrior
|
||||
|
||||
TIME_FORMAT = '%Y%m%dT%H%M%SZ'
|
||||
UDA_KEY = 'dailyactivetime'
|
||||
|
||||
w = TaskWarrior()
|
||||
config = w.load_config()
|
||||
if ('max_active_tasks' in config):
|
||||
MAX_ACTIVE = int(config['max_active_tasks'])
|
||||
else:
|
||||
MAX_ACTIVE = 1
|
||||
|
||||
ISO8601DURATION = re.compile(
|
||||
"P((\d*)Y)?((\d*)M)?((\d*)D)?T((\d*)H)?((\d*)M)?((\d*)S)?")
|
||||
|
||||
# Convert duration string into a timedelta object.
|
||||
# Valid formats for duration_str include
|
||||
# - int (in seconds)
|
||||
# - string ending in seconds e.g "123seconds"
|
||||
# - ISO-8601: e.g. "PT1H10M31S"
|
||||
def duration_str_to_time_delta(duration_str):
|
||||
if (duration_str.startswith("P")):
|
||||
match = ISO8601DURATION.match(duration_str)
|
||||
if (match):
|
||||
year = match.group(2)
|
||||
month = match.group(4)
|
||||
day = match.group(6)
|
||||
hour = match.group(8)
|
||||
minute = match.group(10)
|
||||
second = match.group(12)
|
||||
value = 0
|
||||
if (second):
|
||||
value += int(second)
|
||||
if (minute):
|
||||
value += int(minute)*60
|
||||
if (hour):
|
||||
value += int(hour)*3600
|
||||
if (day):
|
||||
value += int(day)*3600*24
|
||||
if (month):
|
||||
# Assume a month is 30 days for now.
|
||||
value += int(month)*3600*24*30
|
||||
if (year):
|
||||
# Assume a year is 365 days for now.
|
||||
value += int(year)*3600*24*365
|
||||
else:
|
||||
value = int(duration_str)
|
||||
elif (duration_str.endswith("seconds")):
|
||||
value = int(duration_str.rstrip("seconds"))
|
||||
else:
|
||||
value = int(duration_str)
|
||||
return datetime.timedelta(seconds=value)
|
||||
|
||||
def main():
|
||||
original = json.loads(sys.stdin.readline())
|
||||
modified = json.loads(sys.stdin.readline())
|
||||
|
||||
# An inactive task has just been started.
|
||||
if 'start' in modified and 'start' not in original:
|
||||
# Check if `task +ACTIVE count` is greater than MAX_ACTIVE. If so
|
||||
# prevent this task from starting.
|
||||
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)
|
||||
|
||||
# An active task has just been stopped.
|
||||
if 'start' in original and 'start' not in modified:
|
||||
# Let's see how much time has elapsed
|
||||
start = datetime.datetime.strptime(original['start'], TIME_FORMAT)
|
||||
end = datetime.datetime.utcnow()
|
||||
|
||||
if UDA_KEY not in modified:
|
||||
modified[UDA_KEY] = 0
|
||||
|
||||
this_duration = (end - start)
|
||||
total_duration = (
|
||||
this_duration
|
||||
+ duration_str_to_time_delta(str(modified[UDA_KEY]))
|
||||
)
|
||||
print(
|
||||
"Daily Time Tracked: %s (%s in this instance)" % (
|
||||
total_duration,
|
||||
this_duration,
|
||||
)
|
||||
)
|
||||
modified[UDA_KEY] = str(int(
|
||||
total_duration.days * (60 * 60 * 24) + total_duration.seconds
|
||||
)) + "seconds"
|
||||
|
||||
return json.dumps(modified, separators=(',',':'))
|
||||
|
||||
|
||||
def cmdline():
|
||||
sys.stdout.write(main())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cmdline()
|
Reference in New Issue
Block a user