timetrackr 0.1.2 → 0.1.3

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/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  group :development do
4
+ gem 'sqlite3'
4
5
  gem 'shoulda', '>= 0'
5
6
  gem 'bundler', '~> 1.0.0'
6
7
  gem 'jeweler', '~> 1.5.2'
data/Gemfile.lock CHANGED
@@ -9,6 +9,7 @@ GEM
9
9
  rake (0.8.7)
10
10
  rcov (0.9.9)
11
11
  shoulda (2.11.3)
12
+ sqlite3 (1.3.3)
12
13
 
13
14
  PLATFORMS
14
15
  ruby
@@ -18,3 +19,4 @@ DEPENDENCIES
18
19
  jeweler (~> 1.5.2)
19
20
  rcov
20
21
  shoulda
22
+ sqlite3
data/README.mkd CHANGED
@@ -4,19 +4,23 @@ A simple CLI time tracking utility.
4
4
 
5
5
  ## Example
6
6
 
7
- >tt start work
7
+ $ tt start work
8
8
 
9
- >tt switch play
9
+ $ tt switch play
10
10
 
11
- >tt
11
+ $ tt
12
12
  work 0h 0m 3s
13
13
  play * 0h 0m 1s
14
14
 
15
- >tt clear work
15
+ $ tt clear work
16
16
 
17
- >tt time
17
+ $ tt time
18
18
  play * 0h 0m 5s
19
19
 
20
+ $ tt log
21
+ 2011-05-17 work 08:05 08:20 0h 15m 41s
22
+ something * 09:05 0h 0m 4s
23
+
20
24
 
21
25
 
22
26
  ## Contributing to timetrackr
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
data/bin/timetrackr CHANGED
@@ -6,13 +6,13 @@ require 'timetrackr'
6
6
  require 'timetrackr/period'
7
7
 
8
8
  DEFAULTS = {
9
- :backend => 'yaml',
10
- :verbose => false,
11
- :single_task => false,
12
- :path => File.join(ENV['HOME'],'.timetrackr.db'),
13
- :relative_format => "%2<hours>dh %2<minutes>dm %2<seconds>ds",
14
- :absolute_time => "%H:%m",
15
- :absolute_day => "%Y-%m-%d"
9
+ 'backend' => 'yaml',
10
+ 'verbose' => false,
11
+ 'single_task' => false,
12
+ 'path' => File.join(ENV['HOME'],'.timetrackr.db'),
13
+ 'relative_format' => "%2<hours>dh %2<minutes>dm %2<seconds>ds",
14
+ 'absolute_time' => "%H:%M",
15
+ 'absolute_day' => "%Y-%m-%d"
16
16
  }
17
17
 
18
18
  def show_help
@@ -56,7 +56,7 @@ end
56
56
  # global options
57
57
  while (cmd = ARGV.shift) && cmd.start_with?('-')
58
58
  if ['-v','--verbose'].include? cmd
59
- config[:verbose] = true
59
+ config['verbose'] = true
60
60
  end
61
61
  if ['-h','--help'].include? cmd
62
62
  show_help
@@ -65,8 +65,8 @@ while (cmd = ARGV.shift) && cmd.start_with?('-')
65
65
  end
66
66
 
67
67
  config = DEFAULTS.merge(config || {})
68
- $verbose = config[:verbose]
69
- trackr = TimeTrackr.create(config[:backend], config)
68
+ $verbose = config['verbose']
69
+ trackr = TimeTrackr.create(config['backend'], config)
70
70
 
71
71
  #
72
72
  # commands
@@ -76,7 +76,7 @@ when 'start','in','s'
76
76
  task = ARGV.shift
77
77
  notes = ARGV.join(' ')
78
78
  # switch tasks if config says so
79
- if config[:single_task] && trackr.current != task
79
+ if config['single_task'] && trackr.current != task
80
80
  trackr.current.each { |t|
81
81
  trackr.stop(t) unless t == task
82
82
  }
@@ -118,7 +118,7 @@ when 'time','status',nil
118
118
  t = t + period.length
119
119
  }
120
120
  name = trackr.current.include?(task) ? task+' *' : task
121
- puts name.ljust(15) << format_time(total,config[:relative_format])
121
+ puts name.ljust(15) << format_time(total,config['relative_format'])
122
122
  end
123
123
 
124
124
  when 'log'
@@ -131,16 +131,16 @@ when 'log'
131
131
  periods = tasks.each.collect{ |t| trackr.history(t) }.flatten
132
132
  lastday = nil
133
133
  table << periods.sort{|x,y| x.start <=> y.start}.collect{ |period|
134
- currday = period.start.strftime(config[:absolute_day])
134
+ currday = period.start.strftime(config['absolute_day'])
135
135
  day = (currday == lastday) ? ' ' : currday
136
136
  lastday = currday
137
137
  name = period.current? ? period.task+' *' : period.task
138
- start = period.start.strftime(config[:absolute_time])
139
- stop = period.current? ? ' ' : period.stop.strftime(config[:absolute_time])
140
- length = format_time(period.length, config[:relative_format])
138
+ start = period.start.strftime(config['absolute_time'])
139
+ stop = period.current? ? ' ' : period.stop.strftime(config['absolute_time'])
140
+ length = format_time(period.length, config['relative_format'])
141
141
  "#{day.ljust(12)} #{name.ljust(15)} #{start.ljust(7)} #{stop.ljust(7)} #{length}"
142
142
  }
143
- puts table.join("\n")
143
+ puts table
144
144
 
145
145
 
146
146
  when 'clear','delete','del'
@@ -15,7 +15,7 @@ class Period
15
15
  end
16
16
 
17
17
  def current?
18
- stop.nil?
18
+ @stop.nil?
19
19
  end
20
20
 
21
21
  end
@@ -0,0 +1,65 @@
1
+ class SqliteTimeTrackr < TimeTrackr
2
+
3
+ def initialize(path)
4
+ @log_path = path
5
+ if !File.exist? @log_path
6
+ @db = SQLite3::Database.new(@log_path)
7
+ sql_events = "CREATE TABLE events (
8
+ id INTEGER PRIMARY KEY,
9
+ task TEXT,
10
+ start TIME,
11
+ stop TIME,
12
+ notes TEXT);"
13
+ @db.execute(sql_events)
14
+ else
15
+ @db = SQLite3::Database.open(@log_path)
16
+ end
17
+ @db.type_translation = true
18
+ puts "Using DB file '#{@log_path}'" if $verbose
19
+ end
20
+
21
+ def current
22
+ sql = "SELECT DISTINCT task FROM events WHERE stop IS NULL;"
23
+ @db.execute(sql).collect{|row|
24
+ row.first
25
+ }
26
+ end
27
+
28
+ def tasks
29
+ sql = "SELECT DISTINCT task FROM events;"
30
+ @db.execute(sql).collect{ |row|
31
+ row.first
32
+ }
33
+ end
34
+
35
+ def start(task, notes)
36
+ sql = "SELECT id FROM events WHERE task = :task AND stop IS NULL;"
37
+ exists = @db.get_first_value(sql, 'task' => task)
38
+ if !exists
39
+ sql = "INSERT INTO events (task,start,notes) VALUES (:task,:start,:notes);"
40
+ @db.execute(sql,'task' => task, 'start' => Time.now.to_s, 'notes' => notes)
41
+ end
42
+ end
43
+
44
+ def stop(task)
45
+ sql = "SELECT id FROM events WHERE task = :task AND stop IS NULL;"
46
+ exists = @db.get_first_value(sql, 'task' => task)
47
+ if exists
48
+ sql = "UPDATE events SET stop = :stop WHERE id = :current;"
49
+ @db.execute(sql, 'current' => exists, 'stop' => Time.now.to_s)
50
+ end
51
+ end
52
+
53
+ def history(task, p_begin=nil, p_end=nil)
54
+ sql = "SELECT start, stop, notes FROM events WHERE task = :task ORDER BY start;"
55
+ @db.execute(sql,'task' => task).collect{ |row|
56
+ Period.new(task,row[0],row[1],row[2])
57
+ }
58
+ end
59
+
60
+ def clear(task)
61
+ sql = "DELETE FROM events WHERE task = :task;"
62
+ @db.execute(sql, 'task' => task)
63
+ end
64
+
65
+ end
data/lib/timetrackr.rb CHANGED
@@ -2,12 +2,12 @@ autoload 'YamlTimeTrackr', 'timetrackr/yaml'
2
2
  autoload 'SqliteTimeTrackr', 'timetrackr/sqlite'
3
3
 
4
4
  class TimeTrackr
5
- def self.create(type,options={})
5
+ def self.create(type, options={})
6
6
  case type.to_s
7
7
  when 'yaml'
8
8
  begin
9
9
  require 'yaml'
10
- log = YamlTimeTrackr.new(options[:path])
10
+ log = YamlTimeTrackr.new(options['path'])
11
11
  puts 'Loaded yaml tracker' if $verbose
12
12
  rescue LoadError
13
13
  puts 'Yaml not found'
@@ -15,7 +15,7 @@ class TimeTrackr
15
15
  when 'sqlite'
16
16
  begin
17
17
  require 'sqlite3'
18
- log = SqliteTimeTrackr.new(options[:path])
18
+ log = SqliteTimeTrackr.new(options['path'])
19
19
  puts 'Loaded sqlite tracker' if $verbose
20
20
  rescue LoadError
21
21
  puts 'Sqlite not found'
@@ -34,7 +34,7 @@ class TimeTrackr
34
34
  end
35
35
 
36
36
  #
37
- # start a period
37
+ # start a period with optional notes
38
38
  #
39
39
  def start(task,notes)
40
40
  raise 'Not implemented'
@@ -50,4 +50,41 @@ class TestTimetrackr < Test::Unit::TestCase
50
50
 
51
51
  end
52
52
  end
53
+
54
+ context 'an Sqlite based tracker' do
55
+ setup do
56
+ @config = {:path => '/tmp/timetracker.test'}
57
+ @t = TimeTrackr.create('sqlite',@config)
58
+ end
59
+
60
+ def teardown
61
+ File.unlink(@config[:path]) rescue nil
62
+ end
63
+
64
+ should 'initialise a log file' do
65
+ assert File.exist?(@config[:path])
66
+ end
67
+
68
+ context 'with empty db' do
69
+
70
+ should 'not fail on current command' do
71
+ assert_nothing_raised Exception do
72
+ @t.current
73
+ end
74
+ end
75
+
76
+ should 'not fail on tasks command' do
77
+ assert_nothing_raised Exception do
78
+ @t.tasks
79
+ end
80
+ end
81
+
82
+ should 'not fail on close command' do
83
+ assert_nothing_raised Exception do
84
+ @t.close
85
+ end
86
+ end
87
+
88
+ end
89
+ end
53
90
  end
data/timetrackr.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{timetrackr}
8
- s.version = "0.1.2"
8
+ s.version = "0.1.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Felix Hanley"]
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
28
28
  "bin/timetrackr",
29
29
  "lib/timetrackr.rb",
30
30
  "lib/timetrackr/period.rb",
31
+ "lib/timetrackr/sqlite.rb",
31
32
  "lib/timetrackr/yaml.rb",
32
33
  "test/helper.rb",
33
34
  "test/test_timetrackr.rb",
@@ -47,17 +48,20 @@ Gem::Specification.new do |s|
47
48
  s.specification_version = 3
48
49
 
49
50
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_development_dependency(%q<sqlite3>, [">= 0"])
50
52
  s.add_development_dependency(%q<shoulda>, [">= 0"])
51
53
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
52
54
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
53
55
  s.add_development_dependency(%q<rcov>, [">= 0"])
54
56
  else
57
+ s.add_dependency(%q<sqlite3>, [">= 0"])
55
58
  s.add_dependency(%q<shoulda>, [">= 0"])
56
59
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
60
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
58
61
  s.add_dependency(%q<rcov>, [">= 0"])
59
62
  end
60
63
  else
64
+ s.add_dependency(%q<sqlite3>, [">= 0"])
61
65
  s.add_dependency(%q<shoulda>, [">= 0"])
62
66
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
63
67
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: timetrackr
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.2
5
+ version: 0.1.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Felix Hanley
@@ -14,7 +14,7 @@ date: 2011-05-17 00:00:00 +07:00
14
14
  default_executable: timetrackr
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: shoulda
17
+ name: sqlite3
18
18
  requirement: &id001 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
@@ -25,8 +25,19 @@ dependencies:
25
25
  prerelease: false
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: shoulda
29
29
  requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: bundler
40
+ requirement: &id003 !ruby/object:Gem::Requirement
30
41
  none: false
31
42
  requirements:
32
43
  - - ~>
@@ -34,10 +45,10 @@ dependencies:
34
45
  version: 1.0.0
35
46
  type: :development
36
47
  prerelease: false
37
- version_requirements: *id002
48
+ version_requirements: *id003
38
49
  - !ruby/object:Gem::Dependency
39
50
  name: jeweler
40
- requirement: &id003 !ruby/object:Gem::Requirement
51
+ requirement: &id004 !ruby/object:Gem::Requirement
41
52
  none: false
42
53
  requirements:
43
54
  - - ~>
@@ -45,10 +56,10 @@ dependencies:
45
56
  version: 1.5.2
46
57
  type: :development
47
58
  prerelease: false
48
- version_requirements: *id003
59
+ version_requirements: *id004
49
60
  - !ruby/object:Gem::Dependency
50
61
  name: rcov
51
- requirement: &id004 !ruby/object:Gem::Requirement
62
+ requirement: &id005 !ruby/object:Gem::Requirement
52
63
  none: false
53
64
  requirements:
54
65
  - - ">="
@@ -56,7 +67,7 @@ dependencies:
56
67
  version: "0"
57
68
  type: :development
58
69
  prerelease: false
59
- version_requirements: *id004
70
+ version_requirements: *id005
60
71
  description: A simple time tracking utility
61
72
  email: felix@seconddrawer.com.au
62
73
  executables:
@@ -76,6 +87,7 @@ files:
76
87
  - bin/timetrackr
77
88
  - lib/timetrackr.rb
78
89
  - lib/timetrackr/period.rb
90
+ - lib/timetrackr/sqlite.rb
79
91
  - lib/timetrackr/yaml.rb
80
92
  - test/helper.rb
81
93
  - test/test_timetrackr.rb
@@ -94,7 +106,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
94
106
  requirements:
95
107
  - - ">="
96
108
  - !ruby/object:Gem::Version
97
- hash: -3115143978170493963
109
+ hash: -4194975739738215101
98
110
  segments:
99
111
  - 0
100
112
  version: "0"