--- /dev/null
+ Copyright 2015-2017 Tomas Babej
+ https://github.com/tbabej/taskpirate
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null
+ Taskpirate
+ ----------
+
+ Taskpirate is a pluggable system for TaskWarrior python hooks.
+
+ Why?
+ ----
+
+ Simpler hooks:
+
+ def hook_example(task):
+ task['description'] += "changed by a hook"
+
+ The above is fully working example, no more boilerplate needed.
+
+ Much faster execution time in case of multiple hooks (read the more details section).
+
+ Install
+ -------
+
+ You'll need tasklib as a dependency:
+
+ pip install --user git+git://github.com/tbabej/tasklib@develop
+
+ Then you need to drop ```on-add-pirate``` and ```on-modify-pirate``` into ~/.task/hooks/.
+
+ After that, you can just clone any taskpirate-enabled hook as a subfolder into ~/.task/hooks/:
+
+ git clone https://github.com/tbabej/task.default-date-time ~/.task/hooks/default-date-time/
+
+ How to write a taskpirate hook
+ ------------------------------
+
+ In your hook's repository, any file matching ```pirate_add*.py``` will be searched for hooks in on-add event. In the same sense, any file matching ```pirate_mod*.py``` will be searched for hooks in on-modify event.
+
+ Now, the pirate_add_example.py might look as follows:
+
+ def hook_example(task):
+ task['description'] += "changed by a hook"
+
+ Any function in pirate_add_example that is called ```hook_*``` will be considered as a hook in on-add event. It will be passed the ```Task``` object corresponding to the current state of the task being added (as modified by the previous hooks).
+
+ More details
+ ------------
+
+ TaskWarrior hooks are intended to be simple, but they involve writing some boilerplate code (parsing/formatting json). To allow users to write dead simple code, they can leverage tasklib.
+
+ Using tasklib simplifies things a lot, however, it's not a super-lightweight - usage of tasklib can slow down the hook by as much as 30-50ms (usual python hook can probably run in under 40ms), since it imports multiple libraries.
+
+ This becomes a problem when user has multiple tasklib-based hooks, since the import time adds up.
+
+ Also, note that taskpirate with arbitrary number of hooks will be most likely faster than 2-3 regular python hooks.
+
+ Example hooks
+ -------------
+
+ You can look into my ```task.default-date-time``` or ```task.shift-recurrence``` hooks.
--- /dev/null
+ #!/usr/bin/env python
+
+ import glob
+ import imp
+ import os
+
+ from tasklib import TaskWarrior, Task
+
+
+ def find_hooks(file_prefix):
+ # Find all files in subdirectories whose names start with <file_prefix>
+ file_pattern = os.path.dirname(__file__) + '/*/' + file_prefix + "*.py"
+ module_paths = [f for f in glob.glob(file_pattern) if os.path.isfile(f)]
+ module_paths.sort()
+
+ # Gather all hooks in these files
+ hooks = []
+
+ for module_path in module_paths:
+ # Load the module
+ module_dir = os.path.dirname(module_path)
+ module_filename = os.path.basename(module_path)
+ module_name = 'pirate_{0}_{1}'.format(module_dir, module_filename)
+ module_name = module_name.replace('.', '_')
+ module = imp.load_source(module_name, module_path)
+
+ # Find all hook methods available
+ module_hooks = [
+ getattr(module, hook_name)
+ for hook_name in dir(module)
+ if hook_name.startswith('hook_')
+ ]
+
+ hooks += module_hooks
+
+ return hooks
+
+ task = Task.from_input()
+
+ for hook in find_hooks('pirate_add'):
+ hook(task)
+
+ print(task.export_data())
--- /dev/null
+ #!/usr/bin/env python
+
+ import glob
+ import imp
+ import os
+
+ from tasklib import TaskWarrior, Task
+
+
+ def find_hooks(file_prefix):
+ # Find all files in subdirectories whose names start with <file_prefix>
+ file_pattern = os.path.dirname(__file__) + '/*/' + file_prefix + "*.py"
+ module_paths = [f for f in glob.glob(file_pattern) if os.path.isfile(f)]
+ module_paths.sort()
+
+ # Gather all hooks in these files
+ hooks = []
+
+ for module_path in module_paths:
+ # Load the module
+ module_dir = os.path.dirname(module_path)
+ module_filename = os.path.basename(module_path)
+ module_name = 'pirate_{0}_{1}'.format(module_dir, module_filename)
+ module_name = module_name.replace('.', '_')
+ module = imp.load_source(module_name, module_path)
+
+ # Find all hook methods available
+ module_hooks = [
+ getattr(module, hook_name)
+ for hook_name in dir(module)
+ if hook_name.startswith('hook_')
+ ]
+
+ hooks += module_hooks
+
+ return hooks
+
+ task = Task.from_input()
+
+ for hook in find_hooks('pirate_mod'):
+ hook(task)
+
+ print(task.export_data())