timekeeper 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/tk +4 -65
- data/bin/tv +4 -71
- data/lib/timekeeper.rb +8 -4
- data/lib/timekeeper/keep.rb +48 -55
- data/lib/timekeeper/keeper.rb +50 -0
- data/lib/timekeeper/keeper_options.rb +59 -0
- data/lib/timekeeper/runner.rb +37 -0
- data/lib/timekeeper/viewer.rb +38 -0
- data/lib/timekeeper/viewer_options.rb +55 -0
- metadata +6 -3
- data/lib/timekeeper/timekeeper.rb +0 -37
- data/lib/timekeeper/timeviewer.rb +0 -31
data/bin/tk
CHANGED
@@ -1,68 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
#
|
4
|
-
# Timekeeper. Keeping track of your time.
|
5
|
-
#
|
6
|
-
# == Usage
|
7
|
-
#
|
8
|
-
# tk [OPTIONS]
|
9
|
-
#
|
10
|
-
# -h, --help:
|
11
|
-
# show help
|
12
|
-
#
|
13
|
-
# --config [file]
|
14
|
-
# Location of your configuration file
|
15
|
-
#
|
16
|
-
# --title [title], -t [title]:
|
17
|
-
# What do you want to register
|
18
|
-
#
|
19
|
-
# --target [target], -c [target]:
|
20
|
-
# Who is going to pay?
|
21
|
-
#
|
22
|
-
# --time [time], -s [time]:
|
23
|
-
# How long did it take?
|
24
|
-
#
|
25
|
-
# --description [description], -m [description]
|
26
|
-
# More? You want to be more specific?
|
27
|
-
#
|
28
|
-
# --date [date], -d [date]
|
29
|
-
# When exactly did it happen?
|
30
|
-
#
|
31
|
-
# --remove [id]
|
32
|
-
# Remove a record.
|
33
|
-
#
|
34
|
-
require File.expand_path(File.dirname(__FILE__) + "/../lib/timekeeper")
|
2
|
+
require 'rubygems'
|
35
3
|
|
36
|
-
|
37
|
-
require
|
4
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
+
require 'timekeeper'
|
38
6
|
|
39
|
-
|
40
|
-
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
|
41
|
-
[ "--title", "-t", GetoptLong::REQUIRED_ARGUMENT ],
|
42
|
-
[ "--target", "-c", GetoptLong::REQUIRED_ARGUMENT ],
|
43
|
-
[ "--time", "-s", GetoptLong::REQUIRED_ARGUMENT ],
|
44
|
-
[ "--description","-m", GetoptLong::REQUIRED_ARGUMENT ],
|
45
|
-
[ "--date", "-d", GetoptLong::REQUIRED_ARGUMENT ],
|
46
|
-
[ "--remove" , GetoptLong::REQUIRED_ARGUMENT ],
|
47
|
-
[ "--config" , GetoptLong::REQUIRED_ARGUMENT ]
|
48
|
-
)
|
49
|
-
|
50
|
-
if ARGV.length == 0
|
51
|
-
puts "Please provide some options, type --help"
|
52
|
-
exit 0
|
53
|
-
end
|
54
|
-
|
55
|
-
tk = Timekeeper.new
|
56
|
-
|
57
|
-
attributes = {}
|
58
|
-
opts.each do |opt, arg|
|
59
|
-
case opt
|
60
|
-
when "--help": RDoc::usage
|
61
|
-
when "--config": tk.config arg
|
62
|
-
when "--remove": tk.delete(arg); exit 0
|
63
|
-
else
|
64
|
-
attributes.store(opt.gsub("-",""), arg)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
tk.store(attributes)
|
7
|
+
Timekeeper::Runner.tk(ARGV)
|
data/bin/tv
CHANGED
@@ -1,74 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
#
|
4
|
-
# Timeviewer. Keeping an eye on your tracked time.
|
5
|
-
#
|
6
|
-
# == Usage
|
7
|
-
#
|
8
|
-
# tv [OPTIONS]
|
9
|
-
#
|
10
|
-
# -h, --help:
|
11
|
-
# show help
|
12
|
-
#
|
13
|
-
# --config [file]
|
14
|
-
# Location of your configuration file
|
15
|
-
#
|
16
|
-
# --name [name], -n [name]:
|
17
|
-
# Query by name
|
18
|
-
#
|
19
|
-
# --title [title], -t [title]:
|
20
|
-
# Query by title
|
21
|
-
#
|
22
|
-
# --target [target], -c [target]:
|
23
|
-
# Query by target
|
24
|
-
#
|
25
|
-
# --description [description], -m [description]
|
26
|
-
# Query by description
|
27
|
-
#
|
28
|
-
# --date [date], -d [date]
|
29
|
-
# Query by date
|
30
|
-
#
|
31
|
-
require File.dirname(__FILE__) + '/../lib/timekeeper'
|
32
|
-
|
33
|
-
require "getoptlong"
|
34
|
-
require "rdoc/usage"
|
35
|
-
require "fastercsv"
|
2
|
+
require 'rubygems'
|
36
3
|
|
37
|
-
|
38
|
-
|
39
|
-
[ "--csv" , GetoptLong::NO_ARGUMENT ],
|
40
|
-
[ "--all" , GetoptLong::NO_ARGUMENT ],
|
41
|
-
[ "--name", "-n", GetoptLong::REQUIRED_ARGUMENT ],
|
42
|
-
[ "--title", "-t", GetoptLong::REQUIRED_ARGUMENT ],
|
43
|
-
[ "--target", "-c", GetoptLong::REQUIRED_ARGUMENT ],
|
44
|
-
[ "--time", "-s", GetoptLong::REQUIRED_ARGUMENT ],
|
45
|
-
[ "--description","-m", GetoptLong::REQUIRED_ARGUMENT ],
|
46
|
-
[ "--date", "-d", GetoptLong::REQUIRED_ARGUMENT ],
|
47
|
-
[ "--config" , GetoptLong::REQUIRED_ARGUMENT ]
|
48
|
-
)
|
4
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
5
|
+
require 'timekeeper'
|
49
6
|
|
50
|
-
|
51
|
-
puts "Please provide some options, type --help"
|
52
|
-
exit 0
|
53
|
-
end
|
54
|
-
|
55
|
-
tv = Timeviewer.new
|
56
|
-
output = nil
|
57
|
-
|
58
|
-
attributes = {}
|
59
|
-
opts.each do |opt, arg|
|
60
|
-
case opt
|
61
|
-
when "--help": RDoc::usage
|
62
|
-
when "--csv" : output = :csv
|
63
|
-
when "--config": tv.config arg
|
64
|
-
else
|
65
|
-
attributes.store(opt.gsub("-",""), arg)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
records = tv.all
|
70
|
-
if output
|
71
|
-
Timeviewer.export(records, "export", output)
|
72
|
-
else
|
73
|
-
puts records.collect{|r| Keep.new(r) }
|
74
|
-
end
|
7
|
+
Timekeeper::Runner.tv(ARGV)
|
data/lib/timekeeper.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
require "rubygems"
|
2
1
|
require "rufus/tokyo"
|
2
|
+
require "fastercsv"
|
3
|
+
require "optparse"
|
3
4
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
5
|
+
require "timekeeper/keep"
|
6
|
+
require "timekeeper/keeper"
|
7
|
+
require "timekeeper/viewer"
|
8
|
+
require "timekeeper/runner"
|
9
|
+
require "timekeeper/keeper_options"
|
10
|
+
require "timekeeper/viewer_options"
|
data/lib/timekeeper/keep.rb
CHANGED
@@ -1,72 +1,65 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module Timekeeper
|
2
|
+
|
3
|
+
class Keep
|
4
4
|
|
5
|
-
|
5
|
+
attr_accessor :name, :time, :title, :description, :target, :date, :pk
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
def initialize(attributes)
|
8
|
+
set_attributes(attributes)
|
9
|
+
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def update(attributes)
|
12
|
+
set_attributes(attributes)
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
def date=(value)
|
16
|
+
if value
|
17
|
+
if value.is_a?(Date)
|
18
|
+
@date = value
|
19
|
+
else
|
20
|
+
@date = parse_date(value.to_s)
|
21
|
+
end
|
21
22
|
end
|
22
23
|
end
|
23
|
-
|
24
|
+
|
25
|
+
def validate
|
26
|
+
mandatory(%w(name target title date time))
|
27
|
+
end
|
24
28
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
elsif NO.include?(value)
|
29
|
-
@track = false
|
29
|
+
def to_hash
|
30
|
+
{:name => name, :time => time, :title => title, :description => description,
|
31
|
+
:target => target, :date => date}
|
30
32
|
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def validate
|
34
|
-
mandatory(%w(name target title date time))
|
35
|
-
end
|
36
|
-
|
37
|
-
def to_hash
|
38
|
-
{:name => name, :time => time, :title => title, :description => description,
|
39
|
-
:target => target, :date => date, :track => track}
|
40
|
-
end
|
41
33
|
|
42
|
-
|
43
|
-
|
44
|
-
|
34
|
+
def to_s
|
35
|
+
"#{pk}|#{name}|#{target}|#{title}|#{description}|#{date}|#{time}"
|
36
|
+
end
|
45
37
|
|
46
|
-
|
38
|
+
private
|
47
39
|
|
48
|
-
|
49
|
-
|
50
|
-
|
40
|
+
def set_attributes(attributes)
|
41
|
+
attributes.each do |key, value|
|
42
|
+
respond_to?("#{key}=") ? send("#{key}=", value) : raise(StandardError, "unknown attribute: #{key}")
|
43
|
+
end
|
44
|
+
validate
|
45
|
+
self
|
51
46
|
end
|
52
|
-
validate
|
53
|
-
self
|
54
|
-
end
|
55
47
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
48
|
+
def parse_date(value)
|
49
|
+
case value
|
50
|
+
when "today" : Date.today
|
51
|
+
when "yesterday": Date.today - 1
|
52
|
+
when "tomorrow" : Date.today + 1
|
53
|
+
else
|
54
|
+
Date.parse(value)
|
55
|
+
end
|
63
56
|
end
|
64
|
-
end
|
65
57
|
|
66
|
-
|
67
|
-
|
68
|
-
|
58
|
+
def mandatory(attributes)
|
59
|
+
attributes.each do |attribute|
|
60
|
+
raise(StandardError, "#{attribute} is mandatory") unless send(attribute)
|
61
|
+
end
|
69
62
|
end
|
70
|
-
end
|
71
63
|
|
72
|
-
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Timekeeper
|
2
|
+
|
3
|
+
class Keeper
|
4
|
+
|
5
|
+
def config(file="timekeeper.yml")
|
6
|
+
@config ||= YAML.load_file(file)
|
7
|
+
end
|
8
|
+
|
9
|
+
def delete(id)
|
10
|
+
table.delete(id)
|
11
|
+
end
|
12
|
+
|
13
|
+
def delete_all
|
14
|
+
table.clear
|
15
|
+
end
|
16
|
+
|
17
|
+
def close
|
18
|
+
table.close
|
19
|
+
end
|
20
|
+
|
21
|
+
def count
|
22
|
+
table.count
|
23
|
+
end
|
24
|
+
|
25
|
+
def store(attributes)
|
26
|
+
attributes.store("name", config["name"])
|
27
|
+
attributes.store("date", Date.today) unless attributes["date"]
|
28
|
+
table[table.genuid] = Keep.new(attributes).to_hash
|
29
|
+
end
|
30
|
+
|
31
|
+
def get(id)
|
32
|
+
if attributes = table.lget(id.to_s).values.first
|
33
|
+
Keep.new(attributes)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def update(id, attributes_to_update)
|
38
|
+
if attributes = table.lget(id.to_s).values.first
|
39
|
+
table[id] = Keep.new(attributes).update(attributes_to_update).to_hash
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def table
|
46
|
+
@table ||= Rufus::Tokyo::Table.new(File.join(config["db_path"],"#{config["name"]}-time.tct"))
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Timekeeper
|
2
|
+
|
3
|
+
class KeeperOptions < Hash
|
4
|
+
attr_reader :opts
|
5
|
+
|
6
|
+
def initialize(args)
|
7
|
+
super()
|
8
|
+
|
9
|
+
@opts = OptionParser.new do |o|
|
10
|
+
o.banner = "Usage: #{File.basename($0)} [options]"
|
11
|
+
|
12
|
+
o.on("--config FILE", "location of your configuration file - default is ./timekeeper.yml") do |file|
|
13
|
+
self[:config] = file
|
14
|
+
end
|
15
|
+
|
16
|
+
o.on('-t', '--title TITLE', 'What do you want to register?') do |title|
|
17
|
+
self[:title] = title
|
18
|
+
end
|
19
|
+
|
20
|
+
o.on('-c', '--target TARGET', 'Who is going to pay?') do |target|
|
21
|
+
self[:target] = target
|
22
|
+
end
|
23
|
+
|
24
|
+
o.on('-s', '--time TIME', 'How long did it take?') do |time|
|
25
|
+
self[:time] = time
|
26
|
+
end
|
27
|
+
|
28
|
+
o.on('-m', '--description DESCRIPTION', 'More? You want to be more specific?') do |description|
|
29
|
+
self[:description] = description
|
30
|
+
end
|
31
|
+
|
32
|
+
o.on('-d', '--date DATE', 'When exactly did it happen?') do |date|
|
33
|
+
self[:date] = date
|
34
|
+
end
|
35
|
+
|
36
|
+
o.on('--remove ID', 'Remove a record.') do |id|
|
37
|
+
self[:remove] = id
|
38
|
+
end
|
39
|
+
|
40
|
+
o.on('--update ID', 'Remove a record.') do |id|
|
41
|
+
self[:update] = id
|
42
|
+
end
|
43
|
+
|
44
|
+
o.on_tail('-h', '--help', 'Display this help and exit') do
|
45
|
+
puts @opts
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
@opts.parse!(args)
|
53
|
+
rescue OptionParser::InvalidOption => e
|
54
|
+
self[:invalid_argument] = e.message
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Timekeeper
|
2
|
+
|
3
|
+
class Runner
|
4
|
+
|
5
|
+
def self.tk(args)
|
6
|
+
options = KeeperOptions.new(args)
|
7
|
+
if options.any?
|
8
|
+
tk = Keeper.new
|
9
|
+
tk.config(options.delete(:config)) if options[:config]
|
10
|
+
|
11
|
+
if id = options[:remove]
|
12
|
+
tk.delete(id)
|
13
|
+
elsif id = options.delete(:update)
|
14
|
+
tk.update(id, options)
|
15
|
+
else
|
16
|
+
tk.store(options)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
puts options.opts
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.tv(args)
|
24
|
+
options = ViewerOptions.new(args)
|
25
|
+
tv = Viewer.new
|
26
|
+
tv.config(options.delete(:config)) if options[:config]
|
27
|
+
records = tv.all
|
28
|
+
if output = options.delete(:output)
|
29
|
+
Viewer.export(records, output[0], output[1])
|
30
|
+
else
|
31
|
+
puts records
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Timekeeper
|
2
|
+
|
3
|
+
class Viewer
|
4
|
+
|
5
|
+
def config(file="timekeeper.yml")
|
6
|
+
@config ||= YAML.load_file(file)
|
7
|
+
end
|
8
|
+
|
9
|
+
def all
|
10
|
+
tables.collect{|table| table.query.collect{|attrs| Keep.new(attrs)}}.flatten!
|
11
|
+
end
|
12
|
+
|
13
|
+
def close
|
14
|
+
tables.each {|table| table.close}
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.export(records, name="timekeeper", type= :csv)
|
18
|
+
if records.any?
|
19
|
+
case type.to_s
|
20
|
+
when "csv"
|
21
|
+
FasterCSV.open("#{name}.#{type}", "w") do |csv|
|
22
|
+
csv << records[0].keys
|
23
|
+
records.each do |record|
|
24
|
+
csv << record.values
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def tables
|
34
|
+
@tables ||= config["team"].collect{|t| Rufus::Tokyo::Table.new(File.join(config["db_path"],"#{t}-time.tct"))}
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Timekeeper
|
2
|
+
|
3
|
+
class ViewerOptions < Hash
|
4
|
+
attr_reader :opts
|
5
|
+
|
6
|
+
def initialize(args)
|
7
|
+
super()
|
8
|
+
|
9
|
+
@opts = OptionParser.new do |o|
|
10
|
+
o.banner = "Usage: #{File.basename($0)} [options]"
|
11
|
+
|
12
|
+
o.on("--config FILE", "location of your configuration file - default is ./timekeeper.yml") do |file|
|
13
|
+
self[:config] = file
|
14
|
+
end
|
15
|
+
|
16
|
+
o.on("--csv [FILE]", "export to csv") do |file|
|
17
|
+
self[:output] = [(file || "timekeeper"), :csv]
|
18
|
+
end
|
19
|
+
|
20
|
+
o.on('-n', '--name NAME', 'Query on name') do |title|
|
21
|
+
self[:title] = title
|
22
|
+
end
|
23
|
+
|
24
|
+
o.on('-t', '--title TITLE', 'Query on title') do |title|
|
25
|
+
self[:title] = title
|
26
|
+
end
|
27
|
+
|
28
|
+
o.on('-c', '--target TARGET', 'Query on target') do |target|
|
29
|
+
self[:target] = target
|
30
|
+
end
|
31
|
+
|
32
|
+
o.on('-m', '--description DESCRIPTION', 'Query on description') do |description|
|
33
|
+
self[:description] = description
|
34
|
+
end
|
35
|
+
|
36
|
+
o.on('-d', '--date DATE', 'Query on date') do |date|
|
37
|
+
self[:date] = date
|
38
|
+
end
|
39
|
+
|
40
|
+
o.on_tail('-h', '--help', 'Display this help and exit') do
|
41
|
+
puts @opts
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
begin
|
48
|
+
@opts.parse!(args)
|
49
|
+
rescue OptionParser::InvalidOption => e
|
50
|
+
self[:invalid_argument] = e.message
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timekeeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- atog
|
@@ -55,8 +55,11 @@ extra_rdoc_files:
|
|
55
55
|
files:
|
56
56
|
- lib/timekeeper.rb
|
57
57
|
- lib/timekeeper/keep.rb
|
58
|
-
- lib/timekeeper/
|
59
|
-
- lib/timekeeper/
|
58
|
+
- lib/timekeeper/keeper.rb
|
59
|
+
- lib/timekeeper/keeper_options.rb
|
60
|
+
- lib/timekeeper/runner.rb
|
61
|
+
- lib/timekeeper/viewer.rb
|
62
|
+
- lib/timekeeper/viewer_options.rb
|
60
63
|
- LICENSE
|
61
64
|
- README.rdoc
|
62
65
|
has_rdoc: true
|
@@ -1,37 +0,0 @@
|
|
1
|
-
class Timekeeper
|
2
|
-
|
3
|
-
def config(file="timekeeper.yml")
|
4
|
-
@config ||= YAML.load_file(file)
|
5
|
-
end
|
6
|
-
|
7
|
-
def delete(id)
|
8
|
-
table.delete(id)
|
9
|
-
end
|
10
|
-
|
11
|
-
def delete_all
|
12
|
-
table.clear
|
13
|
-
end
|
14
|
-
|
15
|
-
def store(attributes)
|
16
|
-
attributes.store("name", config["name"])
|
17
|
-
attributes.store("date", Date.today) unless attributes["date"]
|
18
|
-
table[table.genuid] = Keep.new(attributes).to_hash
|
19
|
-
end
|
20
|
-
|
21
|
-
def get(id)
|
22
|
-
if attributes = table.lget(id.to_s).values.first
|
23
|
-
Keep.new(attributes)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def update(id, attributes_to_update)
|
28
|
-
if attributes = table.lget(id.to_s).values.first
|
29
|
-
table[id] = Keep.new(attributes).update(attributes_to_update).to_hash
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def table
|
34
|
-
@table ||= Rufus::Tokyo::Table.new(File.join(config["db_path"],"#{config["name"]}-time.tct"))
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
class Timeviewer
|
2
|
-
|
3
|
-
def config(file="timekeeper.yml")
|
4
|
-
@config ||= YAML.load_file(file)
|
5
|
-
end
|
6
|
-
|
7
|
-
def all
|
8
|
-
tables.collect{|table| table.query}.flatten!
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.export(records, name="export", type= :csv)
|
12
|
-
if records.any?
|
13
|
-
case type
|
14
|
-
when :csv
|
15
|
-
FasterCSV.open("#{name}.#{type}", "w") do |csv|
|
16
|
-
csv << records[0].keys
|
17
|
-
records.each do |record|
|
18
|
-
csv << record.values
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def tables
|
28
|
-
@tables ||= config["team"].collect{|t| Rufus::Tokyo::Table.new(File.join(config["db_path"],"#{t}-time.tct"))}
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|