--- /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())