syc-task 0.3.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
- data/README.rdoc +73 -30
- data/bin/console_timer +1 -1
- data/bin/syctask +7 -38
- data/lib/syctask/environment.rb +157 -151
- data/lib/syctask/evaluator.rb +21 -1
- data/lib/syctask/scanner.rb +14 -4
- data/lib/syctask/schedule.rb +126 -118
- data/lib/syctask/settings.rb +6 -4
- data/lib/syctask/statistics.rb +6 -0
- data/lib/syctask/task.rb +91 -82
- data/lib/syctask/task_planner.rb +52 -16
- data/lib/syctask/task_scheduler.rb +3 -3
- data/lib/syctask/task_service.rb +13 -10
- data/lib/syctask/task_tracker.rb +12 -6
- data/lib/syctask/version.rb +2 -2
- data/lib/syctime/time_util.rb +62 -11
- data/lib/sycutil/console_timer.rb +5 -9
- metadata +198 -149
data/lib/syctask/task.rb
CHANGED
@@ -1,30 +1,28 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'rainbow'
|
3
3
|
require_relative 'evaluator'
|
4
|
-
require_relative 'environment
|
5
|
-
require_relative 'task_tracker
|
4
|
+
require_relative 'environment'
|
5
|
+
require_relative 'task_tracker'
|
6
6
|
|
7
7
|
# Syctask provides functions for managing tasks in a task list
|
8
8
|
module Syctask
|
9
|
-
|
10
9
|
# A Task is the basic element of the task list and holds all information
|
11
10
|
# about a task.
|
12
11
|
class Task
|
13
|
-
|
14
12
|
include Comparable
|
15
13
|
|
16
14
|
# The fields that can be set for a task
|
17
|
-
FIELDS = [
|
18
|
-
|
19
|
-
|
20
|
-
# Holds the options of the task.
|
15
|
+
FIELDS = %w[title description
|
16
|
+
follow_up due_date prio
|
17
|
+
note tags]
|
18
|
+
# Holds the options of the task.
|
21
19
|
# Options are
|
22
20
|
# * description - additional information about the task
|
23
21
|
# * follow_up - follow-up date of the task
|
24
22
|
# * due_date - due date of the task
|
25
23
|
# * prio - priority of the task
|
26
24
|
# * note - information about the progress or state of the task
|
27
|
-
# * tags - can be used to search for tasks that belong to a certain
|
25
|
+
# * tags - can be used to search for tasks that belong to a certain
|
28
26
|
# category
|
29
27
|
attr_accessor :options
|
30
28
|
# Title of the class
|
@@ -48,12 +46,14 @@ module Syctask
|
|
48
46
|
|
49
47
|
# Creates a new task. If the options contain a note than the current date
|
50
48
|
# and time is added.
|
51
|
-
def initialize(options={}, title, id)
|
52
|
-
@creation_date = Time.now.strftime(
|
49
|
+
def initialize(options = {}, title, id)
|
50
|
+
@creation_date = Time.now.strftime('%Y-%m-%d - %H:%M:%S')
|
53
51
|
@title = title
|
54
52
|
@options = options
|
55
|
-
@options[:note]
|
56
|
-
|
53
|
+
if @options[:note]
|
54
|
+
@options[:note] =
|
55
|
+
"#{@creation_date}\n#{@options[:note]}\n"
|
56
|
+
end
|
57
57
|
if @options[:follow_up] or @options[:due_date]
|
58
58
|
@duration = 2 * 15 * 60
|
59
59
|
@remaining = 2 * 15 * 60
|
@@ -63,14 +63,14 @@ module Syctask
|
|
63
63
|
end
|
64
64
|
@id = id
|
65
65
|
end
|
66
|
-
|
67
|
-
# Compares this task with another task regarding id and dir. If both are
|
66
|
+
|
67
|
+
# Compares this task with another task regarding id and dir. If both are
|
68
68
|
# equal true is returned otherwise false
|
69
69
|
def ==(other)
|
70
70
|
@id == other.id and @dir == other.dir
|
71
71
|
end
|
72
72
|
|
73
|
-
# Compares this Task to the other task and compares them regarding the ID
|
73
|
+
# Compares this Task to the other task and compares them regarding the ID
|
74
74
|
# and the dir. If ID is equal then dir is compared
|
75
75
|
def <=>(other)
|
76
76
|
id_compare = @id.to_i <=> other.id.to_i
|
@@ -84,7 +84,7 @@ module Syctask
|
|
84
84
|
# Updates the task with new values. Except for note and tags which are
|
85
85
|
# supplemented with the new values and not overridden.
|
86
86
|
def update(options)
|
87
|
-
@update_date = Time.now.strftime(
|
87
|
+
@update_date = Time.now.strftime('%Y-%m-%d - %H:%M:%S')
|
88
88
|
if options[:duration]
|
89
89
|
set_duration(options.delete(:duration).to_i * 15 * 60)
|
90
90
|
elsif options[:follow_up] or options[:due_date]
|
@@ -92,22 +92,22 @@ module Syctask
|
|
92
92
|
end
|
93
93
|
options.keys.each do |key|
|
94
94
|
new_value = options[key]
|
95
|
-
|
95
|
+
|
96
96
|
case key
|
97
97
|
when :note
|
98
98
|
new_value = "#{@update_date}\n#{new_value}\n#{@options[key]}"
|
99
99
|
when :tags
|
100
100
|
unless @options[key].nil?
|
101
|
-
if @options[key].include? new_value
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
101
|
+
new_value = if @options[key].include? new_value
|
102
|
+
@options[key]
|
103
|
+
else
|
104
|
+
"#{@options[key]},#{new_value}"
|
105
|
+
end
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
109
|
@options[key] = new_value
|
110
|
-
end
|
110
|
+
end
|
111
111
|
end
|
112
112
|
|
113
113
|
# Checks whether this task has been updated. Returns true if updated
|
@@ -140,12 +140,10 @@ module Syctask
|
|
140
140
|
|
141
141
|
# Marks the task as done. When done than the done date is set. Optionally a
|
142
142
|
# note can be provided.
|
143
|
-
def done(note=
|
144
|
-
@done_date = Time.now.strftime(
|
145
|
-
if note
|
146
|
-
|
147
|
-
end
|
148
|
-
Syctask::log_task("done", self)
|
143
|
+
def done(note = '')
|
144
|
+
@done_date = Time.now.strftime('%Y-%m-%d - %H:%M:%S')
|
145
|
+
options[:note] = "#{@done_date}\n#{note}\n#{@options[:note]}" if note
|
146
|
+
Syctask.log_task('done', self)
|
149
147
|
end
|
150
148
|
|
151
149
|
# Checks if this task is done. Returns true if done otherwise false
|
@@ -157,9 +155,9 @@ module Syctask
|
|
157
155
|
# date is today otherwise false.
|
158
156
|
def today?
|
159
157
|
evaluator = Evaluator.new
|
160
|
-
today = Time.now.strftime(
|
158
|
+
today = Time.now.strftime('%Y-%m-%d')
|
161
159
|
evaluator.compare_dates(@options[:follow_up], today) or \
|
162
|
-
|
160
|
+
evaluator.compare_dates(@options[:due_date], today)
|
163
161
|
end
|
164
162
|
|
165
163
|
# Checks whether the task is currently tracked. Returns true if so otherwise
|
@@ -173,7 +171,7 @@ module Syctask
|
|
173
171
|
# Compares the provided elements in the filter with the correspondent
|
174
172
|
# elements in the task. When all comparissons match than true is returned.
|
175
173
|
# If one comparisson does not match false is returned. If filter is empty
|
176
|
-
# than true is returned. The values can be compared regarding <, =, > or
|
174
|
+
# than true is returned. The values can be compared regarding <, =, > or
|
177
175
|
# whether the task's value is part of a list of provided values. It is also
|
178
176
|
# possible to provide a regex as a filter. Following comparissons are
|
179
177
|
# available
|
@@ -187,6 +185,7 @@ module Syctask
|
|
187
185
|
# :due <|=|>
|
188
186
|
def matches?(filter = {})
|
189
187
|
return true if filter.empty?
|
188
|
+
|
190
189
|
evaluator = Evaluator.new
|
191
190
|
filter.each do |key, value|
|
192
191
|
matches = false
|
@@ -195,8 +194,8 @@ module Syctask
|
|
195
194
|
matches = evaluator.matches?(@title, value)
|
196
195
|
when :description
|
197
196
|
matches = evaluator.matches?(@options[:description], value)
|
198
|
-
when :id, :i,
|
199
|
-
matches = (evaluator.includes?(@id, value) or
|
197
|
+
when :id, :i, 'id', 'i'
|
198
|
+
matches = (evaluator.includes?(@id, value) or
|
200
199
|
evaluator.compare_numbers(@id, value))
|
201
200
|
when :prio, :p
|
202
201
|
matches = (evaluator.includes?(@options[:prio], value) or
|
@@ -213,7 +212,7 @@ module Syctask
|
|
213
212
|
|
214
213
|
# Prints the task in a formatted way eather all values when long is true
|
215
214
|
# or only id, title, prio, follow-up and due date.
|
216
|
-
def print_pretty(long=false)
|
215
|
+
def print_pretty(long = false)
|
217
216
|
pretty_string(long)
|
218
217
|
end
|
219
218
|
|
@@ -235,12 +234,12 @@ module Syctask
|
|
235
234
|
def create_task_id
|
236
235
|
tasks = dir.glob("#{@dir}/*")
|
237
236
|
ids = []
|
238
|
-
tasks.each {|task| ids << task.scan(/^\d+(?=\.task)/)[0].to_i }
|
239
|
-
if ids.empty?
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
237
|
+
tasks.each { |task| ids << task.scan(/^\d+(?=\.task)/)[0].to_i }
|
238
|
+
@id = if ids.empty?
|
239
|
+
1
|
240
|
+
else
|
241
|
+
ids[ids.size - 1] + 1
|
242
|
+
end
|
244
243
|
end
|
245
244
|
|
246
245
|
# Prints the task formatted. Values that are nil are not printed. A type all
|
@@ -248,41 +247,53 @@ module Syctask
|
|
248
247
|
# prio, follow-up and due date are printed.
|
249
248
|
def pretty_string(long)
|
250
249
|
color = :default
|
251
|
-
color = :green if
|
252
|
-
|
250
|
+
color = :green if done?
|
251
|
+
|
253
252
|
title = split_lines(@title, 70)
|
254
|
-
title = title.chomp.gsub(/\n/, "\n#{' '*7}")
|
255
|
-
title <<
|
256
|
-
puts
|
253
|
+
title = title.chomp.gsub(/\n/, "\n#{' ' * 7}")
|
254
|
+
title << '>' unless options[:note].nil?
|
255
|
+
puts format('%04d - %s', @id, title.bright).color(color)
|
257
256
|
|
258
257
|
if @options[:description]
|
259
258
|
description = split_lines(@options[:description].chomp, 70)
|
260
|
-
description = description.chomp.gsub(/\n/, "\n#{' '*7}")
|
261
|
-
puts
|
259
|
+
description = description.chomp.gsub(/\n/, "\n#{' ' * 7}")
|
260
|
+
puts format('%6s %s', ' ', description.chomp).color(color)
|
262
261
|
end
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
puts
|
284
|
-
|
262
|
+
if @options[:prio]
|
263
|
+
puts format('%6s Prio: %s', ' ', @options[:prio])
|
264
|
+
.color(color)
|
265
|
+
end
|
266
|
+
if @options[:follow_up]
|
267
|
+
puts format('%6s Follow-up: %s', ' ', @options[:follow_up])
|
268
|
+
.color(color)
|
269
|
+
end
|
270
|
+
if @options[:due_date]
|
271
|
+
puts format('%6s Due: %s', ' ', @options[:due_date])
|
272
|
+
.color(color)
|
273
|
+
end
|
274
|
+
return unless long
|
275
|
+
|
276
|
+
if @options[:note]
|
277
|
+
note = split_lines(@options[:note].chomp, 70)
|
278
|
+
note = note.chomp
|
279
|
+
.gsub(/\n(?!\d{4}-\d{2}-\d{2} - \d{2}:\d{2}:\d{2})/, "\n#{' ' * 9}")
|
280
|
+
note = note
|
281
|
+
.gsub(/\n(?=\d{4}-\d{2}-\d{2} - \d{2}:\d{2}:\d{2})/, "\n#{' ' * 7}")
|
282
|
+
puts format('%6s %s', ' ', note.chomp).color(color)
|
283
|
+
end
|
284
|
+
if @options[:tags]
|
285
|
+
puts format('%6s Tags: %s', ' ', @options[:tags])
|
286
|
+
.color(color)
|
287
|
+
end
|
288
|
+
puts format('%6s Created: %s', ' ', @creation_date).color(color)
|
289
|
+
if @update_date
|
290
|
+
puts format('%6s Updated: %s', ' ', @update_date)
|
291
|
+
.color(color)
|
285
292
|
end
|
293
|
+
return unless @done_date
|
294
|
+
|
295
|
+
puts format('%6s Closed: %s', ' ', @done_date)
|
296
|
+
.color(color)
|
286
297
|
end
|
287
298
|
|
288
299
|
# Prints all values as a csv separated with ";". This string can be read by
|
@@ -293,22 +304,22 @@ module Syctask
|
|
293
304
|
string = "#{@id};#{@title};"
|
294
305
|
string += "#{@options[:description]};#{@options[:prio]};"
|
295
306
|
string += "#{@options[:follow_up]};#{@options[:due_date]};"
|
296
|
-
string += "#{@options[:note] ? @options[:note].gsub(/\n/, '\\n') :
|
307
|
+
string += "#{@options[:note] ? @options[:note].gsub(/\n/, '\\n') : ''};"
|
297
308
|
string += "#{@options[:tags]};"
|
298
309
|
string += "#{@creation_date};"
|
299
|
-
string += "#{@udpate_date ?
|
300
|
-
string += "#{@done_date ?
|
310
|
+
string += "#{@udpate_date ? 'UPDATED' : 'UNCHANGED'};"
|
311
|
+
string += "#{@done_date ? 'DONE' : 'OPEN'}"
|
301
312
|
string
|
302
313
|
end
|
303
314
|
|
304
315
|
# Splits a string to size (chars) less or equal to length
|
305
316
|
def split_lines(string, length)
|
306
|
-
lines = string.squeeze(
|
317
|
+
lines = string.squeeze(' ').split("\n")
|
307
318
|
i = 0
|
308
319
|
new_lines = []
|
309
|
-
new_lines[i] =
|
320
|
+
new_lines[i] = ''
|
310
321
|
lines.each do |line|
|
311
|
-
line.squeeze(
|
322
|
+
line.squeeze(' ').split.each do |w|
|
312
323
|
if new_lines[i].length + w.length < length
|
313
324
|
new_lines[i] += "#{w} "
|
314
325
|
else
|
@@ -317,13 +328,11 @@ module Syctask
|
|
317
328
|
end
|
318
329
|
end
|
319
330
|
i += 1
|
320
|
-
new_lines[i] =
|
331
|
+
new_lines[i] = ''
|
321
332
|
end
|
322
|
-
text =
|
323
|
-
new_lines.each {|l| text << "#{l}\n"}
|
333
|
+
text = ''
|
334
|
+
new_lines.each { |l| text << "#{l}\n" }
|
324
335
|
text.chomp
|
325
336
|
end
|
326
|
-
|
327
337
|
end
|
328
|
-
|
329
338
|
end
|
data/lib/syctask/task_planner.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'rainbow'
|
3
3
|
require_relative '../sycutil/console.rb'
|
4
|
+
require_relative '../syctime/time_util.rb'
|
4
5
|
require_relative 'task_service.rb'
|
5
6
|
require_relative 'environment.rb'
|
6
7
|
|
@@ -8,8 +9,8 @@ module Syctask
|
|
8
9
|
# String that is prompted during planning
|
9
10
|
PROMPT_STRING = '(a)dd, (c)omplete, (s)kip, (q)uit: '
|
10
11
|
# String that is prompted during inspect
|
11
|
-
INSPECT_STRING = '(e)dit, (d)one, de(l)ete, (p)lan, (
|
12
|
-
'(q)uit: '
|
12
|
+
INSPECT_STRING = '(e)dit, (d)one, de(l)ete, (p)lan, da(t)e, (c)omplete, '+
|
13
|
+
'(s)kip, (b)ack, (q)uit: '
|
13
14
|
# String that is prompted during prioritization
|
14
15
|
PRIORITIZE_STRING = 'Task 1 has (h)igher or (l)ower priority, or (q)uit: '
|
15
16
|
|
@@ -31,12 +32,12 @@ module Syctask
|
|
31
32
|
# duration will be set to 30 minutes which equals two time chunks. The
|
32
33
|
# count of planned tasks is returned
|
33
34
|
def plan_tasks(tasks, date=Time.now.strftime("%Y-%m-%d"))
|
34
|
-
|
35
|
+
already_planned_tasks = self.get_tasks(date)
|
36
|
+
tasks = tasks.delete_if { |t| already_planned_tasks.include?(t) }
|
35
37
|
count = 0
|
36
38
|
re_display = false
|
37
39
|
planned = []
|
38
40
|
tasks.each do |task|
|
39
|
-
next if already_planned.find_index {|t| t == task}
|
40
41
|
unless re_display
|
41
42
|
task.print_pretty
|
42
43
|
else
|
@@ -72,12 +73,14 @@ module Syctask
|
|
72
73
|
|
73
74
|
# Inspect allows to edit, delete and mark tasks as done
|
74
75
|
def inspect_tasks(tasks, date=Time.now.strftime("%Y-%m-%d"))
|
75
|
-
|
76
|
+
already_planned_tasks = self.get_tasks(date)
|
77
|
+
tasks = tasks.delete_if { |t| already_planned_tasks.include?(t) }
|
76
78
|
count = 0
|
77
79
|
re_display = false
|
78
80
|
planned = []
|
79
|
-
|
80
|
-
|
81
|
+
index = 0
|
82
|
+
while index < tasks.length
|
83
|
+
task = tasks[index]
|
81
84
|
unless re_display
|
82
85
|
task.print_pretty
|
83
86
|
else
|
@@ -88,21 +91,28 @@ module Syctask
|
|
88
91
|
case choice
|
89
92
|
when 'e'
|
90
93
|
task_file = "#{task.dir}/#{task.id}.task"
|
91
|
-
system "vi #{task_file}" if File.
|
94
|
+
system "vi #{task_file}" if File.exist? task_file
|
95
|
+
tasks[index] = @service.read(task.dir, task.id)
|
92
96
|
redo
|
93
97
|
when 'd'
|
94
98
|
puts "Enter a note or hit <RETURN>"
|
95
99
|
note = gets.chomp
|
96
100
|
task.done(note)
|
97
101
|
@service.save(task.dir, task)
|
102
|
+
tasks.delete(task)
|
98
103
|
STDOUT.puts sprintf("--> Marked task %d as done",
|
99
104
|
task.id).color(:green)
|
100
105
|
when 'l'
|
101
106
|
print "Confirm delete task (Y/n)? "
|
102
107
|
answer = gets.chomp
|
103
|
-
|
104
|
-
|
105
|
-
|
108
|
+
del = @service.delete(task.dir, {id: task.id.to_s}) if answer == "Y"
|
109
|
+
if del.nil? or del == 0
|
110
|
+
puts sprintf("--> Task not deleted").color(:green)
|
111
|
+
elsif del > 0
|
112
|
+
tasks.delete(task)
|
113
|
+
puts sprintf("--> Deleted %d task%s",
|
114
|
+
del, del == 1 ? "" : "s").color(:green)
|
115
|
+
end
|
106
116
|
when 'p'
|
107
117
|
duration = 0
|
108
118
|
until duration > 0
|
@@ -114,12 +124,38 @@ module Syctask
|
|
114
124
|
task.options[:follow_up] = date
|
115
125
|
@service.save(task.dir, task)
|
116
126
|
planned << task
|
127
|
+
tasks.delete(task)
|
117
128
|
count += 1
|
129
|
+
when 't'
|
130
|
+
begin
|
131
|
+
print "Date (yyyy-mm-dd or 'time distance', e.g. tom, i2d, nfr): "
|
132
|
+
specific_date = gets.chomp
|
133
|
+
end until valid_date?(specific_date)
|
134
|
+
|
135
|
+
duration = 0
|
136
|
+
until duration > 0
|
137
|
+
print "Duration (1 = 15 minutes, RETURN defaults to 30 minutes): "
|
138
|
+
answer = gets.chomp
|
139
|
+
duration = answer.empty? ? 2 : answer.to_i
|
140
|
+
end
|
141
|
+
|
142
|
+
task.set_duration(units_to_time(duration))
|
143
|
+
task.options[:follow_up] = extract_time(specific_date)
|
144
|
+
@service.save(task.dir, task)
|
145
|
+
if task.options[:follow_up] == date
|
146
|
+
planned << task
|
147
|
+
tasks.delete(task)
|
148
|
+
count += 1
|
149
|
+
else
|
150
|
+
index += 1
|
151
|
+
end
|
118
152
|
when 'c'
|
119
153
|
re_display = true
|
120
154
|
redo
|
155
|
+
when 'b'
|
156
|
+
index -= 1 if index > 0
|
121
157
|
when 's'
|
122
|
-
|
158
|
+
index += 1
|
123
159
|
when 'q'
|
124
160
|
break
|
125
161
|
end
|
@@ -239,7 +275,7 @@ module Syctask
|
|
239
275
|
task = @service.read(dir, id)
|
240
276
|
tasks << task if not task.nil? and task.matches?(filter)
|
241
277
|
end
|
242
|
-
end if File.
|
278
|
+
end if File.exist? @todo_today_file
|
243
279
|
tasks
|
244
280
|
end
|
245
281
|
|
@@ -257,11 +293,11 @@ module Syctask
|
|
257
293
|
@todo_today_file = WORK_DIR+"/"+file_name
|
258
294
|
end
|
259
295
|
|
260
|
-
# Save the tasks to
|
261
|
-
# otherwise the tasks are appended
|
296
|
+
# Save the tasks to the todo_today_file. If override is true the file is
|
297
|
+
# overriden otherwise the tasks are appended
|
262
298
|
def save_tasks(tasks, override=false)
|
263
299
|
mode = override ? 'w' : 'a'
|
264
|
-
FileUtils.mkdir_p WORK_DIR unless File.
|
300
|
+
FileUtils.mkdir_p WORK_DIR unless File.exist? WORK_DIR
|
265
301
|
File.open(@todo_today_file, mode) do |file|
|
266
302
|
tasks.each do |task|
|
267
303
|
file.puts("#{task.dir},#{task.id}")
|
@@ -153,7 +153,7 @@ module Syctask
|
|
153
153
|
busy_time: busy_time,
|
154
154
|
meetings: meetings,
|
155
155
|
assignments: assignments}
|
156
|
-
FileUtils.mkdir WORK_DIR unless File.
|
156
|
+
FileUtils.mkdir WORK_DIR unless File.exist? WORK_DIR
|
157
157
|
state_file = WORK_DIR+'/'+Time.now.strftime("%Y-%m-%d_time_schedule")
|
158
158
|
File.open(state_file, 'w') do |file|
|
159
159
|
YAML.dump(state, file)
|
@@ -164,8 +164,8 @@ module Syctask
|
|
164
164
|
# time, meetings and assignments
|
165
165
|
def restore_state
|
166
166
|
state_file = WORK_DIR+'/'+Time.now.strftime("%Y-%m-%d_time_schedule")
|
167
|
-
return [[], [], [], []] unless File.
|
168
|
-
state = YAML.
|
167
|
+
return [[], [], [], []] unless File.exist? state_file
|
168
|
+
state = YAML.safe_load_file(state_file, permitted_classes: [Syctask::Task, Symbol])
|
169
169
|
if state
|
170
170
|
[state[:work_time],
|
171
171
|
state[:busy_time],
|
data/lib/syctask/task_service.rb
CHANGED
@@ -37,7 +37,7 @@ module Syctask
|
|
37
37
|
return task unless task.nil?
|
38
38
|
#task = nil
|
39
39
|
Dir.glob("#{dir}/*.task").each do |file|
|
40
|
-
task = YAML.
|
40
|
+
task = YAML.safe_load_file(file, permitted_classes: [Syctask::Task, Symbol]) if File.file? file
|
41
41
|
if not task.nil? and task.class == Syctask::Task and task.id == id.to_i
|
42
42
|
return task
|
43
43
|
end
|
@@ -46,12 +46,15 @@ module Syctask
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# Reads the task identified by ID. If no task with ID is found nil is
|
49
|
-
# returned otherwise the task
|
49
|
+
# returned otherwise the task.
|
50
|
+
# Note: This method might return nil even though the task exists. You should
|
51
|
+
# always use #read instead.
|
50
52
|
def read_by_id(id)
|
51
|
-
return nil unless File.
|
53
|
+
return nil unless File.exist? Syctask::IDS
|
52
54
|
ids = File.read(Syctask::IDS)
|
53
55
|
entry = ids.scan(/(^#{id}),(.*\n)/)[0]
|
54
|
-
return YAML.
|
56
|
+
return YAML.safe_load_file(entry[1].chomp,
|
57
|
+
permitted_classes: [Syctask::Task, Symbol]) if entry
|
55
58
|
return nil
|
56
59
|
end
|
57
60
|
|
@@ -69,7 +72,7 @@ module Syctask
|
|
69
72
|
tasks = []
|
70
73
|
Dir.glob("#{dir}/*.task").sort.each do |file|
|
71
74
|
begin
|
72
|
-
File.file?(file) ? task = YAML.
|
75
|
+
File.file?(file) ? task = YAML.safe_load_file(file, permitted_classes: [Syctask::Task, Symbol]) : next
|
73
76
|
rescue Exception => e
|
74
77
|
next # If the file is no task but read by YAML ignore it
|
75
78
|
end
|
@@ -96,7 +99,7 @@ module Syctask
|
|
96
99
|
task = read_by_id(id)
|
97
100
|
unless task
|
98
101
|
task_file = Dir.glob("#{dir}/#{id}.task")[0]
|
99
|
-
task = YAML.
|
102
|
+
task = YAML.safe_load_file(task_file, permitted_classes: [Syctask::Task, Symbol]) if task_file
|
100
103
|
end
|
101
104
|
updated = false
|
102
105
|
if task
|
@@ -115,7 +118,7 @@ module Syctask
|
|
115
118
|
deleted = 0
|
116
119
|
Dir.glob("#{dir}/*.task").each do |file|
|
117
120
|
begin
|
118
|
-
File.file?(file) ? task = YAML.
|
121
|
+
File.file?(file) ? task = YAML.safe_load_file(file, permitted_classes: [Syctask::Task, Symbol]) : next
|
119
122
|
rescue Exception => e
|
120
123
|
next # If the file is no task but read by YAML ignore it
|
121
124
|
end
|
@@ -135,7 +138,7 @@ module Syctask
|
|
135
138
|
def save(dir, task)
|
136
139
|
task.dir = dir.nil? ? DEFAULT_DIR : File.expand_path(dir)
|
137
140
|
task_file = "#{task.dir}/#{task.id}.task"
|
138
|
-
unless File.
|
141
|
+
unless File.exist? task_file
|
139
142
|
File.open(Syctask::IDS, 'a') {|f| f.puts "#{task.id},#{task_file}"}
|
140
143
|
end
|
141
144
|
File.open(task_file, 'w') {|f| YAML.dump(task, f)}
|
@@ -145,7 +148,7 @@ module Syctask
|
|
145
148
|
|
146
149
|
# Creates the task directory if it does not exist
|
147
150
|
def create_dir(dir)
|
148
|
-
FileUtils.mkdir_p dir unless File.
|
151
|
+
FileUtils.mkdir_p dir unless File.exist? dir
|
149
152
|
end
|
150
153
|
|
151
154
|
# Checks for the next possible task's ID based on the tasks available in
|
@@ -167,7 +170,7 @@ module Syctask
|
|
167
170
|
# the next ID.
|
168
171
|
def next_id(dir)
|
169
172
|
local = local_id(dir)
|
170
|
-
id = File.readlines(Syctask::ID)[0] if File.
|
173
|
+
id = File.readlines(Syctask::ID)[0] if File.exist? Syctask::ID
|
171
174
|
id = id ? id.to_i + 1 : 1
|
172
175
|
STDERR.puts "Warning: global id < local id" if id < local
|
173
176
|
id = [id, local].max
|
data/lib/syctask/task_tracker.rb
CHANGED
@@ -2,7 +2,7 @@ require 'yaml'
|
|
2
2
|
require 'fileutils'
|
3
3
|
require_relative 'environment.rb'
|
4
4
|
require_relative 'task_service.rb'
|
5
|
-
#require_relative '../sycutil/console_timer.rb'
|
5
|
+
# require_relative '../sycutil/console_timer.rb'
|
6
6
|
|
7
7
|
module Syctask
|
8
8
|
|
@@ -86,7 +86,7 @@ module Syctask
|
|
86
86
|
|
87
87
|
# Saves the tracks to the tracked tasks file
|
88
88
|
def save_tracks
|
89
|
-
FileUtils.mkdir_p WORK_DIR unless File.
|
89
|
+
FileUtils.mkdir_p WORK_DIR unless File.exist? WORK_DIR
|
90
90
|
File.open(TRACKED_TASKS_FILE, 'w') do |file|
|
91
91
|
YAML.dump(@tracks, file)
|
92
92
|
end
|
@@ -96,21 +96,27 @@ module Syctask
|
|
96
96
|
# @tracks. If no tracked tasks exist @tracks and @tasks will be
|
97
97
|
# empty
|
98
98
|
def load_tracks
|
99
|
-
unless File.
|
99
|
+
unless File.exist? TRACKED_TASKS_FILE
|
100
100
|
@tracks = []
|
101
101
|
@tasks = []
|
102
102
|
else
|
103
|
-
@tracks ||= YAML.
|
103
|
+
@tracks ||= YAML.safe_load_file(TRACKED_TASKS_FILE,
|
104
|
+
permitted_classes: [Syctask::Task,
|
105
|
+
Syctask::Track,
|
106
|
+
Time,
|
107
|
+
Symbol])
|
104
108
|
@tasks = []
|
105
109
|
if @tracks
|
106
110
|
@tracks.each { |track| @tasks << @service.read(track.dir, track.id) }
|
111
|
+
else
|
112
|
+
@tracks = []
|
107
113
|
end
|
108
114
|
end
|
109
115
|
end
|
110
116
|
|
111
117
|
# Logs the start and stop of a task.
|
112
118
|
def log_task(type, track)
|
113
|
-
FileUtils.mkdir_r Syctask::WORK_DIR unless File.
|
119
|
+
FileUtils.mkdir_r Syctask::WORK_DIR unless File.exist? Syctask::WORK_DIR
|
114
120
|
File.open(TASK_LOG_FILE, 'a') do |file|
|
115
121
|
log_entry = "#{type.to_s};"
|
116
122
|
log_entry += "#{track.id};#{track.dir};"
|
@@ -159,7 +165,7 @@ module Syctask
|
|
159
165
|
|
160
166
|
# Stops the task tracking and returns the lead time of the task
|
161
167
|
def stop
|
162
|
-
FileUtils.rm @semaphore if @semaphore and File.
|
168
|
+
FileUtils.rm @semaphore if @semaphore and File.exist? @semaphore
|
163
169
|
@stopped ||= Time.now
|
164
170
|
@stopped - @started
|
165
171
|
end
|
data/lib/syctask/version.rb
CHANGED