Skip to content

Instantly share code, notes, and snippets.

@zarelit
Forked from wbsch/on-modify.blocks_attr.py
Created May 10, 2018 11:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zarelit/0266eb27e02af026d977a20bdef5ebf3 to your computer and use it in GitHub Desktop.
Save zarelit/0266eb27e02af026d977a20bdef5ebf3 to your computer and use it in GitHub Desktop.
Taskwarrior hook script that adds a "blocks:" pseudo-attribute for adding/modifying tasks.
#!/usr/bin/env python
#
# Adds the ability to add / modify tasks using a "blocks:" attribute,
# the opposite of "depends:".
#
# This script acts as an on-modify, on-add and on-launch hook at the same time.
#
### SETUP
# Save this file as
# ~/.task/hooks/on-modify.blocks_attr.py
# change to that directory:
# $ cd ~/.task/hooks
# make the script executable:
# $ chmod +x on-modify.blocks_attr.py
# then create symlinks to that file with the other hook names:
# $ ln -s on-modify.blocks_attr.py on-add.blocks_attr.py
# $ ln -s on-modify.blocks_attr.py on-launch.blocks_attr.py
#
# Now tell Taskwarrior about the "blocks" attribute:
# $ task config uda.blocks.type string
# $ task config uda.blocks.label Blocks
#
# And we're ready to go!
#
# bf@id:~$ t add a
# Created task 1.
#
# bf@id:~$ t add b
# Created task 2.
#
# bf@id:~$ t add c blocks:1
# Created task 3.
#
# bf@id:~$ t 2 mod blocks:1
# Modifying task 2 'b'.
# Modified 1 task.
#
# bf@id:~$ t
# [t next]
#
# ID Age Deps Description Urg
# 2 18s b 8
# 3 8s c 8
# 1 29s 2 3 a -5
#
import json
import os
import subprocess
import sys
# Adjust this if "task" is not regular Taskwarrior.
TASK = 'task'
# Adjust path if needed. It is a temporary file managed by the hook.
SHIMFILE = "%s/.task/hooks/blocks_shim.txt" % os.getenv('HOME')
def on_launch():
try:
with open(SHIMFILE, 'r') as f:
shim = f.readlines()
except IOError:
sys.exit(0)
while shim:
line = shim.pop(0).rstrip()
if not line:
continue
if subprocess.call(line.split()) != 0:
# Error handling by escalating to the user :)
print("%s ERROR: First line in %s is failing to run!" % (sys.argv[0], SHIMFILE))
print("Feel free to delete the file, or edit its contents to resolve the problem.")
shim = [line + '\n'] + shim
break
if shim:
with open(SHIMFILE, 'w') as f:
f.write(''.join(shim))
sys.exit(1)
else:
os.remove(SHIMFILE)
def handle_blocks_attribute(new):
if 'blocks' in new:
with open(SHIMFILE, "a") as f:
# This needs error handling. If a later hook aborts, the UUID is invalid.
f.write("%s rc.hooks=off rc.confirmation=no rc.bulk=10000 rc.verbose=nothing %s mod dep:%s\n" % (TASK, new['blocks'], new['uuid']))
del new['blocks']
print(json.dumps(new))
old = sys.stdin.readline()
new = sys.stdin.readline()
if not old:
on_launch()
elif not new:
handle_blocks_attribute(json.loads(old))
else:
handle_blocks_attribute(json.loads(new))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment