remote_table 1.2.4 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,10 +14,9 @@ class RemoteTable
14
14
  end
15
15
  def legacy_transformer
16
16
  return @legacy_transformer if @legacy_transformer
17
- return unless t.options['transform']
18
- transform_options = t.options['transform'].dup
19
- transform_options.stringify_keys!
20
- @legacy_transformer = transform_options['class'].new transform_options.except('class')
17
+ return unless t.options[:transform]
18
+ transform_options = t.options[:transform].symbolize_keys
19
+ @legacy_transformer = transform_options[:class].new transform_options.except(:class)
21
20
  end
22
21
  end
23
22
  end
@@ -0,0 +1,157 @@
1
+ require 'fileutils'
2
+ require 'posix/spawn'
3
+ require 'tmpdir'
4
+
5
+ class RemoteTable
6
+ class SpawnError < ::RuntimeError; end
7
+
8
+ module Utils
9
+ def self.tmp_path(ancestor)
10
+ basename = ::File.basename(ancestor).sub(/remote_table-[0-9]+-/, '')
11
+ ::Kernel.srand
12
+ ::File.join ::Dir.tmpdir, "remote_table-#{::Kernel.rand(1e11)}-#{basename}"
13
+ end
14
+
15
+ def self.spawn(*argv)
16
+ options = argv.extract_options!
17
+ if options[:in] or options[:out]
18
+ # capture these now because posix/spawn is known to bork them
19
+ in_out = options.slice(:in, :out).map { |k, v| ":#{k} => #{v.path}" }.join(', ')
20
+ # --
21
+ pid = ::POSIX::Spawn.spawn *argv, options
22
+ ::Process.waitpid pid
23
+ raise SpawnError, "[remote_table] spawn #{argv.join(' ')} (#{in_out}) failed with exit status #{$?.exitstatus}" unless $?.success?
24
+ else
25
+ child = ::POSIX::Spawn::Child.new *argv
26
+ raise SpawnError, "[remote_table] spawn #{argv.join(' ')}) failed with #{child.err}" unless child.success?
27
+ end
28
+ nil
29
+ end
30
+
31
+ def self.in_place(*args)
32
+ options = args.extract_options!
33
+ input = args.shift
34
+ argv = args
35
+ output = tmp_path input
36
+ ::File.open(input, 'r') do |f0|
37
+ ::File.open(output, 'wb') do |f1|
38
+ spawn *argv, :in => f0, :out => f1
39
+ end
40
+ end
41
+ ::FileUtils.mv output, input
42
+ nil
43
+ rescue SpawnError => e
44
+ if options[:ignore_error]
45
+ $stderr.puts "#{e.inspect} (ignoring error...)"
46
+ ::FileUtils.mv output, input
47
+ else
48
+ raise e
49
+ end
50
+ end
51
+
52
+ def self.download(uri, form_data = nil)
53
+ output = tmp_path uri.path
54
+
55
+ if uri.scheme == 'file'
56
+ $stderr.puts "[remote_table] Getting #{uri.path} from the local file system" if ::ENV['REMOTE_TABLE_VERBOSE'] == 'true'
57
+ ::FileUtils.cp uri.path, output
58
+ return output
59
+ end
60
+
61
+ argv = [ 'curl', '--location', '--show-error', '--silent', '--compressed', '--header', 'Expect: ' ]
62
+ if form_data
63
+ argv += [ '--data', form_data ]
64
+ end
65
+ argv += [ uri.to_s, '--output', output ]
66
+
67
+ # sabshere 7/20/11 make web requests move more slowly so you don't get accused of DOS
68
+ if ::ENV.has_key?('REMOTE_TABLE_DELAY_BETWEEN_REQUESTS')
69
+ ::Kernel.sleep ::ENV['REMOTE_TABLE_DELAY_BETWEEN_REQUESTS'].to_i
70
+ end
71
+
72
+ $stderr.puts "[remote_table] Downloading #{uri.to_s}" if ::ENV['REMOTE_TABLE_VERBOSE'] == 'true'
73
+ spawn *argv
74
+ output
75
+ end
76
+
77
+ def self.decompress(input, compression)
78
+ case compression
79
+ when :zip, :exe
80
+ Utils.unzip input
81
+ when :bz2
82
+ Utils.bunzip2 input
83
+ when :gz
84
+ Utils.gunzip input
85
+ else
86
+ raise ::ArgumentError, "[remote_table] Unrecognized compression #{compression}"
87
+ end
88
+ end
89
+
90
+ def self.unpack(input, packing)
91
+ case packing
92
+ when :tar
93
+ Utils.untar input
94
+ else
95
+ raise ::ArgumentError, "[remote_table] Unrecognized packing #{packing}"
96
+ end
97
+ end
98
+
99
+ def self.pick(input, options = {})
100
+ options = options.symbolize_keys
101
+ if (options[:filename] or options[:glob]) and not ::File.directory?(input)
102
+ raise ::RuntimeError, "[remote_table] Expecting #{input} to be a directory"
103
+ end
104
+ if filename = options[:filename]
105
+ src = ::File.join input, filename
106
+ raise(::RuntimeError, "[remote_table] Expecting #{src} to be a file") unless ::File.file?(src)
107
+ output = tmp_path src
108
+ ::FileUtils.mv src, output
109
+ ::FileUtils.rm_rf input if ::File.dirname(input).start_with?(::Dir.tmpdir)
110
+ elsif glob = options[:glob]
111
+ src = ::Dir[input+glob].first
112
+ raise(::RuntimeError, "[remote_table] Expecting #{glob} to find a file in #{input}") unless src and ::File.file?(src)
113
+ output = tmp_path src
114
+ ::FileUtils.mv src, output
115
+ ::FileUtils.rm_rf input if ::File.dirname(input).start_with?(::Dir.tmpdir)
116
+ else
117
+ output = tmp_path input
118
+ ::FileUtils.mv input, output
119
+ end
120
+ output
121
+ end
122
+
123
+ def self.gunzip(input)
124
+ output = tmp_path input
125
+ ::File.open(output, 'wb') do |f|
126
+ spawn 'gunzip', '--stdout', input, :out => f
127
+ end
128
+ ::FileUtils.rm_f input
129
+ output
130
+ end
131
+
132
+ def self.bunzip2(input)
133
+ output = tmp_path input
134
+ ::File.open(output, 'wb') do |f|
135
+ spawn 'bunzip2', '--stdout', input, :out => f
136
+ end
137
+ ::FileUtils.rm_f input
138
+ output
139
+ end
140
+
141
+ def self.untar(input)
142
+ dest_dir = tmp_path input
143
+ ::FileUtils.mkdir dest_dir
144
+ spawn 'tar', '-xf', input, '-C', dest_dir
145
+ ::FileUtils.rm_f input
146
+ dest_dir
147
+ end
148
+
149
+ def self.unzip(input)
150
+ dest_dir = tmp_path input
151
+ ::FileUtils.mkdir dest_dir
152
+ spawn 'unzip', '-qq', '-n', input, '-d', dest_dir
153
+ ::FileUtils.rm_f input
154
+ dest_dir
155
+ end
156
+ end
157
+ end
@@ -1,3 +1,3 @@
1
1
  class RemoteTable
2
- VERSION = "1.2.4"
2
+ VERSION = "1.3.0"
3
3
  end
data/remote_table.gemspec CHANGED
@@ -20,15 +20,9 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  s.add_runtime_dependency 'activesupport', '>=2.3.4'
23
- s.add_runtime_dependency 'roo', '~>1.9'
23
+ s.add_runtime_dependency 'roo', '>=1.9'
24
24
  s.add_runtime_dependency 'fixed_width-multibyte' # TODO replace with fixed_width once timon gets off vacation
25
25
  s.add_runtime_dependency 'i18n' # activesupport?
26
- s.add_runtime_dependency 'builder' # roo?
27
- s.add_runtime_dependency 'zip' # roo
28
- s.add_runtime_dependency 'nokogiri', '>=1.4.1' # roo
29
- s.add_runtime_dependency 'spreadsheet' #roo
30
- s.add_runtime_dependency 'google-spreadsheet-ruby' #roo
31
- s.add_runtime_dependency 'escape', '>=0.0.4'
32
26
  s.add_runtime_dependency 'posix-spawn'
33
27
  s.add_runtime_dependency 'ensure-encoding'
34
28
  s.add_runtime_dependency 'fastercsv', '>=1.5.0'
data/test/test_big.rb CHANGED
@@ -41,9 +41,9 @@ class TestBig < Test::Unit::TestCase
41
41
 
42
42
  should "send form data, follow redirects and use a filename glob" do
43
43
  url = 'http://www.transtats.bts.gov/DownLoad_Table.asp?Table_ID=293&Has_Group=3&Is_Zipped=0'
44
- form_data = 'UserTableName=T_100_Segment__All_Carriers&DBShortName=Air_Carriers&RawDataTable=T_T100_SEGMENT_ALL_CARRIER&sqlstr=+SELECT+DEPARTURES_SCHEDULED%2CDEPARTURES_PERFORMED%2CPAYLOAD%2CSEATS%2CPASSENGERS%2CFREIGHT%2CMAIL%2CDISTANCE%2CRAMP_TO_RAMP%2CAIR_TIME%2CUNIQUE_CARRIER%2CAIRLINE_ID%2CUNIQUE_CARRIER_NAME%2CUNIQUE_CARRIER_ENTITY%2CREGION%2CCARRIER%2CCARRIER_NAME%2CCARRIER_GROUP%2CCARRIER_GROUP_NEW%2CORIGIN%2CORIGIN_CITY_NAME%2CORIGIN_CITY_NUM%2CORIGIN_STATE_ABR%2CORIGIN_STATE_FIPS%2CORIGIN_STATE_NM%2CORIGIN_COUNTRY%2CORIGIN_COUNTRY_NAME%2CORIGIN_WAC%2CDEST%2CDEST_CITY_NAME%2CDEST_CITY_NUM%2CDEST_STATE_ABR%2CDEST_STATE_FIPS%2CDEST_STATE_NM%2CDEST_COUNTRY%2CDEST_COUNTRY_NAME%2CDEST_WAC%2CAIRCRAFT_GROUP%2CAIRCRAFT_TYPE%2CAIRCRAFT_CONFIG%2CYEAR%2CQUARTER%2CMONTH%2CDISTANCE_GROUP%2CCLASS%2CDATA_SOURCE+FROM++T_T100_SEGMENT_ALL_CARRIER+WHERE+Month+%3D1+AND+YEAR%3D2008&varlist=DEPARTURES_SCHEDULED%2CDEPARTURES_PERFORMED%2CPAYLOAD%2CSEATS%2CPASSENGERS%2CFREIGHT%2CMAIL%2CDISTANCE%2CRAMP_TO_RAMP%2CAIR_TIME%2CUNIQUE_CARRIER%2CAIRLINE_ID%2CUNIQUE_CARRIER_NAME%2CUNIQUE_CARRIER_ENTITY%2CREGION%2CCARRIER%2CCARRIER_NAME%2CCARRIER_GROUP%2CCARRIER_GROUP_NEW%2CORIGIN%2CORIGIN_CITY_NAME%2CORIGIN_CITY_NUM%2CORIGIN_STATE_ABR%2CORIGIN_STATE_FIPS%2CORIGIN_STATE_NM%2CORIGIN_COUNTRY%2CORIGIN_COUNTRY_NAME%2CORIGIN_WAC%2CDEST%2CDEST_CITY_NAME%2CDEST_CITY_NUM%2CDEST_STATE_ABR%2CDEST_STATE_FIPS%2CDEST_STATE_NM%2CDEST_COUNTRY%2CDEST_COUNTRY_NAME%2CDEST_WAC%2CAIRCRAFT_GROUP%2CAIRCRAFT_TYPE%2CAIRCRAFT_CONFIG%2CYEAR%2CQUARTER%2CMONTH%2CDISTANCE_GROUP%2CCLASS%2CDATA_SOURCE&grouplist=&suml=&sumRegion=&filter1=title%3D&filter2=title%3D&geo=All%A0&time=January&timename=Month&GEOGRAPHY=All&XYEAR=2008&FREQUENCY=1&AllVars=All&VarName=DEPARTURES_SCHEDULED&VarDesc=DepScheduled&VarType=Num&VarName=DEPARTURES_PERFORMED&VarDesc=DepPerformed&VarType=Num&VarName=PAYLOAD&VarDesc=Payload&VarType=Num&VarName=SEATS&VarDesc=Seats&VarType=Num&VarName=PASSENGERS&VarDesc=Passengers&VarType=Num&VarName=FREIGHT&VarDesc=Freight&VarType=Num&VarName=MAIL&VarDesc=Mail&VarType=Num&VarName=DISTANCE&VarDesc=Distance&VarType=Num&VarName=RAMP_TO_RAMP&VarDesc=RampToRamp&VarType=Num&VarName=AIR_TIME&VarDesc=AirTime&VarType=Num&VarName=UNIQUE_CARRIER&VarDesc=UniqueCarrier&VarType=Char&VarName=AIRLINE_ID&VarDesc=AirlineID&VarType=Num&VarName=UNIQUE_CARRIER_NAME&VarDesc=UniqueCarrierName&VarType=Char&VarName=UNIQUE_CARRIER_ENTITY&VarDesc=UniqCarrierEntity&VarType=Char&VarName=REGION&VarDesc=CarrierRegion&VarType=Char&VarName=CARRIER&VarDesc=Carrier&VarType=Char&VarName=CARRIER_NAME&VarDesc=CarrierName&VarType=Char&VarName=CARRIER_GROUP&VarDesc=CarrierGroup&VarType=Num&VarName=CARRIER_GROUP_NEW&VarDesc=CarrierGroupNew&VarType=Num&VarName=ORIGIN&VarDesc=Origin&VarType=Char&VarName=ORIGIN_CITY_NAME&VarDesc=OriginCityName&VarType=Char&VarName=ORIGIN_CITY_NUM&VarDesc=OriginCityNum&VarType=Num&VarName=ORIGIN_STATE_ABR&VarDesc=OriginState&VarType=Char&VarName=ORIGIN_STATE_FIPS&VarDesc=OriginStateFips&VarType=Char&VarName=ORIGIN_STATE_NM&VarDesc=OriginStateName&VarType=Char&VarName=ORIGIN_COUNTRY&VarDesc=OriginCountry&VarType=Char&VarName=ORIGIN_COUNTRY_NAME&VarDesc=OriginCountryName&VarType=Char&VarName=ORIGIN_WAC&VarDesc=OriginWac&VarType=Num&VarName=DEST&VarDesc=Dest&VarType=Char&VarName=DEST_CITY_NAME&VarDesc=DestCityName&VarType=Char&VarName=DEST_CITY_NUM&VarDesc=DestCityNum&VarType=Num&VarName=DEST_STATE_ABR&VarDesc=DestState&VarType=Char&VarName=DEST_STATE_FIPS&VarDesc=DestStateFips&VarType=Char&VarName=DEST_STATE_NM&VarDesc=DestStateName&VarType=Char&VarName=DEST_COUNTRY&VarDesc=DestCountry&VarType=Char&VarName=DEST_COUNTRY_NAME&VarDesc=DestCountryName&VarType=Char&VarName=DEST_WAC&VarDesc=DestWac&VarType=Num&VarName=AIRCRAFT_GROUP&VarDesc=AircraftGroup&VarType=Num&VarName=AIRCRAFT_TYPE&VarDesc=AircraftType&VarType=Char&VarName=AIRCRAFT_CONFIG&VarDesc=AircraftConfig&VarType=Num&VarName=YEAR&VarDesc=Year&VarType=Num&VarName=QUARTER&VarDesc=Quarter&VarType=Num&VarName=MONTH&VarDesc=Month&VarType=Num&VarName=DISTANCE_GROUP&VarDesc=DistanceGroup&VarType=Num&VarName=CLASS&VarDesc=Class&VarType=Char&VarName=DATA_SOURCE&VarDesc=DataSource&VarType=Char'
44
+ form_data = 'UserTableName=T_100_Segment__All_Carriers&DBShortName=Air_Carriers&RawDataTable=T_T100_SEGMENT_ALL_CARRIER&sqlstr=+SELECT+DEPARTURES_SCHEDULED%2CDEPARTURES_PERFORMED%2CPAYLOAD%2CSEATS%2CPASSENGERS%2CFREIGHT%2CMAIL%2CDISTANCE%2CRAMP_TO_RAMP%2CAIR_TIME%2CUNIQUE_CARRIER%2CAIRLINE_ID%2CUNIQUE_CARRIER_NAME%2CUNIQUE_CARRIER_ENTITY%2CREGION%2CCARRIER%2CCARRIER_NAME%2CCARRIER_GROUP%2CCARRIER_GROUP_NEW%2CORIGIN%2CORIGIN_CITY_NAME%2CORIGIN_STATE_ABR%2CORIGIN_STATE_FIPS%2CORIGIN_STATE_NM%2CORIGIN_COUNTRY%2CORIGIN_COUNTRY_NAME%2CORIGIN_WAC%2CDEST%2CDEST_CITY_NAME%2CDEST_STATE_ABR%2CDEST_STATE_FIPS%2CDEST_STATE_NM%2CDEST_COUNTRY%2CDEST_COUNTRY_NAME%2CDEST_WAC%2CAIRCRAFT_GROUP%2CAIRCRAFT_TYPE%2CAIRCRAFT_CONFIG%2CYEAR%2CQUARTER%2CMONTH%2CDISTANCE_GROUP%2CCLASS%2CDATA_SOURCE+FROM++T_T100_SEGMENT_ALL_CARRIER+WHERE+Month+%3D1+AND+YEAR%3D2008&varlist=DEPARTURES_SCHEDULED%2CDEPARTURES_PERFORMED%2CPAYLOAD%2CSEATS%2CPASSENGERS%2CFREIGHT%2CMAIL%2CDISTANCE%2CRAMP_TO_RAMP%2CAIR_TIME%2CUNIQUE_CARRIER%2CAIRLINE_ID%2CUNIQUE_CARRIER_NAME%2CUNIQUE_CARRIER_ENTITY%2CREGION%2CCARRIER%2CCARRIER_NAME%2CCARRIER_GROUP%2CCARRIER_GROUP_NEW%2CORIGIN%2CORIGIN_CITY_NAME%2CORIGIN_STATE_ABR%2CORIGIN_STATE_FIPS%2CORIGIN_STATE_NM%2CORIGIN_COUNTRY%2CORIGIN_COUNTRY_NAME%2CORIGIN_WAC%2CDEST%2CDEST_CITY_NAME%2CDEST_STATE_ABR%2CDEST_STATE_FIPS%2CDEST_STATE_NM%2CDEST_COUNTRY%2CDEST_COUNTRY_NAME%2CDEST_WAC%2CAIRCRAFT_GROUP%2CAIRCRAFT_TYPE%2CAIRCRAFT_CONFIG%2CYEAR%2CQUARTER%2CMONTH%2CDISTANCE_GROUP%2CCLASS%2CDATA_SOURCE&grouplist=&suml=&sumRegion=&filter1=title%3D&filter2=title%3D&geo=All%A0&time=January&timename=Month&GEOGRAPHY=All&XYEAR=2008&FREQUENCY=1&AllVars=All&VarName=DEPARTURES_SCHEDULED&VarDesc=DepScheduled&VarType=Num&VarName=DEPARTURES_PERFORMED&VarDesc=DepPerformed&VarType=Num&VarName=PAYLOAD&VarDesc=Payload&VarType=Num&VarName=SEATS&VarDesc=Seats&VarType=Num&VarName=PASSENGERS&VarDesc=Passengers&VarType=Num&VarName=FREIGHT&VarDesc=Freight&VarType=Num&VarName=MAIL&VarDesc=Mail&VarType=Num&VarName=DISTANCE&VarDesc=Distance&VarType=Num&VarName=RAMP_TO_RAMP&VarDesc=RampToRamp&VarType=Num&VarName=AIR_TIME&VarDesc=AirTime&VarType=Num&VarName=UNIQUE_CARRIER&VarDesc=UniqueCarrier&VarType=Char&VarName=AIRLINE_ID&VarDesc=AirlineID&VarType=Num&VarName=UNIQUE_CARRIER_NAME&VarDesc=UniqueCarrierName&VarType=Char&VarName=UNIQUE_CARRIER_ENTITY&VarDesc=UniqCarrierEntity&VarType=Char&VarName=REGION&VarDesc=CarrierRegion&VarType=Char&VarName=CARRIER&VarDesc=Carrier&VarType=Char&VarName=CARRIER_NAME&VarDesc=CarrierName&VarType=Char&VarName=CARRIER_GROUP&VarDesc=CarrierGroup&VarType=Num&VarName=CARRIER_GROUP_NEW&VarDesc=CarrierGroupNew&VarType=Num&VarName=ORIGIN&VarDesc=Origin&VarType=Char&VarName=ORIGIN_CITY_NAME&VarDesc=OriginCityName&VarType=Char&VarName=ORIGIN_STATE_ABR&VarDesc=OriginState&VarType=Char&VarName=ORIGIN_STATE_FIPS&VarDesc=OriginStateFips&VarType=Char&VarName=ORIGIN_STATE_NM&VarDesc=OriginStateName&VarType=Char&VarName=ORIGIN_COUNTRY&VarDesc=OriginCountry&VarType=Char&VarName=ORIGIN_COUNTRY_NAME&VarDesc=OriginCountryName&VarType=Char&VarName=ORIGIN_WAC&VarDesc=OriginWac&VarType=Num&VarName=DEST&VarDesc=Dest&VarType=Char&VarName=DEST_CITY_NAME&VarDesc=DestCityName&VarType=Char&VarName=DEST_STATE_ABR&VarDesc=DestState&VarType=Char&VarName=DEST_STATE_FIPS&VarDesc=DestStateFips&VarType=Char&VarName=DEST_STATE_NM&VarDesc=DestStateName&VarType=Char&VarName=DEST_COUNTRY&VarDesc=DestCountry&VarType=Char&VarName=DEST_COUNTRY_NAME&VarDesc=DestCountryName&VarType=Char&VarName=DEST_WAC&VarDesc=DestWac&VarType=Num&VarName=AIRCRAFT_GROUP&VarDesc=AircraftGroup&VarType=Num&VarName=AIRCRAFT_TYPE&VarDesc=AircraftType&VarType=Char&VarName=AIRCRAFT_CONFIG&VarDesc=AircraftConfig&VarType=Num&VarName=YEAR&VarDesc=Year&VarType=Num&VarName=QUARTER&VarDesc=Quarter&VarType=Num&VarName=MONTH&VarDesc=Month&VarType=Num&VarName=DISTANCE_GROUP&VarDesc=DistanceGroup&VarType=Num&VarName=CLASS&VarDesc=Class&VarType=Char&VarName=DATA_SOURCE&VarDesc=DataSource&VarType=Char'
45
45
  t = RemoteTable.new :url => url, :form_data => form_data, :compression => :zip, :glob => '/*.csv'
46
- assert_equal 'United States of America', t.rows.first['DEST_COUNTRY_NAME']
46
+ assert_equal 'United States', t.rows.first['DEST_COUNTRY_NAME']
47
47
  end
48
48
 
49
49
  # should "provide a row_hash on demand" do
@@ -16,12 +16,14 @@ $test2_rows.freeze
16
16
  class TestOldSyntax < Test::Unit::TestCase
17
17
  should "open an XLSX like an array (numbered columns)" do
18
18
  t = RemoteTable.new(:url => 'www.customerreferenceprogram.org/uploads/CRP_RFP_template.xlsx', :headers => false)
19
+ assert_equal "Requirements", t.rows[0][0]
19
20
  assert_equal "Software-As-A-Service", t.rows[5][0]
20
21
  end
21
22
 
22
23
  should "open an XLSX with custom headers" do
23
24
  t = RemoteTable.new(:url => 'www.customerreferenceprogram.org/uploads/CRP_RFP_template.xlsx', :headers => %w{foo bar baz})
24
- assert_equal "Secure encryption of all data", t.rows[5]['foo']
25
+ assert_equal "Requirements", t.rows[0]['foo']
26
+ assert_equal "Software-As-A-Service", t.rows[5]['foo']
25
27
  end
26
28
 
27
29
  should "open an XLSX" do
@@ -114,27 +116,25 @@ class TestOldSyntax < Test::Unit::TestCase
114
116
  end
115
117
 
116
118
  %w{ csv ods xls }.each do |format|
117
- eval %{
118
- should "read #{format}" do
119
- t = RemoteTable.new(:url => 'http://cloud.github.com/downloads/seamusabshere/remote_table/test2.#{format}')
120
- # no blank headers
121
- assert t.rows.all? { |row| row.keys.all?(&:present?) }
122
- # correct values
123
- t.rows.each_with_index do |row, index|
124
- assert_equal row.except('row_hash'), $test2_rows[index]
125
- end
119
+ should "read #{format}" do
120
+ t = RemoteTable.new(:url => "http://cloud.github.com/downloads/seamusabshere/remote_table/test2.#{format}")
121
+ # no blank headers
122
+ assert t.rows.all? { |row| row.keys.all?(&:present?) }
123
+ # correct values
124
+ t.rows.each_with_index do |row, index|
125
+ assert_equal $test2_rows[index], row.except('row_hash')
126
126
  end
127
-
128
- should "read #{format}, keeping blank rows" do
129
- t = RemoteTable.new(:url => 'http://cloud.github.com/downloads/seamusabshere/remote_table/test2.#{format}', :keep_blank_rows => true)
130
- # no blank headers
131
- assert t.rows.all? { |row| row.keys.all?(&:present?) }
132
- # correct values
133
- t.rows.each_with_index do |row, index|
134
- assert_equal row.except('row_hash'), $test2_rows_with_blanks[index]
135
- end
127
+ end
128
+
129
+ should "read #{format}, keeping blank rows" do
130
+ t = RemoteTable.new(:url => "http://cloud.github.com/downloads/seamusabshere/remote_table/test2.#{format}", :keep_blank_rows => true)
131
+ # no blank headers
132
+ assert t.rows.all? { |row| row.keys.all?(&:present?) }
133
+ # correct values
134
+ t.rows.each_with_index do |row, index|
135
+ assert_equal $test2_rows_with_blanks[index], row.except('row_hash')
136
136
  end
137
- }
137
+ end
138
138
  end
139
139
 
140
140
  should "read fixed width correctly" do
@@ -124,4 +124,15 @@ class TestRemoteTable < Test::Unit::TestCase
124
124
  t = RemoteTable.new 'https://openflights.svn.sourceforge.net/svnroot/openflights/openflights/data/airports.dat', :headers => false#, :encoding => 'UTF-8'
125
125
  assert_equal 'Goroka', t[0][1]
126
126
  end
127
+
128
+ should "read only certain rows of an XLSX" do
129
+ t = RemoteTable.new 'www.customerreferenceprogram.org/uploads/CRP_RFP_template.xlsx', :crop => 11..16, :headers => false
130
+ assert_equal "Permissioning and access groups for all content", t[0][0]
131
+ assert_equal "Manage Multiple Incentive Programs for Participants", t[4][0]
132
+
133
+ t = RemoteTable.new 'www.customerreferenceprogram.org/uploads/CRP_RFP_template.xlsx', :crop => 11..16, :headers => %w{ col1 }
134
+ assert_equal "Permissioning and access groups for all content", t[0]['col1']
135
+ assert_equal "Manage Multiple Incentive Programs for Participants", t[4]['col1']
136
+ end
137
+
127
138
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remote_table
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-11-29 00:00:00.000000000Z
13
+ date: 2011-12-27 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
17
- requirement: &2164990540 !ruby/object:Gem::Requirement
17
+ requirement: &2165420280 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,21 +22,21 @@ dependencies:
22
22
  version: 2.3.4
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2164990540
25
+ version_requirements: *2165420280
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: roo
28
- requirement: &2164990040 !ruby/object:Gem::Requirement
28
+ requirement: &2165419500 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
- - - ~>
31
+ - - ! '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.9'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2164990040
36
+ version_requirements: *2165419500
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: fixed_width-multibyte
39
- requirement: &2164989660 !ruby/object:Gem::Requirement
39
+ requirement: &2165418920 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,32 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *2164989660
47
+ version_requirements: *2165418920
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: i18n
50
- requirement: &2164989200 !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
53
- - - ! '>='
54
- - !ruby/object:Gem::Version
55
- version: '0'
56
- type: :runtime
57
- prerelease: false
58
- version_requirements: *2164989200
59
- - !ruby/object:Gem::Dependency
60
- name: builder
61
- requirement: &2164988780 !ruby/object:Gem::Requirement
62
- none: false
63
- requirements:
64
- - - ! '>='
65
- - !ruby/object:Gem::Version
66
- version: '0'
67
- type: :runtime
68
- prerelease: false
69
- version_requirements: *2164988780
70
- - !ruby/object:Gem::Dependency
71
- name: zip
72
- requirement: &2164988360 !ruby/object:Gem::Requirement
50
+ requirement: &2165418440 !ruby/object:Gem::Requirement
73
51
  none: false
74
52
  requirements:
75
53
  - - ! '>='
@@ -77,54 +55,10 @@ dependencies:
77
55
  version: '0'
78
56
  type: :runtime
79
57
  prerelease: false
80
- version_requirements: *2164988360
81
- - !ruby/object:Gem::Dependency
82
- name: nokogiri
83
- requirement: &2164987860 !ruby/object:Gem::Requirement
84
- none: false
85
- requirements:
86
- - - ! '>='
87
- - !ruby/object:Gem::Version
88
- version: 1.4.1
89
- type: :runtime
90
- prerelease: false
91
- version_requirements: *2164987860
92
- - !ruby/object:Gem::Dependency
93
- name: spreadsheet
94
- requirement: &2164987440 !ruby/object:Gem::Requirement
95
- none: false
96
- requirements:
97
- - - ! '>='
98
- - !ruby/object:Gem::Version
99
- version: '0'
100
- type: :runtime
101
- prerelease: false
102
- version_requirements: *2164987440
103
- - !ruby/object:Gem::Dependency
104
- name: google-spreadsheet-ruby
105
- requirement: &2164986980 !ruby/object:Gem::Requirement
106
- none: false
107
- requirements:
108
- - - ! '>='
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- type: :runtime
112
- prerelease: false
113
- version_requirements: *2164986980
114
- - !ruby/object:Gem::Dependency
115
- name: escape
116
- requirement: &2164986480 !ruby/object:Gem::Requirement
117
- none: false
118
- requirements:
119
- - - ! '>='
120
- - !ruby/object:Gem::Version
121
- version: 0.0.4
122
- type: :runtime
123
- prerelease: false
124
- version_requirements: *2164986480
58
+ version_requirements: *2165418440
125
59
  - !ruby/object:Gem::Dependency
126
60
  name: posix-spawn
127
- requirement: &2164986060 !ruby/object:Gem::Requirement
61
+ requirement: &2165407660 !ruby/object:Gem::Requirement
128
62
  none: false
129
63
  requirements:
130
64
  - - ! '>='
@@ -132,10 +66,10 @@ dependencies:
132
66
  version: '0'
133
67
  type: :runtime
134
68
  prerelease: false
135
- version_requirements: *2164986060
69
+ version_requirements: *2165407660
136
70
  - !ruby/object:Gem::Dependency
137
71
  name: ensure-encoding
138
- requirement: &2164985600 !ruby/object:Gem::Requirement
72
+ requirement: &2165407140 !ruby/object:Gem::Requirement
139
73
  none: false
140
74
  requirements:
141
75
  - - ! '>='
@@ -143,10 +77,10 @@ dependencies:
143
77
  version: '0'
144
78
  type: :runtime
145
79
  prerelease: false
146
- version_requirements: *2164985600
80
+ version_requirements: *2165407140
147
81
  - !ruby/object:Gem::Dependency
148
82
  name: fastercsv
149
- requirement: &2164985100 !ruby/object:Gem::Requirement
83
+ requirement: &2165406380 !ruby/object:Gem::Requirement
150
84
  none: false
151
85
  requirements:
152
86
  - - ! '>='
@@ -154,10 +88,10 @@ dependencies:
154
88
  version: 1.5.0
155
89
  type: :runtime
156
90
  prerelease: false
157
- version_requirements: *2164985100
91
+ version_requirements: *2165406380
158
92
  - !ruby/object:Gem::Dependency
159
93
  name: hash_digest
160
- requirement: &2164984680 !ruby/object:Gem::Requirement
94
+ requirement: &2165405380 !ruby/object:Gem::Requirement
161
95
  none: false
162
96
  requirements:
163
97
  - - ! '>='
@@ -165,10 +99,10 @@ dependencies:
165
99
  version: '0'
166
100
  type: :runtime
167
101
  prerelease: false
168
- version_requirements: *2164984680
102
+ version_requirements: *2165405380
169
103
  - !ruby/object:Gem::Dependency
170
104
  name: errata
171
- requirement: &2164984140 !ruby/object:Gem::Requirement
105
+ requirement: &2165404500 !ruby/object:Gem::Requirement
172
106
  none: false
173
107
  requirements:
174
108
  - - ! '>='
@@ -176,10 +110,10 @@ dependencies:
176
110
  version: 0.2.0
177
111
  type: :development
178
112
  prerelease: false
179
- version_requirements: *2164984140
113
+ version_requirements: *2165404500
180
114
  - !ruby/object:Gem::Dependency
181
115
  name: test-unit
182
- requirement: &2165000080 !ruby/object:Gem::Requirement
116
+ requirement: &2165404080 !ruby/object:Gem::Requirement
183
117
  none: false
184
118
  requirements:
185
119
  - - ! '>='
@@ -187,10 +121,10 @@ dependencies:
187
121
  version: '0'
188
122
  type: :development
189
123
  prerelease: false
190
- version_requirements: *2165000080
124
+ version_requirements: *2165404080
191
125
  - !ruby/object:Gem::Dependency
192
126
  name: shoulda
193
- requirement: &2164999620 !ruby/object:Gem::Requirement
127
+ requirement: &2165403480 !ruby/object:Gem::Requirement
194
128
  none: false
195
129
  requirements:
196
130
  - - ! '>='
@@ -198,10 +132,10 @@ dependencies:
198
132
  version: '0'
199
133
  type: :development
200
134
  prerelease: false
201
- version_requirements: *2164999620
135
+ version_requirements: *2165403480
202
136
  - !ruby/object:Gem::Dependency
203
137
  name: rake
204
- requirement: &2164999200 !ruby/object:Gem::Requirement
138
+ requirement: &2165403060 !ruby/object:Gem::Requirement
205
139
  none: false
206
140
  requirements:
207
141
  - - ! '>='
@@ -209,7 +143,7 @@ dependencies:
209
143
  version: '0'
210
144
  type: :development
211
145
  prerelease: false
212
- version_requirements: *2164999200
146
+ version_requirements: *2165403060
213
147
  description: Gives you a standard way to parse various formats and treat them as an
214
148
  array of hashes.
215
149
  email:
@@ -226,7 +160,6 @@ files:
226
160
  - README.rdoc
227
161
  - Rakefile
228
162
  - lib/remote_table.rb
229
- - lib/remote_table/executor.rb
230
163
  - lib/remote_table/format.rb
231
164
  - lib/remote_table/format/delimited.rb
232
165
  - lib/remote_table/format/excel.rb
@@ -241,6 +174,7 @@ files:
241
174
  - lib/remote_table/local_file.rb
242
175
  - lib/remote_table/properties.rb
243
176
  - lib/remote_table/transformer.rb
177
+ - lib/remote_table/utils.rb
244
178
  - lib/remote_table/version.rb
245
179
  - remote_table.gemspec
246
180
  - test/helper.rb