timetrap 1.7.3 → 1.7.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,3 +3,4 @@
3
3
  * Ammar Ali
4
4
  * Brian V. Hughes
5
5
  * Thorben Schröder
6
+ * Ryan Funduk
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 5 output formats.
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 also provided, because hackers love json.
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
 
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 7
4
- :patch: 3
4
+ :patch: 4
@@ -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
- unless sheet =~ /.+/
274
+ case sheet
275
+ when nil, ''
274
276
  list
275
- else
276
- Timer.current_sheet = sheet
277
- warn "Switching to sheet #{sheet.inspect}"
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.start, entry.end_or_now)}".gsub(/ /, ' ')
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.start, e_end),
27
+ format_duration(e.duration),
29
28
  e.note
30
29
  ]
31
30
 
@@ -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){|m, e|e_end = e.end_or_now; m += e_end.to_i - e.start.to_i if e_end && e.start;m}
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
 
@@ -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
@@ -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
@@ -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
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{timetrap}
8
- s.version = "1.7.3"
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-02-06}
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: 13
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 7
9
- - 3
10
- version: 1.7.3
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-02-06 00:00:00 -08:00
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