wlog 1.1.1 → 1.1.5
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/README.md +33 -48
- data/Rakefile +1 -0
- data/lib/wlog/commands/archive_finished_issues.rb +2 -2
- data/lib/wlog/commands/archive_issues.rb +1 -1
- data/lib/wlog/commands/bootstrap_templates.rb +37 -0
- data/lib/wlog/commands/concat_description.rb +7 -11
- data/lib/wlog/commands/delete_issue.rb +6 -5
- data/lib/wlog/commands/innit_db.rb +62 -6
- data/lib/wlog/commands/make_csv.rb +2 -6
- data/lib/wlog/commands/new_entry.rb +10 -7
- data/lib/wlog/commands/replace_pattern.rb +7 -5
- data/lib/wlog/domain/attachment.rb +50 -75
- data/lib/wlog/domain/invoice.rb +8 -2
- data/lib/wlog/domain/issue.rb +32 -132
- data/lib/wlog/domain/key_value.rb +10 -35
- data/lib/wlog/domain/log_entry.rb +18 -95
- data/lib/wlog/domain/static_configurations.rb +6 -0
- data/lib/wlog/domain/sys_config.rb +2 -5
- data/lib/wlog/migrations/make_standard_tables.rb +59 -0
- data/lib/wlog/ui/cli_interface.rb +55 -44
- data/lib/wlog/ui/commands/create_issue.rb +4 -8
- data/lib/wlog/ui/edit_handler.rb +74 -0
- data/lib/wlog/ui/invoice_ui.rb +133 -0
- data/lib/wlog/ui/issue_ui.rb +21 -77
- data/lib/wlog/ui/template_ui.rb +66 -0
- data/lib/wlog/version.rb +1 -1
- data/spec/domain/attachment_spec.rb +58 -59
- data/spec/domain/commands/concat_desc_spec.rb +10 -13
- data/spec/domain/commands/new_entry_spec.rb +10 -13
- data/spec/domain/commands/replace_pattern_spec.rb +11 -12
- data/spec/domain/issue_spec.rb +35 -38
- data/spec/domain/key_value_spec.rb +5 -8
- data/spec/domain/log_entry_spec.rb +20 -31
- data/spec/domain/sys_config_spec.rb +4 -7
- data/spec/make_db.rb +30 -4
- data/spec/tech/wlog_string_spec.rb +14 -14
- data/wlog.gemspec +2 -1
- metadata +26 -13
- data/lib/wlog/db_registry.rb +0 -38
- data/lib/wlog/domain/sql_modules/attachment_sql.rb +0 -21
- data/lib/wlog/domain/sql_modules/issue_sql.rb +0 -37
- data/lib/wlog/domain/sql_modules/key_value_sql.rb +0 -20
- data/lib/wlog/domain/sql_modules/log_entry_sql.rb +0 -35
- data/lib/wlog/ui/commands/attach_to_issue.rb +0 -0
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'readline'
|
2
|
-
require 'turntables'
|
3
2
|
require 'wlog/domain/issue'
|
4
3
|
require 'wlog/domain/static_configurations'
|
5
4
|
require 'wlog/domain/sys_config'
|
@@ -13,6 +12,8 @@ require 'wlog/commands/archive_issues'
|
|
13
12
|
require 'wlog/commands/archive_finished_issues'
|
14
13
|
require 'wlog/commands/delete_issue'
|
15
14
|
require 'wlog/ui/issue_ui'
|
15
|
+
require 'wlog/ui/template_ui'
|
16
|
+
require 'wlog/ui/invoice_ui'
|
16
17
|
|
17
18
|
module Wlog
|
18
19
|
# @author Simon Symeonidis
|
@@ -24,7 +25,6 @@ class CliInterface
|
|
24
25
|
# This is the main entry point of the application. Therefore when we init,
|
25
26
|
# we want to trigger the table creation stuff.
|
26
27
|
def initialize
|
27
|
-
@db = DbRegistry.new(nil)
|
28
28
|
@strmaker = SysConfig.string_decorator
|
29
29
|
end
|
30
30
|
|
@@ -43,13 +43,15 @@ class CliInterface
|
|
43
43
|
when /^generateinvoice/ then generate_invoice
|
44
44
|
when /^attach/ then attach
|
45
45
|
when /^focus/ then focus(cmd)
|
46
|
-
when
|
46
|
+
when /new/ then new_issue
|
47
47
|
when /^(ls|show)/ then show_issues
|
48
48
|
when /^outcsv/ then outcsv
|
49
49
|
when /^delete/ then delete_issue(cmd)
|
50
50
|
when /^help/ then print_help
|
51
51
|
when /^search/ then search
|
52
52
|
when /^config/ then config
|
53
|
+
when /^templates/ then TemplateUi.new.run
|
54
|
+
when /^invoices/ then InvoiceUi.new.run
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
@@ -65,34 +67,38 @@ class CliInterface
|
|
65
67
|
private
|
66
68
|
|
67
69
|
# Create a new issue
|
68
|
-
def new_issue; CreateIssue.new
|
70
|
+
def new_issue; CreateIssue.new.execute end
|
69
71
|
|
70
72
|
# Procedure to delete an issue
|
71
73
|
def delete_issue(cmd)
|
72
74
|
issue_id = cmd.split[1]
|
73
75
|
|
74
76
|
if !issue_id
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
dcmd = DeleteIssue.new(
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
77
|
+
puts 'usage:'
|
78
|
+
puts ' delete <id>'
|
79
|
+
else
|
80
|
+
issue_id = issue_id.to_i
|
81
|
+
end
|
82
|
+
|
83
|
+
dcmd = DeleteIssue.new(issue_id)
|
84
|
+
if dcmd
|
85
|
+
choice = Readline.readline("Delete issue #{issue_id}? [y/n]").strip
|
86
|
+
if choice == "y"
|
87
|
+
dcmd.execute
|
88
|
+
else
|
89
|
+
puts "Did nothing"
|
90
|
+
return
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
91
94
|
puts "No such issue" unless dcmd.deleted?
|
92
95
|
end
|
93
96
|
|
94
97
|
# Wriet out the data contained in the database of the attachment
|
95
98
|
def output_attach
|
99
|
+
puts "Migration of implementation pending"
|
100
|
+
return
|
101
|
+
|
96
102
|
att_id = Readline.readline('Which attachment to output? : ').to_i
|
97
103
|
loc = Readline.readline('Output where (abs dir) ? : ')
|
98
104
|
loc.chomp!
|
@@ -104,6 +110,8 @@ private
|
|
104
110
|
end
|
105
111
|
|
106
112
|
def show_attach
|
113
|
+
puts "Migration of implementation pending"
|
114
|
+
return
|
107
115
|
issue_id = Readline.readline('Which issue id? : ').to_i
|
108
116
|
atts = Attachment.find_all_by_discriminator(@db, Issue.name, issue_id)
|
109
117
|
atts.each do |att|
|
@@ -118,7 +126,7 @@ private
|
|
118
126
|
if args.length > 0
|
119
127
|
if args[0] == 'finished'
|
120
128
|
puts "Archiving finished issues."
|
121
|
-
ArchiveFinishedIssues.new
|
129
|
+
ArchiveFinishedIssues.new.execute
|
122
130
|
else # gave ids
|
123
131
|
ids = args.map{|sids| sids.to_i}
|
124
132
|
issues = ids.map{|id| Issue.find(@db, id)} - [nil]
|
@@ -132,6 +140,9 @@ private
|
|
132
140
|
end
|
133
141
|
|
134
142
|
def attach
|
143
|
+
puts "Migration of implementation pending"
|
144
|
+
return
|
145
|
+
|
135
146
|
issue_id = Readline.readline('Attach to issue id: ').to_i
|
136
147
|
loc = Readline.readline('Absolute file location: ')
|
137
148
|
loc.strip!
|
@@ -157,17 +168,17 @@ private
|
|
157
168
|
# Focus on an issue to log work etc
|
158
169
|
def focus(cmd)
|
159
170
|
issue_id = cmd.split[1]
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
issue = Issue.find(
|
171
|
+
if !issue_id
|
172
|
+
puts 'usage: '
|
173
|
+
puts ' focus <id>'
|
174
|
+
return
|
175
|
+
else
|
176
|
+
issue_id = issue_id.to_i
|
177
|
+
end
|
178
|
+
|
179
|
+
issue = Issue.find(issue_id)
|
169
180
|
if issue
|
170
|
-
IssueUi.new(
|
181
|
+
IssueUi.new(issue).run
|
171
182
|
else
|
172
183
|
puts "No such issue"
|
173
184
|
end
|
@@ -188,23 +199,23 @@ private
|
|
188
199
|
'help', 'print this dialog',
|
189
200
|
'end', 'Exit the progam',
|
190
201
|
'delete', 'Remove the issue with a given id',
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
202
|
+
'archive', 'Archive a file into a specific issue',
|
203
|
+
'showattach', 'Show what files have been attached to an issue',
|
204
|
+
'outattach', 'Extract a file from the database',
|
205
|
+
'generateinvoice', 'todo',
|
206
|
+
'focus', 'Focus on a particular ',
|
207
|
+
'show', 'List all the issues',
|
208
|
+
'help', 'Show this information',
|
209
|
+
'search', 'Search for a specific text',
|
210
|
+
'config', 'Set differeing configuration parameters'
|
211
|
+
].each_with_index do |el,ix|
|
201
212
|
print ' ' if 1 == ix % 2
|
202
213
|
puts el
|
203
214
|
end
|
204
215
|
end
|
205
216
|
|
206
217
|
def show_issues
|
207
|
-
entries_arr = Issue.
|
218
|
+
entries_arr = Issue.find_not_archived
|
208
219
|
print_list(entries_arr)
|
209
220
|
end
|
210
221
|
|
@@ -229,7 +240,7 @@ private
|
|
229
240
|
end
|
230
241
|
|
231
242
|
def make_csv
|
232
|
-
cmd = MakeCsv.new
|
243
|
+
cmd = MakeCsv.new
|
233
244
|
cmd.execute
|
234
245
|
cmd.ret
|
235
246
|
end
|
@@ -248,7 +259,7 @@ private
|
|
248
259
|
# Search for an issue
|
249
260
|
def search
|
250
261
|
term = Readline.readline("search issues for term : ")
|
251
|
-
issues = Issue.
|
262
|
+
issues = Issue.where(["description like ?", "%#{term}%"])
|
252
263
|
print_list(issues)
|
253
264
|
end
|
254
265
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_record'
|
1
2
|
require 'readline'
|
2
3
|
require 'wlog/ui/commands/ui_command'
|
3
4
|
require 'wlog/domain/issue'
|
@@ -6,18 +7,13 @@ module Wlog
|
|
6
7
|
# Creational logic for issues
|
7
8
|
# @author Simon Symeonidis
|
8
9
|
class CreateIssue < UiCommand
|
9
|
-
def initialize(db)
|
10
|
-
@db = db
|
11
|
-
end
|
12
|
-
|
13
10
|
# Execute create issue transaction
|
14
11
|
def execute
|
15
|
-
@ret = Issue.new(@db)
|
16
12
|
desc = Readline.readline("Small issue description :") || "None."
|
17
13
|
ldesc = Readline.readline("Long issue description :") || "None."
|
18
|
-
@ret.description
|
19
|
-
|
20
|
-
|
14
|
+
@ret = Issue.create(:description =>desc.chomp, :long_description => ldesc,
|
15
|
+
:status => 0, :created_at => Time.now, :updated_at => Time.now,
|
16
|
+
:due_date => Time.now, :timelog => 0)
|
21
17
|
end
|
22
18
|
attr_accessor :ret
|
23
19
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
|
2
|
+
module Wlog
|
3
|
+
# @author Simon Symeonidis
|
4
|
+
class EditHandler
|
5
|
+
|
6
|
+
def initialize(issue); @issue = issue end
|
7
|
+
|
8
|
+
# Command comes in as edit <...>. This definition will check what comes
|
9
|
+
# next and invoke the proper method to execute.
|
10
|
+
def edit_what(terms_a)
|
11
|
+
case terms_a[0]
|
12
|
+
when /^title/
|
13
|
+
title = (terms_a.drop 1).join ' '
|
14
|
+
@issue.description = title
|
15
|
+
@issue.update
|
16
|
+
|
17
|
+
when /^desc/
|
18
|
+
long = (terms_a.drop 1).join ' '
|
19
|
+
@issue.long_description = long
|
20
|
+
@issue.update
|
21
|
+
|
22
|
+
when /^due/
|
23
|
+
date_time = terms_a.drop 1
|
24
|
+
edit_time(date_time.join(' '))
|
25
|
+
|
26
|
+
when /^reported/
|
27
|
+
date_time = terms_a.drop 1
|
28
|
+
edit_reported_time(date_time.join(' '))
|
29
|
+
|
30
|
+
else
|
31
|
+
$stdout.puts "Usage: "
|
32
|
+
$stdout.puts " edit title - to edit the title"
|
33
|
+
$stdout.puts " edit desc - to edit the long description"
|
34
|
+
$stdout.puts " edit due - to edit the due date"
|
35
|
+
$stdout.puts " edit time - to edit the time"
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param time is the date-time in string format (eg Oct 28)
|
41
|
+
def edit_time(time)
|
42
|
+
date_time = time_handle(time)
|
43
|
+
@issue.due_date = date_time.to_time
|
44
|
+
@issue.update
|
45
|
+
puts @strmaker.green('Updated due date')
|
46
|
+
rescue ArgumentError
|
47
|
+
$stderr.puts @strmaker.red \
|
48
|
+
"Invalid date/time format. Try format like 'Oct 28'"
|
49
|
+
end
|
50
|
+
|
51
|
+
def edit_reported_time(time_str)
|
52
|
+
date_time = time_handle(time_str)
|
53
|
+
@issue.reported_date = date_time.to_time
|
54
|
+
@issue.update
|
55
|
+
puts @strmaker.green('Updated reported date')
|
56
|
+
rescue ArgumentError
|
57
|
+
$stderr.puts @strmaker.red \
|
58
|
+
"Invalid date/time format. Try format like 'Oct 28'"
|
59
|
+
end
|
60
|
+
|
61
|
+
# TODO fix me
|
62
|
+
# @param time_str The time that we want to kind of sanitize
|
63
|
+
# @return a Time object which is set to 9am on that day if no time
|
64
|
+
# is provided
|
65
|
+
def time_handle(time_str)
|
66
|
+
date_time = DateTime.parse(time)
|
67
|
+
date_time = DateTime.parse(time + ' 9:00') if date_time.hour == 0
|
68
|
+
end
|
69
|
+
|
70
|
+
# Pass the issue from the previous ui to this one. This ui modifies
|
71
|
+
attr :issue
|
72
|
+
|
73
|
+
end
|
74
|
+
end # wlog
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'readline'
|
2
|
+
require 'wlog/domain/invoice'
|
3
|
+
require 'wlog/domain/sys_config'
|
4
|
+
require 'wlog/domain/static_configurations'
|
5
|
+
require 'erb'
|
6
|
+
|
7
|
+
module Wlog
|
8
|
+
# An interface for the invoices
|
9
|
+
# @author Simon Symeonidis
|
10
|
+
class InvoiceUi
|
11
|
+
include StaticConfigurations
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@strmaker = SysConfig.string_decorator
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
cmd = "default"
|
19
|
+
|
20
|
+
while cmd != 'end'
|
21
|
+
cmd = Readline.readline("[#{@strmaker.red('invoice')}] ") || ""
|
22
|
+
case cmd
|
23
|
+
when /^new/ then make_invoice
|
24
|
+
when /^(ls|show)/ then ls
|
25
|
+
when /^delete/ then delete(cmd.split.drop 1)
|
26
|
+
when /^generate/ then generate(cmd.split.drop 1)
|
27
|
+
when /^end/ then next
|
28
|
+
else
|
29
|
+
puts "type 'help' for a list of options"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# TODO maybe separate this in the future for better testing.
|
37
|
+
def generate(rest)
|
38
|
+
num = rest.first || 1
|
39
|
+
invoice = Invoice.find(num.to_i)
|
40
|
+
|
41
|
+
# NOTE: these need to be instance vars, so we expose them to ERB later on
|
42
|
+
@les = invoice.log_entries_within_dates
|
43
|
+
@issues = [Issue.find(*(@les.collect(&:issue_id).uniq))].compact.flatten
|
44
|
+
|
45
|
+
# Get the template
|
46
|
+
num = SysConfig.get_config('template') || 1
|
47
|
+
tpath = Dir[TemplateDir + '*'][num.to_i - 1]
|
48
|
+
template_s = File.read(tpath)
|
49
|
+
|
50
|
+
renderer = ERB.new(template_s)
|
51
|
+
output = renderer.result(binding)
|
52
|
+
|
53
|
+
FileUtils.mkdir_p TemplateOutputDir
|
54
|
+
template_ext = tpath.split(File::SEPARATOR).last.split('.').last
|
55
|
+
filename = TemplateOutputDir + "#{invoice.id}-invoice.#{template_ext}"
|
56
|
+
|
57
|
+
File.write(filename, output)
|
58
|
+
|
59
|
+
rescue ActiveRecord::RecordNotFound
|
60
|
+
puts 'No such invoice'
|
61
|
+
rescue => e
|
62
|
+
puts e.message
|
63
|
+
end
|
64
|
+
|
65
|
+
def delete(rest)
|
66
|
+
id = rest[0]
|
67
|
+
cmd = Readline.readline("Are you sure you want to delete invoice ##{id}? [y/n]: ")
|
68
|
+
return if cmd != 'y'
|
69
|
+
Invoice.delete(id)
|
70
|
+
end
|
71
|
+
|
72
|
+
def ls
|
73
|
+
Invoice.all.each do |invoice|
|
74
|
+
print " [#{invoice.id}] "
|
75
|
+
print @strmaker.yellow(invoice.from.strftime("%d-%m-%Y"))
|
76
|
+
print @strmaker.blue(" -> ")
|
77
|
+
print @strmaker.yellow(invoice.to.strftime("%d-%m-%Y"))
|
78
|
+
puts " #{invoice.description.split.first}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def print_help
|
83
|
+
['new', 'make a new invoice',
|
84
|
+
'ls,show', 'list the current invoice templates',
|
85
|
+
'delete', 'delete an invoice (eg: delete 2)',
|
86
|
+
'generate', 'generate an invoice using set template (eg: generate 2)'
|
87
|
+
].each_with_index do |cmd,ix|
|
88
|
+
print ' ' if ix % 2 == 1
|
89
|
+
puts cmd
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# TODO this should be extracted for testing
|
94
|
+
def make_invoice
|
95
|
+
from_s = Readline.readline("#{@strmaker.blue('From')} (dd-mm-yyyy) ")
|
96
|
+
to_s = Readline.readline("#{@strmaker.blue('To')} (dd-mm-yyyy) ")
|
97
|
+
|
98
|
+
from_d = DateTime.parse(from_s)
|
99
|
+
to_d = DateTime.parse(to_s + " 23:59")
|
100
|
+
description = longtext()
|
101
|
+
|
102
|
+
Invoice.create(:from => from_d, :to => to_d, :description => description)
|
103
|
+
end
|
104
|
+
|
105
|
+
# TODO: this would have to be factored out at some point. Also I think the
|
106
|
+
# implementation is crappy. I have to recheck at some point.
|
107
|
+
def longtext
|
108
|
+
times = 3
|
109
|
+
str = ""
|
110
|
+
count = 0
|
111
|
+
|
112
|
+
while times != 0 do
|
113
|
+
cur = Readline.readline()
|
114
|
+
str.concat(cur)
|
115
|
+
str.concat($/)
|
116
|
+
if ["", nil].include? cur
|
117
|
+
str.concat($/)
|
118
|
+
count += 1
|
119
|
+
if count == 2
|
120
|
+
times -= 1
|
121
|
+
count = 0
|
122
|
+
end
|
123
|
+
else
|
124
|
+
# reset blank line count. The user will have to hammer enter a few times
|
125
|
+
# to escape from this menu
|
126
|
+
count = 0
|
127
|
+
end
|
128
|
+
end
|
129
|
+
str end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
data/lib/wlog/ui/issue_ui.rb
CHANGED
@@ -8,14 +8,14 @@ require 'wlog/commands/innit_db'
|
|
8
8
|
require 'wlog/commands/concat_description'
|
9
9
|
require 'wlog/domain/sys_config'
|
10
10
|
require 'wlog/domain/timelog_helper'
|
11
|
+
require 'wlog/ui/edit_handler'
|
11
12
|
|
12
13
|
module Wlog
|
13
14
|
# The interface when focusing on an issue
|
14
15
|
# @author Simon
|
15
16
|
class IssueUi
|
16
|
-
def initialize(
|
17
|
+
def initialize(issue)
|
17
18
|
@issue = issue
|
18
|
-
@db = db
|
19
19
|
@strmaker = SysConfig.string_decorator
|
20
20
|
end
|
21
21
|
|
@@ -31,13 +31,13 @@ class IssueUi
|
|
31
31
|
when /^(ls|show)/ then show_entries
|
32
32
|
when /^desc/ then describe_issue
|
33
33
|
when /^delete/ then delete_entry
|
34
|
-
when /^edit/ then edit_what(cmd.split.drop 1)
|
34
|
+
when /^edit/ then EditHandler.new(@issue).edit_what(cmd.split.drop 1)
|
35
35
|
when /^concat/ then concat_description
|
36
36
|
when /^replace/ then replace_pattern
|
37
|
-
when /^search/ then search_term(cmd.split.drop 1)
|
37
|
+
when /^search/ then search_term((cmd.split.drop 1).join ' ')
|
38
38
|
when /^lt/ then time(cmd.split.drop 1) # lt for log time
|
39
39
|
when /^forget/ then cmd = "end"
|
40
|
-
when /^finish/ then finish
|
40
|
+
when /^finish/ then finish ? cmd = "end" : nil
|
41
41
|
when /^help/ then print_help
|
42
42
|
when /^end/ then next
|
43
43
|
else puts "Type 'help' for help"
|
@@ -78,7 +78,7 @@ private
|
|
78
78
|
question = 'Are you done with this task? [yes/no] :'
|
79
79
|
if ret = !! Readline.readline(question).match(/^yes/i)
|
80
80
|
@issue.mark_finished!
|
81
|
-
@issue.
|
81
|
+
@issue.save
|
82
82
|
end
|
83
83
|
ret end
|
84
84
|
|
@@ -87,20 +87,21 @@ private
|
|
87
87
|
description = Readline.readline("Enter new issue:#{$/} ")
|
88
88
|
description.chomp!
|
89
89
|
@issue.mark_working!
|
90
|
-
@issue.
|
91
|
-
NewEntry.new(
|
90
|
+
@issue.save
|
91
|
+
NewEntry.new(description, @issue).execute
|
92
92
|
end
|
93
93
|
|
94
94
|
def delete_entry
|
95
95
|
id = Readline.readline('Remove task log with id : ').to_i
|
96
|
-
LogEntry.
|
96
|
+
LogEntry.delete(id)
|
97
97
|
end
|
98
98
|
|
99
99
|
# Concatenate an aggregate description to a previous item
|
100
100
|
def concat_description
|
101
101
|
id = Readline.readline("ID of task to concatenate to: ").to_i
|
102
102
|
str = Readline.readline("Information to concatenate: ").chomp
|
103
|
-
ConcatDescription.new(
|
103
|
+
ok = ConcatDescription.new(id, str).execute
|
104
|
+
puts "No such issue" if !ok
|
104
105
|
end
|
105
106
|
|
106
107
|
# Replace a pattern from a description of a log entry
|
@@ -108,84 +109,27 @@ private
|
|
108
109
|
id = Readline.readline("ID of task to perform replace: ").to_i
|
109
110
|
old_pattern = Readline.readline('replace : ').chomp
|
110
111
|
new_pattern = Readline.readline('with : ').chomp
|
111
|
-
ReplacePattern.new(
|
112
|
+
ok = ReplacePattern.new(id, old_pattern, new_pattern).execute
|
113
|
+
puts "No such task" if !ok
|
112
114
|
end
|
113
115
|
|
114
116
|
def search_term(term)
|
115
117
|
term ||= ''
|
116
118
|
term.chomp!
|
117
|
-
print_entries(LogEntry.
|
118
|
-
end
|
119
|
-
|
120
|
-
# Command comes in as edit <...>. This definition will check what comes
|
121
|
-
# next and invoke the proper method to execute.
|
122
|
-
def edit_what(terms_a)
|
123
|
-
case terms_a[0]
|
124
|
-
when /^title/
|
125
|
-
title = (terms_a.drop 1).join ' '
|
126
|
-
@issue.description = title
|
127
|
-
@issue.update
|
128
|
-
|
129
|
-
when /^desc/
|
130
|
-
long = (terms_a.drop 1).join ' '
|
131
|
-
@issue.long_description = long
|
132
|
-
@issue.update
|
133
|
-
|
134
|
-
when /^due/
|
135
|
-
date_time = terms_a.drop 1
|
136
|
-
edit_time(date_time.join(' '))
|
137
|
-
|
138
|
-
when /^reported/
|
139
|
-
date_time = terms_a.drop 1
|
140
|
-
edit_reported_time(date_time.join(' '))
|
141
|
-
|
142
|
-
else
|
143
|
-
$stdout.puts "Usage: "
|
144
|
-
$stdout.puts " edit title - to edit the title"
|
145
|
-
$stdout.puts " edit desc - to edit the long description"
|
146
|
-
$stdout.puts " edit due - to edit the due date"
|
147
|
-
$stdout.puts " edit time - to edit the time"
|
148
|
-
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
# @param time is the date-time in string format (eg Oct 28)
|
153
|
-
def edit_time(time)
|
154
|
-
date_time = time_handle(time)
|
155
|
-
@issue.due_date = date_time.to_time
|
156
|
-
@issue.update
|
157
|
-
puts @strmaker.green('Updated due date')
|
158
|
-
rescue ArgumentError
|
159
|
-
$stderr.puts @strmaker.red \
|
160
|
-
"Invalid date/time format. Try format like 'Oct 28'"
|
161
|
-
end
|
162
|
-
|
163
|
-
def edit_reported_time(time_str)
|
164
|
-
date_time = time_handle(time_str)
|
165
|
-
@issue.reported_date = date_time.to_time
|
166
|
-
@issue.update
|
167
|
-
puts @strmaker.green('Updated reported date')
|
168
|
-
rescue ArgumentError
|
169
|
-
$stderr.puts @strmaker.red \
|
170
|
-
"Invalid date/time format. Try format like 'Oct 28'"
|
171
|
-
end
|
172
|
-
|
173
|
-
# TODO fix me
|
174
|
-
# @param time_str The time that we want to kind of sanitize
|
175
|
-
# @return a Time object which is set to 9am on that day if no time
|
176
|
-
# is provided
|
177
|
-
def time_handle(time_str)
|
178
|
-
date_time = DateTime.parse(time)
|
179
|
-
date_time = DateTime.parse(time + ' 9:00') if date_time.hour == 0
|
119
|
+
print_entries(LogEntry.where(["description LIKE ?", "%#{term}%"]))
|
180
120
|
end
|
181
121
|
|
182
122
|
# TODO might need refactoring
|
183
123
|
def show_entries
|
184
|
-
|
185
|
-
|
124
|
+
@issue.reload
|
125
|
+
print_entries(@issue.log_entries)
|
126
|
+
end
|
127
|
+
|
128
|
+
def print_entries(entries_a)
|
129
|
+
date_collections = entries_a.group_by{|le| le.created_at.strftime("%Y-%m-%d")}
|
186
130
|
date_collections.each_key do |date_c|
|
187
131
|
print @strmaker.green("#{date_c} - ")
|
188
|
-
print @strmaker.yellow(date_collections[date_c].first.
|
132
|
+
print @strmaker.yellow(date_collections[date_c].first.created_at.strftime("%A"))
|
189
133
|
puts " [#{@strmaker.magenta(date_collections[date_c].count.to_s)}]"
|
190
134
|
date_collections[date_c].each do |le|
|
191
135
|
puts " #{le}"
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'readline'
|
2
|
+
require 'wlog/domain/sys_config'
|
3
|
+
require 'wlog/commands/bootstrap_templates'
|
4
|
+
require 'wlog/domain/sys_config'
|
5
|
+
require 'wlog/domain/static_configurations'
|
6
|
+
|
7
|
+
module Wlog
|
8
|
+
# To list, and choose which template we want to use when making invoices.
|
9
|
+
# @author Simon Symeonidis
|
10
|
+
class TemplateUi
|
11
|
+
include StaticConfigurations
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@strmaker = SysConfig.string_decorator
|
15
|
+
# Checks for templates dir each run
|
16
|
+
BootstrapTemplates.new.execute
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
cmd = 'default'
|
21
|
+
|
22
|
+
while cmd != 'end'
|
23
|
+
cmd = Readline.readline("[#{@strmaker.green('templates')}] ").chomp
|
24
|
+
case cmd
|
25
|
+
when /^(ls|show)/ then ls
|
26
|
+
when /^set/ then set(cmd.split.drop 1)
|
27
|
+
when /^help/ then print_help
|
28
|
+
when /^end/ then next
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def print_help
|
36
|
+
['ls, show', 'list the current templates you can use',
|
37
|
+
'set <num>', 'set the template you want to use',
|
38
|
+
'help', 'print this menu'].each_with_index do |cmd,ix|
|
39
|
+
print " " if ix % 2 == 1
|
40
|
+
puts cmd
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def ls
|
45
|
+
num = SysConfig.get_config('template') || 1
|
46
|
+
num = num.to_i
|
47
|
+
Dir[TemplateDir + "*"].each_with_index do |file,ix|
|
48
|
+
print " #{ix + 1 == num ? @strmaker.blue('*') : ' '} "
|
49
|
+
print "[%3d] " % (ix + 1)
|
50
|
+
puts file
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def set(rest)
|
55
|
+
num = rest[0]
|
56
|
+
unless num
|
57
|
+
puts "usage: set <number>"
|
58
|
+
return
|
59
|
+
end
|
60
|
+
|
61
|
+
SysConfig.store_config('template', num)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
data/lib/wlog/version.rb
CHANGED