Class: Syctask::TaskPlanner

Inherits:
Object
  • Object
show all
Defined in:
lib/syctask/task_planner.rb

Overview

A TaskPlanner prompts the user to select tasks for today. These tasks can be prioritized to determine the most to the least important tasks.

Constant Summary collapse

WORK_DIR =

The task where the planned tasks are saved to

Syctask::SYC_DIR

Instance Method Summary collapse

Constructor Details

#initializeTaskPlanner

Creates a new TaskPlanner



24
25
26
27
28
# File 'lib/syctask/task_planner.rb', line 24

def initialize
  @console = Sycutil::Console.new
  @service = TaskService.new
  make_todo_today_file(Time.now.strftime("%Y-%m-%d"))
end

Instance Method Details

#add_task(task, date = Time.now.strftime("%Y-%m-%d")) ⇒ Object

Add the task to the planned tasks of the specified date. The task is only added if not already present



217
218
219
# File 'lib/syctask/task_planner.rb', line 217

def add_task(task, date=Time.now.strftime("%Y-%m-%d"))
  add_tasks([task], date)
end

#add_tasks(tasks, date = Time.now.strftime("%Y-%m-%d")) ⇒ Object

Add the tasks to the planned tasks. A task is only added if not already present



223
224
225
226
227
228
229
# File 'lib/syctask/task_planner.rb', line 223

def add_tasks(tasks, date=Time.now.strftime("%Y-%m-%d"))
  planned = get_tasks(date)
  tasks.each do |task|
    planned << task unless planned.find_index {|t| t == task}
  end
  save_tasks(planned, true)
end

#get_tasks(date = Time.now.strftime("%Y-%m-%d"), filter = {}) ⇒ Object

Get planned tasks of the specified date. Retrieve only tasks that match the specified filter (filter options see Task#matches?)



269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/syctask/task_planner.rb', line 269

def get_tasks(date=Time.now.strftime("%Y-%m-%d"), filter={})
  make_todo_today_file(date)
  tasks = []
  File.open(@todo_today_file, 'r') do |file|
    file.each do |line|
      dir, id = line.chomp.split(",")
      task = @service.read(dir, id)
      tasks << task if not task.nil? and task.matches?(filter)
    end
  end if File.exist? @todo_today_file
  tasks
end

#inspect_tasks(tasks, date = Time.now.strftime("%Y-%m-%d")) ⇒ Object

Inspect allows to edit, delete and mark tasks as done



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/syctask/task_planner.rb', line 75

def inspect_tasks(tasks, date=Time.now.strftime("%Y-%m-%d"))
  already_planned_tasks = self.get_tasks(date)
  tasks = tasks.delete_if { |t| already_planned_tasks.include?(t) }
  count = 0
  re_display = false
  planned = []
  index = 0
  while index < tasks.length
    task = tasks[index]
    unless re_display
      task.print_pretty
    else
      task.print_pretty(true)
      re_display = false
    end
    choice = @console.prompt INSPECT_STRING
    case choice
    when 'e'
      task_file = "#{task.dir}/#{task.id}.task"
      system "vi #{task_file}" if File.exist? task_file
      tasks[index] = @service.read(task.dir, task.id)
      redo
    when 'd'
      puts "Enter a note or hit <RETURN>"
      note = gets.chomp
      task.done(note)
      @service.save(task.dir, task)
      tasks.delete(task)
      STDOUT.puts sprintf("--> Marked task %d as done", 
                          task.id).color(:green)
    when 'l'
      print "Confirm delete task (Y/n)? "
      answer = gets.chomp
      del = @service.delete(task.dir, {id: task.id.to_s}) if answer == "Y"
      if del.nil? or del == 0
        puts sprintf("--> Task not deleted").color(:green)
      elsif del > 0
        tasks.delete(task)
        puts sprintf("--> Deleted %d task%s", 
                     del, del == 1 ? "" : "s").color(:green)
      end
    when 'p'
      duration = 0
      until duration > 0
        print "Duration (1 = 15 minutes, RETURN defaults to 30 minutes): "
        answer = gets.chomp
        duration = answer.empty? ? 2 : answer.to_i
      end
      task.set_duration(units_to_time(duration))
      task.options[:follow_up] = date
      @service.save(task.dir, task)
      planned << task
      tasks.delete(task)
      count += 1
    when 't'
      begin
        print "Date (yyyy-mm-dd or 'time distance', e.g. tom, i2d, nfr): "
        specific_date = gets.chomp
      end until valid_date?(specific_date)

      duration = 0
      until duration > 0
        print "Duration (1 = 15 minutes, RETURN defaults to 30 minutes): "
        answer = gets.chomp
        duration = answer.empty? ? 2 : answer.to_i
      end

      task.set_duration(units_to_time(duration))
      task.options[:follow_up] = extract_time(specific_date)
      @service.save(task.dir, task)
      if task.options[:follow_up] == date
        planned << task
        tasks.delete(task)
        count += 1
      else
        index += 1
      end
    when 'c'
      re_display = true
      redo
    when 'b'
      index -= 1 if index > 0
    when 's'
      index += 1
    when 'q'
      break
    end
  end
  save_tasks(planned)
  count
end

#move_tasks(filter = {}, from_date = Time.now.strftime("%Y-%m-%d"), to_date) ⇒ Object

Moves the specified tasks to the specified date. Sets the remaining timer to at least 15 minutes and sets the duration to the remaining timer’s values. Returns the count of moved files



234
235
236
237
238
239
240
241
242
243
244
# File 'lib/syctask/task_planner.rb', line 234

def move_tasks(filter={}, from_date=Time.now.strftime("%Y-%m-%d"), to_date)
  return 0 if from_date == to_date
  moved = get_tasks(from_date, filter)
  moved.each do |task| 
    task.options[:follow_up] = to_date
    task.set_duration([task.remaining, 900].max)
    @service.save(task.dir, task)
  end
  add_tasks(moved, to_date)
  remove_tasks(from_date, filter)
end

#order_tasks(date, ids, pos = 0) ⇒ Object

Order tasks in the provided IDs sequence at the specified date. If not all IDs are provided than rest of tasks is appended to the end of the plan. If a position (last, first and a number) is provided the ordered tasks are inserted at the specified position. Returns the count of ordered tasks, the count of the rest of the tasks and the position where the ordered tasks have been inserted.



173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/syctask/task_planner.rb', line 173

def order_tasks(date, ids, pos=0)
  tasks = get_tasks(date)
  pos = "0" if pos.class == String and pos.downcase == 'first'
  pos = tasks.size.to_s if pos.class == String and pos.downcase == 'last'
  ordered = []
  ids.each do |id|
    index = tasks.find_index {|t| t.id == id.to_i}
    ordered << tasks.delete_at(index) if index
  end
  pos = [pos.to_i.abs,tasks.size].min
  tasks.insert(pos, ordered)
  save_tasks(tasks.flatten!, true)
  [ordered.size, tasks.size, pos]
end

#plan_tasks(tasks, date = Time.now.strftime("%Y-%m-%d")) ⇒ Object

List each task and prompt the user whether to add the task to the planned tasks. The user doesn’t specify a duration for the task operation the duration will be set to 30 minutes which equals two time chunks. The count of planned tasks is returned



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/syctask/task_planner.rb', line 34

def plan_tasks(tasks, date=Time.now.strftime("%Y-%m-%d"))
  already_planned_tasks = self.get_tasks(date)
  tasks = tasks.delete_if { |t| already_planned_tasks.include?(t) }
  count = 0
  re_display = false
  planned = []
  tasks.each do |task|
    unless re_display
      task.print_pretty
    else
      task.print_pretty(true)
      re_display = false
    end
    choice = @console.prompt PROMPT_STRING
    case choice
    when 'a'
      duration = 0
      until duration > 0
        print "Duration (1 = 15 minutes, RETURN defaults to 30 minutes): "
        answer = gets.chomp
        duration = answer.empty? ? 2 : answer.to_i
      end
      task.set_duration(units_to_time(duration))
      task.options[:follow_up] = date
      @service.save(task.dir, task)
      planned << task
      count += 1
    when 'c'
      re_display = true
      redo
    when 's'
      #do nothing
    when 'q'
      break
    end
  end
  save_tasks(planned)
  count
end

#prioritize_tasks(date = Time.now.strftime("%Y-%m-%d"), filter = {}) ⇒ Object

Prioritize tasks by pair wise comparisson. Each task is compared to the other tasks and the user can select the task with the higher priority. So the task with highest priority will bubble on top followed by the task with second highest priority and so on.



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/syctask/task_planner.rb', line 192

def prioritize_tasks(date=Time.now.strftime("%Y-%m-%d"), filter={})
  tasks = get_tasks(date, filter)
  return false if tasks.nil?
  quit = false
  0.upto(tasks.size-1) do |i|
    (i+1).upto(tasks.size-1) do |j|
      puts " 1: #{tasks[i].title}"
      puts " 2: #{tasks[j].title}"
      choice = @console.prompt PRIORITIZE_STRING
      case choice
      when 'q'
        quit = true
        break
      when 'l'
        tasks[i],tasks[j] = tasks[j],tasks[i]
      end
    end
    break if quit
  end
  save_tasks(tasks, true)
  true
end

#remove_tasks(date = Time.now.strftime("%Y-%m-%d"), filter = {}) ⇒ Object

Remove planned tasks from the task plan based on the provided filter (filter options see Task#matches?). Returns the count of removed tasks



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/syctask/task_planner.rb', line 248

def remove_tasks(date=Time.now.strftime("%Y-%m-%d"), filter={})
  planned = []
  tasks = self.get_tasks(date)
  tasks.each do |task|
    planned << task unless task.matches?(filter)
  end
  (tasks - planned).each do |task|
    if task.options[:follow_up] == date
      task.options[:follow_up] = nil
    end
    if task.options[:due_date] == date
      task.options[:due_date] = nil
    end
    @service.save(task.dir, task)
  end
  save_tasks(planned, true)
  tasks.size - planned.size
end