ttrack 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/bin/ttrack +23 -0
  2. data/lib/ttrack/datastore.rb +137 -0
  3. data/lib/ttrack.rb +164 -0
  4. metadata +59 -0
data/bin/ttrack ADDED
@@ -0,0 +1,23 @@
1
+ #!/Users/alex/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -w
2
+ require 'ttrack'
3
+
4
+ tt = TTrack.new
5
+ case ARGV[0]
6
+ when 'start' then
7
+ tt.start ARGV[1], ARGV[2]
8
+ when 'stop' then
9
+ tt.stop
10
+ when 'status' then
11
+ tt.status ARGV[1]
12
+ when 'init' then
13
+ tt.init
14
+ when 'report' then
15
+ tt.report ARGV[1]
16
+ when 'beguin' then
17
+ timestamp = ARGV[3] ? "%s %s" % ARGV[2..3] : ARGV[2]
18
+ tt.setstart ARGV[1], timestamp
19
+ when 'end' then
20
+ timestamp = ARGV[3] ? "%s %s" % ARGV[2..3] : ARGV[2]
21
+ tt.setstop ARGV[1], timestamp
22
+ else tt.usage
23
+ end
@@ -0,0 +1,137 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'sqlite3'
3
+
4
+ class TTrack::DataStore
5
+
6
+ def initialize dbname=".timetrackerdb", timezone="+02:00", version='v0.1.0', verbosity=0
7
+ @dbname = dbname
8
+ @timezone = timezone
9
+ @version = version
10
+ @verbosity = verbosity
11
+
12
+ if FileTest.zero?(dbname) or not FileTest.file?(dbname)
13
+ @db = SQLite3::Database.new( dbname )
14
+ createschema
15
+ init(timezone, version, verbosity)
16
+ else
17
+ @db = SQLite3::Database.open( dbname )
18
+ end
19
+ end
20
+
21
+ private
22
+ def createschema
23
+ @db.execute <<-SQL
24
+ CREATE TABLE system (
25
+ current,
26
+ latest,
27
+ timezone NOT NULL,
28
+ version INTEGER NOT NULL,
29
+ verbosity NOT NULL,
30
+ redmine
31
+ )
32
+ SQL
33
+
34
+ @db.execute <<-SQL
35
+ CREATE TABLE timesheet (
36
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
37
+ name,
38
+ tstart DEFAULT CURRENT_TIMESTAMP,
39
+ tstop,
40
+ synced DEFAULT 'false',
41
+ notes
42
+ )
43
+ SQL
44
+ end
45
+
46
+ def init timezone, version, verbosity
47
+ @db.execute 'INSERT INTO system ( timezone, version, verbosity ) VALUES ( "%s", "%s", "%s" )' %
48
+ [timezone, version, verbosity]
49
+ end
50
+
51
+ def droptables
52
+ for table in ['system', 'timesheet']
53
+ @db.execute 'DROP TABLE IF EXISTS %s' % table
54
+ end
55
+ end
56
+
57
+ def setcurrent issueid
58
+ oldcurrent = @db.execute 'SELECT current, latest FROM system'
59
+ @db.execute "UPDATE system SET current = '%d', latest = '%s'" %
60
+ [issueid, oldcurrent[0][0] != '' ? oldcurrent[0][0] : oldcurrent[0][1]]
61
+ end
62
+
63
+ public
64
+ def getcurrent
65
+ current = @db.execute "SELECT current FROM system"
66
+ current[0][0] == "" ? nil : current[0][0]
67
+ end
68
+
69
+ def getstatus
70
+ current = getcurrent
71
+ if current
72
+ status = @db.execute "SELECT id,name FROM timesheet WHERE id=%d" % current
73
+ status[0]
74
+ else
75
+ nil
76
+ end
77
+ end
78
+
79
+ def startnew issuename, notes=''
80
+ @db.execute "INSERT INTO timesheet ( name, notes ) VALUES ( '%s', '%s' )" %
81
+ [issuename, notes]
82
+ latest = @db.execute "SELECT id FROM timesheet ORDER BY id DESC LIMIT 1"
83
+ setcurrent latest[0][0]
84
+ end
85
+
86
+ def stoprunning
87
+ current = getcurrent
88
+ if current
89
+ @db.execute "UPDATE timesheet set tstop = datetime('now') WHERE id = %d" % current
90
+ @db.execute "UPDATE system SET current = '', latest = '%d'" % current
91
+ else
92
+ p "Not tracking"
93
+ end
94
+ end
95
+
96
+ def gettime issueid=false
97
+ issueid = issueid ? issueid : getcurrent
98
+ if issueid
99
+ time = @db.execute "SELECT tstart,tstop FROM timesheet WHERE id=%d" % issueid
100
+ time[0]
101
+ else
102
+ false
103
+ end
104
+ end
105
+
106
+ def gettimesbyissuename issuename
107
+ @db.execute "SELECT tstart,tstop FROM timesheet WHERE name='%s'" % issuename
108
+ end
109
+
110
+ def getissuesandtimesbyname issuename
111
+ @db.execute "SELECT tstart,tstop FROM timesheet WHERE name='%s'" % issuename
112
+ end
113
+
114
+ def getissuesidsbyname issuename
115
+ @db.execute "SELECT id,tstart,tstop,notes FROM timesheet WHERE name='%s'" % issuename
116
+ end
117
+
118
+ def settstart id, tstart
119
+ @db.execute "UPDATE timesheet SET tstart=datetime('%s') WHERE id=%d" % [tstart, id]
120
+ end
121
+
122
+ def settstop id, tstop
123
+ @db.execute "UPDATE timesheet SET tstop=datetime('%s') WHERE id=%d" % [tstop, id]
124
+ end
125
+
126
+ def isissue? id
127
+ r = @db.execute "SELECT id from timesheet WHERE id=%d" % id
128
+ r[0].nil? ? false : true
129
+ end
130
+
131
+ def cleanup
132
+ droptables
133
+ createschema
134
+ init(@timezone, @version, @verbosity)
135
+ end
136
+
137
+ end # End DataStore class
data/lib/ttrack.rb ADDED
@@ -0,0 +1,164 @@
1
+ # -*- coding: utf-8 -*-
2
+ class TTrack
3
+
4
+ def initialize
5
+ @db = DataStore.new
6
+ end
7
+
8
+ def start issuename, notes
9
+ unless issuename.nil?
10
+ if @db.getcurrent
11
+ @db.stoprunning
12
+ end
13
+ @db.startnew issuename, notes
14
+ else
15
+ usage
16
+ end
17
+ end
18
+
19
+ def stop
20
+ @db.stoprunning
21
+ end
22
+
23
+ def status issuename
24
+ unless issuename
25
+ status = @db.getstatus
26
+ if status
27
+ delta = Time.now - gettstart(@db.getcurrent)
28
+ puts "Task '%s' run time: %d seconds (%.2f hours)" % [status[1], delta, delta / 3600]
29
+ else
30
+ puts "Not tracking"
31
+ end
32
+ else
33
+ total = gettotalissueduration(issuename)
34
+ unless total == 0
35
+ puts "Total seconds for task %s: %d (%.2f hours)" %
36
+ [
37
+ issuename,
38
+ total,
39
+ total / 3600
40
+ ]
41
+ else
42
+ puts "No entry for issue '%s'" % issuename
43
+ end
44
+ end
45
+ end
46
+
47
+ def report issuename
48
+ r = @db.getissuesidsbyname issuename
49
+ unless r[0].nil?
50
+ puts "id | tstart | tstop | notes"
51
+ r.each do |x|
52
+ puts "%s | %s | %s | %s" % x
53
+ end
54
+ else
55
+ usage
56
+ end
57
+ end
58
+
59
+ def setstart issueid, timestamp
60
+ if validateissueid issueid
61
+ t = validatetimestamp timestamp
62
+ @db.settstart issueid, t
63
+ end
64
+ end
65
+
66
+ def setstop issueid, timestamp
67
+ if validateissueid issueid
68
+ t = validatetimestamp timestamp
69
+ @db.settstop issueid, t
70
+ end
71
+ end
72
+
73
+ def init
74
+ @db.cleanup
75
+ end
76
+
77
+ def usage
78
+ puts "Usage: ttrack [start|stop|status|init|report|begin|end] issue_name"
79
+ end
80
+
81
+ private
82
+ def gettimeobject timestamp
83
+ if timestamp
84
+ Time.utc(
85
+ timestamp[0..3],
86
+ timestamp[5..6],
87
+ timestamp[8..9],
88
+ timestamp[11..12],
89
+ timestamp[14..15],
90
+ timestamp[17..18]
91
+ )
92
+ else
93
+ Time.now
94
+ end
95
+ end
96
+
97
+ def validatetimestamp timestamp
98
+ t = Time.utc(
99
+ timestamp[0..3],
100
+ timestamp[5..6],
101
+ timestamp[8..9],
102
+ timestamp[11..12],
103
+ timestamp[14..15],
104
+ timestamp[17..18]
105
+ )
106
+ "%.4d-%.2d-%.2d %.2d:%.2d:%.2d" % [
107
+ t.year,
108
+ t.month,
109
+ t.day,
110
+ t.hour,
111
+ t.min,
112
+ t.sec
113
+ ]
114
+ end
115
+
116
+ def validateissueid issueid
117
+ unless @db.isissue? issueid
118
+ puts "Issueid invalid"
119
+ false
120
+ else
121
+ true
122
+ end
123
+ end
124
+
125
+ def gettotalissueduration issuename
126
+ r = @db.getissuesandtimesbyname(issuename)
127
+ total = 0
128
+ r.each do |timestamps|
129
+ if timestamps[0]
130
+ t0, t1 = gettimeobject(timestamps[0]), gettimeobject(timestamps[1])
131
+ total = total + (t1 - t0)
132
+ end
133
+ end
134
+ total
135
+ end
136
+
137
+ def getissueduration issueid
138
+ timestamps = @db.gettime issueid
139
+ if timestamps and timestamps[1]
140
+ t0, t1 = gettimeobject(timestamps[0]), gettimeobject(timestamps[1])
141
+ t1 - t0
142
+ else
143
+ false
144
+ end
145
+ end
146
+
147
+ def gettstart issueid
148
+ timestamps = @db.gettime issueid
149
+ unless timestamps[0].nil?
150
+ gettimeobject timestamps[0]
151
+ end
152
+ end
153
+
154
+ def gettstop issueid
155
+ timestamps = @db.gettime issueid
156
+ unless timestamps[1].nil?
157
+ gettimeobject timestamps[1]
158
+ end
159
+ end
160
+
161
+ end # End TTrack class
162
+
163
+ require 'ttrack/datastore'
164
+ # TODO: add support for timezone
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ttrack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alexander Fortin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-30 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sqlite3
16
+ requirement: &70137978508080 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.6
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70137978508080
25
+ description: A simple CLI time tracker
26
+ email: alexander.fortin@gmail.com
27
+ executables:
28
+ - ttrack
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - lib/ttrack.rb
33
+ - lib/ttrack/datastore.rb
34
+ - bin/ttrack
35
+ homepage: https://rubygems.org/gems/ttrack
36
+ licenses: []
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 1.8.10
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: Time Tracker
59
+ test_files: []