seamusabshere-csv_bootstrap 0.1.0 → 0.1.1
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/README.rdoc +4 -4
- data/VERSION.yml +1 -1
- data/lib/csv_bootstrap.rb +27 -23
- data/test/csv_bootstrap_ext_test.rb +8 -8
- data/test/csv_bootstrap_test.rb +18 -13
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -13,7 +13,7 @@ You can specify other sheets (starts at 1):
|
|
13
13
|
|
14
14
|
class FuelType
|
15
15
|
csv_bootstrap :url => 'http://spreadsheets.google.com/pub?key=p70r3FHguhimIdBKyVz3iPA',
|
16
|
-
|
16
|
+
:sheet => 1
|
17
17
|
end
|
18
18
|
|
19
19
|
The gem will always request the CSV-formatted version of the document in question.
|
@@ -32,13 +32,13 @@ All of the other columns will be included as attributes, based on the column hea
|
|
32
32
|
would generate
|
33
33
|
|
34
34
|
a = FuelType.find_or_create_by_name('coal')
|
35
|
-
a.update_attributes(:
|
35
|
+
a.update_attributes(:emission_factor => '5246.89', :units => 'lbs/short ton')
|
36
36
|
|
37
37
|
a = FuelType.find_or_create_by_name('natural gas')
|
38
|
-
a.update_attributes(:
|
38
|
+
a.update_attributes(:emission_factor => '1.25', :units => 'pounds / therm (nat gas)')
|
39
39
|
|
40
40
|
a = FuelType.find_or_create_by_name('fuel oil')
|
41
|
-
a.update_attributes(:
|
41
|
+
a.update_attributes(:emission_factor => '22.51', :units => 'lbs/gallon')
|
42
42
|
|
43
43
|
== Copyright
|
44
44
|
|
data/VERSION.yml
CHANGED
data/lib/csv_bootstrap.rb
CHANGED
@@ -4,25 +4,39 @@ require 'open-uri'
|
|
4
4
|
require 'active_support'
|
5
5
|
|
6
6
|
class CsvBootstrap
|
7
|
-
attr_accessor :url, :
|
7
|
+
attr_accessor :url, :klass_name, :key_sprintf, :sheet # set in options
|
8
8
|
attr_accessor :key_name, :headers, :dictionary, :width
|
9
9
|
|
10
10
|
def bootstrap!
|
11
11
|
load_dictionary unless dictionary_loaded?
|
12
12
|
dictionary.each do |k, v|
|
13
|
-
|
14
|
-
|
13
|
+
instance_of_klass = klass_name.constantize.send("find_or_create_by_#{key_name}", v[key_name])
|
14
|
+
instance_of_klass.update_attributes(v.except(key_name))
|
15
15
|
end
|
16
16
|
true
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
-
def initialize(options = {})
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@target_class_name = options[:target_class_name]
|
21
|
+
def initialize(klass_name, options = {})
|
22
|
+
@klass_name = klass_name
|
23
|
+
@sheet = options[:sheet] ? options[:sheet] - 1 : nil
|
25
24
|
@key_sprintf = options[:key_sprintf] || '%s'
|
25
|
+
@url = options[:url]
|
26
|
+
validate
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate
|
30
|
+
raise 'Please specify a class name.' if klass_name.blank?
|
31
|
+
raise 'Please specify a url.' if url.blank?
|
32
|
+
raise ':sheet option is only supported for Google Docs Spreadsheet URLs.' if not sheet.nil? and not google_docs_spreadsheet_url?(url)
|
33
|
+
if google_docs_spreadsheet_url?(url) and /\&gid=(.*)(\&|$)/.match(url)
|
34
|
+
raise "Your Google Docs Spreadsheet URL includes a sheet number (&gid=#{$1}). Please remove it and set the sheet with :sheet => #{$1.to_i + 1}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def google_docs_spreadsheet_url?(url)
|
39
|
+
url.include?('spreadsheets.google.com')
|
26
40
|
end
|
27
41
|
|
28
42
|
def dictionary_loaded?
|
@@ -31,7 +45,7 @@ class CsvBootstrap
|
|
31
45
|
|
32
46
|
def load_dictionary
|
33
47
|
self.dictionary = {}
|
34
|
-
open(url) do |data|
|
48
|
+
open(interpret_url(url)) do |data|
|
35
49
|
FasterCSV.parse(data, :headers => :first_row) do |row|
|
36
50
|
self.width ||= row.fields.size
|
37
51
|
self.key_name ||= row.headers[0].to_sym
|
@@ -43,15 +57,8 @@ class CsvBootstrap
|
|
43
57
|
end
|
44
58
|
end
|
45
59
|
|
46
|
-
def interpret_sheet(sheet)
|
47
|
-
sheet.to_i >= 1 ? sheet.to_i - 1 : 0
|
48
|
-
end
|
49
|
-
|
50
60
|
def interpret_url(url)
|
51
|
-
if
|
52
|
-
if /\&gid=(.*)(\&|$)/.match(url)
|
53
|
-
raise "Your Google Docs URL includes a sheet number (&gid=#{$1}). Please remove it and set the sheet with :sheet => #{$1.to_i + 1}"
|
54
|
-
end
|
61
|
+
if google_docs_spreadsheet_url?(url)
|
55
62
|
url = url.gsub(/\&output=.*(\&|$)/, '')
|
56
63
|
url << "&output=csv&gid=#{sheet}"
|
57
64
|
end
|
@@ -73,9 +80,6 @@ class CsvBootstrap
|
|
73
80
|
memo
|
74
81
|
end
|
75
82
|
|
76
|
-
def target_class
|
77
|
-
target_class_name.constantize
|
78
|
-
end
|
79
83
|
end
|
80
84
|
|
81
85
|
module ActiveRecord
|
@@ -90,15 +94,15 @@ module ActiveRecord
|
|
90
94
|
module ClassMethods
|
91
95
|
def csv_bootstrap(options = {})
|
92
96
|
self.csv_bootstraps ||= []
|
93
|
-
options
|
94
|
-
csv_bootstraps << CsvBootstrap.new(options)
|
97
|
+
klass_name = options.delete(:klass_name) || self.class_name
|
98
|
+
csv_bootstraps << CsvBootstrap.new(klass_name, options)
|
95
99
|
end
|
96
100
|
|
97
|
-
def
|
101
|
+
def clear_csv_bootstraps
|
98
102
|
self.csv_bootstraps = []
|
99
103
|
end
|
100
104
|
|
101
|
-
def
|
105
|
+
def csv_bootstrap!
|
102
106
|
csv_bootstraps.each { |b| b.bootstrap! }
|
103
107
|
end
|
104
108
|
end
|
@@ -6,25 +6,25 @@ class CsvBootstrapExtTest < Test::Unit::TestCase
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def teardown
|
9
|
-
Scrum.
|
9
|
+
Scrum.clear_csv_bootstraps
|
10
10
|
CsvBootstrapTestHelper.teardown_database
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_should_mixin_methods
|
14
14
|
assert Scrum.respond_to?(:csv_bootstrap)
|
15
|
-
assert Scrum.respond_to?(:
|
16
|
-
assert Scrum.respond_to?(:
|
15
|
+
assert Scrum.respond_to?(:clear_csv_bootstraps)
|
16
|
+
assert Scrum.respond_to?(:csv_bootstrap!)
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
options = { :
|
21
|
-
CsvBootstrap.expects(:new).with(options)
|
19
|
+
def test_should_configure_bootstrap
|
20
|
+
options = { :url => CSV_URL, :sheet => 1 }
|
21
|
+
CsvBootstrap.expects(:new).with('Scrum', options)
|
22
22
|
Scrum.csv_bootstrap options
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_should_bootstrap
|
26
26
|
Scrum.csv_bootstrap :url => CSV_URL
|
27
|
-
|
28
|
-
Scrum.
|
27
|
+
Scrum.csv_bootstraps.first.expects(:bootstrap!)
|
28
|
+
Scrum.csv_bootstrap!
|
29
29
|
end
|
30
30
|
end
|
data/test/csv_bootstrap_test.rb
CHANGED
@@ -3,34 +3,39 @@ require 'test_helper'
|
|
3
3
|
class CsvBootstrapTest < Test::Unit::TestCase
|
4
4
|
def setup
|
5
5
|
CsvBootstrapTestHelper.setup_database
|
6
|
-
@bootstrap = CsvBootstrap.new(
|
6
|
+
@bootstrap = CsvBootstrap.new('Scrum', :url => GDOCS_URL, :sheet => 1)
|
7
7
|
end
|
8
8
|
|
9
9
|
def teardown
|
10
|
-
Scrum.
|
10
|
+
Scrum.clear_csv_bootstraps
|
11
11
|
CsvBootstrapTestHelper.teardown_database
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
assert_equal @bootstrap.
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_should_have_zero_based_sheet
|
19
|
-
assert_equal @bootstrap.sheet, 0
|
14
|
+
def test_should_set_klass_name
|
15
|
+
assert_equal 'Scrum', @bootstrap.klass_name
|
20
16
|
end
|
21
17
|
|
22
18
|
def test_should_set_url
|
23
|
-
|
24
|
-
|
19
|
+
assert_equal GDOCS_URL, @bootstrap.url
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_should_set_zero_based_sheet
|
23
|
+
assert_equal 0, @bootstrap.sheet
|
25
24
|
end
|
26
25
|
|
27
|
-
def
|
28
|
-
assert_equal
|
26
|
+
def test_should_interpret_gdocs_urls
|
27
|
+
assert_equal GDOCS_URL + '&output=csv&gid=0', @bootstrap.send(:interpret_url, @bootstrap.url)
|
29
28
|
end
|
30
29
|
|
31
30
|
def test_should_raise_if_gdocs_url_includes_gid
|
32
31
|
assert_raise RuntimeError do
|
33
|
-
CsvBootstrap.new(
|
32
|
+
CsvBootstrap.new('Scrum', :url => GDOCS_URL + '&gid=1')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_raise_if_sheet_option_set_on_non_gdocs_url
|
37
|
+
assert_raise RuntimeError do
|
38
|
+
CsvBootstrap.new('Scrum', :url => CSV_URL, :sheet => 1)
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|