├── .gitignore ├── LICENCE ├── README.md └── pirate_add_shift_recurrence.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | Copyright 2015 Tomas Babej 2 | http://github.com/tbabej/taskwarrior-shift-all-recurrence-hook 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Taskwarrior Shift All Recurrence Attributes Hook 2 | ------------------------------------------------ 3 | 4 | This is a hook for TaskWarrior (http://www.taskwarrior.org), 5 | which allow your recurrent tasks to inherit ``wait``, ``scheduled`` 6 | and ``until`` attributes from the parent. 7 | 8 | Install 9 | ------- 10 | 11 | Note: This hook has been rewritten to leverage taskpirate, for greater hook efficiency. 12 | Please see https://github.com/tbabej/taskpirate for instructions. Don't worry, it's straightforward. 13 | 14 | ``` 15 | git clone https://github.com/tbabej/taskwarrior-shift-all-recurrence-hook.git 16 | cp taskwarrior-shift-all-recurrence-hook/on-* ~/.task/hooks/ 17 | ``` 18 | 19 | This hook leverages tasklib, so you need to install that too: 20 | 21 | ``` 22 | pip install tasklib 23 | ``` 24 | 25 | Use case 26 | -------- 27 | 28 | Consider you have a periodic task, which is valid only for the certain day, 29 | e.g. on every Sunday you go running. 30 | 31 | ``` 32 | $ task add due:sunday recur:weekly 33 | ``` 34 | 35 | However, TaskWarrior will display the task right away, and you want to 36 | showing up only during the weekend, so that it does not distract your task 37 | list during the work week. 38 | 39 | If you try to add the recurrence again, this time with ``wait`` attribute, 40 | to hide the task until it is not relevant for you: 41 | 42 | ``` 43 | $ task add due:sunday recur:weekly wait:saturday 44 | ``` 45 | 46 | You will find out that TaskWarrior does not let tasks generated by this 47 | recurrence inherit the ``wait`` attribute, in the same manner as it does 48 | with the ``due`` attribute. 49 | 50 | This hook solves that. 51 | -------------------------------------------------------------------------------- /pirate_add_shift_recurrence.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | import os 5 | from tasklib import TaskWarrior 6 | 7 | time_attributes = ('wait', 'scheduled', 'until') 8 | 9 | def is_new_local_recurrence_child_task(task): 10 | # Do not affect tasks not spun by recurrence 11 | if not task['parent']: 12 | return False 13 | 14 | # Newly created recurrence tasks actually have 15 | # modified field copied from the parent, thus 16 | # older than entry field (until their ID is generated) 17 | if (task['modified'] - task['entry']).total_seconds() < 0: 18 | return True 19 | 20 | tw = TaskWarrior(data_location=os.path.dirname(os.path.dirname(sys.argv[0]))) 21 | tw.overrides.update(dict(recurrence="no", hooks="no")) 22 | 23 | def hook_shift_recurrence(task): 24 | if is_new_local_recurrence_child_task(task): 25 | parent = tw.tasks.get(uuid=task['parent']['uuid']) 26 | parent_due_shift = task['due'] - parent['due'] 27 | for attr in time_attributes: 28 | if parent[attr]: 29 | task[attr] = parent[attr] + parent_due_shift 30 | --------------------------------------------------------------------------------