syc-task 0.0.7 → 0.1.15
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.
- data/README.rdoc +159 -15
- data/bin/console_timer +75 -0
- data/bin/syctask +246 -68
- data/lib/syctask.rb +4 -1
- data/lib/syctask/environment.rb +427 -2
- data/lib/syctask/schedule.rb +84 -21
- data/lib/syctask/settings.rb +43 -0
- data/lib/syctask/statistics.rb +196 -0
- data/lib/syctask/task.rb +58 -2
- data/lib/syctask/task_planner.rb +94 -13
- data/lib/syctask/task_scheduler.rb +5 -1
- data/lib/syctask/task_service.rb +55 -15
- data/lib/syctask/task_tracker.rb +27 -17
- data/lib/syctask/times.rb +29 -0
- data/lib/syctask/version.rb +1 -1
- data/lib/syctime/time_util.rb +46 -7
- data/lib/sycutil/console_timer.rb +75 -0
- metadata +215 -136
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'schedule.rb'
|
2
|
+
require_relative 'environment.rb'
|
2
3
|
|
3
4
|
module Syctask
|
4
5
|
|
@@ -37,7 +38,7 @@ module Syctask
|
|
37
38
|
ASSIGNMENT_PATTERN = /([a-zA-Z]):(\d+(?:,\d+|\d+;)*)/
|
38
39
|
|
39
40
|
# Working directory
|
40
|
-
WORK_DIR = File.expand_path("~/.tasks")
|
41
|
+
WORK_DIR = Syctask::SYC_DIR #File.expand_path("~/.tasks")
|
41
42
|
|
42
43
|
# Creates a new TaskScheduler.
|
43
44
|
def initialize
|
@@ -54,6 +55,7 @@ module Syctask
|
|
54
55
|
unless sequential?(@work_time)
|
55
56
|
raise Exception, "Begin time has to be before end time"
|
56
57
|
end
|
58
|
+
Syctask::log_work_time("work", @work_time)
|
57
59
|
end
|
58
60
|
|
59
61
|
# Set the busy times. Raises an exception if one begin time is after start
|
@@ -66,12 +68,14 @@ module Syctask
|
|
66
68
|
raise Exception, "Begin time has to be before end time"
|
67
69
|
end
|
68
70
|
end
|
71
|
+
Syctask::log_meetings("meeting", @busy_time, @meetings)
|
69
72
|
end
|
70
73
|
|
71
74
|
# Sets the titles of the meetings (busy times)
|
72
75
|
# Invokation: set_meeting_titles("title1,title2,title3")
|
73
76
|
def set_meeting_titles(titles)
|
74
77
|
@meetings = titles.split(",") if titles
|
78
|
+
Syctask::log_meetings("meeting", @busy_time, @meetings)
|
75
79
|
end
|
76
80
|
|
77
81
|
# Sets the tasks for scheduling
|
data/lib/syctask/task_service.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
require 'csv'
|
1
2
|
require 'yaml'
|
3
|
+
require_relative 'environment.rb'
|
2
4
|
|
3
5
|
# Syctask provides functions for managing tasks in a task list
|
4
6
|
module Syctask
|
@@ -8,7 +10,7 @@ module Syctask
|
|
8
10
|
class TaskService
|
9
11
|
# Default directory where the tasks are saved to if no directory is
|
10
12
|
# specified
|
11
|
-
DEFAULT_DIR = File.expand_path("~/.tasks")
|
13
|
+
DEFAULT_DIR = Syctask::WORK_DIR #File.expand_path("~/.tasks")
|
12
14
|
|
13
15
|
# Creates a new task in the specified directory, with the specified options
|
14
16
|
# and the specified title. If the directory doesn't exist it is created.
|
@@ -22,15 +24,18 @@ module Syctask
|
|
22
24
|
# * tags - can be used to searching tasks that belong to a certain category
|
23
25
|
def create(dir, options, title)
|
24
26
|
create_dir(dir)
|
25
|
-
task = Task.new(options, title,
|
27
|
+
task = Task.new(options, title, next_id(dir))
|
26
28
|
save(dir, task)
|
29
|
+
Syctask::log_task("create", task)
|
27
30
|
task.id
|
28
31
|
end
|
29
32
|
|
30
33
|
# Reads the task with given ID id located in given directory dir. If task
|
31
34
|
# does not exist nil is returned otherwise the task is returned
|
32
35
|
def read(dir, id)
|
33
|
-
task =
|
36
|
+
task = read_by_id(id)
|
37
|
+
return task unless task.nil?
|
38
|
+
#task = nil
|
34
39
|
Dir.glob("#{dir}/*.task").each do |file|
|
35
40
|
task = YAML.load_file(file) if File.file? file
|
36
41
|
if not task.nil? and task.class == Syctask::Task and task.id == id.to_i
|
@@ -40,6 +45,16 @@ module Syctask
|
|
40
45
|
nil
|
41
46
|
end
|
42
47
|
|
48
|
+
# Reads the task identified by ID. If no task with ID is found nil is
|
49
|
+
# returned otherwise the task
|
50
|
+
def read_by_id(id)
|
51
|
+
return nil unless File.exists? Syctask::IDS
|
52
|
+
ids = File.read(Syctask::IDS)
|
53
|
+
entry = ids.scan(/(^#{id}),(.*\n)/)[0]
|
54
|
+
return YAML.load_file(entry[1].chomp) if entry
|
55
|
+
return nil
|
56
|
+
end
|
57
|
+
|
43
58
|
# Finds all tasks that match the given filter. The filter can be provided
|
44
59
|
# for :id, :title, :description, :follow_up, :due, :tags and :prio.
|
45
60
|
# id can be eather a selection of IDs ID1,ID2,ID3 or a comparison <|=|>ID.
|
@@ -52,7 +67,7 @@ module Syctask
|
|
52
67
|
# open tasks
|
53
68
|
def find(dir, filter={}, all=true)
|
54
69
|
tasks = []
|
55
|
-
Dir.glob("#{dir}
|
70
|
+
Dir.glob("#{dir}/*.task").sort.each do |file|
|
56
71
|
begin
|
57
72
|
File.file?(file) ? task = YAML.load_file(file) : next
|
58
73
|
rescue Exception => e
|
@@ -78,12 +93,16 @@ module Syctask
|
|
78
93
|
# new value. If note and tags are provided these are added to the existing
|
79
94
|
# values.
|
80
95
|
def update(dir, id, options)
|
81
|
-
|
82
|
-
task
|
96
|
+
task = read_by_id(id)
|
97
|
+
unless task
|
98
|
+
task_file = Dir.glob("#{dir}/#{id}.task")[0]
|
99
|
+
task = YAML.load_file(task_file) if task_file
|
100
|
+
end
|
83
101
|
updated = false
|
84
102
|
if task
|
85
103
|
task.update(options)
|
86
|
-
save(dir, task)
|
104
|
+
save(task.dir, task)
|
105
|
+
Syctask::log_task("update", task)
|
87
106
|
updated = true
|
88
107
|
end
|
89
108
|
updated
|
@@ -94,7 +113,7 @@ module Syctask
|
|
94
113
|
# returned
|
95
114
|
def delete(dir, filter)
|
96
115
|
deleted = 0
|
97
|
-
Dir.glob("#{dir}
|
116
|
+
Dir.glob("#{dir}/*.task").each do |file|
|
98
117
|
begin
|
99
118
|
File.file?(file) ? task = YAML.load_file(file) : next
|
100
119
|
rescue Exception => e
|
@@ -103,6 +122,9 @@ module Syctask
|
|
103
122
|
next unless not task.nil? and task.class == Syctask::Task
|
104
123
|
if task.matches?(filter)
|
105
124
|
deleted += File.delete(file)
|
125
|
+
ids = File.read(Syctask::IDS)
|
126
|
+
File.write(Syctask::IDS, ids.gsub("#{task.id},#{file}",""))
|
127
|
+
Syctask::log_task("delete", task)
|
106
128
|
end
|
107
129
|
end
|
108
130
|
deleted
|
@@ -112,7 +134,11 @@ module Syctask
|
|
112
134
|
# ~/.tasks will be set.
|
113
135
|
def save(dir, task)
|
114
136
|
task.dir = dir.nil? ? DEFAULT_DIR : File.expand_path(dir)
|
115
|
-
|
137
|
+
task_file = "#{task.dir}/#{task.id}.task"
|
138
|
+
unless File.exists? task_file
|
139
|
+
File.open(Syctask::IDS, 'a') {|f| f.puts "#{task.id},#{task_file}"}
|
140
|
+
end
|
141
|
+
File.open(task_file, 'w') {|f| YAML.dump(task, f)}
|
116
142
|
end
|
117
143
|
|
118
144
|
private
|
@@ -122,18 +148,32 @@ module Syctask
|
|
122
148
|
FileUtils.mkdir_p dir unless File.exists? dir
|
123
149
|
end
|
124
150
|
|
125
|
-
#
|
126
|
-
# The task's file name is in the form ID.task.
|
127
|
-
# the biggest number and adds one to
|
128
|
-
|
129
|
-
|
151
|
+
# Checks for the next possible task's ID based on the tasks available in
|
152
|
+
# the task directory. The task's file name is in the form ID.task.
|
153
|
+
# local_ID seeks for the biggest number and adds one to determine the
|
154
|
+
# next valid task ID.
|
155
|
+
def local_id(dir)
|
156
|
+
tasks = Dir.glob("#{dir}/*.task")
|
130
157
|
ids = []
|
131
158
|
tasks.each do |task|
|
132
159
|
id = File.basename(task).scan(/^\d+(?=\.task)/)[0]
|
133
160
|
ids << id.to_i if id
|
134
161
|
end
|
135
162
|
ids.empty? ? 1 : ids.sort[ids.size-1] + 1
|
136
|
-
|
163
|
+
end
|
164
|
+
|
165
|
+
# Retrieves a new unique ID for a task. If next id is less than the next
|
166
|
+
# ID in the directory a warning is printed and the higher ID is taken as
|
167
|
+
# the next ID.
|
168
|
+
def next_id(dir)
|
169
|
+
local = local_id(dir)
|
170
|
+
id = File.readlines(Syctask::ID)[0] if File.exists? Syctask::ID
|
171
|
+
id = id ? id.to_i + 1 : 1
|
172
|
+
STDERR.puts "Warning: global id < local id" if id < local
|
173
|
+
id = [id, local].max
|
174
|
+
File.open(Syctask::ID, 'w') {|f| f.puts id}
|
175
|
+
id
|
176
|
+
end
|
137
177
|
|
138
178
|
end
|
139
179
|
end
|
data/lib/syctask/task_tracker.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
1
3
|
require_relative 'environment.rb'
|
2
4
|
require_relative 'task_service.rb'
|
5
|
+
#require_relative '../sycutil/console_timer.rb'
|
3
6
|
|
4
7
|
module Syctask
|
5
8
|
|
@@ -14,9 +17,9 @@ module Syctask
|
|
14
17
|
class TaskTracker
|
15
18
|
|
16
19
|
# File name of the file where the tracked files are saved to
|
17
|
-
TRACKED_TASKS_FILE = Syctask::WORK_DIR + '/' + 'tracked_tasks'
|
20
|
+
TRACKED_TASKS_FILE = Syctask::TRACKED_TASK #Syctask::WORK_DIR + '/' + 'tracked_tasks'
|
18
21
|
# File name of the task log file
|
19
|
-
TASK_LOG_FILE = Syctask::WORK_DIR + '/' + 'tasks.log'
|
22
|
+
TASK_LOG_FILE = Syctask::TASKS_LOG #Syctask::WORK_DIR + '/' + 'tasks.log'
|
20
23
|
|
21
24
|
# Creates a new TaskTracker
|
22
25
|
def initialize
|
@@ -26,19 +29,22 @@ module Syctask
|
|
26
29
|
|
27
30
|
# When a task is started it is saved with the start time. If a task is
|
28
31
|
# already tracked it is stopped (see #stop). A started task will print
|
29
|
-
# every
|
32
|
+
# every second a message to the console if the show parameter is true.
|
30
33
|
# start returns
|
31
34
|
# * [false, nil ] if the task is already tracked
|
32
35
|
# * [true, nil ] if the task is started and no task was running.
|
33
36
|
# * [true, task] if task is started and the previously running task stopped
|
34
|
-
def start(task)
|
37
|
+
def start(task, show=true)
|
38
|
+
raise ArgumentError, "Error: Task without directory.\n"+
|
39
|
+
"--> Update task with syctask -t <dir> update "+
|
40
|
+
"#{task.id}" unless task.dir
|
35
41
|
index = @tasks.find_index(task)
|
36
42
|
return [false, nil] if not index.nil? and index == 0
|
37
43
|
|
38
44
|
stopped_task = stop
|
39
45
|
track = Track.new(task)
|
40
46
|
|
41
|
-
track.start
|
47
|
+
track.start(show)
|
42
48
|
log_task(:start, track)
|
43
49
|
|
44
50
|
@tracks.insert(0,track)
|
@@ -59,18 +65,15 @@ module Syctask
|
|
59
65
|
return nil unless @tasks[0]
|
60
66
|
|
61
67
|
task = @tasks[0]
|
62
|
-
|
63
|
-
task.lead_time += @tracks[0].stop
|
64
|
-
else
|
65
|
-
task.lead_time = @tracks[0].stop
|
66
|
-
end
|
67
|
-
|
68
|
+
task.update_lead_time(@tracks[0].stop)
|
68
69
|
@service.save(task.dir, task)
|
70
|
+
|
69
71
|
log_task(:stop, @tracks[0])
|
70
72
|
|
71
73
|
@tracks.delete_at(0)
|
72
74
|
@tasks.delete_at(0)
|
73
75
|
save_tracks
|
76
|
+
|
74
77
|
task
|
75
78
|
end
|
76
79
|
|
@@ -99,7 +102,9 @@ module Syctask
|
|
99
102
|
else
|
100
103
|
@tracks ||= YAML.load_file(TRACKED_TASKS_FILE)
|
101
104
|
@tasks = []
|
102
|
-
@tracks
|
105
|
+
if @tracks
|
106
|
+
@tracks.each { |track| @tasks << @service.read(track.dir, track.id) }
|
107
|
+
end
|
103
108
|
end
|
104
109
|
end
|
105
110
|
|
@@ -108,7 +113,7 @@ module Syctask
|
|
108
113
|
FileUtils.mkdir_r Syctask::WORK_DIR unless File.exists? Syctask::WORK_DIR
|
109
114
|
File.open(TASK_LOG_FILE, 'a') do |file|
|
110
115
|
log_entry = "#{type.to_s};"
|
111
|
-
log_entry += "#{track.id}
|
116
|
+
log_entry += "#{track.id};#{track.dir};"
|
112
117
|
log_entry += "#{track.title};"
|
113
118
|
log_entry += "#{track.started};"
|
114
119
|
log_entry += "#{track.stopped}"
|
@@ -119,7 +124,7 @@ module Syctask
|
|
119
124
|
end
|
120
125
|
|
121
126
|
# A Track holds a task and stops the time the task is processed. The Track
|
122
|
-
# will print every
|
127
|
+
# will print every second the elapsed time and the time left to the
|
123
128
|
# specified Task#duration.
|
124
129
|
class Track
|
125
130
|
|
@@ -139,17 +144,22 @@ module Syctask
|
|
139
144
|
@dir = task.dir
|
140
145
|
@id = task.id
|
141
146
|
@title = task.title
|
147
|
+
@duration = task.remaining.to_i
|
148
|
+
@semaphore = "#{Syctask::SYC_DIR}/#{@id}.track"
|
142
149
|
end
|
143
150
|
|
144
|
-
# Starts the tracking and a timer that will print to STDOUT every
|
151
|
+
# Starts the tracking and a timer that will print to STDOUT every second
|
145
152
|
# the elapsed time and the time left until Task#duration
|
146
|
-
def start
|
153
|
+
def start(show)
|
147
154
|
@started ||= Time.now
|
148
|
-
# start a timer that prints
|
155
|
+
# start a timer that prints id and elapsed time
|
156
|
+
FileUtils.touch @semaphore
|
157
|
+
system "console_timer #{@duration} #{@id} #{@semaphore} &" if show
|
149
158
|
end
|
150
159
|
|
151
160
|
# Stops the task tracking and returns the lead time of the task
|
152
161
|
def stop
|
162
|
+
FileUtils.rm @semaphore if @semaphore and File.exists? @semaphore
|
153
163
|
@stopped ||= Time.now
|
154
164
|
@stopped - @started
|
155
165
|
end
|
data/lib/syctask/times.rb
CHANGED
@@ -20,6 +20,35 @@ module Syctask
|
|
20
20
|
@m > 0 ? @h+1 : @h
|
21
21
|
end
|
22
22
|
|
23
|
+
# Returns a Time object with the current date and the hour and minute of
|
24
|
+
# this Times object
|
25
|
+
def time
|
26
|
+
now = Time.now
|
27
|
+
Time.local(now.year,now.mon,now.day,@h,@m,0)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Calculates the difference between this time and the provided time. If no
|
31
|
+
# time is given the current time is used.
|
32
|
+
# Example:
|
33
|
+
# This time = 9:35
|
34
|
+
# New time = 10:20
|
35
|
+
# diff(time) = 0:45
|
36
|
+
# Will return [hour,min] in the example [0,45]
|
37
|
+
def diff(time = Time.now)
|
38
|
+
diff_minutes = (time.hour - @h) * 60 + (time.min - @m)
|
39
|
+
signum = diff_minutes == 0 ? 0 : diff_minutes / diff_minutes.abs
|
40
|
+
diff_h = diff_minutes.abs / 60
|
41
|
+
diff_m = diff_minutes.abs % 60
|
42
|
+
if signum < 0
|
43
|
+
if diff_h > 0
|
44
|
+
[signum * diff_h, diff_m]
|
45
|
+
else
|
46
|
+
[diff_h, signum * diff_m]
|
47
|
+
end
|
48
|
+
else
|
49
|
+
[diff_h, diff_m]
|
50
|
+
end
|
51
|
+
end
|
23
52
|
end
|
24
53
|
|
25
54
|
end
|
data/lib/syctask/version.rb
CHANGED
data/lib/syctime/time_util.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
1
3
|
# Functions for time operations
|
2
4
|
module Syctime
|
3
5
|
|
@@ -6,13 +8,13 @@ module Syctime
|
|
6
8
|
def seconds_to_time(seconds)
|
7
9
|
seconds = seconds.round
|
8
10
|
duration = []
|
9
|
-
duration << seconds % 60
|
10
|
-
duration << seconds / 60 % 60
|
11
|
-
duration << seconds / 60 / 60 %
|
12
|
-
duration << seconds / 60 / 60 /
|
13
|
-
duration << seconds / 60 / 60 /
|
14
|
-
duration << seconds / 60 / 60 /
|
15
|
-
duration << seconds / 60 / 60 /
|
11
|
+
duration << seconds % 60 # seconds
|
12
|
+
duration << seconds / 60 % 60 # minutes
|
13
|
+
duration << seconds / 60 / 60 % 24 # hours
|
14
|
+
duration << seconds / 60 / 60 / 24 % 7 # days
|
15
|
+
duration << seconds / 60 / 60 / 24 / 7 % 4 # weeks
|
16
|
+
duration << seconds / 60 / 60 / 24 / 7 / 4 % 12 # months
|
17
|
+
duration << seconds / 60 / 60 / 24 / 7 / 4 / 12 # years
|
16
18
|
end
|
17
19
|
|
18
20
|
# Translates seconds into a time string like 1 year 2 weeks 5 days 10 minutes.
|
@@ -27,4 +29,41 @@ module Syctime
|
|
27
29
|
time_string
|
28
30
|
end
|
29
31
|
|
32
|
+
# Creates a time string separating hours, minutes and seconds with the
|
33
|
+
# provided separator like 12:50:33
|
34
|
+
def separated_time_string(seconds, separator)
|
35
|
+
secs = seconds % 60
|
36
|
+
mins = seconds / 60 % 60
|
37
|
+
hours = seconds / 60 / 60
|
38
|
+
time_string = sprintf("%02d#{separator}%02d#{separator}%02d", hours, mins, secs)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Translates a time in the ISO 8601 schema to a time object.
|
42
|
+
# 2013-04-09 21:45 -200
|
43
|
+
def time_for_string(time)
|
44
|
+
time = time.scan(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/)[0].sub(' ','T')
|
45
|
+
Time.xmlschema(time)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Tests whether the date is between from and to. Returns true then otherwise
|
49
|
+
# false. Time, from and to are Time objects as retrieved from Time.now or
|
50
|
+
# Time.local(2013,"apr",13,10,50,0). Alternatively time strings can be
|
51
|
+
# provided in the form of "2013-04-13".
|
52
|
+
def date_between?(date, from, to)
|
53
|
+
date = date.strftime("%Y-%m-%d") if date.class == Time
|
54
|
+
from = from.strftime("%Y-%m-%d") if from.class == Time
|
55
|
+
to = to.strftime("%Y-%m-%d") if to.class == Time
|
56
|
+
time_pattern = /\d{4}-\d{2}-\d{2}/
|
57
|
+
raise ArgumentError if date.scan(time_pattern).empty?
|
58
|
+
raise ArgumentError if from.scan(time_pattern).empty?
|
59
|
+
raise ArgumentError if to.scan(time_pattern).empty?
|
60
|
+
date >= from && date <= to
|
61
|
+
end
|
62
|
+
|
63
|
+
# Checks whether the time is between from and to. Returns true then otherwise
|
64
|
+
# false. time, from and to have to be Time objects.
|
65
|
+
def time_between?(time, from, to)
|
66
|
+
time >= from && time <= to
|
67
|
+
end
|
68
|
+
|
30
69
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'rainbow'
|
5
|
+
|
6
|
+
# ConsoleTimer prints a task and the lead time at the upper right corner of the
|
7
|
+
# schreen. Invokation example:
|
8
|
+
# * Create a semaphore like id.track
|
9
|
+
# * Console time in a new ruby process
|
10
|
+
# semaphore = File.expand_path("~/.syc/syctask/#{id}.track"
|
11
|
+
# FileUtils.touch semaphore
|
12
|
+
# system "ruby lib/sycutil/console_timer.rb 60 10 semaphore"
|
13
|
+
# This will start the ConsoleTimer with a lead time of 1 minute for task 10.
|
14
|
+
# To stop the timer the semaphore has to be deleted
|
15
|
+
# FileUtils.rm semaphore
|
16
|
+
class ConsoleTimer
|
17
|
+
|
18
|
+
# Create a new ConsoleTimer with the time to count down, the task's ID and a
|
19
|
+
# semaphore. The semaphore is a file named id.track where id is equal to the
|
20
|
+
# provided id. The semaphore is checked for existence. If the semaphore is
|
21
|
+
# deleted than ConsoleTimer is stopped.
|
22
|
+
def initialize(time, id, semaphore)
|
23
|
+
@time = time.to_i
|
24
|
+
@id = id
|
25
|
+
@start = Time.now
|
26
|
+
@semaphore = semaphore
|
27
|
+
end
|
28
|
+
|
29
|
+
# Starts the timer. The timer is run as long the semaphore is available
|
30
|
+
def start
|
31
|
+
track = true
|
32
|
+
while track
|
33
|
+
sleep 1
|
34
|
+
output
|
35
|
+
track = File.exists? @semaphore
|
36
|
+
end
|
37
|
+
exit 0
|
38
|
+
end
|
39
|
+
|
40
|
+
# Prints the id and the lead time of the currently tracked task. As long as
|
41
|
+
# the provided time is greater than 0 the time is printed in green, otherwise
|
42
|
+
# red
|
43
|
+
def output
|
44
|
+
color = :green
|
45
|
+
difference = @time - (Time.now - @start).round
|
46
|
+
if difference < 0
|
47
|
+
difference = difference.abs
|
48
|
+
color = :red
|
49
|
+
end
|
50
|
+
seconds = difference % 60
|
51
|
+
minutes = difference / 60 % 60
|
52
|
+
hours = difference / 60 / 60 % 60
|
53
|
+
count_down = sprintf("%d: %02d:%02d:%02d", @id, hours, minutes, seconds)
|
54
|
+
size = count_down.size
|
55
|
+
count_down = count_down.color(color)
|
56
|
+
command = "tput sc;"+
|
57
|
+
"tput cup 0 $(($(tput cols) - #{size}));"+
|
58
|
+
"echo #{count_down};tput rc"
|
59
|
+
system command
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
# Expects to receive parameters duration, id and semaphore
|
65
|
+
if ARGV.size == 3
|
66
|
+
duration = ARGV.shift
|
67
|
+
id = ARGV.shift
|
68
|
+
semaphore = ARGV.shift
|
69
|
+
timer = ConsoleTimer.new(duration, id, semaphore)
|
70
|
+
timer.start
|
71
|
+
else
|
72
|
+
exit -1
|
73
|
+
end
|
74
|
+
|
75
|
+
|