wlog 1.0.0 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/README.md +57 -9
- data/Rakefile +24 -0
- data/bin/wlog +10 -0
- data/lib/wlog/commands/archive_finished_issues.rb +20 -0
- data/lib/wlog/commands/archive_issues.rb +22 -0
- data/lib/wlog/commands/concat_description.rb +8 -2
- data/lib/wlog/commands/delete_issue.rb +31 -0
- data/lib/wlog/commands/innit_db.rb +0 -2
- data/lib/wlog/commands/make_csv.rb +7 -1
- data/lib/wlog/commands/new_entry.rb +7 -2
- data/lib/wlog/commands/replace_pattern.rb +4 -6
- data/lib/wlog/commands/taint_setup.rb +18 -0
- data/lib/wlog/db_registry.rb +3 -5
- data/lib/wlog/domain.rb +13 -0
- data/lib/wlog/domain/attachment.rb +25 -17
- data/lib/wlog/domain/helpers.rb +4 -0
- data/lib/wlog/domain/issue.rb +77 -23
- data/lib/wlog/domain/key_value.rb +21 -17
- data/lib/wlog/domain/log_entry.rb +35 -21
- data/lib/wlog/domain/session.rb +17 -0
- data/lib/wlog/domain/sql_modules/issue_sql.rb +13 -5
- data/lib/wlog/domain/static_configurations.rb +9 -0
- data/lib/wlog/domain/sys_config.rb +76 -6
- data/lib/wlog/domain/template_engine.rb +55 -0
- data/lib/wlog/domain/timelog_helper.rb +53 -0
- data/lib/wlog/sql/seq/2.sql +4 -0
- data/lib/wlog/{domain → tech}/ansi_colors.rb +7 -6
- data/lib/wlog/tech/uncolored_string.rb +14 -0
- data/lib/wlog/tech/wlog_string.rb +23 -0
- data/lib/wlog/ui/bootstrap.rb +18 -0
- data/lib/wlog/ui/cli_interface.rb +94 -34
- data/lib/wlog/ui/commands/create_issue.rb +8 -4
- data/lib/wlog/ui/issue_ui.rb +47 -41
- data/lib/wlog/ui/setup_wizard.rb +34 -0
- data/lib/wlog/version.rb +1 -1
- data/spec/domain/attachment_spec.rb +59 -0
- data/spec/domain/commands/concat_desc_spec.rb +51 -0
- data/spec/domain/commands/new_entry_spec.rb +41 -0
- data/spec/domain/commands/replace_pattern_spec.rb +46 -0
- data/spec/domain/issue_spec.rb +127 -0
- data/spec/domain/key_value_spec.rb +42 -0
- data/spec/domain/log_entry_spec.rb +85 -0
- data/spec/domain/sys_config_spec.rb +38 -0
- data/spec/make_db.rb +8 -0
- data/spec/old-databases/README.md +6 -0
- data/spec/old-databases/default +0 -0
- data/spec/tech/uncolored_string.rb +20 -0
- data/spec/tech/wlog_string_spec.rb +46 -0
- data/wlog.gemspec +5 -3
- metadata +44 -6
- data/spec/key_vale_spec.rb +0 -9
@@ -0,0 +1,55 @@
|
|
1
|
+
module Wlog
|
2
|
+
# A very simple templating engine that supports generating text files in order
|
3
|
+
# for them to be, in turn parsed by some other tool in order to generate nice
|
4
|
+
# invoices. The 'other' tool I have in mind is pandoc; this somewhat defeats
|
5
|
+
# the purpose of 'lightweight' in the sense that we indirectly need that tool,
|
6
|
+
# but on the other hand writing a more complex templating engine might prove
|
7
|
+
# too costly for now.
|
8
|
+
#
|
9
|
+
# @author Simon Symeonidis
|
10
|
+
class TemplateEngine
|
11
|
+
|
12
|
+
# These can either be atomic elements, or arrays of two. In the former, they
|
13
|
+
# just join entries by adding the separator. The latter makes the two a
|
14
|
+
# prefix, and postfix.
|
15
|
+
# @param issue_sep is what to separate issues with
|
16
|
+
# @param log_entry_sep is what to separate log entries with
|
17
|
+
def initialize(issue_sep, log_entry_sep, issues, invoice_id)
|
18
|
+
@issue_sep, @log_entry_sep, @issues, @invoice_id = \
|
19
|
+
issue_sep, log_entry_sep, issues, invoice_id
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate(filename)
|
23
|
+
contents = File.open(filename).read
|
24
|
+
contens.gsub(InvoiceId, @invoice_id)
|
25
|
+
end
|
26
|
+
|
27
|
+
# What to separate issues with
|
28
|
+
attr_accessor :issue_sep
|
29
|
+
|
30
|
+
# What to separate log entries with
|
31
|
+
attr_accessor :log_entry_sep
|
32
|
+
|
33
|
+
# An issue list
|
34
|
+
attr_accessor :issues
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# The tag to look for in order to add the issue info
|
39
|
+
IssueTag = '<issue-sep>'
|
40
|
+
|
41
|
+
# The log entry tag to add the log entries
|
42
|
+
LogEntrySep = '<log-entry-sep>'
|
43
|
+
|
44
|
+
InvoiceId = '<id>'
|
45
|
+
|
46
|
+
DateFrom = '<date-from>'
|
47
|
+
|
48
|
+
DateTo = '<date-to>'
|
49
|
+
|
50
|
+
StartSegment = '[segment]'
|
51
|
+
EndSegment = '[/segment]'
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Wlog
|
2
|
+
# Helper class that reads in a string in the form of eg: 4h20m and should be
|
3
|
+
# able to extract time in seconds.
|
4
|
+
# @author Simon Symeonidis
|
5
|
+
class TimelogHelper
|
6
|
+
# Parse a timelog string
|
7
|
+
def self.parse(str)
|
8
|
+
loggings = str.scan(/\d+[A-Za-z]/)
|
9
|
+
self.calculate_time(loggings)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param time is time in seconds
|
13
|
+
# @return in nice format (2d 1h 20m)
|
14
|
+
def self.time_to_s(time)
|
15
|
+
str = ""
|
16
|
+
TimesArr.each do |interval|
|
17
|
+
rem = time % interval
|
18
|
+
occ = (time - rem) / interval
|
19
|
+
str.concat("#{occ}#{TimesRev[interval]} ") if occ > 0
|
20
|
+
time = rem
|
21
|
+
end
|
22
|
+
str end
|
23
|
+
|
24
|
+
private_class_method
|
25
|
+
# Calculate time interface (get an array of time entries, and calculate)
|
26
|
+
def self.calculate_time(time_arr)
|
27
|
+
time_arr.inject(0){|sum,el| sum += self.calculate_item(el)}
|
28
|
+
end
|
29
|
+
|
30
|
+
# Calculate one time entry
|
31
|
+
def self.calculate_item(time_item)
|
32
|
+
magnitude = Times[time_item[-1]]
|
33
|
+
time_item.to_i * magnitude
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.count_occurences(time, step)
|
37
|
+
end
|
38
|
+
|
39
|
+
Times = {
|
40
|
+
'h' => 60 * 60,
|
41
|
+
's' => 1,
|
42
|
+
'm' => 60,
|
43
|
+
'd' => 8 * 60 * 60, # We assume logging a day = 8 hours
|
44
|
+
'w' => 8 * 60 * 60 * 7
|
45
|
+
}
|
46
|
+
|
47
|
+
# Reverse format for times
|
48
|
+
TimesRev = Hash[Times.to_a.collect{|arr| arr.reverse}]
|
49
|
+
|
50
|
+
# For a format to output a given int to time (1221 => 20m 21s)
|
51
|
+
TimesArr = Times.to_a.sort{|x1,x2| x2[1] <=> x1[1]}.collect{|e| e[1]}
|
52
|
+
end
|
53
|
+
end
|
@@ -3,13 +3,14 @@ module Wlog
|
|
3
3
|
# Store some ansi color codes in a module
|
4
4
|
# TODO this is a placeholder, and might not be correct.
|
5
5
|
module AnsiColors
|
6
|
-
|
7
|
-
|
8
|
-
Green =
|
9
|
-
|
10
|
-
|
6
|
+
Black = 30
|
7
|
+
Red = 31
|
8
|
+
Green = 32
|
9
|
+
Yellow = 33
|
10
|
+
Blue = 34
|
11
|
+
Magenta = 35
|
12
|
+
Cyan = 36
|
11
13
|
White = 37
|
12
|
-
Black = 38
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Wlog
|
2
|
+
# Use this if the system does not support colored strings.
|
3
|
+
# @author Simon Symeonidis
|
4
|
+
class UncoloredString
|
5
|
+
def self.red(str); str end
|
6
|
+
def self.yellow(str); str end
|
7
|
+
def self.magenta(str); str end
|
8
|
+
def self.green(str); str end
|
9
|
+
def self.blue(str); str end
|
10
|
+
def self.white(str); str end
|
11
|
+
def self.black(str); str end
|
12
|
+
def self.cyan(str); str end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'wlog/tech/ansi_colors'
|
2
|
+
|
3
|
+
module Wlog
|
4
|
+
# This should take care of multiplatform color stuff.
|
5
|
+
# @author Simon Symeonidis
|
6
|
+
class WlogString
|
7
|
+
include AnsiColors
|
8
|
+
|
9
|
+
def self.red(str); colorize(str,Red) end
|
10
|
+
def self.yellow(str); colorize(str,Yellow) end
|
11
|
+
def self.magenta(str); colorize(str,Magenta) end
|
12
|
+
def self.green(str); colorize(str,Green) end
|
13
|
+
def self.blue(str); colorize(str,Blue) end
|
14
|
+
def self.white(str); colorize(str,White) end
|
15
|
+
def self.black(str); colorize(str,Black) end
|
16
|
+
def self.cyan(str); colorize(str,Cyan) end
|
17
|
+
|
18
|
+
private
|
19
|
+
def self.colorize(str,col)
|
20
|
+
"\x1b[#{col};1m#{str}\x1b[0m"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'wlog/commands/innit_db'
|
2
|
+
require 'wlog/ui/setup_wizard'
|
3
|
+
require 'wlog/domain/helpers'
|
4
|
+
|
5
|
+
module Wlog
|
6
|
+
# This takes care of initialization. Place this class between the main entry
|
7
|
+
# point of the application and, the first transaction you require.
|
8
|
+
# @author Simon Symeonidis
|
9
|
+
class Bootstrap
|
10
|
+
def self.configure!
|
11
|
+
Helpers.make_dirs!
|
12
|
+
InnitDb.new.execute
|
13
|
+
# Initial setup if first time running
|
14
|
+
SetupWizard.new.run if Helpers.first_setup?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -1,10 +1,15 @@
|
|
1
|
+
require 'readline'
|
1
2
|
require 'turntables'
|
2
3
|
require 'wlog/domain/issue'
|
3
4
|
require 'wlog/domain/static_configurations'
|
4
5
|
require 'wlog/domain/sys_config'
|
5
6
|
require 'wlog/domain/attachment'
|
6
|
-
require 'wlog/
|
7
|
+
require 'wlog/domain/helpers'
|
7
8
|
require 'wlog/ui/commands/create_issue'
|
9
|
+
|
10
|
+
require 'wlog/commands/archive_issues'
|
11
|
+
require 'wlog/commands/archive_finished_issues'
|
12
|
+
require 'wlog/commands/delete_issue'
|
8
13
|
require 'wlog/ui/issue_ui'
|
9
14
|
|
10
15
|
module Wlog
|
@@ -16,26 +21,32 @@ class CliInterface
|
|
16
21
|
|
17
22
|
# This is the main entry point of the application. Therefore when we init,
|
18
23
|
# we want to trigger the table creation stuff.
|
19
|
-
def initialize
|
24
|
+
def initialize
|
25
|
+
@db = DbRegistry.new(nil)
|
26
|
+
@strmaker = SysConfig.string_decorator
|
27
|
+
end
|
20
28
|
|
21
29
|
# Run the interface
|
22
30
|
def run
|
23
31
|
cmd = "default"
|
32
|
+
label = @strmaker.white('wlog')
|
24
33
|
until cmd == "end" do
|
25
|
-
|
26
|
-
cmd = $stdin.gets || "end"
|
34
|
+
cmd = Readline.readline("[#{label}] ") || "end"
|
27
35
|
cmd.chomp!
|
28
36
|
|
29
37
|
case cmd
|
38
|
+
when /archive/ then archive cmd
|
30
39
|
when /showattach/ then show_attach
|
31
40
|
when /outattach/ then output_attach
|
41
|
+
when /generateinvoice/ then generate_invoice
|
32
42
|
when /attach/ then attach
|
33
43
|
when /focus/ then focus
|
34
44
|
when /new/ then new_issue
|
35
45
|
when /show/ then show_issues
|
36
46
|
when /outcsv/ then outcsv
|
37
|
-
when /delete/ then
|
47
|
+
when /delete/ then delete_issue
|
38
48
|
when /help/ then print_help
|
49
|
+
when /search/ then search
|
39
50
|
end
|
40
51
|
end
|
41
52
|
end
|
@@ -51,16 +62,22 @@ class CliInterface
|
|
51
62
|
private
|
52
63
|
|
53
64
|
# Create a new issue
|
54
|
-
def new_issue; CreateIssue.new.execute end
|
65
|
+
def new_issue; CreateIssue.new(@db).execute end
|
66
|
+
|
67
|
+
# Procedure to delete an issue
|
68
|
+
def delete_issue
|
69
|
+
issue_id = Readline.readline('Which issue id to delete? : ').to_i
|
70
|
+
dcmd = DeleteIssue.new(@db, issue_id)
|
71
|
+
dcmd.execute
|
72
|
+
puts "No such issue" unless dcmd.deleted?
|
73
|
+
end
|
55
74
|
|
56
75
|
# Wriet out the data contained in the database of the attachment
|
57
76
|
def output_attach
|
58
|
-
|
59
|
-
|
60
|
-
print "Output where (abs dir) : "
|
61
|
-
loc = $stdin.gets
|
77
|
+
att_id = Readline.readline('Which attachment to output? : ').to_i
|
78
|
+
loc = Readline.readline('Output where (abs dir) ? : ')
|
62
79
|
loc.chomp!
|
63
|
-
att = Attachment.find(Issue.name, att_id)
|
80
|
+
att = Attachment.find(@db, Issue.name, att_id)
|
64
81
|
|
65
82
|
fh = File.open("#{loc}/#{att.filename}", 'w')
|
66
83
|
fh.write(att.data)
|
@@ -68,30 +85,46 @@ private
|
|
68
85
|
end
|
69
86
|
|
70
87
|
def show_attach
|
71
|
-
|
72
|
-
|
73
|
-
atts = Attachment.find_all_by_discriminator(Issue.name, issue_id)
|
88
|
+
issue_id = Readline.readline('Which issue id? : ').to_i
|
89
|
+
atts = Attachment.find_all_by_discriminator(@db, Issue.name, issue_id)
|
74
90
|
atts.each do |att|
|
75
91
|
printf "[%d] - %s (alias: %s)\n", att.id, att.filename, att.given_name
|
76
92
|
end
|
77
93
|
end
|
78
94
|
|
95
|
+
# Archive means set status to 3 (arhive status) to the listed issues
|
96
|
+
def archive(cmd)
|
97
|
+
args = cmd.split[1..-1]
|
98
|
+
|
99
|
+
if args.length > 0
|
100
|
+
if args[0] == 'finished'
|
101
|
+
puts "Archiving finished issues."
|
102
|
+
ArchiveFinishedIssues.new(@db).execute
|
103
|
+
else # gave ids
|
104
|
+
ids = args.map{|sids| sids.to_i}
|
105
|
+
issues = ids.map{|id| Issue.find(@db, id)} - [nil]
|
106
|
+
ArchiveIssues.new(issues).execute
|
107
|
+
end
|
108
|
+
else
|
109
|
+
puts "usage: "
|
110
|
+
puts " archive finished"
|
111
|
+
puts " archive <id>+"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
79
115
|
def attach
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
print "Alias name for file (optional) :"
|
86
|
-
name_alias = $stdin.gets
|
87
|
-
name_alias.chomp!
|
116
|
+
issue_id = Readline.readline('Attach to issue id: ').to_i
|
117
|
+
loc = Readline.readline('Absolute file location: ')
|
118
|
+
loc.strip!
|
119
|
+
name_alias = Readline.readline('Alias name for file (optional): ')
|
120
|
+
name_alias.strip!
|
88
121
|
|
89
122
|
unless loc.nil?
|
90
123
|
fh = File.open(loc, "r")
|
91
124
|
data = fh.read
|
92
125
|
fh.close
|
93
126
|
|
94
|
-
att = Attachment.new(Issue.name, issue_id)
|
127
|
+
att = Attachment.new(@db, Issue.name, issue_id)
|
95
128
|
att.data = data
|
96
129
|
att.filename = loc.split('/').last
|
97
130
|
att.given_name = name_alias
|
@@ -103,11 +136,13 @@ private
|
|
103
136
|
end
|
104
137
|
|
105
138
|
def focus
|
106
|
-
|
107
|
-
|
108
|
-
issue
|
109
|
-
|
110
|
-
|
139
|
+
issue_id = Readline.readline('Focus on issue : ').to_i
|
140
|
+
issue = Issue.find(@db, issue_id)
|
141
|
+
if issue
|
142
|
+
IssueUi.new(@db, issue).run
|
143
|
+
else
|
144
|
+
puts "No such issue"
|
145
|
+
end
|
111
146
|
end
|
112
147
|
|
113
148
|
def outcsv
|
@@ -117,6 +152,7 @@ private
|
|
117
152
|
fh.close
|
118
153
|
end
|
119
154
|
|
155
|
+
# FIXME (update the command stuff)
|
120
156
|
# Print the help of the cli app
|
121
157
|
def print_help
|
122
158
|
["new", "Create a new log entry",
|
@@ -129,24 +165,48 @@ private
|
|
129
165
|
end
|
130
166
|
end
|
131
167
|
|
132
|
-
# TODO might need refactoring
|
133
168
|
def show_issues
|
134
|
-
entries_arr = Issue.find_all
|
169
|
+
entries_arr = Issue.find_all(@db)
|
170
|
+
print_list(entries_arr)
|
171
|
+
end
|
172
|
+
|
173
|
+
# TODO might need refactoring
|
174
|
+
def print_list(entries_arr)
|
135
175
|
issue_collections = entries_arr.reverse.group_by{|iss| iss.status_s}
|
136
176
|
issue_collections.each_key do |stat|
|
137
|
-
print "
|
138
|
-
puts "
|
177
|
+
print @strmaker.green("#{stat}")
|
178
|
+
puts @strmaker.magenta(" #{issue_collections[stat].count}")
|
139
179
|
issue_collections[stat].each do |iss|
|
140
|
-
|
180
|
+
print @strmaker.red(" [#{iss.id}] ")
|
181
|
+
puts "#{iss.description}"
|
141
182
|
end
|
142
183
|
end
|
143
184
|
end
|
144
185
|
|
145
186
|
def make_csv
|
146
|
-
cmd = MakeCsv.new
|
187
|
+
cmd = MakeCsv.new(@db)
|
147
188
|
cmd.execute
|
148
189
|
cmd.ret
|
149
190
|
end
|
191
|
+
|
192
|
+
def generate_invoice
|
193
|
+
require 'time'
|
194
|
+
puts "Eg: valid input is Oct 2013 15"
|
195
|
+
from = Readline.readline("From: ")
|
196
|
+
to = Readline.readline("To : ")
|
197
|
+
|
198
|
+
from_time = Time.parse(from).to_i
|
199
|
+
to_time = Time.parse(to).to_i
|
200
|
+
issues = Issue.find_in_time_range(@db, from_time, to_time)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Search for an issue
|
204
|
+
def search
|
205
|
+
term = Readline.readline("search issues for term : ")
|
206
|
+
issues = Issue.find_all(@db).select{|el| el.description.match(/#{term}/)}
|
207
|
+
print_list(issues)
|
208
|
+
end
|
209
|
+
|
150
210
|
end
|
151
211
|
end # module Wlog
|
152
212
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'readline'
|
1
2
|
require 'wlog/ui/commands/ui_command'
|
2
3
|
require 'wlog/domain/issue'
|
3
4
|
|
@@ -5,14 +6,17 @@ module Wlog
|
|
5
6
|
# Creational logic for issues
|
6
7
|
# @author Simon Symeonidis
|
7
8
|
class CreateIssue < UiCommand
|
9
|
+
def initialize(db)
|
10
|
+
@db = db
|
11
|
+
end
|
12
|
+
|
13
|
+
# Execute create issue transaction
|
8
14
|
def execute
|
9
|
-
@ret = Issue.new
|
10
|
-
|
11
|
-
desc = $stdin.gets || "None."
|
15
|
+
@ret = Issue.new(@db)
|
16
|
+
desc = Readline.readline("Small issue description :") || "None."
|
12
17
|
@ret.description = desc.chomp
|
13
18
|
@ret.insert
|
14
19
|
end
|
15
|
-
|
16
20
|
attr_accessor :ret
|
17
21
|
end
|
18
22
|
end
|
data/lib/wlog/ui/issue_ui.rb
CHANGED
@@ -1,38 +1,43 @@
|
|
1
|
+
require 'readline'
|
2
|
+
|
1
3
|
require 'wlog/commands/replace_pattern'
|
2
4
|
require 'wlog/commands/new_entry'
|
3
5
|
require 'wlog/commands/make_csv'
|
4
6
|
require 'wlog/commands/innit_db'
|
5
7
|
require 'wlog/commands/concat_description'
|
8
|
+
require 'wlog/domain/sys_config'
|
9
|
+
require 'wlog/domain/timelog_helper'
|
6
10
|
|
7
11
|
module Wlog
|
8
12
|
# The interface when focusing on an issue
|
9
13
|
# @author Simon
|
10
14
|
class IssueUi
|
11
|
-
def initialize(issue)
|
15
|
+
def initialize(db, issue)
|
12
16
|
@issue = issue
|
17
|
+
@db = db
|
18
|
+
@strmaker = SysConfig.string_decorator
|
13
19
|
end
|
14
20
|
|
15
21
|
# Start up the interface
|
16
22
|
def run
|
17
23
|
cmd = "default"
|
18
24
|
until cmd == "end" do
|
19
|
-
|
20
|
-
cmd = $stdin.gets || ""
|
25
|
+
cmd = Readline.readline("[issue ##{@issue.id}] ") || ""
|
21
26
|
cmd.chomp!
|
22
27
|
|
23
28
|
case cmd
|
24
|
-
when /
|
25
|
-
when /
|
26
|
-
when /
|
27
|
-
when /
|
28
|
-
when /
|
29
|
-
when /
|
30
|
-
when /
|
31
|
-
when /
|
32
|
-
when /
|
33
|
-
when
|
34
|
-
when
|
35
|
-
when
|
29
|
+
when /^new/ then new_entry
|
30
|
+
when /^show/ then show_entries
|
31
|
+
when /^desc/ then describe_issue
|
32
|
+
when /^delete/ then delete_entry
|
33
|
+
when /^search/ then search_term
|
34
|
+
when /^concat/ then concat_description
|
35
|
+
when /^replace/ then replace_pattern
|
36
|
+
when /^search/ then search_term
|
37
|
+
when /^lt/ then time(cmd.split.drop 1) # lt for log time
|
38
|
+
when /^forget/ then cmd = "end"
|
39
|
+
when /^finish/ then finish.nil? ? nil : cmd = "end"
|
40
|
+
when /^help/ then print_help
|
36
41
|
else puts "Type 'help' for help"
|
37
42
|
end
|
38
43
|
end
|
@@ -43,6 +48,13 @@ class IssueUi
|
|
43
48
|
|
44
49
|
private
|
45
50
|
|
51
|
+
# Time logging command
|
52
|
+
def time(rest)
|
53
|
+
time = TimelogHelper.parse(rest.join)
|
54
|
+
@issue.log_time(time)
|
55
|
+
puts @strmaker.green('logged time!')
|
56
|
+
end
|
57
|
+
|
46
58
|
# Print the description of the issue
|
47
59
|
def describe_issue; puts @issue end
|
48
60
|
|
@@ -61,8 +73,8 @@ private
|
|
61
73
|
|
62
74
|
# Exit the issue, mark as finished
|
63
75
|
def finish
|
64
|
-
|
65
|
-
if ret =
|
76
|
+
question = 'Are you done with this task? [yes/no] :'
|
77
|
+
if ret = !! Readline.readline(question).match(/^yes/i)
|
66
78
|
@issue.mark_finished!
|
67
79
|
@issue.update
|
68
80
|
end
|
@@ -70,52 +82,46 @@ private
|
|
70
82
|
|
71
83
|
# new entry command
|
72
84
|
def new_entry
|
73
|
-
|
74
|
-
description
|
85
|
+
description = Readline.readline("Enter new issue:#{$/} ")
|
86
|
+
description.chomp!
|
75
87
|
@issue.mark_working!
|
76
88
|
@issue.update
|
77
|
-
NewEntry.new(description, @issue.id).execute
|
89
|
+
NewEntry.new(@db, description, @issue.id).execute
|
78
90
|
end
|
79
91
|
|
80
92
|
def delete_entry
|
81
|
-
|
82
|
-
LogEntry.
|
93
|
+
id = Readline.readline('Remove task log with id : ').to_i
|
94
|
+
LogEntry.delete_by_id(@db, id)
|
83
95
|
end
|
84
96
|
|
85
97
|
# Concatenate an aggregate description to a previous item
|
86
98
|
def concat_description
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
str = $stdin.gets.chomp!
|
91
|
-
ConcatDescription.new(id, str).execute
|
99
|
+
id = Readline.readline("ID of task to concatenate to: ").to_i
|
100
|
+
str = Readline.readline("Information to concatenate: ").chomp
|
101
|
+
ConcatDescription.new(@db, id, str).execute
|
92
102
|
end
|
93
103
|
|
94
104
|
# Replace a pattern from a description of a log entry
|
95
105
|
def replace_pattern
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
old_pattern
|
100
|
-
print "with : "
|
101
|
-
new_pattern = $stdin.gets.chomp!
|
102
|
-
ReplacePattern.new(id, old_pattern, new_pattern).execute
|
106
|
+
id = Readline.readline("ID of task to perform replace: ").to_i
|
107
|
+
old_pattern = Readline.readline('replace : ').chomp
|
108
|
+
new_pattern = Readline.readline('with : ').chomp
|
109
|
+
ReplacePattern.new(@db, id, old_pattern, new_pattern).execute
|
103
110
|
end
|
104
111
|
|
105
112
|
def search_term
|
106
|
-
|
107
|
-
term
|
108
|
-
print_entries(LogEntry.search_descriptions(term))
|
113
|
+
term = Readline.readline('search : ').chomp!
|
114
|
+
print_entries(LogEntry.search_descriptions(@db, term))
|
109
115
|
end
|
110
116
|
|
111
117
|
# TODO might need refactoring
|
112
118
|
def show_entries
|
113
|
-
entries_arr = LogEntry.find_all_by_issue_id @issue.id
|
119
|
+
entries_arr = LogEntry.find_all_by_issue_id(@db, @issue.id)
|
114
120
|
date_collections = entries_arr.group_by{|le| le.date.strftime("%Y-%m-%d")}
|
115
121
|
date_collections.each_key do |date_c|
|
116
|
-
print "
|
117
|
-
print
|
118
|
-
puts "[
|
122
|
+
print @strmaker.green("#{date_c} - ")
|
123
|
+
print @strmaker.yellow(date_collections[date_c].first.date.strftime("%A"))
|
124
|
+
puts " [#{@strmaker.magenta(date_collections[date_c].count.to_s)}]"
|
119
125
|
date_collections[date_c].each do |le|
|
120
126
|
puts " #{le}"
|
121
127
|
end
|