1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 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 105 106 107 108 109 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
|
module Fog
module Local
class Storage
class File < Fog::Model
identity :key, :aliases => 'Key'
attribute :content_length, :aliases => 'Content-Length', :type => :integer
# attribute :content_type, :aliases => 'Content-Type'
attribute :last_modified, :aliases => 'Last-Modified'
require 'uri'
def body
attributes[:body] ||= if last_modified
collection.get(identity).body
else
''
end
end
def body=(new_body)
attributes[:body] = new_body
end
def content_type
@content_type ||= begin
unless (mime_types = ::MIME::Types.of(key)).empty?
mime_types.first.content_type
end
end
end
def directory
@directory
end
def copy(target_directory_key, target_file_key, options={})
requires :directory, :key
service.copy_object(directory.key, key, target_directory_key, target_file_key)
target_directory = service.directories.new(:key => target_directory_key)
target_directory.files.get(target_file_key)
end
def destroy
requires :directory, :key
::File.delete(path) if ::File.exist?(path)
dirs = path.split(::File::SEPARATOR)[0...-1]
dirs.length.times do |index|
dir_path = dirs[0..-index].join(::File::SEPARATOR)
if dir_path.empty? # path starts with ::File::SEPARATOR
next
end
# don't delete the containing directory or higher
if dir_path == service.path_to(directory.key)
break
end
rm_if_empty_dir(dir_path)
end
true
end
def public=(new_public)
new_public
end
def public_url
requires :directory, :key
if service.endpoint
escaped_directory = uri_escape(directory.key)
escaped_key = uri_escape(key)
::File.join(service.endpoint, escaped_directory, escaped_key)
else
nil
end
end
def save(options = {})
requires :body, :directory, :key
# Once 1.9.3 support is dropped, the following two lines
# can be replaced with `File.dirname(path)`
dirs = path.split(::File::SEPARATOR)[0...-1]
dir_path = dirs.join(::File::SEPARATOR)
# Create all directories in file path that do not yet exist
FileUtils.mkdir_p(dir_path)
if (body.is_a?(::File) || body.is_a?(Tempfile)) && ::File.exist?(body.path)
FileUtils.cp(body.path, path)
else
write_file(path, body)
end
merge_attributes(
:content_length => Fog::Storage.get_body_size(body),
:last_modified => ::File.mtime(path)
)
true
end
private
def directory=(new_directory)
@directory = new_directory
end
def uri_escape(string)
string.b.gsub(URI::DEFAULT_PARSER.regexp[:UNSAFE]) do |m|
'%' + m.unpack('H2' * m.bytesize).join('%').upcase
end
end
def path
service.path_to(::File.join(directory.key, key))
end
def write_file(path, content)
input_io = StringIO.new(content) if content.is_a?(String)
input_io ||= content
::File.open(path, 'wb') do |file|
IO.copy_stream(input_io, file)
end
end
def rm_if_empty_dir(dir_path)
if ::File.directory?(dir_path)
Dir.rmdir(dir_path) if dir_empty?(dir_path)
end
end
def dir_empty?(dir_path)
# NOTE: There’s Dir.empty?, but it is only available on Ruby 2.4+
# NOTE: `entries` will be empty on Windows, and contain . and .. on
# unix-like systems (macOS, Linux, BSD, …)
entries = Dir.entries(dir_path)
entries.empty? || entries.all? { |e| ['.', '..'].include?(e) }
end
end
end
end
end
|