Class: SkadateGems::Dev::Remote::File
- Inherits:
-
Object
- Object
- SkadateGems::Dev::Remote::File
- Defined in:
- lib/skadategems/dev/remote/file.rb
Overview
Remote file accessor.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#path ⇒ String
readonly
Relative path to a file.
-
#size ⇒ Fixnum
readonly
Remote file size in bytes.
Instance Method Summary collapse
-
#basename ⇒ String
Remote file basename.
- #directory? ⇒ Boolean
-
#extname ⇒ String
Remote file extension.
-
#friendly_size ⇒ String
Human readable file size.
-
#initialize(remote, path, size = nil) ⇒ File
constructor
A new instance of File.
-
#request(md5_checksum: nil) {|response| ... } ⇒ Object
Request remote file to read it’s contents.
-
#save_as(filename) {|chunk_size| ... } ⇒ Object
Download and save a remote file as a given filename.
Constructor Details
#initialize(remote, path, size = nil) ⇒ File
Returns a new instance of File.
19 20 21 |
# File 'lib/skadategems/dev/remote/file.rb', line 19 def initialize(remote, path, size = nil) @remote, @path, @size = remote, path, size end |
Instance Attribute Details
#path ⇒ String (readonly)
Returns relative path to a file.
14 15 16 |
# File 'lib/skadategems/dev/remote/file.rb', line 14 def path @path end |
#size ⇒ Fixnum (readonly)
Returns remote file size in bytes.
17 18 19 |
# File 'lib/skadategems/dev/remote/file.rb', line 17 def size @size end |
Instance Method Details
#basename ⇒ String
Returns remote file basename.
28 29 30 |
# File 'lib/skadategems/dev/remote/file.rb', line 28 def basename ::File.basename(@path) end |
#directory? ⇒ Boolean
23 24 25 |
# File 'lib/skadategems/dev/remote/file.rb', line 23 def directory? false end |
#extname ⇒ String
Returns remote file extension.
33 34 35 |
# File 'lib/skadategems/dev/remote/file.rb', line 33 def extname ::File.extname(@path) end |
#friendly_size ⇒ String
Returns human readable file size.
38 39 40 41 42 43 44 45 46 |
# File 'lib/skadategems/dev/remote/file.rb', line 38 def friendly_size units = %W(B KiB MiB GiB TiB) size, unit = units.reduce(@size.to_f) do |(fsize, _), type| fsize > 512 ? [fsize / 1024, type] : (break [fsize, type]) end "#{size > 9 || size.modulo(1) < 0.1 ? '%d' : '%.1f'} %s" % [size, unit] end |
#request(md5_checksum: nil) {|response| ... } ⇒ Object
Request remote file to read it’s contents.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/skadategems/dev/remote/file.rb', line 50 def request(md5_checksum: nil, &block) path = self.path.dup path[0] = '' if path[0] == '/' batch = ScriptBatch.new batch << <<-PHPSCRIPT $filename = DIR_SITE_ROOT . '#{path.gsub(/['\\]/, '\\\\\0')}'; if (!file_exists($filename)) { header('HTTP/1.1 404 Not Found'); exit; } $md5_checksum = md5_file($filename); PHPSCRIPT if md5_checksum raise ':md5_checksum must be a String' unless md5_checksum.is_a? String batch << <<-PHPSCRIPT if ($md5_checksum === '#{md5_checksum.gsub(/['\\]/, '\\\\\0')}') { header('HTTP/1.1 304 Not Modified'); exit; } PHPSCRIPT end batch << <<-PHPSCRIPT header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename($filename)); header('Content-Length: ' . filesize($filename)); header('X-Content-MD5-Checksum: ' . $md5_checksum); ob_clean(); flush(); readfile($filename); exit; PHPSCRIPT @remote.accessor.exec(batch) do |response| if response.is_a?(Net::HTTPNotModified) block.call(response) elsif response.is_a?(Net::HTTPOK) if response['content-disposition'] == "attachment; filename=#{basename}" && response['x-content-md5-checksum'] block.call(response) else raise 'unexpected response headers' end else raise "[#{response.code} \"#{response.}\"]" end end end |
#save_as(filename) {|chunk_size| ... } ⇒ Object
Download and save a remote file as a given filename.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/skadategems/dev/remote/file.rb', line 110 def save_as(filename) current_checksum = if ::File.exists?(filename) Digest::MD5.file(filename).hexdigest end request(md5_checksum: current_checksum) do |response| if response.is_a?(Net::HTTPNotModified) return false elsif response.is_a?(Net::HTTPOK) @size = response['content-length'].to_i if @size.nil? new_checksum = response['x-content-md5-checksum'] md5 = Digest::MD5.new begin tempfile = Tempfile.create([basename, extname]) response.read_body do |chunk| tempfile << chunk md5 << chunk yield chunk.size if block_given? end tempfile.close if md5.hexdigest != new_checksum raise "md5 checksum mismatch:\n [#{md5.hexdigest}]\n [#{new_checksum}]" end parent_dir = ::File.dirname(filename) FileUtils.mkdir_p(parent_dir) unless ::File.exists?(parent_dir) FileUtils.mv(tempfile.path, filename) FileUtils.chmod(0644, filename) return true ensure tempfile.close unless tempfile.closed? end else raise "unexpected response #{response}" end end end |