61 lines
1.8 KiB
Ruby
Executable file
61 lines
1.8 KiB
Ruby
Executable file
#!/usr/bin/env ruby
|
|
|
|
require 'json'
|
|
require 'time'
|
|
|
|
DAYS = 60 * 60 * 24
|
|
WEEKS = DAYS * 7
|
|
|
|
TASKWARRIOR_DATE_FORMAT = "%Y%m%dT060000Z"
|
|
|
|
# Find the -final- task state that's passed to us.
|
|
json_task = $stdin.map{ |line| line }.last
|
|
|
|
task = JSON.parse(json_task)
|
|
last_task_form = json_task
|
|
|
|
# Only modify tasks that are done, but have a recur.
|
|
# Emit all other tasks' final states unchanged.
|
|
unless task.has_key?('status') && task.has_key?('every') && (task['status'] == 'completed')
|
|
puts(json_task)
|
|
exit 0
|
|
end
|
|
|
|
#
|
|
# We have an every-recurring task -- modify it!
|
|
#
|
|
|
|
unless task.has_key? 'due'
|
|
puts "ERROR: task #{task['id']} has an 'every' recurrance, but no due date!"
|
|
exit -1
|
|
end
|
|
|
|
# Figure our our next recurrance based on the taskwarrior period/duration syntax.
|
|
previous_due_date = Time.parse(task['due'])
|
|
recur_date = case task['every']
|
|
when /P(\d+)D/ then previous_due_date + ($1.to_i * DAYS)
|
|
when /P(\d+)W/ then previous_due_date + ($1.to_i * WEEKS)
|
|
when /P(\d+)M/ then Time.new(previous_due_date.year, previous_due_date.month + $1.to_i, previous_due_date.day)
|
|
when /P(\d+)H/ then Time.new(previous_due_date.year + $1.to_i, previous_due_date.month, previous_due_date.day)
|
|
else
|
|
puts "ERROR: task #{task['id']} has unsupported'every' duration #{task['every']}"
|
|
exit -1
|
|
end
|
|
|
|
# Mutate the task to be pending, still, but with new dates.
|
|
task['status'] = 'pending'
|
|
task['due'] = recur_date.strftime(TASKWARRIOR_DATE_FORMAT)
|
|
|
|
|
|
# If this task has ancillary dates, maintain the offset between them and the due date.
|
|
['wait', 'start'].each do |field|
|
|
if task.has_key?(field)
|
|
field_offset = previous_due_date - Time.parse(task[field])
|
|
new_field_date = Time.parse(task['due']) - field_offset
|
|
|
|
task[field] = new_field_date.strftime(TASKWARRIOR_DATE_FORMAT)
|
|
end
|
|
end
|
|
|
|
# Emit the task back to TaskWarrior.
|
|
puts task.to_json
|