remote_table 1.1.2 → 1.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/lib/remote_table.rb CHANGED
@@ -16,7 +16,6 @@ class RemoteTable
16
16
  autoload :Transformer, 'remote_table/transformer'
17
17
 
18
18
  # singletons
19
- autoload :Cleaner, 'remote_table/cleaner'
20
19
  autoload :Executor, 'remote_table/executor'
21
20
  autoload :Hasher, 'remote_table/hasher'
22
21
 
@@ -52,7 +51,6 @@ class RemoteTable
52
51
  end
53
52
  @url.freeze
54
53
  @options.freeze
55
- at_exit { ::RemoteTable.cleaner.cleanup }
56
54
  end
57
55
 
58
56
  def each(&blk)
@@ -85,12 +83,7 @@ class RemoteTable
85
83
  @to_a.freeze
86
84
  end
87
85
  alias :rows :to_a
88
-
89
- # Used internally as a sort of garbage collector.
90
- def self.cleaner
91
- Cleaner.instance
92
- end
93
-
86
+
94
87
  # Used internally to execute stuff in shells.
95
88
  def self.executor
96
89
  Executor.instance
@@ -1,27 +1,30 @@
1
1
  require 'singleton'
2
2
  require 'escape'
3
3
  require 'fileutils'
4
+ require 'posix/spawn'
5
+
4
6
  class RemoteTable
5
7
  class Executor
6
8
  include ::Singleton
7
9
  def bang(path, cmd)
8
10
  tmp_path = "#{path}.bang.#{rand}"
9
- backtick_with_reporting "/bin/cat #{::Escape.shell_single_word path} | #{cmd} > #{::Escape.shell_single_word tmp_path}"
11
+ backtick_with_reporting "cat #{::Escape.shell_single_word path} | #{cmd} > #{::Escape.shell_single_word tmp_path}"
10
12
  ::FileUtils.mv tmp_path, path
11
13
  end
12
14
 
13
- def backtick_with_reporting(cmd)
14
- cmd = cmd.gsub /[ ]*\n[ ]*/m, ' '
15
- output = `#{cmd}`
16
- if not $?.success?
15
+ def backtick_with_reporting(cmd, raise_on_error = false)
16
+ cmd = cmd.gsub /\n/m, ' '
17
+ pid = ::POSIX::Spawn.spawn({ 'PATH' => '/usr/local/bin:/usr/bin:/bin' }, cmd)
18
+ stat = ::Process::waitpid pid
19
+ if raise_on_error and not stat.success?
17
20
  raise %{
18
21
  From the remote_table gem...
19
22
 
20
23
  Command failed:
21
24
  #{cmd}
22
25
 
23
- Output:
24
- #{output}
26
+ Exit code:
27
+ #{stat.exitstatus}
25
28
  }
26
29
  end
27
30
  end
@@ -20,14 +20,9 @@ class RemoteTable
20
20
  def each
21
21
  raise "must be defined by format"
22
22
  end
23
-
24
- def backup_file!
25
- ::FileUtils.cp t.local_file.path, "#{t.local_file.path}.backup"
26
- end
27
-
28
- def restore_file!
29
- return unless ::File.readable? "#{t.local_file.path}.backup"
30
- ::FileUtils.mv "#{t.local_file.path}.backup", t.local_file.path
23
+
24
+ def delete_file!
25
+ ::FileUtils.rm_rf t.properties.staging_dir_path
31
26
  end
32
27
  end
33
28
  end
@@ -15,7 +15,6 @@ class RemoteTable
15
15
  class Delimited < Format
16
16
  include Textual
17
17
  def each(&blk)
18
- backup_file!
19
18
  convert_file_to_utf8!
20
19
  remove_useless_characters!
21
20
  skip_rows!
@@ -42,7 +41,7 @@ class RemoteTable
42
41
  yield ordered_hash if t.properties.keep_blank_rows or filled_values > 0
43
42
  end
44
43
  ensure
45
- restore_file!
44
+ delete_file!
46
45
  end
47
46
 
48
47
  private
@@ -4,7 +4,6 @@ class RemoteTable
4
4
  class FixedWidth < Format
5
5
  include Textual
6
6
  def each(&blk)
7
- backup_file!
8
7
  convert_file_to_utf8!
9
8
  remove_useless_characters!
10
9
  crop_rows!
@@ -15,7 +14,7 @@ class RemoteTable
15
14
  yield hash if t.properties.keep_blank_rows or hash.any? { |k, v| v.present? }
16
15
  end
17
16
  ensure
18
- restore_file!
17
+ delete_file!
19
18
  end
20
19
  private
21
20
  def parser
@@ -5,7 +5,6 @@ class RemoteTable
5
5
  class HTML < Format
6
6
  include Textual
7
7
  def each(&blk)
8
- backup_file!
9
8
  convert_file_to_utf8!
10
9
  remove_useless_characters!
11
10
  html_headers = (t.properties.headers.is_a?(::Array)) ? t.properties.headers : nil
@@ -19,7 +18,7 @@ class RemoteTable
19
18
  yield hash if t.properties.keep_blank_rows or hash.any? { |k, v| v.present? }
20
19
  end
21
20
  ensure
22
- restore_file!
21
+ delete_file!
23
22
  end
24
23
 
25
24
  private
@@ -19,7 +19,7 @@ class RemoteTable
19
19
 
20
20
  def save_locally
21
21
  return if @path.is_a?(::String)
22
- @path = ::File.join(staging_dir_path, ::File.basename(t.properties.uri.path))
22
+ @path = ::File.join(t.properties.staging_dir_path, ::File.basename(t.properties.uri.path))
23
23
  download
24
24
  decompress
25
25
  unpack
@@ -35,6 +35,7 @@ class RemoteTable
35
35
  ::RemoteTable.executor.backtick_with_reporting %{
36
36
  curl
37
37
  --silent
38
+ --show-error
38
39
  --location
39
40
  --header "Expect: "
40
41
  #{"--data #{::Escape.shell_single_word t.properties.form_data}" if t.properties.form_data.present?}
@@ -48,18 +49,20 @@ class RemoteTable
48
49
  def decompress
49
50
  return unless t.properties.compression
50
51
  new_path = @path.chomp ".#{t.properties.compression}"
52
+ raise_on_error = true
51
53
  cmd = case t.properties.compression
52
54
  when 'zip', 'exe'
53
- "unzip #{::Escape.shell_single_word @path} -d #{::File.dirname(@path)}"
54
55
  # can't set path yet because there may be multiple files
56
+ raise_on_error = false
57
+ "unzip -qq -n #{::Escape.shell_single_word @path} -d #{::File.dirname(@path)}"
55
58
  when 'bz2'
56
- "bunzip2 --stdout #{::Escape.shell_single_word @path} > #{::Escape.shell_single_word new_path}"
57
59
  @path = new_path
60
+ "bunzip2 --stdout #{::Escape.shell_single_word @path} > #{::Escape.shell_single_word new_path}"
58
61
  when 'gz'
59
- "gunzip --stdout #{::Escape.shell_single_word @path} > #{::Escape.shell_single_word new_path}"
60
62
  @path = new_path
63
+ "gunzip --stdout #{::Escape.shell_single_word @path} > #{::Escape.shell_single_word new_path}"
61
64
  end
62
- ::RemoteTable.executor.backtick_with_reporting cmd
65
+ ::RemoteTable.executor.backtick_with_reporting cmd, raise_on_error
63
66
  end
64
67
 
65
68
  def unpack
@@ -81,13 +84,5 @@ class RemoteTable
81
84
  @path = ::Dir[::File.dirname(@path)+t.properties.glob].first
82
85
  end
83
86
  end
84
-
85
- def staging_dir_path
86
- return @staging_dir_path if @staging_dir_path.is_a?(::String)
87
- @staging_dir_path = ::File.join ::Dir.tmpdir, 'remote_table_gem', rand.to_s
88
- ::FileUtils.mkdir_p @staging_dir_path
89
- ::RemoteTable.cleaner.remove_at_exit @staging_dir_path
90
- @staging_dir_path
91
- end
92
87
  end
93
88
  end
@@ -209,5 +209,12 @@ class RemoteTable
209
209
  Format::Delimited
210
210
  end
211
211
  end
212
+
213
+ def staging_dir_path #:nodoc:
214
+ return @staging_dir_path if @staging_dir_path.is_a?(::String)
215
+ @staging_dir_path = ::File.join ::Dir.tmpdir, 'remote_table_gem', rand.to_s
216
+ ::FileUtils.mkdir_p @staging_dir_path
217
+ @staging_dir_path
218
+ end
212
219
  end
213
220
  end
@@ -1,3 +1,3 @@
1
1
  class RemoteTable
2
- VERSION = "1.1.2"
2
+ VERSION = "1.1.3"
3
3
  end
data/remote_table.gemspec CHANGED
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
29
29
  s.add_dependency 'spreadsheet' #roo
30
30
  s.add_dependency 'google-spreadsheet-ruby' #roo
31
31
  s.add_dependency 'escape', '>=0.0.4'
32
+ s.add_dependency 'posix-spawn'
32
33
  unless RUBY_VERSION >= '1.9'
33
34
  s.add_dependency 'fastercsv', '>=1.5.0'
34
35
  end
@@ -35,4 +35,12 @@ class TestRemoteTable < Test::Unit::TestCase
35
35
  assert_equal %{Body example with a <a href="">link</a>}, t[0][2]
36
36
  f.close
37
37
  end
38
+
39
+ should "open a csv inside a zip file" do
40
+ t = RemoteTable.new 'http://www.epa.gov/climatechange/emissions/downloads10/2010-Inventory-Annex-Tables.zip',
41
+ :filename => 'Annex Tables/Annex 3/Table A-93.csv',
42
+ :skip => 1,
43
+ :select => lambda { |row| row['Vehicle Age'].to_i.to_s == row['Vehicle Age'] }
44
+ assert_equal '9.09%', t[0]['LDGV']
45
+ end
38
46
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remote_table
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 2
10
- version: 1.1.2
9
+ - 3
10
+ version: 1.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Seamus Abshere
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-03-24 00:00:00 -05:00
19
+ date: 2011-03-29 00:00:00 -05:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -169,9 +169,23 @@ dependencies:
169
169
  type: :runtime
170
170
  version_requirements: *id010
171
171
  - !ruby/object:Gem::Dependency
172
- name: fastercsv
172
+ name: posix-spawn
173
173
  prerelease: false
174
174
  requirement: &id011 !ruby/object:Gem::Requirement
175
+ none: false
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ hash: 3
180
+ segments:
181
+ - 0
182
+ version: "0"
183
+ type: :runtime
184
+ version_requirements: *id011
185
+ - !ruby/object:Gem::Dependency
186
+ name: fastercsv
187
+ prerelease: false
188
+ requirement: &id012 !ruby/object:Gem::Requirement
175
189
  none: false
176
190
  requirements:
177
191
  - - ">="
@@ -183,11 +197,11 @@ dependencies:
183
197
  - 0
184
198
  version: 1.5.0
185
199
  type: :runtime
186
- version_requirements: *id011
200
+ version_requirements: *id012
187
201
  - !ruby/object:Gem::Dependency
188
202
  name: errata
189
203
  prerelease: false
190
- requirement: &id012 !ruby/object:Gem::Requirement
204
+ requirement: &id013 !ruby/object:Gem::Requirement
191
205
  none: false
192
206
  requirements:
193
207
  - - ">="
@@ -199,11 +213,11 @@ dependencies:
199
213
  - 0
200
214
  version: 0.2.0
201
215
  type: :development
202
- version_requirements: *id012
216
+ version_requirements: *id013
203
217
  - !ruby/object:Gem::Dependency
204
218
  name: test-unit
205
219
  prerelease: false
206
- requirement: &id013 !ruby/object:Gem::Requirement
220
+ requirement: &id014 !ruby/object:Gem::Requirement
207
221
  none: false
208
222
  requirements:
209
223
  - - ">="
@@ -213,11 +227,11 @@ dependencies:
213
227
  - 0
214
228
  version: "0"
215
229
  type: :development
216
- version_requirements: *id013
230
+ version_requirements: *id014
217
231
  - !ruby/object:Gem::Dependency
218
232
  name: shoulda
219
233
  prerelease: false
220
- requirement: &id014 !ruby/object:Gem::Requirement
234
+ requirement: &id015 !ruby/object:Gem::Requirement
221
235
  none: false
222
236
  requirements:
223
237
  - - ">="
@@ -227,11 +241,11 @@ dependencies:
227
241
  - 0
228
242
  version: "0"
229
243
  type: :development
230
- version_requirements: *id014
244
+ version_requirements: *id015
231
245
  - !ruby/object:Gem::Dependency
232
246
  name: ruby-debug
233
247
  prerelease: false
234
- requirement: &id015 !ruby/object:Gem::Requirement
248
+ requirement: &id016 !ruby/object:Gem::Requirement
235
249
  none: false
236
250
  requirements:
237
251
  - - ">="
@@ -241,7 +255,7 @@ dependencies:
241
255
  - 0
242
256
  version: "0"
243
257
  type: :development
244
- version_requirements: *id015
258
+ version_requirements: *id016
245
259
  description: Gives you a standard way to parse various formats and treat them as an array of hashes.
246
260
  email:
247
261
  - seamus@abshere.net
@@ -260,7 +274,6 @@ files:
260
274
  - README.rdoc
261
275
  - Rakefile
262
276
  - lib/remote_table.rb
263
- - lib/remote_table/cleaner.rb
264
277
  - lib/remote_table/executor.rb
265
278
  - lib/remote_table/format.rb
266
279
  - lib/remote_table/format/delimited.rb
@@ -1,19 +0,0 @@
1
- require 'singleton'
2
- require 'fileutils'
3
- class RemoteTable
4
- class Cleaner
5
- include ::Singleton
6
- def paths_for_removal
7
- @paths_for_removal ||= []
8
- end
9
- def cleanup
10
- paths_for_removal.each do |path|
11
- ::FileUtils.rm_rf path
12
- paths_for_removal.delete path
13
- end
14
- end
15
- def remove_at_exit(path)
16
- paths_for_removal << path
17
- end
18
- end
19
- end