timetrap 1.7.3 → 1.7.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/CONTRIBUTORS +1 -0
- data/README.md +23 -3
- data/VERSION.yml +1 -1
- data/lib/timetrap/cli.rb +17 -7
- data/lib/timetrap/formatters/factor.rb +19 -0
- data/lib/timetrap/formatters/text.rb +1 -2
- data/lib/timetrap/helpers.rb +4 -7
- data/lib/timetrap/models.rb +7 -0
- data/lib/timetrap/timer.rb +9 -0
- data/spec/timetrap_spec.rb +60 -0
- data/timetrap.gemspec +3 -2
- metadata +5 -4
data/CONTRIBUTORS
CHANGED
data/README.md
CHANGED
@@ -118,9 +118,9 @@ list of parsable time formats, but all of these should work.
|
|
118
118
|
|
119
119
|
#### Built-in Formatters
|
120
120
|
|
121
|
-
Timetrap has built-in support for
|
121
|
+
Timetrap has built-in support for 6 output formats.
|
122
122
|
|
123
|
-
These are **text**, **csv**, **ical**, **json**, and **ids**
|
123
|
+
These are **text**, **csv**, **ical**, **json**, **factor** and **ids**
|
124
124
|
|
125
125
|
The default is a plain **text** format. (You can change the default format using
|
126
126
|
`t configure`).
|
@@ -167,10 +167,29 @@ from one sheet to another sheet. You could do something like this:
|
|
167
167
|
editing entry #44
|
168
168
|
editing entry #46
|
169
169
|
|
170
|
-
A *json* formatter is
|
170
|
+
A *json* formatter is provided because hackers love json.
|
171
171
|
|
172
172
|
$ t d -fjson
|
173
173
|
|
174
|
+
The *factor* formatter is like the default *text* formatter, except it reads special
|
175
|
+
notes in your entry descriptions, and multiplies the entry's duration by them.
|
176
|
+
A note like *f:2* will multiply the entry's duration by two in the output.
|
177
|
+
See https://github.com/samg/timetrap/issues#issue/13 for more details.
|
178
|
+
|
179
|
+
$ # note durations are multiplications of start and end times, based on notes
|
180
|
+
$ t d -ffactor
|
181
|
+
Timesheet: nopoconi
|
182
|
+
Day Start End Duration Notes
|
183
|
+
Mon Mar 07, 2011 19:56:06 - 20:18:37 0:22:31 merge factor in timetrap, f:3
|
184
|
+
20:19:04 - 20:23:02 0:01:59 document factor formatter f:0.5
|
185
|
+
|
186
|
+
0:22:34
|
187
|
+
---------------------------------------------------------
|
188
|
+
Total 0:22:34
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
|
174
193
|
#### Custom Formatters
|
175
194
|
|
176
195
|
Timetrap tries to make it easy to define custom output formats.
|
@@ -302,6 +321,7 @@ Commands
|
|
302
321
|
**sheet**
|
303
322
|
Switch to a timesheet creating it if necessary. The default timesheet is
|
304
323
|
called "default". When no sheet is specified list all existing sheets.
|
324
|
+
The special timesheet name '-' will switch to the last active sheet.
|
305
325
|
|
306
326
|
usage: ``t sheet [TIMESHEET]``
|
307
327
|
|
data/VERSION.yml
CHANGED
data/lib/timetrap/cli.rb
CHANGED
@@ -40,7 +40,7 @@ COMMAND is one of:
|
|
40
40
|
-s, --start <date:qs> Include entries that start on this date or later
|
41
41
|
-e, --end <date:qs> Include entries that start on this date or earlier
|
42
42
|
-f, --format <format> The output format. Valid built-in formats are
|
43
|
-
ical, csv, json, ids, and text (default).
|
43
|
+
ical, csv, json, ids, factor, and text (default).
|
44
44
|
Documentation on defining custom formats can be
|
45
45
|
found in the README included in this
|
46
46
|
distribution.
|
@@ -79,7 +79,8 @@ COMMAND is one of:
|
|
79
79
|
-a, --at <time:qs> Use this time instead of now
|
80
80
|
|
81
81
|
* sheet - Switch to a timesheet creating it if necessary. When no sheet is
|
82
|
-
specified list all sheets.
|
82
|
+
specified list all sheets. The special sheetname '-' will switch to the
|
83
|
+
last active sheet.
|
83
84
|
usage: t sheet [TIMESHEET]
|
84
85
|
|
85
86
|
* week - Shortcut for display with start date set to monday of this week.
|
@@ -270,12 +271,21 @@ COMMAND is one of:
|
|
270
271
|
|
271
272
|
def sheet
|
272
273
|
sheet = unused_args
|
273
|
-
|
274
|
+
case sheet
|
275
|
+
when nil, ''
|
274
276
|
list
|
275
|
-
|
276
|
-
|
277
|
-
|
277
|
+
return
|
278
|
+
when '-'
|
279
|
+
if Timer.last_sheet
|
280
|
+
sheet = Timer.last_sheet
|
281
|
+
else
|
282
|
+
warn 'LAST_SHEET is not set'
|
283
|
+
return
|
284
|
+
end
|
278
285
|
end
|
286
|
+
|
287
|
+
Timer.current_sheet = sheet
|
288
|
+
warn "Switching to sheet #{sheet.inspect}"
|
279
289
|
end
|
280
290
|
|
281
291
|
def list
|
@@ -314,7 +324,7 @@ COMMAND is one of:
|
|
314
324
|
Timer.running_entries.each do |entry|
|
315
325
|
current = entry[:sheet] == Timer.current_sheet
|
316
326
|
out = current ? '*' : ' '
|
317
|
-
out << "#{entry[:sheet]}: #{format_duration(entry.
|
327
|
+
out << "#{entry[:sheet]}: #{format_duration(entry.duration)}".gsub(/ /, ' ')
|
318
328
|
out << " (#{entry.note})" if entry.note =~ /.+/
|
319
329
|
puts out
|
320
330
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Timetrap
|
2
|
+
module Formatters
|
3
|
+
require File.join( File.dirname(__FILE__), 'text' )
|
4
|
+
|
5
|
+
class Factor < Text
|
6
|
+
def initialize entries
|
7
|
+
entries.map! do |e|
|
8
|
+
factor = 1
|
9
|
+
if e.note =~ /\bf(actor)?:([\d\.]+)\b/
|
10
|
+
factor = $2.to_f
|
11
|
+
end
|
12
|
+
e.duration = (e.end_or_now.to_i - e.start.to_i) * factor
|
13
|
+
e
|
14
|
+
end
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -19,13 +19,12 @@ module Timetrap
|
|
19
19
|
from_current_day = []
|
20
20
|
sheets[sheet].each_with_index do |e, i|
|
21
21
|
from_current_day << e
|
22
|
-
e_end = e.end_or_now
|
23
22
|
self.output << "%-4s%16s%11s -%9s%10s %s\n" % [
|
24
23
|
(Timetrap::CLI.args['-v'] ? e.id : ''),
|
25
24
|
format_date_if_new(e.start, last_start),
|
26
25
|
format_time(e.start),
|
27
26
|
format_time(e.end),
|
28
|
-
format_duration(e.
|
27
|
+
format_duration(e.duration),
|
29
28
|
e.note
|
30
29
|
]
|
31
30
|
|
data/lib/timetrap/helpers.rb
CHANGED
@@ -60,18 +60,15 @@ module Timetrap
|
|
60
60
|
format_date(time) == format_date(other_time)
|
61
61
|
end
|
62
62
|
|
63
|
-
def format_duration stime, etime
|
64
|
-
return '' unless stime and etime
|
65
|
-
secs = etime.to_i - stime.to_i
|
66
|
-
format_seconds secs
|
67
|
-
end
|
68
|
-
|
69
63
|
def format_seconds secs
|
70
64
|
"%2s:%02d:%02d" % [secs/3600, (secs%3600)/60, secs%60]
|
71
65
|
end
|
66
|
+
alias :format_duration :format_seconds
|
72
67
|
|
73
68
|
def format_total entries
|
74
|
-
secs = entries.inject(0)
|
69
|
+
secs = entries.inject(0) do |m, e|
|
70
|
+
m += e.duration
|
71
|
+
end
|
75
72
|
"%2s:%02d:%02d" % [secs/3600, (secs%3600)/60, secs%60]
|
76
73
|
end
|
77
74
|
|
data/lib/timetrap/models.rb
CHANGED
@@ -29,6 +29,13 @@ module Timetrap
|
|
29
29
|
round? ? rounded_end : self[:end]
|
30
30
|
end
|
31
31
|
|
32
|
+
def duration
|
33
|
+
@duration ||= self.end_or_now.to_i - self.start.to_i
|
34
|
+
end
|
35
|
+
def duration=( nd )
|
36
|
+
@duration = nd.to_i
|
37
|
+
end
|
38
|
+
|
32
39
|
def end_or_now
|
33
40
|
self.end || (round? ? round(Time.now) : Time.now)
|
34
41
|
end
|
data/lib/timetrap/timer.rb
CHANGED
@@ -43,6 +43,10 @@ module Timetrap
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def current_sheet= sheet
|
46
|
+
last = Meta.find_or_create(:key => 'last_sheet')
|
47
|
+
last.value = current_sheet
|
48
|
+
last.save
|
49
|
+
|
46
50
|
m = Meta.find_or_create(:key => 'current_sheet')
|
47
51
|
m.value = sheet
|
48
52
|
m.save
|
@@ -55,6 +59,11 @@ module Timetrap
|
|
55
59
|
Meta.find(:key => 'current_sheet').value
|
56
60
|
end
|
57
61
|
|
62
|
+
def last_sheet
|
63
|
+
m = Meta.find(:key => 'last_sheet')
|
64
|
+
m and m.value
|
65
|
+
end
|
66
|
+
|
58
67
|
def entries sheet = nil
|
59
68
|
Entry.filter(:sheet => sheet).order_by(:start)
|
60
69
|
end
|
data/spec/timetrap_spec.rb
CHANGED
@@ -323,6 +323,38 @@ Grand Total 10:00:00
|
|
323
323
|
end
|
324
324
|
end
|
325
325
|
|
326
|
+
describe "factor" do
|
327
|
+
before do
|
328
|
+
Timetrap::Entry.create( :sheet => 'SpecSheet',
|
329
|
+
:note => 'entry f:2', :start => '2008-10-03 16:00:00', :end => '2008-10-03 18:00:00'
|
330
|
+
)
|
331
|
+
Timetrap::Entry.create( :sheet => 'SpecSheet',
|
332
|
+
:note => 'entry f:0.5', :start => '2008-10-04 16:00:00', :end => '2008-10-04 18:00:00'
|
333
|
+
)
|
334
|
+
Timetrap::Entry.create( :sheet => 'SpecSheet',
|
335
|
+
:note => 'entry', :start => '2008-10-04 19:00:00'
|
336
|
+
)
|
337
|
+
Time.stub!(:now).and_return local_time('2008-10-04 20:00:00')
|
338
|
+
@desired_output = <<-OUTPUT
|
339
|
+
Timesheet: SpecSheet
|
340
|
+
Day Start End Duration Notes
|
341
|
+
Fri Oct 03, 2008 16:00:00 - 18:00:00 4:00:00 entry f:2
|
342
|
+
4:00:00
|
343
|
+
Sat Oct 04, 2008 16:00:00 - 18:00:00 1:00:00 entry f:0.5
|
344
|
+
19:00:00 - 1:00:00 entry
|
345
|
+
2:00:00
|
346
|
+
---------------------------------------------------------
|
347
|
+
Total 6:00:00
|
348
|
+
OUTPUT
|
349
|
+
end
|
350
|
+
|
351
|
+
it "should correctly handle factors in notes" do
|
352
|
+
Timetrap::Timer.current_sheet = 'SpecSheet'
|
353
|
+
invoke 'display --format factor'
|
354
|
+
$stdout.string.should == @desired_output
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
326
358
|
describe "default" do
|
327
359
|
before do
|
328
360
|
create_entry(:start => '2008-10-03 12:00:00', :end => '2008-10-03 14:00:00')
|
@@ -733,6 +765,34 @@ END:VCALENDAR
|
|
733
765
|
invoke 'sheet'
|
734
766
|
$stdout.string.should == " Timesheet Running Today Total Time\n*sheet 1 0:00:00 0:00:00 0:00:00\n"
|
735
767
|
end
|
768
|
+
|
769
|
+
describe "using - to switch to the last sheet" do
|
770
|
+
it "should warn if there isn't a sheet set" do
|
771
|
+
lambda do
|
772
|
+
invoke 'sheet -'
|
773
|
+
end.should_not change(Timetrap::Timer, :current_sheet)
|
774
|
+
$stderr.string.should include 'LAST_SHEET is not set'
|
775
|
+
end
|
776
|
+
|
777
|
+
it "should switch to the last active sheet" do
|
778
|
+
invoke 'sheet second'
|
779
|
+
lambda do
|
780
|
+
invoke 'sheet -'
|
781
|
+
end.should change(Timetrap::Timer, :current_sheet).
|
782
|
+
from('second').to('default')
|
783
|
+
end
|
784
|
+
|
785
|
+
it "should toggle back and forth" do
|
786
|
+
invoke 'sheet first'
|
787
|
+
invoke 'sheet second'
|
788
|
+
5.times do
|
789
|
+
invoke 's -'
|
790
|
+
Timetrap::Timer.current_sheet.should == 'first'
|
791
|
+
invoke 's -'
|
792
|
+
Timetrap::Timer.current_sheet.should == 'second'
|
793
|
+
end
|
794
|
+
end
|
795
|
+
end
|
736
796
|
end
|
737
797
|
end
|
738
798
|
end
|
data/timetrap.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{timetrap}
|
8
|
-
s.version = "1.7.
|
8
|
+
s.version = "1.7.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Sam Goldstein"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-03-07}
|
13
13
|
s.default_executable = %q{t}
|
14
14
|
s.description = %q{Command line time tracker}
|
15
15
|
s.email = %q{sgrock@gmail.com}
|
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
"lib/timetrap/config.rb",
|
35
35
|
"lib/timetrap/formatters.rb",
|
36
36
|
"lib/timetrap/formatters/csv.rb",
|
37
|
+
"lib/timetrap/formatters/factor.rb",
|
37
38
|
"lib/timetrap/formatters/ical.rb",
|
38
39
|
"lib/timetrap/formatters/ids.rb",
|
39
40
|
"lib/timetrap/formatters/json.rb",
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timetrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 7
|
9
|
-
-
|
10
|
-
version: 1.7.
|
9
|
+
- 4
|
10
|
+
version: 1.7.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sam Goldstein
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-03-07 00:00:00 -08:00
|
19
19
|
default_executable: t
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- lib/timetrap/config.rb
|
107
107
|
- lib/timetrap/formatters.rb
|
108
108
|
- lib/timetrap/formatters/csv.rb
|
109
|
+
- lib/timetrap/formatters/factor.rb
|
109
110
|
- lib/timetrap/formatters/ical.rb
|
110
111
|
- lib/timetrap/formatters/ids.rb
|
111
112
|
- lib/timetrap/formatters/json.rb
|