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.
@@ -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