Pratt 1.6.2 → 1.6.4
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/.gitignore +2 -0
- data/Pratt.gemspec +38 -12
- data/README.html +85 -0
- data/README.txt +6 -3
- data/TODO +6 -3
- data/VERSION +1 -1
- data/config.rb +3 -17
- data/db/zips.csv.zip +0 -0
- data/lib/models.rb +8 -0
- data/lib/pratt.rb +58 -293
- data/lib/pratt.rb.orig +626 -0
- data/lib/pratt/core_ext.rb +6 -0
- data/lib/pratt/{array.rb → core_ext/array.rb} +5 -0
- data/lib/pratt/core_ext/float.rb +28 -0
- data/lib/pratt/core_ext/nil.rb +5 -0
- data/lib/pratt/core_ext/numeric.rb +9 -0
- data/lib/pratt/{string.rb → core_ext/string.rb} +13 -0
- data/lib/pratt/core_ext/time.rb +20 -0
- data/lib/pratt/dialogs.rb +81 -0
- data/lib/pratt/formatting.rb +24 -0
- data/lib/pratt/project_actions.rb +25 -0
- data/lib/pratt/reports.rb +127 -0
- data/models/app.rb +1 -2
- data/models/customer.rb +22 -0
- data/models/invoice.rb +28 -0
- data/models/invoice_whence.rb +18 -0
- data/models/payment.rb +1 -1
- data/models/pratt.rb +0 -9
- data/models/project.rb +16 -22
- data/models/whence.rb +10 -1
- data/models/zip.rb +27 -0
- data/spec/fixtures/graph.expectation +0 -5
- data/spec/fixtures/proportions.expectation +4 -0
- data/spec/float_spec.rb +24 -0
- data/spec/numeric_spec.rb +30 -0
- data/spec/pratt_spec.rb +5 -4
- data/spec/project_spec.rb +8 -2
- data/spec/spec.opts +1 -1
- data/spec/spec_helper.rb +31 -1
- data/spec/string_ext_spec.rb +33 -0
- data/views/current.eruby +5 -0
- data/views/general-invoice.eruby +538 -0
- data/views/graph.eruby +2 -7
- data/views/invoice.eruby +3 -3
- data/views/main.rb +8 -6
- data/views/proportions.eruby +4 -0
- data/views/raw.eruby +1 -1
- metadata +86 -33
- data/lib/pratt/time.rb +0 -12
- data/views/env.rb +0 -22
data/.gitignore
CHANGED
data/Pratt.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{Pratt}
|
8
|
-
s.version = "1.6.
|
8
|
+
s.version = "1.6.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Scott Noel-Hemming"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-05-30}
|
13
13
|
s.default_executable = %q{pratt.rb}
|
14
14
|
s.description = %q{
|
15
15
|
Need a way to keep track of your time, but get caught up in work? Or constant interruptions?
|
@@ -26,7 +26,8 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.email = %q{frogstarr78@gmail.com}
|
27
27
|
s.executables = ["pratt.rb"]
|
28
28
|
s.extra_rdoc_files = [
|
29
|
-
"README.
|
29
|
+
"README.html",
|
30
|
+
"README.txt",
|
30
31
|
"TODO"
|
31
32
|
]
|
32
33
|
s.files = [
|
@@ -36,6 +37,7 @@ Gem::Specification.new do |s|
|
|
36
37
|
"Manifest.txt",
|
37
38
|
"Pratt.gemspec",
|
38
39
|
"Pratt.mm",
|
40
|
+
"README.html",
|
39
41
|
"README.txt",
|
40
42
|
"Rakefile",
|
41
43
|
"Session.vim",
|
@@ -44,16 +46,30 @@ Gem::Specification.new do |s|
|
|
44
46
|
"bin/pratt.rb",
|
45
47
|
"config.rb",
|
46
48
|
"db/sqlite_databases_go_here",
|
49
|
+
"db/zips.csv.zip",
|
50
|
+
"lib/models.rb",
|
47
51
|
"lib/pratt.rb",
|
48
|
-
"lib/pratt
|
49
|
-
"lib/pratt/
|
50
|
-
"lib/pratt/
|
52
|
+
"lib/pratt.rb.orig",
|
53
|
+
"lib/pratt/core_ext.rb",
|
54
|
+
"lib/pratt/core_ext/array.rb",
|
55
|
+
"lib/pratt/core_ext/float.rb",
|
56
|
+
"lib/pratt/core_ext/nil.rb",
|
57
|
+
"lib/pratt/core_ext/numeric.rb",
|
58
|
+
"lib/pratt/core_ext/string.rb",
|
59
|
+
"lib/pratt/core_ext/time.rb",
|
60
|
+
"lib/pratt/dialogs.rb",
|
61
|
+
"lib/pratt/formatting.rb",
|
62
|
+
"lib/pratt/project_actions.rb",
|
63
|
+
"lib/pratt/reports.rb",
|
51
64
|
"models/app.rb",
|
52
65
|
"models/customer.rb",
|
66
|
+
"models/invoice.rb",
|
67
|
+
"models/invoice_whence.rb",
|
53
68
|
"models/payment.rb",
|
54
69
|
"models/pratt.rb",
|
55
70
|
"models/project.rb",
|
56
71
|
"models/whence.rb",
|
72
|
+
"models/zip.rb",
|
57
73
|
"pkgs/tile-0.8.2.tar.gz",
|
58
74
|
"pkgs/tile-0.8.2/ANNOUNCE.txt",
|
59
75
|
"pkgs/tile-0.8.2/ChangeLog",
|
@@ -298,41 +314,51 @@ Gem::Specification.new do |s|
|
|
298
314
|
"pkgs/tktray1.2.tar.gz",
|
299
315
|
"pratt.mm",
|
300
316
|
"reports/travel.log",
|
317
|
+
"reports/travel.log.2009",
|
301
318
|
"spec/app_spec.rb",
|
302
319
|
"spec/customer_spec.rb",
|
303
320
|
"spec/fixtures/graph.expectation",
|
321
|
+
"spec/fixtures/proportions.expectation",
|
322
|
+
"spec/float_spec.rb",
|
323
|
+
"spec/numeric_spec.rb",
|
304
324
|
"spec/payment_spec.rb",
|
305
325
|
"spec/pratt_spec.rb",
|
306
326
|
"spec/project_spec.rb",
|
307
327
|
"spec/rcov.opts",
|
308
328
|
"spec/spec.opts",
|
309
329
|
"spec/spec_helper.rb",
|
330
|
+
"spec/string_ext_spec.rb",
|
310
331
|
"spec/whence_spec.rb",
|
311
332
|
"tasks/pratt.rb",
|
312
333
|
"templates/model.eruby",
|
313
334
|
"templates/spec.eruby",
|
314
|
-
"views/
|
335
|
+
"views/current.eruby",
|
336
|
+
"views/general-invoice.eruby",
|
315
337
|
"views/graph.eruby",
|
316
338
|
"views/invoice.eruby",
|
317
339
|
"views/main.rb",
|
318
340
|
"views/pid.eruby",
|
319
341
|
"views/pop.rb",
|
320
342
|
"views/pop2.rb",
|
343
|
+
"views/proportions.eruby",
|
321
344
|
"views/raw.eruby"
|
322
345
|
]
|
323
346
|
s.homepage = %q{http://github.com/frogstarr78/pratt}
|
324
347
|
s.rdoc_options = ["--charset=UTF-8"]
|
325
348
|
s.require_paths = ["lib"]
|
326
349
|
s.rubyforge_project = %q{Pratt}
|
327
|
-
s.rubygems_version = %q{1.3.
|
350
|
+
s.rubygems_version = %q{1.3.6}
|
328
351
|
s.summary = %q{Pro/Re-Active Time Tracker. Track time based on what you expect to be working on, with frequent prompts to ensure accuracy.}
|
329
352
|
s.test_files = [
|
330
|
-
"spec/
|
331
|
-
"spec/project_spec.rb",
|
332
|
-
"spec/pratt_spec.rb",
|
353
|
+
"spec/whence_spec.rb",
|
333
354
|
"spec/spec_helper.rb",
|
355
|
+
"spec/float_spec.rb",
|
356
|
+
"spec/pratt_spec.rb",
|
357
|
+
"spec/project_spec.rb",
|
358
|
+
"spec/numeric_spec.rb",
|
334
359
|
"spec/app_spec.rb",
|
335
|
-
"spec/
|
360
|
+
"spec/string_ext_spec.rb",
|
361
|
+
"spec/customer_spec.rb",
|
336
362
|
"spec/payment_spec.rb"
|
337
363
|
]
|
338
364
|
|
data/README.html
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
<p>= pratt</p>
|
2
|
+
|
3
|
+
<ul>
|
4
|
+
<li>Pratt (url)</li>
|
5
|
+
</ul>
|
6
|
+
|
7
|
+
|
8
|
+
<p>== DESCRIPTION:</p>
|
9
|
+
|
10
|
+
<p>Pratt (describe your package)
|
11
|
+
(Pro/Re)-Active Time Tracker</p>
|
12
|
+
|
13
|
+
<p>== FEATURES/PROBLEMS:</p>
|
14
|
+
|
15
|
+
<p>(list of features or problems)
|
16
|
+
* Currently you'll need to manually fix the project data since I haven't
|
17
|
+
fully integrated the support for Projects to have customer's and my current
|
18
|
+
implementation is shoddy.
|
19
|
+
* Upgrading versions looses your database. (See TODO)
|
20
|
+
* Windows doesn't work (no fork). (See TODO)</p>
|
21
|
+
|
22
|
+
<p>== SYNOPSIS:</p>
|
23
|
+
|
24
|
+
<ul>
|
25
|
+
<li>pratt (code sample of usage)</li>
|
26
|
+
</ul>
|
27
|
+
|
28
|
+
|
29
|
+
<p><strong> PRATT_ENV=production pratt -D # daemonize (or if already daemonized init the
|
30
|
+
gui)
|
31
|
+
</strong> pratt -h (as you'd expect lists available commands)</p>
|
32
|
+
|
33
|
+
<p>== REQUIREMENTS:</p>
|
34
|
+
|
35
|
+
<ul>
|
36
|
+
<li>pratt
|
37
|
+
debian: libtcltk-ruby tk-tile libsqlite3-dev
|
38
|
+
gems: activerecord sqlite3-ruby rspec mocha
|
39
|
+
tk: http://sourceforge.net/project/showfiles.php?group_id=11464&package_id=107795&release_id=562098</li>
|
40
|
+
</ul>
|
41
|
+
|
42
|
+
|
43
|
+
<p>== INSTALL:</p>
|
44
|
+
|
45
|
+
<ul>
|
46
|
+
<li>sudo gem install</li>
|
47
|
+
</ul>
|
48
|
+
|
49
|
+
|
50
|
+
<p>Credits</p>
|
51
|
+
|
52
|
+
<p>Michael Goff</p>
|
53
|
+
|
54
|
+
<pre><code>Thanks for helping me with some of the workflow details
|
55
|
+
</code></pre>
|
56
|
+
|
57
|
+
<p>Michael and Kent Krenrich</p>
|
58
|
+
|
59
|
+
<pre><code>Thanks for the UI input, suggestions, and testing.
|
60
|
+
</code></pre>
|
61
|
+
|
62
|
+
<p>== LICENSE:</p>
|
63
|
+
|
64
|
+
<p>(The MIT License)</p>
|
65
|
+
|
66
|
+
<p>Copyright (c) 2009 Frogstarr78 Software</p>
|
67
|
+
|
68
|
+
<p>Permission is hereby granted, free of charge, to any person obtaining
|
69
|
+
a copy of this software and associated documentation files (the
|
70
|
+
'Software'), to deal in the Software without restriction, including
|
71
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
72
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
73
|
+
permit persons to whom the Software is furnished to do so, subject to
|
74
|
+
the following conditions:</p>
|
75
|
+
|
76
|
+
<p>The above copyright notice and this permission notice shall be
|
77
|
+
included in all copies or substantial portions of the Software.</p>
|
78
|
+
|
79
|
+
<p>THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
80
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
81
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
82
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
83
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
84
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
85
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p>
|
data/README.txt
CHANGED
@@ -9,10 +9,13 @@ Pratt (describe your package)
|
|
9
9
|
|
10
10
|
== FEATURES/PROBLEMS:
|
11
11
|
|
12
|
-
|
13
|
-
Currently you'll need to manually fix the project data since I haven't
|
12
|
+
(list of features or problems)
|
13
|
+
* Currently you'll need to manually fix the project data since I haven't
|
14
14
|
fully integrated the support for Projects to have customer's and my current
|
15
15
|
implementation is shoddy.
|
16
|
+
* Upgrading versions looses your database. (See TODO)
|
17
|
+
* Windows doesn't work (no fork). (See TODO)
|
18
|
+
|
16
19
|
|
17
20
|
== SYNOPSIS:
|
18
21
|
|
@@ -44,7 +47,7 @@ Michael and Kent Krenrich
|
|
44
47
|
|
45
48
|
(The MIT License)
|
46
49
|
|
47
|
-
Copyright (c) 2009
|
50
|
+
Copyright (c) 2009 Frogstarr78 Software
|
48
51
|
|
49
52
|
Permission is hereby granted, free of charge, to any person obtaining
|
50
53
|
a copy of this software and associated documentation files (the
|
data/TODO
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
General:
|
2
|
-
[ ]
|
2
|
+
[ ] Remove environment ability
|
3
3
|
[ ] Change to use raw command line arguments / Remove optparse lib
|
4
4
|
[ ] Update general package setup (It's messy)
|
5
5
|
[?] Add file watching like merb
|
6
6
|
[?] Move to Observer Pattern for reporting functionality
|
7
7
|
|
8
8
|
Invoicing:
|
9
|
-
[
|
9
|
+
[x] Add shifty week plugin
|
10
10
|
[ ] Add support for variable rates.
|
11
11
|
|
12
12
|
Templating:
|
@@ -14,8 +14,9 @@ Invoicing:
|
|
14
14
|
[ ] Move other output to template based
|
15
15
|
|
16
16
|
Data:
|
17
|
-
[
|
17
|
+
[?] Change to Use DataMapper
|
18
18
|
[?] Put everything in the db? (logs, app locks, etc)
|
19
|
+
[ ] Move database location to central location that doesn't dissappear when upgrading the app.
|
19
20
|
|
20
21
|
GUI:
|
21
22
|
[ ] Add TrayIcon.
|
@@ -23,6 +24,8 @@ GUI:
|
|
23
24
|
[ ] Payment CRUD
|
24
25
|
[ ] Re-design prompts
|
25
26
|
[ ] Remove fork in favor of ( eval OR (!?!) GUI classes )
|
27
|
+
[ ] Don't assume gui.
|
28
|
+
[ ] Add options for cli user prompting.
|
26
29
|
|
27
30
|
Test:
|
28
31
|
[ ] Add more I'm not testing everything
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.6.
|
1
|
+
1.6.4
|
data/config.rb
CHANGED
@@ -2,22 +2,13 @@ require 'active_record'
|
|
2
2
|
PRATT_ENV = ENV["PRATT_ENV"] || 'development' unless Object.const_defined? :PRATT_ENV
|
3
3
|
|
4
4
|
class Pratt
|
5
|
-
@@connected_to = nil
|
6
|
-
module Test
|
7
|
-
end
|
8
|
-
|
9
5
|
include FileUtils
|
10
6
|
|
11
7
|
class << self
|
12
|
-
def connected_to?
|
13
|
-
@@connected_to
|
14
|
-
end
|
15
|
-
|
16
8
|
def connect! to_env = :development
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
unless File.exists? connected_to?
|
9
|
+
connect_to = "db/#{to_env}.sqlite3"
|
10
|
+
ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => connect_to )
|
11
|
+
unless File.exists? connect_to
|
21
12
|
Pratt.migrate
|
22
13
|
end
|
23
14
|
end
|
@@ -25,10 +16,5 @@ class Pratt
|
|
25
16
|
def connected?
|
26
17
|
ActiveRecord::Base.connected?
|
27
18
|
end
|
28
|
-
|
29
|
-
def config= env
|
30
|
-
include Pratt::Test
|
31
|
-
end
|
32
19
|
end
|
33
|
-
|
34
20
|
end
|
data/db/zips.csv.zip
ADDED
Binary file
|
data/lib/models.rb
ADDED
data/lib/pratt.rb
CHANGED
@@ -8,22 +8,18 @@ require 'colored'
|
|
8
8
|
require 'chronic'
|
9
9
|
require 'active_record'
|
10
10
|
require 'erubis'
|
11
|
-
require 'hoe'
|
12
|
-
require 'mocha'
|
13
11
|
require 'config'
|
14
12
|
require 'shifty_week'
|
15
13
|
require 'shifty_week/time'
|
16
14
|
require 'shifty_week/date'
|
17
15
|
|
18
|
-
require 'lib/pratt/
|
19
|
-
require 'lib/pratt/
|
20
|
-
require 'lib/pratt/
|
16
|
+
require 'lib/pratt/formatting'
|
17
|
+
require 'lib/pratt/core_ext'
|
18
|
+
require 'lib/pratt/dialogs'
|
19
|
+
require 'lib/pratt/project_actions'
|
20
|
+
require 'lib/pratt/reports'
|
21
|
+
require 'lib/models'
|
21
22
|
|
22
|
-
require 'models/app'
|
23
|
-
require 'models/customer'
|
24
|
-
require 'models/whence'
|
25
|
-
require 'models/project'
|
26
|
-
require 'models/payment'
|
27
23
|
|
28
24
|
class Pratt
|
29
25
|
|
@@ -49,9 +45,8 @@ class Pratt
|
|
49
45
|
PID_FILE='pratt.pid'
|
50
46
|
FMT = "%a %X %b %d %Y"
|
51
47
|
INVOICE_FMT = "%x"
|
52
|
-
@@color = true
|
53
48
|
|
54
|
-
attr_accessor :when_to, :scale, :color, :show_all, :
|
49
|
+
attr_accessor :when_to, :scale, :color, :show_all, :raw_conditions, :template, :week_day_start
|
55
50
|
attr_reader :project, :todo
|
56
51
|
def initialize proj = nil
|
57
52
|
@when_to = DateTime.now
|
@@ -61,7 +56,6 @@ class Pratt
|
|
61
56
|
@scale = nil
|
62
57
|
@show_all = false
|
63
58
|
@template = nil
|
64
|
-
@env = :development
|
65
59
|
@raw_conditions = ''
|
66
60
|
self.project = proj unless proj.nil?
|
67
61
|
end
|
@@ -82,300 +76,85 @@ class Pratt
|
|
82
76
|
@todo << what
|
83
77
|
end
|
84
78
|
|
85
|
-
#
|
86
|
-
def app
|
87
|
-
@app ||= App.last
|
88
|
-
@app
|
89
|
-
end
|
90
|
-
|
91
|
-
# TODO Rename
|
92
|
-
def graph
|
93
|
-
@primary = @off_total = @rest_total = 0.0
|
94
|
-
self.template = 'graph'
|
95
|
-
|
96
|
-
if project?
|
97
|
-
@projects = [project]
|
98
|
-
|
99
|
-
@primary = project.time_spent(scale, when_to)
|
100
|
-
@scaled_total = project.whences.time_spent(scale, when_to)
|
101
|
-
else
|
102
|
-
@projects = Project.all
|
103
|
-
|
104
|
-
@projects.each do |proj|
|
105
|
-
@primary = proj.time_spent(scale, when_to) if proj.name == Project.primary.name
|
106
|
-
@off_total = proj.time_spent(scale, when_to) if proj.name == Project.off.name
|
107
|
-
@rest_total += proj.time_spent(scale, when_to) if Project.rest.collect(&:name).include?(proj.name)
|
108
|
-
end
|
109
|
-
@scaled_total = Whence.time_spent(scale, when_to)-@off_total
|
110
|
-
end
|
111
|
-
|
112
|
-
if @primary + @off_total + @rest_total > 0.0
|
113
|
-
process_template!
|
114
|
-
else
|
115
|
-
"No data to report"
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
# Generate an invoice for a given time period
|
120
|
-
def invoice
|
121
|
-
self.template = 'invoice'
|
122
|
-
|
123
|
-
if project?
|
124
|
-
@projects = [project]
|
125
|
-
|
126
|
-
@total = project.time_spent(scale, when_to)
|
127
|
-
else
|
128
|
-
@projects = (Project.all - [Project.primary, Project.off])
|
129
|
-
@projects.select! {|proj| show_all or ( !show_all and proj.time_spent(scale, when_to) != 0.0 ) }
|
130
|
-
|
131
|
-
@total = @projects.inject 0.0 do |total, proj|
|
132
|
-
total += proj.time_spent(scale, when_to)
|
133
|
-
total
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
@projects.each do |project|
|
138
|
-
puts "#{project.name} #{project.payment.inspect}"
|
139
|
-
end
|
140
|
-
if @total > 0.0
|
141
|
-
puts process_template!
|
142
|
-
else
|
143
|
-
puts "No data to report"
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
79
|
+
# Connect to the database in irb for manual commands/investigation
|
147
80
|
def console options = []
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
def current
|
153
|
-
project_names = ([Project.primary, Project.off] | Project.rest).collect(&:name)
|
154
|
-
|
155
|
-
if last_whence = Whence.last_unended || Whence.last
|
156
|
-
puts " projects: " << (
|
157
|
-
project_names.collect {|project_name| "'#{project_name.send(last_whence.end_at.nil? && last_whence.project.name == project_name ? :green : :magenta)}'" }
|
158
|
-
) * ' '
|
159
|
-
if last_whence.end_at.nil?
|
160
|
-
puts " started: #{last_whence.start_at.strftime(FMT).send(:blue)}"
|
161
|
-
time_til = ( app.interval - ( Time.now - last_whence.start_at ) )
|
162
|
-
puts "next prompt: %s %s"% [Pratt.fmt_i( time_til / 60.0, 'min', :yellow ), Pratt.fmt_i( time_til % 60, 'sec', :yellow ) ], ''
|
163
|
-
end
|
164
|
-
else
|
165
|
-
puts " projects: " << (
|
166
|
-
project_names.collect do |project_name|
|
167
|
-
"'#{project_name.magenta}'"
|
168
|
-
end
|
169
|
-
) * ' '
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
def begin
|
174
|
-
self.project.start! when_to
|
175
|
-
end
|
176
|
-
def restart
|
177
|
-
if project?
|
178
|
-
project.restart! when_to
|
179
|
-
else
|
180
|
-
Whence.last_unended.project.restart! when_to
|
181
|
-
end
|
182
|
-
end
|
183
|
-
def end
|
184
|
-
if project?
|
185
|
-
project.stop! when_to
|
186
|
-
else
|
187
|
-
Whence.last_unended.stop! when_to
|
188
|
-
end
|
189
|
-
end
|
190
|
-
def change
|
191
|
-
Whence.last.change! project.name
|
192
|
-
end
|
193
|
-
def destroy
|
194
|
-
project.destroy
|
195
|
-
end
|
196
|
-
|
197
|
-
def cpid
|
198
|
-
`pgrep -fl 'bin/pratt'`.chomp.split(' ').first
|
199
|
-
end
|
200
|
-
|
201
|
-
def pid
|
202
|
-
self.template = 'pid'
|
203
|
-
puts process_template!
|
204
|
-
end
|
205
|
-
|
206
|
-
def raw
|
207
|
-
self.template = 'raw'
|
208
|
-
|
209
|
-
if project?
|
210
|
-
@whences = project.whences.all
|
211
|
-
else
|
212
|
-
case raw_conditions
|
213
|
-
when 'all'
|
214
|
-
@whences = Whence.find raw_conditions.to_sym
|
215
|
-
when /^last$/, 'first'
|
216
|
-
@whences = [Whence.find raw_conditions.to_sym]
|
217
|
-
when /last[\(\s]?(\d+)[\)\s]?/
|
218
|
-
@whences = Whence.all.last($1.to_i)
|
219
|
-
else
|
220
|
-
@whences = Whence.all :conditions => ["start_at > ?", Chronic.parse("today 00:00")]
|
221
|
-
end
|
222
|
-
end
|
223
|
-
@whences.sort_by(&:id)
|
224
|
-
puts process_template!
|
81
|
+
require 'irb'
|
82
|
+
require 'irb/completion'
|
83
|
+
ARGV.clear
|
84
|
+
IRB.start
|
225
85
|
end
|
226
86
|
|
87
|
+
# Stop everything and kill daemonized processes.
|
227
88
|
def quit
|
228
89
|
project.stop! if project? and project.whences.last_unended
|
229
90
|
Whence.last_unended.stop! if Whence.last_unended
|
230
91
|
begin
|
231
92
|
Process.kill("KILL", app.pid.to_i)
|
232
93
|
rescue Errno::ESRCH
|
94
|
+
puts "Unable to kill Pratt@pid(#{app.pid})."
|
233
95
|
end
|
234
96
|
app.pid = ''
|
235
97
|
app.gui = ''
|
236
98
|
app.save!
|
237
99
|
end
|
238
100
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
main
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
def show_env
|
248
|
-
defork { system("ruby views/env.rb ") }
|
249
|
-
end
|
250
|
-
|
251
|
-
def detect
|
252
|
-
if self.daemonized?
|
253
|
-
gui
|
254
|
-
else
|
255
|
-
daemonize!
|
256
|
-
end
|
101
|
+
# Singleton Accessor for @app
|
102
|
+
def app
|
103
|
+
@app ||= App.last
|
104
|
+
@app
|
257
105
|
end
|
258
106
|
|
107
|
+
# "Unlock" the gui.
|
259
108
|
def unlock
|
260
109
|
self.app.unlock
|
261
110
|
end
|
262
111
|
|
263
112
|
def run
|
113
|
+
# ensure we've shifted the when_to value to the
|
114
|
+
# current start of week
|
264
115
|
self.when_to.week_day_start = self.week_day_start
|
265
|
-
puts self.when_to.inspect, self.when_to.week_day_start
|
266
|
-
# must happen before any actions but after all cli argument parsing
|
267
|
-
|
268
|
-
self.begin if i_should? :begin
|
269
|
-
self.change if i_should? :change
|
270
|
-
self.restart if i_should? :restart
|
271
|
-
self.end if i_should? :end
|
272
|
-
|
273
|
-
self.destroy if i_should? :destroy
|
274
|
-
|
275
|
-
self.pid if i_should? :pid
|
276
|
-
self.raw if i_should? :raw
|
277
|
-
self.current if i_should? :current
|
278
|
-
puts self.graph if i_should? :graph
|
279
|
-
self.invoice if i_should? :invoice
|
280
|
-
self.console if i_should? :console
|
281
|
-
self.gui if i_should? :gui
|
282
|
-
self.show_env if i_should? :env
|
283
|
-
self.detect if i_should? :detect
|
284
|
-
self.unlock if i_should? :unlock
|
285
|
-
|
286
|
-
self.quit if i_should? :quit
|
287
|
-
self.daemonize! if i_should? :daemonize and not self.daemonized?
|
288
|
-
end
|
289
116
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
self.
|
117
|
+
# << order is semi important
|
118
|
+
self.end if i_should? :end
|
119
|
+
self.begin if i_should? :begin
|
120
|
+
self.change if i_should? :change
|
121
|
+
self.restart if i_should? :restart
|
122
|
+
|
123
|
+
self.destroy if i_should? :destroy
|
124
|
+
# end order is semi important
|
125
|
+
|
126
|
+
# << order doesn't matter within this set
|
127
|
+
self.pid if i_should? :pid
|
128
|
+
self.raw if i_should? :raw
|
129
|
+
self.current if i_should? :current
|
130
|
+
self.graph if i_should? :graph
|
131
|
+
self.proportions if i_should? :proportions
|
132
|
+
self.invoice if i_should? :invoice
|
133
|
+
self.console if i_should? :console
|
134
|
+
self.gui if i_should? :gui
|
135
|
+
self.detect if i_should? :detect
|
136
|
+
self.unlock if i_should? :unlock
|
137
|
+
# end order doesn't matter within this set
|
138
|
+
|
139
|
+
# << these should happen last
|
140
|
+
self.quit if i_should? :quit
|
141
|
+
self.daemonize! if i_should? :daemonize and not self.daemonized?
|
142
|
+
# end these should happen last
|
310
143
|
end
|
311
144
|
|
312
145
|
private
|
313
|
-
def main
|
314
|
-
self.app.reload
|
315
|
-
return if self.app.gui?('main', true)
|
316
|
-
self.app.log('main')
|
317
|
-
projects = ([Project.primary, Project.off] | Project.rest).collect(&:name)
|
318
|
-
if Whence.count == 0
|
319
|
-
# first run
|
320
|
-
project = Whence.new(:project => Project.primary)
|
321
|
-
else
|
322
|
-
project = Whence.last_unended || Whence.last
|
323
|
-
end
|
324
|
-
defork { system("ruby views/main.rb --projects '#{projects*"','"}' --current '#{project.project.name}'") }
|
325
|
-
end
|
326
|
-
def pop
|
327
|
-
self.app.reload
|
328
|
-
return if self.app.gui?('pop', true)
|
329
|
-
self.app.log('pop')
|
330
|
-
self.project = Whence.last_unended.project
|
331
|
-
defork { system("ruby views/pop.rb --project '#{project.name}' --start '#{project.whences.last_unended.start_at}' --project_time '#{Pratt.totals(project.time_spent)}'") }
|
332
|
-
end
|
333
|
-
|
334
146
|
def i_should? what
|
335
147
|
@todo.include?(what)
|
336
148
|
end
|
337
149
|
|
150
|
+
# Is there a project that can be operated on?
|
338
151
|
def project?
|
339
152
|
!@project.nil? and @project.name?
|
340
153
|
end
|
341
154
|
|
342
|
-
def process_template!
|
343
|
-
input = File.open(Pratt.root("views", "#{template}.eruby").first).read
|
344
|
-
erubis = Erubis::Eruby.new(input)
|
345
|
-
erubis.evaluate(self)
|
346
|
-
end
|
347
|
-
|
348
|
-
def padded_to_max string
|
349
|
-
self.class.padded_to_max string
|
350
|
-
end
|
351
|
-
|
352
|
-
def defork &block
|
353
|
-
Process.detach(
|
354
|
-
fork &block
|
355
|
-
)
|
356
|
-
end
|
357
|
-
|
358
155
|
class << self
|
359
156
|
|
360
|
-
|
361
|
-
def max
|
362
|
-
# TODO Fix me
|
363
|
-
@max ||= Project.all.inject(0) {|x,p| x = p.name.length if p.name.length > x; x }
|
364
|
-
end
|
365
|
-
|
366
|
-
def color
|
367
|
-
@@color
|
368
|
-
end
|
369
|
-
|
370
|
-
def color= c
|
371
|
-
@@color = c
|
372
|
-
end
|
373
|
-
|
374
|
-
def color?
|
375
|
-
@@color == true
|
376
|
-
end
|
377
|
-
|
378
|
-
|
157
|
+
# Parse cli arguments and init Pratt
|
379
158
|
def parse args
|
380
159
|
me = Pratt.new
|
381
160
|
|
@@ -409,6 +188,9 @@ class Pratt
|
|
409
188
|
opt.on('-I', "--invoice", "Create an invoice.") do
|
410
189
|
me << :invoice
|
411
190
|
end
|
191
|
+
opt.on('-r', '--proportions', "") do
|
192
|
+
me << :proportions
|
193
|
+
end
|
412
194
|
opt.on('-p', '--pid', "Process id display. (Is it still running)") do
|
413
195
|
me << :pid
|
414
196
|
end
|
@@ -442,7 +224,11 @@ class Pratt
|
|
442
224
|
end
|
443
225
|
|
444
226
|
# Strictly configuration options
|
445
|
-
|
227
|
+
project_names = Project.all.collect(&:name)
|
228
|
+
colored_project_names = project_names.collect{|name|
|
229
|
+
" #{name.cyan}"}
|
230
|
+
opt.on('-P', "--project PROJECT_NAME", project_names, "Set project.
|
231
|
+
Available projects are:\n#{colored_project_names*"\n"}") do |proj|
|
446
232
|
me.project = proj
|
447
233
|
end
|
448
234
|
|
@@ -485,22 +271,11 @@ class Pratt
|
|
485
271
|
opt.parse!
|
486
272
|
end
|
487
273
|
|
488
|
-
me << :env if args.include? 'env'
|
489
274
|
me << :console if args.include? 'console'
|
490
275
|
|
491
276
|
me.run
|
492
277
|
end
|
493
278
|
|
494
|
-
# Calculate totals. I think this should be an instance method on Projects/?/Whences
|
495
|
-
def totals hr, fmt = false
|
496
|
-
"#{fmt_i(hr / 24, 'day', :cyan)} #{fmt_i(hr % 24, 'hour', :yellow)} #{fmt_i((60*(hr -= hr.to_i)), 'min', :green)}"
|
497
|
-
end
|
498
|
-
|
499
|
-
def percent label, off, total, color
|
500
|
-
percent = "%0.2f"% ((off/total)*100)
|
501
|
-
padded_to_max(label) << " #{percent}%".send(color)
|
502
|
-
end
|
503
|
-
|
504
279
|
# Where is Pratt installed.
|
505
280
|
# We've already chdir'd to it's base dir in the bin file
|
506
281
|
def root *globs, &block
|
@@ -518,15 +293,10 @@ class Pratt
|
|
518
293
|
end
|
519
294
|
end
|
520
295
|
|
521
|
-
# Pad the output string to the maximum Project name
|
522
|
-
def padded_to_max string
|
523
|
-
"%#{max}.#{max}s"% string
|
524
|
-
end
|
525
|
-
|
526
296
|
# Migrate schema.
|
527
297
|
def migrate
|
528
298
|
Pratt.root( 'models', '*.rb' ) do |model_file|
|
529
|
-
klass = File.basename( model_file, '.rb' ).
|
299
|
+
klass = File.basename( model_file, '.rb' ).classify.constantize
|
530
300
|
begin
|
531
301
|
ActiveRecord::Base.connection.table_structure(model_file)
|
532
302
|
rescue ActiveRecord::StatementInvalid
|
@@ -534,10 +304,5 @@ class Pratt
|
|
534
304
|
end
|
535
305
|
end
|
536
306
|
end
|
537
|
-
|
538
|
-
def fmt_i int, label, color
|
539
|
-
"%s #{label}"% [("%02i"% int).send(color), label]
|
540
|
-
end
|
541
|
-
|
542
307
|
end
|
543
308
|
end
|