achoo 0.3 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +12 -0
- data/README.rdoc +26 -30
- data/Rakefile +3 -0
- data/bin/achoo +2 -2
- data/lib/achoo.rb +1 -139
- data/lib/achoo/achievo.rb +13 -0
- data/lib/achoo/achievo/form.rb +22 -0
- data/lib/achoo/achievo/hour_administration_form.rb +91 -0
- data/lib/achoo/achievo/hour_registration_form.rb +230 -0
- data/lib/achoo/achievo/hour_registration_form_ranged.rb +49 -0
- data/lib/achoo/achievo/lock_month_form.rb +44 -0
- data/lib/achoo/achievo/login_form.rb +27 -0
- data/lib/achoo/achievo/table.rb +30 -0
- data/lib/achoo/app.rb +153 -0
- data/lib/achoo/awake.rb +86 -100
- data/lib/achoo/extensions.rb +24 -0
- data/lib/achoo/ical.rb +47 -40
- data/lib/achoo/rc_loader.rb +42 -42
- data/lib/achoo/system.rb +8 -3
- data/lib/achoo/system/cstruct.rb +67 -0
- data/lib/achoo/system/log_entry.rb +24 -0
- data/lib/achoo/system/pm_suspend.rb +17 -20
- data/lib/achoo/system/utmp_record.rb +64 -0
- data/lib/achoo/system/wtmp.rb +14 -10
- data/lib/achoo/temporal.rb +8 -0
- data/lib/achoo/temporal/open_timespan.rb +16 -0
- data/lib/achoo/temporal/timespan.rb +122 -0
- data/lib/achoo/term.rb +58 -56
- data/lib/achoo/term/menu.rb +2 -2
- data/lib/achoo/term/table.rb +59 -60
- data/lib/achoo/ui.rb +13 -9
- data/lib/achoo/ui/commands.rb +60 -38
- data/lib/achoo/ui/common.rb +10 -7
- data/lib/achoo/ui/date_chooser.rb +69 -65
- data/lib/achoo/ui/date_choosers.rb +15 -14
- data/lib/achoo/ui/exception_handling.rb +14 -12
- data/lib/achoo/ui/month_chooser.rb +37 -24
- data/lib/achoo/ui/optionally_ranged_date_chooser.rb +29 -25
- data/lib/achoo/ui/register_hours.rb +116 -114
- data/lib/achoo/vcs.rb +32 -30
- data/lib/achoo/vcs/git.rb +18 -14
- data/lib/achoo/vcs/subversion.rb +25 -23
- metadata +30 -24
- data/lib/achoo/binary.rb +0 -7
- data/lib/achoo/binary/cstruct.rb +0 -60
- data/lib/achoo/binary/utmp_record.rb +0 -59
- data/lib/achoo/form.rb +0 -18
- data/lib/achoo/hour_administration_form.rb +0 -131
- data/lib/achoo/hour_registration_form.rb +0 -227
- data/lib/achoo/hour_registration_form_ranged.rb +0 -45
- data/lib/achoo/lock_month_form.rb +0 -40
- data/lib/achoo/open_timespan.rb +0 -13
- data/lib/achoo/timespan.rb +0 -119
@@ -1,137 +1,139 @@
|
|
1
|
+
require 'achoo/achievo'
|
1
2
|
require 'achoo/awake'
|
2
|
-
require 'achoo/hour_registration_form'
|
3
|
-
require 'achoo/hour_registration_form_ranged'
|
4
3
|
require 'achoo/ical'
|
5
4
|
require 'achoo/term'
|
6
5
|
require 'achoo/ui'
|
7
6
|
require 'achoo/vcs'
|
8
|
-
require 'stringio'
|
9
|
-
|
10
|
-
module Achoo::UI::RegisterHours
|
11
|
-
|
12
|
-
include Achoo::UI::DateChoosers
|
13
|
-
include Achoo::UI::ExceptionHandling
|
14
|
-
|
15
|
-
def register_hours(agent)
|
16
|
-
date = optionally_ranged_date_chooser
|
17
|
-
|
18
|
-
puts "Fetching data ..."
|
19
|
-
form = if date.class == Date
|
20
|
-
Achoo::HourRegistrationForm
|
21
|
-
else
|
22
|
-
Achoo::HourRegistrationFormRanged
|
23
|
-
end.new(agent)
|
24
|
-
|
25
|
-
form.date = date
|
26
|
-
form.project = project_chooser(form)
|
27
|
-
form.phase = phase_chooser(form)
|
28
|
-
print_remark_help(date) if date.class == Date
|
29
|
-
form.remark = remark_chooser
|
30
|
-
print_hours_help(date) if date.class == Date
|
31
|
-
form.hours = hours_chooser
|
32
|
-
|
33
|
-
answer = Achoo::Term.ask("Do you want to change the defaults for worktime period and/or billing percentage? [N/y]").downcase
|
34
|
-
if answer == 'y'
|
35
|
-
form.workperiod = workperiod_chooser(form)
|
36
|
-
form.billing = billing_chooser(form)
|
37
|
-
end
|
38
7
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
8
|
+
module Achoo
|
9
|
+
module UI
|
10
|
+
module RegisterHours
|
11
|
+
|
12
|
+
include DateChoosers
|
13
|
+
include ExceptionHandling
|
14
|
+
|
15
|
+
def register_hours(agent)
|
16
|
+
date = optionally_ranged_date_chooser
|
17
|
+
|
18
|
+
puts "Fetching data ..."
|
19
|
+
form = if date.class == Array
|
20
|
+
Achievo::HourRegistrationFormRanged
|
21
|
+
else
|
22
|
+
Achievo::HourRegistrationForm
|
23
|
+
end.new(agent)
|
24
|
+
|
25
|
+
form.date = date
|
26
|
+
form.project = project_chooser(form)
|
27
|
+
form.phase = phase_chooser(form)
|
28
|
+
print_remark_help(date) unless date.class == Array
|
29
|
+
form.remark = remark_chooser
|
30
|
+
print_hours_help(date) unless date.class == Array
|
31
|
+
form.hours = hours_chooser
|
32
|
+
|
33
|
+
answer = Term.ask("Do you want to change the defaults for worktime period and/or billing percentage? [N/y]").downcase
|
34
|
+
if answer == 'y'
|
35
|
+
form.workperiod = workperiod_chooser(form)
|
36
|
+
form.billing = billing_chooser(form)
|
37
|
+
end
|
38
|
+
|
39
|
+
form.print_values
|
40
|
+
if confirm
|
41
|
+
puts "Submitting ..."
|
42
|
+
form.submit
|
43
|
+
else
|
44
|
+
puts "Cancelled"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
47
48
|
|
49
|
+
def phase_chooser(form)
|
50
|
+
phases = form.phases_for_selected_project
|
51
|
+
puts "Phases"
|
52
|
+
answer = Term.choose('Phase', phases.collect {|p| p[1] })
|
53
|
+
phases[answer.to_i-1][0]
|
54
|
+
end
|
48
55
|
|
49
|
-
def phase_chooser(form)
|
50
|
-
phases = form.phases_for_selected_project
|
51
|
-
puts "Phases"
|
52
|
-
answer = Achoo::Term.choose('Phase', phases.collect {|p| p[1] })
|
53
|
-
phases[answer.to_i-1][0]
|
54
|
-
end
|
55
56
|
|
57
|
+
def workperiod_chooser(form)
|
58
|
+
periods = form.worktime_periods
|
59
|
+
puts "Worktime periods"
|
60
|
+
answer = Term.choose('Period [1]', periods.collect {|p| p[1] }, nil, [''])
|
61
|
+
answer = '1' if answer.empty?
|
62
|
+
periods[answer.to_i-1][0]
|
63
|
+
end
|
56
64
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
def billing_chooser(form)
|
66
|
+
options = form.billing_options
|
67
|
+
puts "Billing options"
|
68
|
+
answer = Term.choose('Billing [1]', options.collect {|p| p[1] }, nil, [''])
|
69
|
+
answer = '1' if answer.empty?
|
70
|
+
options[answer.to_i-1][0]
|
71
|
+
end
|
64
72
|
|
65
|
-
def billing_chooser(form)
|
66
|
-
options = form.billing_options
|
67
|
-
puts "Billing options"
|
68
|
-
answer = Achoo::Term.choose('Billing [1]', options.collect {|p| p[1] }, nil, [''])
|
69
|
-
answer = '1' if answer.empty?
|
70
|
-
options[answer.to_i-1][0]
|
71
|
-
end
|
72
73
|
|
74
|
+
def print_hours_help(date)
|
75
|
+
puts "Awake log:"
|
76
|
+
begin
|
77
|
+
awake = Awake.new
|
78
|
+
awake.at(date)
|
79
|
+
puts
|
80
|
+
rescue Exception => e
|
81
|
+
print handle_exception("Failed to retrieve awake log.", e)
|
82
|
+
end
|
83
|
+
end
|
73
84
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
awake.at(date)
|
79
|
-
puts
|
80
|
-
rescue Exception => e
|
81
|
-
print handle_exception("Failed to retrieve awake log.", e)
|
82
|
-
end
|
83
|
-
end
|
85
|
+
def hours_chooser
|
86
|
+
answer = Term::ask 'Hours [7:30]'
|
87
|
+
return answer == '' ? '7.5' : answer
|
88
|
+
end
|
84
89
|
|
85
|
-
def hours_chooser
|
86
|
-
answer = Achoo::Term::ask 'Hours [7:30]'
|
87
|
-
return answer == '' ? '7.5' : answer
|
88
|
-
end
|
89
90
|
|
91
|
+
def print_remark_help(date)
|
92
|
+
puts "VCS logs for #{date}:"
|
93
|
+
begin
|
94
|
+
VCS.print_logs_for(date, RC[:vcs_dirs])
|
95
|
+
rescue Exception => e
|
96
|
+
puts handle_exception("Failed to retrieve VCS logs.", e)
|
97
|
+
end
|
98
|
+
puts '-' * 80
|
99
|
+
puts "Calendar events for #{date}:"
|
100
|
+
puts '---'
|
101
|
+
begin
|
102
|
+
RC[:ical].each do |config|
|
103
|
+
ICal.from_http_request(config).print_events(date)
|
104
|
+
end
|
105
|
+
rescue Exception => e
|
106
|
+
puts handle_exception("Failed to retrieve calendar events.", e)
|
107
|
+
end
|
108
|
+
end
|
90
109
|
|
91
|
-
|
92
|
-
|
93
|
-
begin
|
94
|
-
Achoo::VCS.print_logs_for(date, RC[:vcs_dirs])
|
95
|
-
rescue Exception => e
|
96
|
-
puts handle_exception("Failed to retrieve VCS logs.", e)
|
97
|
-
end
|
98
|
-
puts '-' * 80
|
99
|
-
puts "Calendar events for #{date}:"
|
100
|
-
puts '---'
|
101
|
-
begin
|
102
|
-
RC[:ical].each do |config|
|
103
|
-
Achoo::ICal.from_http_request(config).print_events(date)
|
110
|
+
def remark_chooser
|
111
|
+
Term::ask 'Remark'
|
104
112
|
end
|
105
|
-
rescue Exception => e
|
106
|
-
puts handle_exception("Failed to retrieve calendar events.", e)
|
107
|
-
end
|
108
|
-
end
|
109
113
|
|
110
|
-
def remark_chooser
|
111
|
-
Achoo::Term::ask 'Remark'
|
112
|
-
end
|
113
114
|
|
115
|
+
def project_chooser(form)
|
116
|
+
puts 'Recently used projects'
|
117
|
+
projects = form.recent_projects
|
118
|
+
answer = Term.choose('Project [1]', projects.collect { |p| p[1] },
|
119
|
+
'Other', [''])
|
120
|
+
case answer
|
121
|
+
when ''
|
122
|
+
projects[0][0]
|
123
|
+
when '0'
|
124
|
+
return all_projects_chooser(form)
|
125
|
+
else
|
126
|
+
return projects[answer.to_i-1][0]
|
127
|
+
end
|
128
|
+
end
|
114
129
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
projects[0][0]
|
123
|
-
when '0'
|
124
|
-
return all_projects_chooser(form)
|
125
|
-
else
|
126
|
-
return projects[answer.to_i-1][0]
|
130
|
+
|
131
|
+
def all_projects_chooser(form)
|
132
|
+
projects = form.all_projects
|
133
|
+
answer = Term.choose('Project', projects.collect { |p| p[1] })
|
134
|
+
projects[answer.to_i-1][0]
|
135
|
+
end
|
136
|
+
|
127
137
|
end
|
128
138
|
end
|
129
|
-
|
130
|
-
|
131
|
-
def all_projects_chooser(form)
|
132
|
-
projects = form.all_projects
|
133
|
-
answer = Achoo::Term.choose('Project', projects.collect { |p| p[1] })
|
134
|
-
projects[answer.to_i-1][0]
|
135
|
-
end
|
136
|
-
|
137
139
|
end
|
data/lib/achoo/vcs.rb
CHANGED
@@ -1,43 +1,45 @@
|
|
1
|
-
|
1
|
+
require 'achoo'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module Achoo
|
4
|
+
class VCS
|
5
5
|
|
6
|
-
|
6
|
+
autoload :Git, 'achoo/vcs/git'
|
7
|
+
autoload :Subversion, 'achoo/vcs/subversion'
|
8
|
+
|
9
|
+
LINE_LENGTH = 80
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
def self.factory(dir)
|
12
|
+
klass = [Git, Subversion].find do |k|
|
13
|
+
k.repository?(dir)
|
14
|
+
end
|
15
|
+
return nil if klass.nil?
|
16
|
+
klass.new(dir)
|
13
17
|
end
|
14
|
-
return nil if klass.nil?
|
15
|
-
klass.new(dir)
|
16
|
-
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
def self.print_logs_for(date, vcs_dirs, io=$stdout)
|
20
|
+
vcs_dirs.each do |dir|
|
21
|
+
Dir.glob("#{dir}/*/").each do |dir|
|
22
|
+
vcs = factory(dir)
|
23
|
+
next if vcs.nil?
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
log = vcs.log_for(date)
|
26
|
+
print_log(log, dir, io)
|
27
|
+
end
|
26
28
|
end
|
27
29
|
end
|
28
|
-
end
|
29
30
|
|
30
|
-
|
31
|
+
private
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
def self.print_log(log, dir, io)
|
34
|
+
return if log.empty?
|
35
|
+
io.puts header(dir)
|
36
|
+
io.puts log.chomp
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
def self.header(dir)
|
40
|
+
project = "<( #{File.basename(dir).upcase} )>"
|
41
|
+
dashes = '-' * ((LINE_LENGTH - project.length) / 2)
|
42
|
+
dashes + project + dashes
|
43
|
+
end
|
42
44
|
end
|
43
45
|
end
|
data/lib/achoo/vcs/git.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
|
-
|
1
|
+
require 'achoo/vcs'
|
2
2
|
|
3
|
-
|
3
|
+
module Achoo
|
4
|
+
class VCS
|
5
|
+
class Git
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
7
|
+
def self.repository?(dir)
|
8
|
+
File.exists?("#{dir}/.git")
|
9
|
+
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
def initialize(dir)
|
12
|
+
@dir = dir
|
13
|
+
end
|
14
|
+
|
15
|
+
def log_for(date)
|
16
|
+
today = date.strftime('%Y-%m-%d')
|
17
|
+
tomorrow = date.next.strftime('%Y-%m-%d')
|
18
|
+
|
19
|
+
`cd #@dir; git log --author=#{ENV['USER']} --oneline --after=#{today} --before=#{tomorrow} | cut -d ' ' -f 2-`
|
20
|
+
end
|
12
21
|
|
13
|
-
|
14
|
-
today = date.strftime('%Y-%m-%d')
|
15
|
-
tomorrow = date.next.strftime('%Y-%m-%d')
|
16
|
-
|
17
|
-
`cd #@dir; git log --author=#{ENV['USER']} --oneline --after=#{today} --before=#{tomorrow} | cut -d ' ' -f 2-`
|
22
|
+
end
|
18
23
|
end
|
19
|
-
|
20
24
|
end
|
data/lib/achoo/vcs/subversion.rb
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
+
require 'achoo/vcs'
|
1
2
|
require 'nokogiri'
|
2
3
|
|
3
|
-
|
4
|
+
module Achoo
|
5
|
+
class VCS
|
6
|
+
class Subversion
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
File.exist?("#{dir}/.svn")
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(dir)
|
12
|
-
@dir = dir
|
13
|
-
end
|
8
|
+
def self.repository?(dir)
|
9
|
+
File.exist?("#{dir}/.svn")
|
10
|
+
end
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
logentries = xml.xpath("/log/logentry/author[contains(., \"#{ENV['USER']}\")]/parent::*")
|
12
|
+
def initialize(dir)
|
13
|
+
@dir = dir
|
14
|
+
end
|
19
15
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
def log_for(date)
|
17
|
+
date = date.strftime("%F")
|
18
|
+
xml = Nokogiri::XML(`cd #@dir; svn log --xml`)
|
19
|
+
logentries = xml.xpath("/log/logentry/author[contains(., \"#{ENV['USER']}\")]/parent::*")
|
20
|
+
|
21
|
+
# FIX are the dates in the xml local time, or do they need to be
|
22
|
+
# converted?
|
23
|
+
log = ""
|
24
|
+
logentries.each do |e|
|
25
|
+
if e.css('date').text.start_with?(date)
|
26
|
+
log << e.css('msg').text.strip << "\n"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
log
|
26
30
|
end
|
31
|
+
|
27
32
|
end
|
28
|
-
log
|
29
33
|
end
|
30
|
-
|
31
|
-
|
32
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: achoo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Kjell-Magne \xC3\x98ierud"
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-04-
|
12
|
+
date: 2010-04-20 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -45,41 +45,47 @@ extra_rdoc_files: []
|
|
45
45
|
|
46
46
|
files:
|
47
47
|
- bin/awake
|
48
|
+
- bin/ical
|
48
49
|
- bin/achoo
|
49
50
|
- bin/vcs_commits
|
50
|
-
-
|
51
|
-
- lib/achoo/hour_administration_form.rb
|
52
|
-
- lib/achoo/vcs/git.rb
|
53
|
-
- lib/achoo/vcs/subversion.rb
|
54
|
-
- lib/achoo/ui.rb
|
55
|
-
- lib/achoo/term.rb
|
56
|
-
- lib/achoo/system.rb
|
57
|
-
- lib/achoo/open_timespan.rb
|
58
|
-
- lib/achoo/lock_month_form.rb
|
59
|
-
- lib/achoo/hour_registration_form.rb
|
51
|
+
- lib/achoo.rb
|
60
52
|
- lib/achoo/vcs.rb
|
61
|
-
- lib/achoo/ui/date_chooser.rb
|
62
|
-
- lib/achoo/ui/exception_handling.rb
|
63
53
|
- lib/achoo/ui/month_chooser.rb
|
54
|
+
- lib/achoo/ui/common.rb
|
64
55
|
- lib/achoo/ui/commands.rb
|
56
|
+
- lib/achoo/ui/date_chooser.rb
|
57
|
+
- lib/achoo/ui/exception_handling.rb
|
65
58
|
- lib/achoo/ui/optionally_ranged_date_chooser.rb
|
66
|
-
- lib/achoo/ui/common.rb
|
67
59
|
- lib/achoo/ui/date_choosers.rb
|
68
60
|
- lib/achoo/ui/register_hours.rb
|
69
|
-
- lib/achoo/
|
70
|
-
- lib/achoo/
|
71
|
-
- lib/achoo/
|
61
|
+
- lib/achoo/achievo/form.rb
|
62
|
+
- lib/achoo/achievo/lock_month_form.rb
|
63
|
+
- lib/achoo/achievo/login_form.rb
|
64
|
+
- lib/achoo/achievo/hour_registration_form.rb
|
65
|
+
- lib/achoo/achievo/hour_administration_form.rb
|
66
|
+
- lib/achoo/achievo/hour_registration_form_ranged.rb
|
67
|
+
- lib/achoo/achievo/table.rb
|
68
|
+
- lib/achoo/system.rb
|
69
|
+
- lib/achoo/system/log_entry.rb
|
72
70
|
- lib/achoo/system/wtmp.rb
|
71
|
+
- lib/achoo/system/utmp_record.rb
|
73
72
|
- lib/achoo/system/pm_suspend.rb
|
74
|
-
- lib/achoo/
|
75
|
-
- lib/achoo/
|
73
|
+
- lib/achoo/system/cstruct.rb
|
74
|
+
- lib/achoo/vcs/subversion.rb
|
75
|
+
- lib/achoo/vcs/git.rb
|
76
76
|
- lib/achoo/awake.rb
|
77
|
-
- lib/achoo/
|
78
|
-
- lib/achoo/
|
79
|
-
- lib/achoo/form.rb
|
77
|
+
- lib/achoo/term.rb
|
78
|
+
- lib/achoo/app.rb
|
80
79
|
- lib/achoo/term/menu.rb
|
81
80
|
- lib/achoo/term/table.rb
|
82
|
-
- lib/achoo.rb
|
81
|
+
- lib/achoo/extensions.rb
|
82
|
+
- lib/achoo/temporal/open_timespan.rb
|
83
|
+
- lib/achoo/temporal/timespan.rb
|
84
|
+
- lib/achoo/achievo.rb
|
85
|
+
- lib/achoo/temporal.rb
|
86
|
+
- lib/achoo/rc_loader.rb
|
87
|
+
- lib/achoo/ui.rb
|
88
|
+
- lib/achoo/ical.rb
|
83
89
|
- Rakefile
|
84
90
|
- README.rdoc
|
85
91
|
- CHANGES
|