haora 0.0.6 → 0.1.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 +4 -4
- data/bin/haora +12 -4
- data/lib/haora/add_task.rb +21 -0
- data/lib/haora/command.rb +38 -0
- data/lib/haora/day.rb +74 -2
- data/lib/haora/finish.rb +21 -0
- data/lib/haora/list.rb +29 -0
- data/lib/haora/renderer.rb +42 -27
- data/lib/haora/task.rb +5 -0
- data/lib/haora/timestamp.rb +5 -1
- data/lib/haora/version.rb +1 -1
- data/lib/haora/week_renderer.rb +43 -0
- data/lib/haora.rb +25 -11
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b50be4b063db3e1bdda7a9319f174e9d65c049e
|
4
|
+
data.tar.gz: 38b6246c198ac1cb532ceb0b13ea1bd93eac779a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14d5b903d8cf19545c965b89bf0c55912f20db05a4d8434f7566469279c826c48b3a7815c3a2dc9eba0c130149b2537041c3cd57e30f316d443c5bdb57adc543
|
7
|
+
data.tar.gz: 9e17772fea15a6b217ccaebb29853229ee5850d4f2c09712115c2e2b6d8487688f7df18496bea8583cad8e0d90b21836faf540131dd4a4b9039e719a3d095f3b
|
data/bin/haora
CHANGED
@@ -32,7 +32,7 @@ command :add do |c|
|
|
32
32
|
:project => options[:project],
|
33
33
|
:text => args[0]
|
34
34
|
}
|
35
|
-
Haora::Service.for(file_name).add_task(params)
|
35
|
+
print Haora::Service.for(file_name).add_task(params)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -48,17 +48,25 @@ command :finish do |c|
|
|
48
48
|
:project => options[:project],
|
49
49
|
:text => args[0]
|
50
50
|
}
|
51
|
-
Haora::Service.for(file_name).finish(params)
|
51
|
+
print Haora::Service.for(file_name).finish(params)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
55
|
desc 'Lists tasks of a day'
|
56
56
|
command :list do |c|
|
57
|
+
c.switch :w, :week
|
57
58
|
c.action do |global_actions, options, args|
|
58
59
|
file_name = global_actions[:file]
|
59
|
-
|
60
|
-
|
60
|
+
params = {
|
61
|
+
:date => global_actions[:date],
|
62
|
+
:week => options[:week]
|
63
|
+
}
|
64
|
+
print Haora::Service.for(file_name).list(params)
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
68
|
+
def print(output)
|
69
|
+
puts output unless output.nil?
|
70
|
+
end
|
71
|
+
|
64
72
|
exit run(ARGV)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Haora
|
2
|
+
|
3
|
+
class AddTaskCommand < Command
|
4
|
+
|
5
|
+
def self.with(workbook)
|
6
|
+
AddTaskCommand.new(workbook)
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute
|
10
|
+
day(at: date) << Task.new(@params)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def initialize(workbook)
|
16
|
+
super(workbook)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Haora
|
2
|
+
|
3
|
+
class Command
|
4
|
+
|
5
|
+
def initialize(workbook)
|
6
|
+
@workbook = workbook
|
7
|
+
end
|
8
|
+
|
9
|
+
def params(params)
|
10
|
+
@params = params
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def day(date_params)
|
15
|
+
@workbook[date_params[:at]]
|
16
|
+
end
|
17
|
+
|
18
|
+
def week(date_params)
|
19
|
+
day = day(date_params)
|
20
|
+
date = day.date
|
21
|
+
[
|
22
|
+
day,
|
23
|
+
day(at: date.next_day(1)),
|
24
|
+
day(at: date.next_day(2)),
|
25
|
+
day(at: date.next_day(3)),
|
26
|
+
day(at: date.next_day(4)),
|
27
|
+
day(at: date.next_day(5)),
|
28
|
+
day(at: date.next_day(6)),
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
def date
|
33
|
+
@params[:date]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/haora/day.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
require 'date'
|
2
2
|
|
3
|
+
class Date
|
4
|
+
|
5
|
+
def prev_wday(wday)
|
6
|
+
before = self.prev_day
|
7
|
+
before.wday == wday ? before : before.prev_wday(wday)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
3
12
|
module Haora
|
4
13
|
|
5
14
|
class Day
|
@@ -14,11 +23,28 @@ module Haora
|
|
14
23
|
end
|
15
24
|
|
16
25
|
def hours
|
17
|
-
tasks
|
26
|
+
tasks
|
27
|
+
.collect { |t| t.duration }
|
18
28
|
.reduce { |acc, d| acc + d }
|
19
29
|
.hours
|
20
30
|
end
|
21
31
|
|
32
|
+
def project_names
|
33
|
+
tasks
|
34
|
+
.select { |t| not t.project.noname? }
|
35
|
+
.collect { |t| t.project.name }
|
36
|
+
.uniq
|
37
|
+
end
|
38
|
+
|
39
|
+
def duration(params = {})
|
40
|
+
if (project_name = params[:of_project])
|
41
|
+
selected_tasks = tasks.select { |t| t.project.name == project_name }
|
42
|
+
else
|
43
|
+
selected_tasks = tasks
|
44
|
+
end
|
45
|
+
selected_tasks.reduce(Duration.new) { |acc, t| acc = acc + t.duration }
|
46
|
+
end
|
47
|
+
|
22
48
|
def <<(task)
|
23
49
|
finish(stop: task.start) if tasks.last&.open?
|
24
50
|
tasks << task
|
@@ -70,7 +96,53 @@ module Haora
|
|
70
96
|
class DateParser
|
71
97
|
|
72
98
|
def self.parse(date)
|
73
|
-
|
99
|
+
begin
|
100
|
+
case date
|
101
|
+
when /m([0-9]+)/
|
102
|
+
Day.today.prev_day($1.to_i)
|
103
|
+
when /([0-9]?[0-9]).([0-9]?[0-9]).([0-9]?[0-9]?[0-9][0-9])/
|
104
|
+
return Date.new(year($3), mon($2), mday($1))
|
105
|
+
when /([0-9]?[0-9]).([0-9]?[0-9]).?/
|
106
|
+
return Date.new(year, mon($2), mday($1))
|
107
|
+
when /([0-9]?[0-9]).?/
|
108
|
+
return Date.new(year, mon, mday($1))
|
109
|
+
when /mon?/
|
110
|
+
return Day.today.prev_wday(1)
|
111
|
+
when /tue?/
|
112
|
+
return Day.today.prev_wday(2)
|
113
|
+
when /wed?/
|
114
|
+
return Day.today.prev_wday(3)
|
115
|
+
when /thu?/
|
116
|
+
return Day.today.prev_wday(4)
|
117
|
+
when /fri?/
|
118
|
+
return Day.today.prev_wday(5)
|
119
|
+
when /sat?/
|
120
|
+
return Day.today.prev_wday(6)
|
121
|
+
when /sun?/
|
122
|
+
return Day.today.prev_wday(0)
|
123
|
+
else
|
124
|
+
return Date.today
|
125
|
+
end
|
126
|
+
rescue => error
|
127
|
+
puts error
|
128
|
+
raise ArgumentError, 'invalid date'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def self.year(year_param = Day.today.year)
|
135
|
+
year = year_param.to_i
|
136
|
+
year = year + 2000 if year < 100 && year + 2000 <= Date.today.year
|
137
|
+
year
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.mon(mon_param = Day.today.mon)
|
141
|
+
mon_param.to_i
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.mday(mday_param = Day.today.mday)
|
145
|
+
mday_param.to_i
|
74
146
|
end
|
75
147
|
|
76
148
|
end
|
data/lib/haora/finish.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Haora
|
2
|
+
|
3
|
+
class FinishCommand < Command
|
4
|
+
|
5
|
+
def self.with(workbook)
|
6
|
+
FinishCommand.new(workbook)
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute
|
10
|
+
day(at: date).finish(@params)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def initialize(workbook)
|
16
|
+
super(workbook)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/lib/haora/list.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Haora
|
2
|
+
|
3
|
+
class ListCommand < Command
|
4
|
+
|
5
|
+
def self.with(workbook)
|
6
|
+
ListCommand.new(workbook)
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute
|
10
|
+
if week_display?
|
11
|
+
WeekRenderer.new.render(week(at: date))
|
12
|
+
else
|
13
|
+
DayRenderer.new.render(day(at: date))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def initialize(workbook)
|
20
|
+
super(workbook)
|
21
|
+
end
|
22
|
+
|
23
|
+
def week_display?
|
24
|
+
@params[:week]
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/haora/renderer.rb
CHANGED
@@ -1,54 +1,69 @@
|
|
1
1
|
module Haora
|
2
2
|
|
3
|
-
class
|
3
|
+
class Renderer
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def rendered_timespan(start, stop)
|
8
|
+
timespan = '%s - %s' % [start.to_s, stop.nil? ? ' now ' : stop.to_s]
|
9
|
+
timespan.prepend(' ') if timespan.length < 13
|
10
|
+
timespan
|
11
|
+
end
|
12
|
+
|
13
|
+
def rendered_duration(hours)
|
14
|
+
'%5.2f' % hours
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
class DayRenderer < Renderer
|
4
20
|
|
5
21
|
def render(day)
|
6
22
|
raise 'none' if day.tasks.empty?
|
7
|
-
|
8
|
-
<< rendered(day.tasks) << "\n" \
|
9
|
-
<< rendered_total(day)
|
23
|
+
%W(#{rendered_date_of(day)} #{rendered(day.tasks)} #{rendered_total(day)}).join($/)
|
10
24
|
end
|
11
25
|
|
12
26
|
private
|
13
27
|
|
14
28
|
def rendered_date_of(day)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
day.date.strftime('%d.%m.%Y')
|
19
|
-
end
|
29
|
+
date = day.date.strftime('%a %d.%m.%Y')
|
30
|
+
date << ' (today)' if day.date == Day.today
|
31
|
+
date
|
20
32
|
end
|
21
33
|
|
22
34
|
def rendered(tasks)
|
23
|
-
tasks.map { |task| rendered_task(task) }.join(
|
35
|
+
tasks.map { |task| rendered_task(task, tasks[tasks.index(task) + 1]) }.join($/)
|
24
36
|
end
|
25
37
|
|
26
38
|
def rendered_total(day)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
39
|
+
day.project_names
|
40
|
+
.collect { |name| rendered_project_total(name, day.duration(of_project: name)) }
|
41
|
+
.push(' Total = %5.2f' % day.hours)
|
42
|
+
.join($/)
|
32
43
|
end
|
33
44
|
|
34
|
-
def
|
45
|
+
def rendered_project_total(name, duration)
|
46
|
+
total = '%s =' % name[0..12]
|
47
|
+
'%s %5.2f' % [total.rjust(15), duration.hours]
|
48
|
+
end
|
49
|
+
|
50
|
+
def rendered_task(task, next_task)
|
35
51
|
timespan = rendered_timespan(task.start, task.stop)
|
36
|
-
duration = rendered_duration(task)
|
52
|
+
duration = rendered_duration(task.duration.hours)
|
37
53
|
if task.project.noname?
|
38
|
-
'%s = %s %s' % [timespan, duration, task.text]
|
54
|
+
output = '%s = %s %s' % [timespan, duration, task.text]
|
39
55
|
else
|
40
|
-
'%s = %s %s: %s' % [timespan, duration, task.project.name, task.text]
|
56
|
+
output = '%s = %s %s: %s' % [timespan, duration, task.project.name, task.text]
|
41
57
|
end
|
58
|
+
include_rendered_gap(task, next_task, output)
|
42
59
|
end
|
43
60
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
def rendered_duration(task)
|
51
|
-
'%5.2f' % task.duration.hours
|
61
|
+
def include_rendered_gap(task, next_task, output)
|
62
|
+
unless next_task.nil?
|
63
|
+
gap = task.gap(to_next: next_task)
|
64
|
+
output << "\n %dm" % gap.minutes unless gap.minutes == 0
|
65
|
+
end
|
66
|
+
output
|
52
67
|
end
|
53
68
|
|
54
69
|
end
|
data/lib/haora/task.rb
CHANGED
data/lib/haora/timestamp.rb
CHANGED
@@ -62,6 +62,10 @@ module Haora
|
|
62
62
|
minutes / 60.0
|
63
63
|
end
|
64
64
|
|
65
|
+
def ==(other)
|
66
|
+
@minutes == other.minutes
|
67
|
+
end
|
68
|
+
|
65
69
|
def +(other)
|
66
70
|
Duration.of_minutes(@minutes + other.minutes)
|
67
71
|
end
|
@@ -72,7 +76,7 @@ module Haora
|
|
72
76
|
|
73
77
|
private
|
74
78
|
|
75
|
-
def initialize(minutes)
|
79
|
+
def initialize(minutes = 0)
|
76
80
|
@minutes = minutes
|
77
81
|
end
|
78
82
|
|
data/lib/haora/version.rb
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Haora
|
2
|
+
|
3
|
+
class WeekRenderer < Renderer
|
4
|
+
|
5
|
+
def render(week_days)
|
6
|
+
days = rendered_days(week_days)
|
7
|
+
if days.length > 0
|
8
|
+
days << $/ << rendered_total(week_days)
|
9
|
+
else
|
10
|
+
'none'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def rendered_days(days)
|
17
|
+
days.select { |day| day.tasks.length > 0 }
|
18
|
+
.collect { |day| rendered_day(day) }
|
19
|
+
.join($/)
|
20
|
+
end
|
21
|
+
|
22
|
+
def rendered_total(days)
|
23
|
+
hours = days.select { |day| day.tasks.length > 0 }
|
24
|
+
.collect { |day| day.hours }
|
25
|
+
.reduce(:+)
|
26
|
+
' Total = %s' % rendered_duration(hours)
|
27
|
+
end
|
28
|
+
|
29
|
+
def rendered_day(day)
|
30
|
+
start = day.tasks.first.start
|
31
|
+
stop = day.tasks.last.stop
|
32
|
+
'%s %s = %s' % [rendered_date(day.date),
|
33
|
+
rendered_timespan(start, stop),
|
34
|
+
rendered_duration(day.hours)]
|
35
|
+
end
|
36
|
+
|
37
|
+
def rendered_date(date)
|
38
|
+
date.strftime('%a %d.%m.%Y')
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/haora.rb
CHANGED
@@ -4,10 +4,16 @@ require 'haora/task'
|
|
4
4
|
require 'haora/project'
|
5
5
|
require 'haora/day'
|
6
6
|
require 'haora/renderer'
|
7
|
+
require 'haora/week_renderer'
|
7
8
|
require 'haora/workbook'
|
8
9
|
require 'haora/io'
|
9
10
|
require 'haora/file'
|
10
11
|
|
12
|
+
require 'haora/command'
|
13
|
+
require 'haora/add_task'
|
14
|
+
require 'haora/finish'
|
15
|
+
require 'haora/list'
|
16
|
+
|
11
17
|
module Haora
|
12
18
|
|
13
19
|
class Service
|
@@ -18,22 +24,30 @@ module Haora
|
|
18
24
|
end
|
19
25
|
|
20
26
|
def add_task(params)
|
21
|
-
write
|
22
|
-
|
23
|
-
|
27
|
+
write do
|
28
|
+
AddTaskCommand
|
29
|
+
.with(@workbook)
|
30
|
+
.params(params)
|
31
|
+
.execute
|
32
|
+
end
|
24
33
|
end
|
25
34
|
|
26
35
|
def finish(params)
|
27
|
-
write
|
28
|
-
|
29
|
-
|
36
|
+
write do
|
37
|
+
FinishCommand
|
38
|
+
.with(@workbook)
|
39
|
+
.params(params)
|
40
|
+
.execute
|
41
|
+
end
|
30
42
|
end
|
31
43
|
|
32
|
-
def list(
|
33
|
-
read
|
34
|
-
|
35
|
-
|
36
|
-
|
44
|
+
def list(params)
|
45
|
+
read do
|
46
|
+
ListCommand
|
47
|
+
.with(@workbook)
|
48
|
+
.params(params)
|
49
|
+
.execute
|
50
|
+
end
|
37
51
|
end
|
38
52
|
|
39
53
|
private
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haora
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dirk Rademann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gli
|
@@ -89,14 +89,19 @@ extra_rdoc_files: []
|
|
89
89
|
files:
|
90
90
|
- bin/haora
|
91
91
|
- lib/haora.rb
|
92
|
+
- lib/haora/add_task.rb
|
93
|
+
- lib/haora/command.rb
|
92
94
|
- lib/haora/day.rb
|
93
95
|
- lib/haora/file.rb
|
96
|
+
- lib/haora/finish.rb
|
94
97
|
- lib/haora/io.rb
|
98
|
+
- lib/haora/list.rb
|
95
99
|
- lib/haora/project.rb
|
96
100
|
- lib/haora/renderer.rb
|
97
101
|
- lib/haora/task.rb
|
98
102
|
- lib/haora/timestamp.rb
|
99
103
|
- lib/haora/version.rb
|
104
|
+
- lib/haora/week_renderer.rb
|
100
105
|
- lib/haora/workbook.rb
|
101
106
|
homepage: http://github.com/drademann/haora-cli
|
102
107
|
licenses:
|