remote_table 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
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