syc-task 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,12 +1,12 @@
1
1
  = Simple task organizer
2
- With syctask you can organize your tasks.
2
+ syctask can be used to create, plan, prioritize and schedule tasks.
3
3
 
4
4
  ==Install
5
5
  The application can be installed with
6
6
  $ gem install syc-task
7
7
 
8
8
  == Usage
9
- syctask provides basic task organizer functions as create, update, list und complete a task. Additional functions are to plan tasks you want to accomplish today. If you are not sure in which sequence to conduct the task you can prioritize them with a pair wise comparisson. You can time tasks with start and stop and you can finally extract tasks from a minutes of meetings file. The schedule task will print a graphical timeline of the working day assigning the planned tasks to the timeline. Busy times are marked red. Meetings are listed with associated tasks that are assigned to the meetings.
9
+ syctask provides basic task organizer functions as create, update, list and complete a task. Additional functions are to plan tasks you want to accomplish today. If you are not sure in which sequence to conduct the task you can prioritize them with a pair wise comparisson. You can time tasks with start and stop and you can finally extract tasks from a minutes of meetings file. The schedule task will print a graphical timeline of the working day assigning the planned tasks to the timeline. Busy times are marked red. Meetings are listed with associated tasks that are assigned to the meetings.
10
10
 
11
11
  ===Create tasks with new
12
12
  Create a new task in the default task directory ~/.tasks
@@ -23,7 +23,7 @@ Set a proirity for a task
23
23
 
24
24
  Prompt for task input
25
25
  $ syctask new
26
- will prompt for task titles. When read C-D will end input.
26
+ will prompt for task titles. Ctrl-D will end input.
27
27
 
28
28
  Except for --description you can also provide short forms for the options.
29
29
 
@@ -44,6 +44,32 @@ Invoke plan with a filter
44
44
  1 - My first task
45
45
  (a)dd, (c)omplete, (s)kip, (q)uit?
46
46
 
47
+ ===Prioritize tasks
48
+ Planned tasks can be prioritized in a pair wise comparisson. So each task is
49
+ compared to all other tasks. The task with the highest priority will bubble on
50
+ top followed by the task with the next highest priority and so on.
51
+
52
+ $ syctask prio
53
+ 1: My first task
54
+ 2: My second task
55
+ Task 1 has (h)igher or (l)ower priority, or (q)uit: h
56
+ 1: My first task
57
+ 2: My third task
58
+ Task 1 has (h)igher or (l)ower priority, or (q)uit: l
59
+ 1: My third task
60
+ 2: My fourth task
61
+ Task 1 has (h)igher or (l)ower priority, or (q)uit: h
62
+ ...
63
+
64
+ syctask schedule will then print tasks as follows
65
+ Tasks
66
+ -----
67
+ 0: 10 - My fourth task
68
+ 1: 7 - My third task
69
+ 2: 3 - My first task
70
+ 3: 9 - My second task
71
+ ...
72
+
47
73
  ===Create schedule
48
74
  The schedule command will print a graphical schedule with assigning the tasks
49
75
  added with plan.
@@ -109,17 +135,168 @@ Update task with ID 1 and provide some informative note
109
135
  Complete the task with ID 1 and provide a final note
110
136
  $ syctask done 1 --note "Finalize my first task"
111
137
 
138
+ ===Delete tasks
139
+ Delete tasks with ID 1,3 and 5 from the default task directory
140
+ $ syctask delete --id 1,3,5
141
+
142
+ Delete tasks with ID 8 and 12 from the planned tasks of today. The tasks are
143
+ only removed from the planned tasks and not physically deleted.
144
+ $ syctask delete --plan today --id 8,12
145
+
146
+ ===Task directory and project directory
147
+ The global options --taskdir and --project determine where the command finds
148
+ or creates the tasks. The default task directory is ~/.tasks, so if no task
149
+ directory is specified all commands obtain tasks from or create tasks in
150
+ ~/.tasks. If a project is specified the tasks will be saved to or obtained from the task directories subdirectory specified with the --project flag.
151
+
152
+ --taskdir --project Tasks in
153
+ - - default_task_dir
154
+ x - task_dir
155
+ - x default_task_dir/project
156
+ x x task_dir/project
157
+
158
+ In the table the relation of commands to --taskdir and --project are listed.
159
+
160
+ Command --taskdir --project Comment
161
+ delete x x deletes the tasks in taskdir/project
162
+ done x x marks tasks in taskdir/project as done
163
+ help - -
164
+ list x x lists tasks in taskdir/project
165
+ new x x creates tasks in taskdir/project
166
+ plan x x retrieves tasks to plan from taskdir/projekt
167
+ prio - - input to prio are planned tasks (see plan)
168
+ scan x x creates scanned tasks in taskdir/project
169
+ schedule - - schedules the planned tasks (see plan)
170
+ start - - starts task from planned tasks (see plan)
171
+ stop - - stops task from planned task
172
+ update x x updates task in taskdir/project
173
+
174
+ ===Files
175
+
176
+ * Task files
177
+ The tasks are named ID.task where ID is any Integer as 10.task. The files are
178
+ saved as YAML files and can be edited directly.
179
+
180
+ * Planned tasks files
181
+ The planned tasks are save to YYYY-MM-DD_planned_tasks in the default task
182
+ directory. Each task is saved with the tasks directory and the ID.
183
+
184
+ * Schedule files
185
+ The schedule is saved to YYYY-MM-DD_schedule in the default task directory. The
186
+ files are saved as YAML files and can be changed manually.
187
+
188
+ ==Working with syctask
189
+ To work with syctask and get the most out of it there is to follow a certain
190
+ process.
191
+
192
+ ===Creating a schedule
193
+ ==== View tasks
194
+ In the morning before I start to work I scan my tasks with syctask list to get
195
+ an overview of my open tasks.
196
+ $ syctask list
197
+
198
+ ==== Plan tasks
199
+ Next I start the planning phase with syctask plan. If I have a specific schedule
200
+ for the day I will filter for the respective tasks
201
+ $ syctask plan
202
+
203
+ ==== Prioritize tasks (optionally)
204
+ If I want to process the tasks in a specific sequence I prioritize the tasks
205
+ with
206
+ $ syctask prio
207
+
208
+ ==== Create schedule
209
+ I create a schedule with my working hours and meetings that have been scheduled with
210
+ $ syctask -w "8:00-18:00" -b "9:00-10:00,14:30-16:00" -m "Team,Status"
211
+
212
+ ==== Create an agenda
213
+ I assign the topics I want to discuss in the meetings to the meetings with
214
+ syctask schedule -a "A:1,3,6;B:3,5"
215
+
216
+ ==== Start a task
217
+ To begin I start the first task in the schedule with syctask start 0 (where 0 is the sequence of the planned tasks, the ID is different e.g. 23)
218
+ $ syctask start 0
219
+
220
+ ==== End a task
221
+ To end the task I invoke
222
+ $ syctask stop
223
+ This will stop the last started task
224
+
225
+ ==== Complete a task
226
+ When the task is done I call
227
+ $ syctask done 23
228
+
229
+ ===Attachements
230
+ * E-mails
231
+ If an e-mail creates a task I create a new task with syctask new title_of_task.
232
+ The subject of the e-mail I prepend with the ID and move the e-mail to a
233
+ <b>open topics</b> directory.
234
+
235
+ * Files
236
+ If I create files in the course of a task I create a folder in the task
237
+ directory with the ID and save the files in this directory. If there is an
238
+ existing directory I link to the file from the ID directory
239
+
112
240
  ==Supported platform
113
241
  syc-task has been tested with 1.9.3
114
242
 
243
+ ==Add TAB-completion to syctask
244
+ To activate bash's TAB-completion following lines have to be added to ~/.bashrc
245
+
246
+ complete -F get_syctask_commands syctask
247
+
248
+ function get_syctask_commands
249
+ {
250
+ if [ -z $2 ] ; then
251
+ COMPREPLY=(`syctask help -c`)
252
+ else
253
+ COMPREPLY=(`syctask help -c $2`)
254
+ fi
255
+ }
256
+
257
+ After ~/.bashrc has been updated the shell session has to be restarted with
258
+ $ source ~/.bashrc
259
+
260
+ Now syctask followed by TAB TAB will print
261
+
262
+ $ syctask <TAB><TAB>
263
+ delete done list plan scan stop _doc help new prio schedule start update
264
+
265
+ To complete a command we can type
266
+
267
+ $ syctask sch<TAB>
268
+
269
+ which will complete to
270
+
271
+ $ syctask schedule
272
+
273
+ ==Output to Printer
274
+ To print syctask's output to a printer pipe the command to lpr
275
+
276
+ $ syctask schedule | lpr
277
+
278
+ This will print the schedule to the default printer.
279
+
280
+ To determine all available printer lpstat can be used with the lpstat -a command
281
+
282
+ $ lpstat -a
283
+ Canon-LBP6650-3470 accepting requests since Sat 16 Mar 2013 04:26:15 PM CET
284
+ Dell-B1160w-Mono accepting requests since Sat 16 Mar 2013 04:27:45 PM CET
285
+
286
+ To print to Dell-B1160w-Mono the following command can be used
287
+
288
+ $ syctask schedule | lpr -P Dell-B1160w-Mono
289
+
115
290
  ==Notes
116
- As with version 0.0.1 only new, update, list and done is implemented.
291
+ With version 0.0.1 new, update, list and done is implemented.
292
+ with version 0.0.4 start, stop, scan and prio is not implemented.
117
293
 
118
294
  The test files live in the folder test and start with test_.
119
295
 
120
296
  There is a rake file available to run all tests
121
- $ rake test
122
297
 
298
+ $ rake test
299
+
123
300
  ==License
124
301
  syc-task is released under the {MIT License}[http://opensource.org/licenses/MIT]
125
302
 
data/bin/syctask CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'gli'
3
3
  require 'syctask'
4
4
  include GLI::App
5
+ include Syctime
5
6
 
6
7
  program_desc 'A simple task manager'
7
8
 
@@ -55,6 +56,7 @@ command :new do |c|
55
56
  task_numbers = nil
56
57
  args.each do |title|
57
58
  task_number = @service.create(global_options[:t], options, title)
59
+ add_task_to_plan @service.read(global_options[:t], task_number)
58
60
  if task_numbers.nil?
59
61
  task_numbers = task_number.to_s
60
62
  else
@@ -219,6 +221,10 @@ command :plan do |c|
219
221
  c.arg_name 'complete'
220
222
  c.switch [:c, :complete]
221
223
 
224
+ c.desc 'Move planned task to another day'
225
+ c.arg_name 'DATE'
226
+ c.flag [:m, :move], :must_match => /today|tomorrow|\d{4}-\d{2}-\d{2}/
227
+
222
228
  c.desc 'Filter for ID'
223
229
  c.arg_name 'ID1,ID2,ID3|[<|=|>]ID'
224
230
  c.flag [:i, :id], :must_match => /^\d+(?:,\d+)*|^[<|=|>]\d+/
@@ -253,8 +259,11 @@ command :plan do |c|
253
259
 
254
260
  c.action do |global_options,options,args|
255
261
  ARGV.clear
262
+
263
+ # Any option that is no filter has to be captured before filter is created
256
264
  show = options[:show]
257
265
  complete = options[:complete]
266
+ to_date = extract_time(options[:move]) if options[:move]
258
267
 
259
268
  filter = [:id, :tags, :description, :prio, :due_date, :follow_up,
260
269
  :note, :title]
@@ -282,6 +291,9 @@ command :plan do |c|
282
291
  end
283
292
  STDOUT.puts sprintf("--> found %d planned task(s) for %s", count, date).
284
293
  color(:green)
294
+ elsif to_date
295
+ count = @planner.move_tasks(options, date, to_date)
296
+ STDOUT.puts sprintf("--> %d task(s) moved", count).color(:green)
285
297
  else
286
298
  count = @planner.plan_tasks(@service.find(global_options[:t], options,
287
299
  false), date)
@@ -355,25 +367,81 @@ command :schedule do |c|
355
367
  end
356
368
  end
357
369
 
358
- desc 'Prioritize tasks'
370
+ desc 'Prioritize tasks of today, tomorrow or another day'
371
+ arg_name 'DATE'
372
+ default_value 'today'
359
373
  command :prio do |c|
374
+
375
+ c.desc 'Prioritize in specified order'
376
+ c.arg_name 'ID1,ID2,ID3,...'
377
+ c.flag [:o, :order], :must_match => /^\d+(?:,\d+)*/
378
+
360
379
  c.action do |global_options,options,args|
361
- puts "prio command not implemented yet"
380
+ time = extract_time(args[0])
381
+ planner = Syctask::TaskPlanner.new
382
+ if options[:order]
383
+ ordered, rest = planner.order_tasks(time, options[:order].split(","))
384
+ puts sprintf("--> put %d task%s into new order and %d appended to end",
385
+ ordered, "#{'s' if ordered > 1}", rest).color(:green)
386
+ else
387
+ planner.prioritize_tasks(time)
388
+ end
362
389
  end
363
390
  end
364
391
 
365
- desc 'Start and time a task'
366
- arg_name 'TASK_NUMBER'
392
+ desc 'Start tracking a task'
393
+ arg_name 'TASK_NUMBER|PLAN|TALK|PHONE|EMAIL'
367
394
  command :start do |c|
395
+
396
+ c.desc 'List currently tracked task'
397
+ c.switch [:l, :list]
398
+
399
+ c.desc 'Number of planned task'
400
+ c.switch [:p, :plan]
401
+
368
402
  c.action do |global_options,options,args|
369
- puts "start command not implemented yet"
403
+ tracker = Syctask::TaskTracker.new
404
+ if args[0]
405
+ if options[:plan]
406
+ task = @planner.get_tasks[args[0].to_i]
407
+ else
408
+ task = @service.read(global_options[:taskdir], args[0])
409
+ end
410
+ help_now! sprintf("%s",
411
+ "no task with id #{args[0]}").color(:red) unless task
412
+ started, stopped = tracker.start(task)
413
+ if started
414
+ puts sprintf("--> tracking %s",
415
+ "#{task.id} - #{task.title}").color(:green)
416
+ else
417
+ puts sprintf("--> allready tracking %s",
418
+ "#{task.id} - #{task.title}").color(:red)
419
+ end
420
+ if stopped
421
+ puts sprintf("--> stopped %s",
422
+ "#{stopped.id} - #{stopped.title}").color(:green)
423
+ puts sprintf(" %s", "#{string_for_seconds(stopped.lead_time)}").color(:green)
424
+ end
425
+ end
426
+ if options[:list]
427
+ task = tracker.tracked_task
428
+ puts sprintf("%s", "--> no task tracked").color(:red) unless task
429
+ puts sprintf("%s", "--> #{task.id} - #{task.title}").color(:green) if task
430
+ end
370
431
  end
371
432
  end
372
433
 
373
- desc 'Stop the running task'
434
+ desc 'Stop the tracked task'
374
435
  command :stop do |c|
375
436
  c.action do |global_options,options,args|
376
- puts "stop command not implemented yet"
437
+ tracker = Syctask::TaskTracker.new
438
+ task = tracker.stop
439
+ if task
440
+ puts sprintf("--> stopped %s", "#{task.id} - #{task.title}").color(:green)
441
+ puts sprintf(" %4s", "#{string_for_seconds(task.lead_time)}").color(:green)
442
+ else
443
+ puts sprintf("--> %s", "no task tracked").color(:red)
444
+ end
377
445
  end
378
446
  end
379
447
 
@@ -411,9 +479,12 @@ command :update do |c|
411
479
  options.keep_if {|key, value| filter.find_index(key) and value != nil}
412
480
 
413
481
  success = @service.update(global_options[:t], args[0], options)
414
- STDOUT.puts sprintf("sucessfully updated task with TASK_NUMBER ",
482
+
483
+ add_task_to_plan @service.read(global_options[:t], args[0]) if success
484
+
485
+ STDOUT.puts sprintf("--> sucessfully updated task with TASK_NUMBER %s ",
415
486
  args[0]).color(:green) if success
416
- STDOUT.puts sprintf("could not update task with TASK_NUMBER ",
487
+ STDOUT.puts sprintf("--> could not update task with TASK_NUMBER %s ",
417
488
  args[0]).color(:red) unless success
418
489
  end
419
490
  end
@@ -431,7 +502,8 @@ command :done do |c|
431
502
  c.flag [:n, :note]
432
503
 
433
504
  c.action do |global_options,options,args|
434
- help_now!('TASK_NUMBER is required') if args.empty?
505
+ help_now! sprintf("%s",
506
+ 'TASK_NUMBER is required').color(:red) if args.empty?
435
507
  task = @service.read(global_options[:t], args[0])
436
508
  exit_now!("Task with TASK_NUMBER #{args[0]} does not exist") unless task
437
509
  task.done(options[:note])
@@ -471,4 +543,34 @@ on_error do |exception|
471
543
  true
472
544
  end
473
545
 
546
+ # Extracts the time out of a time string. Accepts 'today', 'tomorrow' or a date
547
+ # in the form 'YYYY-MM-DD'. Returns the date contained in the time_string
548
+ def extract_time(time_string)
549
+ time_string = 'today' if time_string.nil?
550
+ case time_string.downcase
551
+ when 'today'
552
+ date = Time.now.strftime("%Y-%m-%d")
553
+ when 'tomorrow'
554
+ date = (Time.now + (60 * 60 * 24)).strftime("%Y-%m-%d")
555
+ else
556
+ if time_string.match(/\d{4}-\d{2}-\d{2}/)
557
+ date = time_string
558
+ elsif nil
559
+ date = Time.now.strftime("%Y-%m-%d")
560
+ else
561
+ help_now! "Arguments may be 'today', 'tomorrow', YYYY-MM-DD or <RETURN>"
562
+ end
563
+ end
564
+ end
565
+
566
+ # Add task to task plan
567
+ def add_task_to_plan(task)
568
+ if task.options[:follow_up]
569
+ @planner.add_task(task, task.options[:follow_up])
570
+ end
571
+ if task.options[:due_date]
572
+ @planner.add_task(task, task.options[:due_date])
573
+ end
574
+ end
575
+
474
576
  exit run(ARGV)
@@ -0,0 +1,26 @@
1
+ module Sycstring
2
+
3
+ # Splits a string to size (chars) less or equal to length
4
+ def split_lines(string, length)
5
+ lines = string.squeeze(" ").split("\n")
6
+ i = 0
7
+ new_lines = []
8
+ new_lines[i] = ""
9
+ lines.each do |line|
10
+ line.squeeze(" ").split.each do |w|
11
+ if new_lines[i].length + w.length < length
12
+ new_lines[i] += "#{w} "
13
+ else
14
+ i += 1
15
+ new_lines[i] = "#{w} "
16
+ end
17
+ end
18
+ i += 1
19
+ new_lines[i] = ""
20
+ end
21
+ text = ""
22
+ new_lines.each {|l| text << "#{l}\n"}
23
+ text.chomp
24
+ end
25
+
26
+ end
data/lib/syctask.rb CHANGED
@@ -6,6 +6,8 @@ require 'syctask/task_scheduler.rb'
6
6
  require 'syctask/task_planner.rb'
7
7
  require 'syctask/schedule.rb'
8
8
  require 'sycutil/console.rb'
9
+ require 'syctask/task_tracker.rb'
10
+ require 'syctime/time_util.rb'
9
11
 
10
12
  # Add requires for other files you add to your project here, so
11
13
  # you just need to require this one file in your bin file
@@ -0,0 +1,5 @@
1
+ module Syctask
2
+
3
+ WORK_DIR = File.expand_path('~/.tasks')
4
+
5
+ end
@@ -2,11 +2,17 @@ require_relative 'times.rb'
2
2
 
3
3
  module Syctask
4
4
 
5
- class Meeting
5
+ # Meeting represents a meeting containing the begin and end time, a title and
6
+ # an agenda consisting of tasks
7
+ class Meeting
6
8
 
9
+ # The start time of the meeting
7
10
  attr_accessor :starts
11
+ # The end time of the meeting
8
12
  attr_accessor :ends
13
+ # The title of the meeting
9
14
  attr_accessor :title
15
+ # The agenda or tasks of the meeting
10
16
  attr_accessor :tasks
11
17
 
12
18
  # Sets the busy time for the schedule. The busy times have to be provided
@@ -1,5 +1,7 @@
1
1
  require_relative 'times.rb'
2
2
  require_relative 'meeting.rb'
3
+ require_relative '../sycstring/string_util.rb'
4
+ include Sycstring
3
5
 
4
6
  module Syctask
5
7
 
@@ -243,8 +245,11 @@ module Syctask
243
245
  else
244
246
  color = WORK_COLOR
245
247
  end
246
- task_list << sprintf("%#{max_ord_size}d: %#{max_id_size}s - %s\n", i, task.id, task.title).
247
- color(color)
248
+ offset = max_ord_size + max_id_size + 5
249
+ title = split_lines(task.title, 80-offset)
250
+ title = title.chomp.gsub(/\n/, "\n#{' '*offset}")
251
+ task_list << sprintf("%#{max_ord_size}d: %#{max_id_size}s - %s\n",
252
+ i, task.id, title).color(color)
248
253
  end
249
254
 
250
255
  task_caption = ""
data/lib/syctask/task.rb CHANGED
@@ -26,6 +26,8 @@ module Syctask
26
26
  attr_reader :id
27
27
  # Duration specifies the planned time for processing the task
28
28
  attr_accessor :duration
29
+ # Lead time is the time this task has been processed
30
+ attr_accessor :lead_time
29
31
  # Creation date
30
32
  attr_reader :creation_date
31
33
  # Update date
@@ -74,10 +76,12 @@ module Syctask
74
76
  when :note
75
77
  new_value = "#{@update_date}\n#{new_value}\n#{@options[key]}"
76
78
  when :tags
77
- if @options[key].include? new_value
78
- new_value = @options[key]
79
- else
80
- new_value = "#{@options[key]},#{new_value}"
79
+ unless @options[key].nil?
80
+ if @options[key].include? new_value
81
+ new_value = @options[key]
82
+ else
83
+ new_value = "#{@options[key]},#{new_value}"
84
+ end
81
85
  end
82
86
  end
83
87
 
@@ -184,16 +188,22 @@ module Syctask
184
188
  def pretty_string(long)
185
189
  color = :default
186
190
  color = :green if self.done?
191
+
192
+ title = split_lines(@title, 70)
193
+ title = title.chomp.gsub(/\n/, "\n#{' '*7}")
194
+ puts sprintf("%04d - %s", @id, title.bright).color(color)
187
195
 
188
- puts sprintf("%04d - %s", @id, @title.bright).color(color)
189
196
  if @options[:description]
190
197
  description = split_lines(@options[:description].chomp, 70)
191
198
  description = description.chomp.gsub(/\n/, "\n#{' '*7}")
192
199
  puts sprintf("%6s %s", " ", description.chomp).color(color)
193
200
  end
194
- puts sprintf("%6s Prio: %s", " ", @options[:prio]).color(color) if @options[:prio]
195
- puts sprintf("%6s Follow-up: %s", " ", @options[:follow_up]).color(color) if @options[:follow_up]
196
- puts sprintf("%6s Due: %s", " ", @options[:due]).color(color) if @options[:due]
201
+ puts sprintf("%6s Prio: %s", " ", @options[:prio]).
202
+ color(color) if @options[:prio]
203
+ puts sprintf("%6s Follow-up: %s", " ", @options[:follow_up]).
204
+ color(color) if @options[:follow_up]
205
+ puts sprintf("%6s Due: %s", " ", @options[:due_date]).
206
+ color(color) if @options[:due_date]
197
207
  if long
198
208
  if @options[:note]
199
209
  note = split_lines(@options[:note].chomp, 70)
@@ -203,10 +213,13 @@ module Syctask
203
213
  gsub(/\n(?=\d{4}-\d{2}-\d{2} - \d{2}:\d{2}:\d{2})/, "\n#{' '*7}")
204
214
  puts sprintf("%6s %s", " ", note.chomp).color(color)
205
215
  end
206
- puts sprintf("%6s Tags: %s", " ", @options[:tags]).color(color) if @options[:tags]
216
+ puts sprintf("%6s Tags: %s", " ", @options[:tags]).
217
+ color(color) if @options[:tags]
207
218
  puts sprintf("%6s Created: %s", " ", @creation_date).color(color)
208
- puts sprintf("%6s Updated: %s", " ", @update_date).color(color) if @update_date
209
- puts sprintf("%6s Closed: %s", " ", @done_date).color(color) if @done_date
219
+ puts sprintf("%6s Updated: %s", " ", @update_date).
220
+ color(color) if @update_date
221
+ puts sprintf("%6s Closed: %s", " ", @done_date).
222
+ color(color) if @done_date
210
223
  end
211
224
  end
212
225
 
@@ -217,7 +230,7 @@ module Syctask
217
230
  def csv_string
218
231
  string = "\n#{@id};#{@title};"
219
232
  string +" #{@options[:description]};#{@options[:prio]};"
220
- string += "#{@options[:follow_up]};#{@options[:due]};"
233
+ string += "#{@options[:follow_up]};#{@options[:due_date]};"
221
234
  string += "#{@options[:note].gsub(/\n/, '\\n')};"
222
235
  string += "#{@options[:tags]};"
223
236
  string += "#{@creation_date};"
@@ -3,11 +3,18 @@ require_relative '../sycutil/console.rb'
3
3
  require_relative 'task_service.rb'
4
4
 
5
5
  module Syctask
6
+ # String that is prompted during planning
6
7
  PROMPT_STRING = '(a)dd, (c)omplete, (s)kip, (q)uit: '
8
+ # String that is prompted during prioritization
9
+ PRIORITIZE_STRING = 'Task 1 has (h)igher or (l)ower priority, or (q)uit: '
7
10
 
11
+ # A TaskPlanner prompts the user to select tasks for today. These tasks can
12
+ # be prioritized to determine the most to the least important tasks.
8
13
  class TaskPlanner
14
+ # The task where the planned tasks are saved to
9
15
  WORK_DIR = File.expand_path("~/.tasks")
10
16
 
17
+ # Creates a new TaskPlanner
11
18
  def initialize
12
19
  @console = Sycutil::Console.new
13
20
  @service = TaskService.new
@@ -54,9 +61,75 @@ module Syctask
54
61
  count
55
62
  end
56
63
 
57
- # Add the tasks to the planned tasks
58
- def add_tasks(tasks)
59
- save_tasks(tasks)
64
+ # Order tasks in the provided IDs sequence at the specified date. If not
65
+ # IDs are provided than rest of tasks is appended to the end of the plan.
66
+ # Returns the count of ordered tasks and the count of the rest of the tasks.
67
+ def order_tasks(date, ids)
68
+ tasks = get_tasks(date)
69
+ ordered = []
70
+ ids.each do |id|
71
+ index = tasks.find_index {|t| t.id == id.to_i}
72
+ ordered << tasks.delete_at(index) if index
73
+ end
74
+ ordered << tasks
75
+ save_tasks(ordered.flatten!, true)
76
+ [ordered.size - tasks.size, tasks.size]
77
+ end
78
+
79
+ # Prioritize tasks by pair wise comparisson. Each task is compared to the
80
+ # other tasks and the user can select the task with the higher priority. So
81
+ # the task with highest priority will bubble on top followed by the task
82
+ # with second highest priority and so on.
83
+ def prioritize_tasks(date=Time.now.strftime("%Y-%m-%d"), filter={})
84
+ tasks = get_tasks(date, filter)
85
+ return false if tasks.nil?
86
+ quit = false
87
+ 0.upto(tasks.size-1) do |i|
88
+ (i+1).upto(tasks.size-1) do |j|
89
+ puts " 1: #{tasks[i].title}"
90
+ puts " 2: #{tasks[j].title}"
91
+ choice = @console.prompt PRIORITIZE_STRING
92
+ case choice
93
+ when 'q'
94
+ quit = true
95
+ break
96
+ when 'l'
97
+ tasks[i],tasks[j] = tasks[j],tasks[i]
98
+ end
99
+ end
100
+ break if quit
101
+ end
102
+ save_tasks(tasks, true)
103
+ true
104
+ end
105
+
106
+ # Add the task to the planned tasks of the specified date. The task is only
107
+ # added if not already present
108
+ def add_task(task, date=Time.now.strftime("%Y-%m-%d"))
109
+ add_tasks([task], date)
110
+ end
111
+
112
+ # Add the tasks to the planned tasks. A task is only added if not already
113
+ # present
114
+ def add_tasks(tasks, date=Time.now.strftime("%Y-%m-%d"))
115
+ planned = get_tasks(date)
116
+ tasks.each do |task|
117
+ planned << task unless planned.find_index {|t| t == task}
118
+ end
119
+ save_tasks(planned, true)
120
+ end
121
+
122
+ # Moves the specified tasks to the specified date. Returns the count of
123
+ # moved files
124
+ def move_tasks(filter={}, from_date=Time.now.strftime("%Y-%m-%d"), to_date)
125
+ return 0 if from_date == to_date
126
+ moved = get_tasks(from_date, filter)
127
+ moved.each do |task|
128
+ task.options[:follow_up] = to_date
129
+ @service.save(task.dir, task)
130
+ end
131
+ add_tasks(moved, to_date)
132
+ remove_tasks(from_date, filter)
60
133
  end
61
134
 
62
135
  # Remove planned tasks from the task plan based on the provided filter
@@ -67,6 +140,15 @@ module Syctask
67
140
  tasks.each do |task|
68
141
  planned << task unless task.matches?(filter)
69
142
  end
143
+ (tasks - planned).each do |task|
144
+ if task.options[:follow_up] == date
145
+ task.options[:follow_up] = nil
146
+ end
147
+ if task.options[:due_date] == date
148
+ task.options[:due_date] = nil
149
+ end
150
+ @service.save(task.dir, task)
151
+ end
70
152
  save_tasks(planned, true)
71
153
  tasks.size - planned.size
72
154
  end
@@ -74,6 +74,7 @@ module Syctask
74
74
  @meetings = titles.split(",") if titles
75
75
  end
76
76
 
77
+ # Sets the tasks for scheduling
77
78
  def set_tasks(tasks)
78
79
  @tasks = tasks
79
80
  end
@@ -6,6 +6,8 @@ module Syctask
6
6
  # Provides services to operate tasks as create, read, find, update and save
7
7
  # Task objects
8
8
  class TaskService
9
+ # Default directory where the tasks are saved to if no directory is
10
+ # specified
9
11
  DEFAULT_DIR = File.expand_path("~/.tasks")
10
12
 
11
13
  # Creates a new task in the specified directory, with the specified options
@@ -29,7 +31,7 @@ module Syctask
29
31
  # does not exist nil is returned otherwise the task is returned
30
32
  def read(dir, id)
31
33
  task = nil
32
- Dir.glob("#{dir}/*").each do |file|
34
+ Dir.glob("#{dir}/*.task").each do |file|
33
35
  task = YAML.load_file(file) if File.file? file
34
36
  if not task.nil? and task.class == Syctask::Task and task.id == id.to_i
35
37
  return task
@@ -0,0 +1,159 @@
1
+ require_relative 'environment.rb'
2
+ require_relative 'task_service.rb'
3
+
4
+ module Syctask
5
+
6
+ # TaskTracker provides methods to start a task and stop a task. The objective
7
+ # is to track the processing time for a task. The processing time can be
8
+ # analyzed with the TaskStatistics class. When a task is started it is saved
9
+ # to the started_tasks file. If another task is started the currently active
10
+ # task is stopped and the newly started file is put on top of the
11
+ # started_tasks file. When stopping a task the currently started tasks will
12
+ # be returned and one of the idling tasks can be restarted. When a task is
13
+ # stopped the processing time is added to the task's lead_time field.
14
+ class TaskTracker
15
+
16
+ # File name of the file where the tracked files are saved to
17
+ TRACKED_TASKS_FILE = Syctask::WORK_DIR + '/' + 'tracked_tasks'
18
+ # File name of the task log file
19
+ TASK_LOG_FILE = Syctask::WORK_DIR + '/' + 'tasks.log'
20
+
21
+ # Creates a new TaskTracker
22
+ def initialize
23
+ @service = Syctask::TaskService.new
24
+ load_tracks
25
+ end
26
+
27
+ # When a task is started it is saved with the start time. If a task is
28
+ # already tracked it is stopped (see #stop). A started task will print
29
+ # every 15 minutes a message to the console.
30
+ # start returns
31
+ # * [false, nil ] if the task is already tracked
32
+ # * [true, nil ] if the task is started and no task was running.
33
+ # * [true, task] if task is started and the previously running task stopped
34
+ def start(task)
35
+ index = @tasks.find_index(task)
36
+ return [false, nil] if not index.nil? and index == 0
37
+
38
+ stopped_task = stop
39
+ track = Track.new(task)
40
+
41
+ track.start
42
+ log_task(:start, track)
43
+
44
+ @tracks.insert(0,track)
45
+
46
+ @tasks.insert(0,task)
47
+
48
+ save_tracks
49
+
50
+ [true, stopped_task]
51
+
52
+ end
53
+
54
+ # When a task is stopped it is removed from the started_tasks file and the
55
+ # processing time is added to the lead_time field of the task. #stop
56
+ # returns the stopped task in an Array or an empty Array if no task is
57
+ # running an hence no task can be stopped.
58
+ def stop
59
+ return nil unless @tasks[0]
60
+
61
+ task = @tasks[0]
62
+ if task.lead_time
63
+ task.lead_time += @tracks[0].stop
64
+ else
65
+ task.lead_time = @tracks[0].stop
66
+ end
67
+
68
+ @service.save(task.dir, task)
69
+ log_task(:stop, @tracks[0])
70
+
71
+ @tracks.delete_at(0)
72
+ @tasks.delete_at(0)
73
+ save_tracks
74
+ task
75
+ end
76
+
77
+ # Retrieves the currently tracked task returns nil if no task is tracked
78
+ def tracked_task
79
+ @tasks[0]
80
+ end
81
+
82
+ private
83
+
84
+ # Saves the tracks to the tracked tasks file
85
+ def save_tracks
86
+ FileUtils.mkdir_p WORK_DIR unless File.exists? WORK_DIR
87
+ File.open(TRACKED_TASKS_FILE, 'w') do |file|
88
+ YAML.dump(@tracks, file)
89
+ end
90
+ end
91
+
92
+ # Loads the tracks from the tracked tasks file to @tasks and
93
+ # @tracks. If no tracked tasks exist @tracks and @tasks will be
94
+ # empty
95
+ def load_tracks
96
+ unless File.exists? TRACKED_TASKS_FILE
97
+ @tracks = []
98
+ @tasks = []
99
+ else
100
+ @tracks ||= YAML.load_file(TRACKED_TASKS_FILE)
101
+ @tasks = []
102
+ @tracks.each { |track| @tasks << @service.read(track.dir, track.id) }
103
+ end
104
+ end
105
+
106
+ # Logs the start and stop of a task.
107
+ def log_task(type, track)
108
+ FileUtils.mkdir_r Syctask::WORK_DIR unless File.exists? Syctask::WORK_DIR
109
+ File.open(TASK_LOG_FILE, 'a') do |file|
110
+ log_entry = "#{type.to_s};"
111
+ log_entry += "#{track.id}-#{track.dir};"
112
+ log_entry += "#{track.title};"
113
+ log_entry += "#{track.started};"
114
+ log_entry += "#{track.stopped}"
115
+ file.puts log_entry
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ # A Track holds a task and stops the time the task is processed. The Track
122
+ # will print every 5 minutes the elapsed time and the time left to the
123
+ # specified Task#duration.
124
+ class Track
125
+
126
+ # Directory where the tracked task is saved
127
+ attr_reader :dir
128
+ # ID of the tracked task
129
+ attr_reader :id
130
+ # Title of the tracked task
131
+ attr_reader :title
132
+ # When tracking started
133
+ attr_reader :started
134
+ # When tracking stopped
135
+ attr_reader :stopped
136
+
137
+ # Creates a new Track for the provided task
138
+ def initialize(task)
139
+ @dir = task.dir
140
+ @id = task.id
141
+ @title = task.title
142
+ end
143
+
144
+ # Starts the tracking and a timer that will print to STDOUT every 5 minutes
145
+ # the elapsed time and the time left until Task#duration
146
+ def start
147
+ @started ||= Time.now
148
+ # start a timer that prints title and elapsed time every 5 minutes
149
+ end
150
+
151
+ # Stops the task tracking and returns the lead time of the task
152
+ def stop
153
+ @stopped ||= Time.now
154
+ @stopped - @started
155
+ end
156
+
157
+ end
158
+
159
+ end
data/lib/syctask/times.rb CHANGED
@@ -1,15 +1,21 @@
1
1
  module Syctask
2
2
 
3
+ # Times class represents a time consisting of hour and minutes
3
4
  class Times
4
5
 
6
+ # Hour of the Times object
5
7
  attr_reader :h
8
+ # Minute of the Times object
6
9
  attr_reader :m
7
10
 
11
+ # Creates a new Times object. time has to be provided as an array with the
12
+ # content as ["hour","minute"] e.g. ["10","15"] is 15 past 10
8
13
  def initialize(time)
9
14
  @h = time[0].to_i
10
15
  @m = time[1].to_i
11
16
  end
12
17
 
18
+ # Rounds the time to the next hour if minutes is greater than 0
13
19
  def round_up
14
20
  @m > 0 ? @h+1 : @h
15
21
  end
@@ -1,5 +1,5 @@
1
1
  # Syctask provides functions for managing tasks in a task list
2
2
  module Syctask
3
3
  #Holds the version number of syctask
4
- VERSION = '0.0.4'
4
+ VERSION = '0.0.6'
5
5
  end
@@ -0,0 +1,26 @@
1
+ module Syctime
2
+
3
+ def seconds_to_time(seconds)
4
+ seconds = seconds.round
5
+ duration = []
6
+ duration << seconds % 60 # seconds
7
+ duration << seconds / 60 % 60 # minutes
8
+ duration << seconds / 60 / 60 % 60 # hours
9
+ duration << seconds / 60 / 60 / 60 % 24 # days
10
+ duration << seconds / 60 / 60 / 60 / 24 % 7 # weeks
11
+ duration << seconds / 60 / 60 / 60 / 24 / 7 % 4 # months
12
+ duration << seconds / 60 / 60 / 60 / 24 / 7 / 4 % 12 # years
13
+ end
14
+
15
+ def string_for_seconds(seconds)
16
+ time = seconds_to_time(seconds)
17
+ time_name = ['year','month','week','day','hour','minute','second']
18
+ time_string = ""
19
+ time.reverse.each_with_index do |part,index|
20
+ time_string << part.to_s + ' ' + time_name[index] + ' ' if part == 1
21
+ time_string << part.to_s + ' ' + time_name[index] + 's ' if part > 1
22
+ end
23
+ time_string
24
+ end
25
+
26
+ end
@@ -1,6 +1,6 @@
1
1
  require 'io/wait'
2
2
 
3
- # Module Inspector contains functions related to the Console that is helpers
3
+ # Module Sycutil contains functions related to the Console that is helpers
4
4
  # for user input
5
5
  module Sycutil
6
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syc-task
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-14 00:00:00.000000000 Z
12
+ date: 2013-03-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -91,39 +91,49 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
- description: ! "= Simple task organizer\nWith syctask you can organize your tasks.\n\n==Install\nThe
95
- application can be installed with\n $ gem install syc-task\n\n== Usage\nsyctask
96
- provides basic task organizer functions as create, update, list und complete a task.
97
- Additional functions are to plan tasks you want to accomplish today. If you are
98
- not sure in which sequence to conduct the task you can prioritize them with a pair
99
- wise comparisson. You can time tasks with start and stop and you can finally extract
100
- tasks from a minutes of meetings file. The schedule task will print a graphical
101
- timeline of the working day assigning the planned tasks to the timeline. Busy times
102
- are marked red. Meetings are listed with associated tasks that are assigned to the
103
- meetings.\n\n===Create tasks with new\nCreate a new task in the default task directory
104
- ~/.tasks\n $ syctask new \"My first task\"\n\nProvide a description\n $ syctask
105
- new \"My first task\" --description \"Explanation of my first task\"\n\nSchedule
106
- a task with a follow-up and due date\n $ syctask new \"My first task\" --follow-up
107
- \"2013-02-25\" --due \"2013-03-11\"\n\nSet a proirity for a task\n $ syctask
108
- new \"My first task\" --prio 3\n\nPrompt for task input\n $ syctask new\nwill
109
- prompt for task titles. When read C-D will end input.\n\nExcept for --description
110
- you can also provide short forms for the options.\n\n===Plan tasks\nThe plan command
111
- will print tasks and prompts whether to (a)dd or (s)kip the task. If (q)uit is selected
112
- the tasks already added will be add to the today's task\nlist. If (c)omplete is
113
- selected the complete task will be printed and the user\nwill be prompted again
114
- for adding the task.\n\nInvoke plan without filter\n $ syctask plan\n 1 -
115
- My first task\n (a)dd, (c)omplete, (s)kip, (q)uit? a\n Duration (1 = 15 minutes,
116
- return 30 minutes): 3\n --> 1 task(s) planned\n\nInvoke plan with a filter\n
117
- \ $ syctask plan --id \"1,3,5,8\"\n 1 - My first task\n (a)dd, (c)omplete,
118
- (s)kip, (q)uit?\n\n===Create schedule\nThe schedule command will print a graphical
119
- schedule with assigning the tasks\nadded with plan.\n\nCreate a schedule with working
120
- time from 8a.m. to 6p.m. and meetings between\n9a.m. and 9.30a.m. and 1p.m. and
121
- 2.45p.m.\n $ syctask schedule -w \"8:00-18:00\" -b \"9:00-9:30,13:00-14:45\"\n\nAdd
122
- titles to the meetings\n $ syctask schedule -m \"Project status,Management meeting\"\n\nThe
123
- output will be\n Meetings\n --------\n A - Project status\n B - Management
124
- meeting\n\n A B\n xxx-///-|---|---|---///////-|---|---|---|\n
125
- \ 8 9 10 11 12 13 14 15 16 17 18\n 1\n\n Tasks\n -----\n 0
126
- - 1: My first task\n\nAdding a task to a meeting\n $ syctask schedule -a \"A:1\"\n\nwill
94
+ description: ! "= Simple task organizer\nsyctask can be used to create, plan, prioritize
95
+ and schedule tasks.\n\n==Install\nThe application can be installed with\n $ gem
96
+ install syc-task\n\n== Usage\nsyctask provides basic task organizer functions as
97
+ create, update, list and complete a task. Additional functions are to plan tasks
98
+ you want to accomplish today. If you are not sure in which sequence to conduct the
99
+ task you can prioritize them with a pair wise comparisson. You can time tasks with
100
+ start and stop and you can finally extract tasks from a minutes of meetings file.
101
+ The schedule task will print a graphical timeline of the working day assigning the
102
+ planned tasks to the timeline. Busy times are marked red. Meetings are listed with
103
+ associated tasks that are assigned to the meetings.\n\n===Create tasks with new\nCreate
104
+ a new task in the default task directory ~/.tasks\n $ syctask new \"My first
105
+ task\"\n\nProvide a description\n $ syctask new \"My first task\" --description
106
+ \"Explanation of my first task\"\n\nSchedule a task with a follow-up and due date\n
107
+ \ $ syctask new \"My first task\" --follow-up \"2013-02-25\" --due \"2013-03-11\"\n\nSet
108
+ a proirity for a task\n $ syctask new \"My first task\" --prio 3\n\nPrompt for
109
+ task input\n $ syctask new\nwill prompt for task titles. Ctrl-D will end input.\n\nExcept
110
+ for --description you can also provide short forms for the options.\n\n===Plan tasks\nThe
111
+ plan command will print tasks and prompts whether to (a)dd or (s)kip the task. If
112
+ (q)uit is selected the tasks already added will be add to the today's task\nlist.
113
+ If (c)omplete is selected the complete task will be printed and the user\nwill be
114
+ prompted again for adding the task.\n\nInvoke plan without filter\n $ syctask
115
+ plan\n 1 - My first task\n (a)dd, (c)omplete, (s)kip, (q)uit? a\n Duration
116
+ (1 = 15 minutes, return 30 minutes): 3\n --> 1 task(s) planned\n\nInvoke plan
117
+ with a filter\n $ syctask plan --id \"1,3,5,8\"\n 1 - My first task\n (a)dd,
118
+ (c)omplete, (s)kip, (q)uit?\n\n===Prioritize tasks\nPlanned tasks can be prioritized
119
+ in a pair wise comparisson. So each task is\ncompared to all other tasks. The task
120
+ with the highest priority will bubble on\ntop followed by the task with the next
121
+ highest priority and so on.\n\n $ syctask prio\n 1: My first task\n 2:
122
+ My second task\n Task 1 has (h)igher or (l)ower priority, or (q)uit: h\n 1:
123
+ My first task\n 2: My third task\n Task 1 has (h)igher or (l)ower priority,
124
+ or (q)uit: l\n 1: My third task\n 2: My fourth task\n Task 1 has (h)igher
125
+ or (l)ower priority, or (q)uit: h\n ...\n\nsyctask schedule will then print tasks
126
+ as follows\n Tasks\n -----\n 0: 10 - My fourth task\n 1: 7 - My third
127
+ task\n 2: 3 - My first task\n 3: 9 - My second task \n ...\n \n===Create
128
+ schedule\nThe schedule command will print a graphical schedule with assigning the
129
+ tasks\nadded with plan.\n\nCreate a schedule with working time from 8a.m. to 6p.m.
130
+ and meetings between\n9a.m. and 9.30a.m. and 1p.m. and 2.45p.m.\n $ syctask schedule
131
+ -w \"8:00-18:00\" -b \"9:00-9:30,13:00-14:45\"\n\nAdd titles to the meetings\n $
132
+ syctask schedule -m \"Project status,Management meeting\"\n\nThe output will be\n
133
+ \ Meetings\n --------\n A - Project status\n B - Management meeting\n\n
134
+ \ A B\n xxx-///-|---|---|---///////-|---|---|---|\n 8
135
+ \ 9 10 11 12 13 14 15 16 17 18\n 1\n\n Tasks\n -----\n 0 -
136
+ 1: My first task\n\nAdding a task to a meeting\n $ syctask schedule -a \"A:1\"\n\nwill
127
137
  print\n Meetings\n --------\n A - Project status\n 1 - My first
128
138
  task\n B - Management meeting\n\n A B\n ----///-|---|---|---///////-|---|---|---|\n
129
139
  \ 8 9 10 11 12 13 14 15 16 17 18\n \n\n Tasks\n -----\n \n===List
@@ -135,13 +145,78 @@ description: ! "= Simple task organizer\nWith syctask you can organize your task
135
145
  task with ID 1 and provide some informative note\n $ syctask update 1 --note
136
146
  \"Some explanation about the progress on the task\"\n\n===Complete tasks\nComplete
137
147
  the task with ID 1 and provide a final note\n $ syctask done 1 --note \"Finalize
138
- my first task\"\n\n==Supported platform\nsyc-task has been tested with 1.9.3\n\n==Notes\nAs
139
- with version 0.0.1 only new, update, list and done is implemented.\n\nThe test files
140
- live in the folder test and start with test_.\n\nThere is a rake file available
141
- to run all tests\n $ rake test\n\n==License\nsyc-task is released under the {MIT
142
- License}[http://opensource.org/licenses/MIT]\n\n==Links\n* [http://www.github.com/sugaryourcoffee/syc-task]
143
- - Source code on GitHub\n* [http://syc.dyndns.org/drupal/wiki/syc-task] - Development
144
- notebook\n* [https://rubygems.org/gems/syc-backup] - RubyGems\n"
148
+ my first task\"\n\n===Delete tasks\nDelete tasks with ID 1,3 and 5 from the default
149
+ task directory\n $ syctask delete --id 1,3,5\n\nDelete tasks with ID 8 and 12
150
+ from the planned tasks of today. The tasks are\nonly removed from the planned tasks
151
+ and not physically deleted.\n $ syctask delete --plan today --id 8,12\n\n===Task
152
+ directory and project directory\nThe global options --taskdir and --project determine
153
+ where the command finds\nor creates the tasks. The default task directory is ~/.tasks,
154
+ so if no task\ndirectory is specified all commands obtain tasks from or create tasks
155
+ in\n~/.tasks. If a project is specified the tasks will be saved to or obtained from
156
+ the task directories subdirectory specified with the --project flag.\n\n --taskdir
157
+ \ --project Tasks in\n - - default_task_dir\n x -
158
+ \ task_dir\n - x default_task_dir/project\n x x
159
+ \ task_dir/project\n\nIn the table the relation of commands to --taskdir and
160
+ --project are listed.\n\n Command --taskdir --project Comment\n delete
161
+ \ x x deletes the tasks in taskdir/project \n done x
162
+ \ x marks tasks in taskdir/project as done\n help - -
163
+ \ \n list x x lists tasks in taskdir/project\n
164
+ \ new x x creates tasks in taskdir/project\n plan x
165
+ \ x retrieves tasks to plan from taskdir/projekt\n prio -
166
+ \ - input to prio are planned tasks (see plan)\n scan x
167
+ \ x creates scanned tasks in taskdir/project\n schedule - -
168
+ \ schedules the planned tasks (see plan)\n start - - starts
169
+ task from planned tasks (see plan)\n stop - - stops task
170
+ from planned task\n update x x updates task in taskdir/project
171
+ \ \n\n===Files\n\n* Task files\nThe tasks are named ID.task where ID is any Integer
172
+ as 10.task. The files are\nsaved as YAML files and can be edited directly.\n\n*
173
+ Planned tasks files\nThe planned tasks are save to YYYY-MM-DD_planned_tasks in the
174
+ default task\ndirectory. Each task is saved with the tasks directory and the ID.\n\n*
175
+ Schedule files\nThe schedule is saved to YYYY-MM-DD_schedule in the default task
176
+ directory. The\nfiles are saved as YAML files and can be changed manually.\n\n==Working
177
+ with syctask\nTo work with syctask and get the most out of it there is to follow
178
+ a certain\nprocess.\n\n===Creating a schedule\n==== View tasks\nIn the morning before
179
+ I start to work I scan my tasks with syctask list to get\nan overview of my open
180
+ tasks.\n $ syctask list\n \n==== Plan tasks\nNext I start the planning phase
181
+ with syctask plan. If I have a specific schedule\nfor the day I will filter for
182
+ the respective tasks\n $ syctask plan\n\n==== Prioritize tasks (optionally)\nIf
183
+ I want to process the tasks in a specific sequence I prioritize the tasks\nwith
184
+ \n $ syctask prio\n\n==== Create schedule\nI create a schedule with my working
185
+ hours and meetings that have been scheduled with \n $ syctask -w \"8:00-18:00\"
186
+ -b \"9:00-10:00,14:30-16:00\" -m \"Team,Status\"\n\n==== Create an agenda\nI assign
187
+ the topics I want to discuss in the meetings to the meetings with\n syctask schedule
188
+ -a \"A:1,3,6;B:3,5\"\n \n==== Start a task\nTo begin I start the first task in
189
+ the schedule with syctask start 0 (where 0 is the sequence of the planned tasks,
190
+ the ID is different e.g. 23)\n $ syctask start 0\n\n==== End a task\nTo end the
191
+ task I invoke \n $ syctask stop\nThis will stop the last started task\n\n====
192
+ Complete a task\nWhen the task is done I call \n $ syctask done 23\n\n===Attachements\n*
193
+ E-mails\nIf an e-mail creates a task I create a new task with syctask new title_of_task.\nThe
194
+ subject of the e-mail I prepend with the ID and move the e-mail to a\n<b>open topics</b>
195
+ directory.\n\n* Files\nIf I create files in the course of a task I create a folder
196
+ in the task\ndirectory with the ID and save the files in this directory. If there
197
+ is an\nexisting directory I link to the file from the ID directory\n\n==Supported
198
+ platform\nsyc-task has been tested with 1.9.3\n\n==Add TAB-completion to syctask\nTo
199
+ activate bash's TAB-completion following lines have to be added to ~/.bashrc\n\n
200
+ \ complete -F get_syctask_commands syctask\n\n function get_syctask_commands\n
201
+ \ {\n if [ -z $2 ] ; then\n COMPREPLY=(`syctask help -c`)\n else\n
202
+ \ COMPREPLY=(`syctask help -c $2`)\n fi\n }\n\nAfter ~/.bashrc has
203
+ been updated the shell session has to be restarted with\n $ source ~/.bashrc\n\nNow
204
+ syctask followed by TAB TAB will print\n\n $ syctask <TAB><TAB>\n delete done
205
+ list plan scan stop _doc help new prio schedule start update\n \nTo complete a command
206
+ we can type\n\n $ syctask sch<TAB>\n\nwhich will complete to\n\n $ syctask
207
+ schedule\n\n==Output to Printer\nTo print syctask's output to a printer pipe the
208
+ command to lpr\n\n $ syctask schedule | lpr\n\nThis will print the schedule to
209
+ the default printer. \n\nTo determine all available printer lpstat can be used with
210
+ the lpstat -a command\n\n $ lpstat -a\n Canon-LBP6650-3470 accepting requests
211
+ since Sat 16 Mar 2013 04:26:15 PM CET\n Dell-B1160w-Mono accepting requests since
212
+ Sat 16 Mar 2013 04:27:45 PM CET\n \nTo print to Dell-B1160w-Mono the following
213
+ command can be used\n\n $ syctask schedule | lpr -P Dell-B1160w-Mono\n\n==Notes\nWith
214
+ version 0.0.1 new, update, list and done is implemented.\nwith version 0.0.4 start,
215
+ stop, scan and prio is not implemented.\n\nThe test files live in the folder test
216
+ and start with test_.\n\nThere is a rake file available to run all tests\n\n $
217
+ rake test\n \n==License\nsyc-task is released under the {MIT License}[http://opensource.org/licenses/MIT]\n\n==Links\n*
218
+ [http://www.github.com/sugaryourcoffee/syc-task] - Source code on GitHub\n* [http://syc.dyndns.org/drupal/wiki/syc-task]
219
+ - Development notebook\n* [https://rubygems.org/gems/syc-backup] - RubyGems\n"
145
220
  email: pierre@sugaryourcoffee.de
146
221
  executables:
147
222
  - syctask
@@ -162,6 +237,10 @@ files:
162
237
  - lib/syctask/times.rb
163
238
  - lib/syctask/schedule.rb
164
239
  - lib/sycutil/console.rb
240
+ - lib/syctask/environment.rb
241
+ - lib/syctask/task_tracker.rb
242
+ - lib/syctime/time_util.rb
243
+ - lib/sycstring/string_util.rb
165
244
  - README.rdoc
166
245
  - syctask.rdoc
167
246
  homepage: http://syc.dyndns.org/drupal/syc-task