require 'fileutils' require 'escape' require 'tmpdir' class RemoteTable class LocalFile attr_reader :t def initialize(t) @t = t end def path save_locally @path end private def save_locally return if @path.is_a?(::String) @path = ::File.join(staging_dir_path, ::File.basename(t.properties.uri.path)) download decompress unpack pick @path end def download if t.properties.uri.scheme == 'file' ::FileUtils.cp t.properties.uri.path, @path else # sabshere 1/20/11 FIXME: ::RemoteTable.config.curl_bin_path or smth ::RemoteTable.executor.backtick_with_reporting %{ curl --header "Expect: " --location #{"--data #{::Escape.shell_single_word t.properties.form_data}" if t.properties.form_data.present?} --output #{::Escape.shell_single_word @path} #{::Escape.shell_single_word t.properties.uri.to_s} 2>&1 } end end def decompress return unless t.properties.compression new_path = @path.chomp ".#{t.properties.compression}" cmd = case t.properties.compression when 'zip', 'exe' "unzip #{::Escape.shell_single_word @path} -d #{::File.dirname(@path)}" # can't set path yet because there may be multiple files when 'bz2' "bunzip2 --stdout #{::Escape.shell_single_word @path} > #{::Escape.shell_single_word new_path}" @path = new_path when 'gz' "gunzip --stdout #{::Escape.shell_single_word @path} > #{::Escape.shell_single_word new_path}" @path = new_path end ::RemoteTable.executor.backtick_with_reporting cmd end def unpack return unless t.properties.packing cmd = case t.properties.packing when 'tar' "tar -xf #{::Escape.shell_single_word @path} -C #{::File.dirname(@path)}" end ::RemoteTable.executor.backtick_with_reporting cmd end # ex. A: 2007-01.csv.gz (compression not capable of storing multiple files) # ex. B: 2007-01.tar.gz (packing) # ex. C: 2007-01.zip (compression capable of storing multiple files) def pick if t.properties.filename.present? @path = ::File.join ::File.dirname(@path), t.properties.filename elsif t.properties.glob.present? @path = ::Dir[::File.dirname(@path)+t.properties.glob].first end end def staging_dir_path return @staging_dir_path if @staging_dir_path.is_a?(::String) @staging_dir_path = ::File.join ::Dir.tmpdir, 'remote_table_gem', rand.to_s ::FileUtils.mkdir_p @staging_dir_path ::RemoteTable.cleaner.remove_at_exit @staging_dir_path @staging_dir_path end end end