1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

[rackspace|storage] updated file class to use the same metadata implementation as the directory class

This commit is contained in:
Kyle Rames 2013-02-13 14:23:55 -06:00
parent 8adae6d036
commit 56c020d599
7 changed files with 82 additions and 89 deletions

View file

@ -27,7 +27,7 @@ module Fog
end
end
directory.metadata = Metadata.from_headers(data.headers)
directory.metadata = Metadata.from_headers(directory, data.headers)
directory.files.merge_attributes(options)
directory.files.instance_variable_set(:@loaded, true)

View file

@ -16,19 +16,19 @@ module Fog
def metadata=(hash)
if hash.is_a? Fog::Storage::Rackspace::Metadata
@metadata = hash
attributes[:metadata] = hash
else
@metadata = Fog::Storage::Rackspace::Metadata.new(hash)
attributes[:metadata] = Fog::Storage::Rackspace::Metadata.new(self, hash)
end
@metadata
attributes[:metadata]
end
def metadata
unless @metadata
unless attributes[:metadata]
response = service.head_container(key)
@metadata = Fog::Storage::Rackspace::Metadata.from_headers(response.headers)
attributes[:metadata] = Fog::Storage::Rackspace::Metadata.from_headers(self, response.headers)
end
@metadata
attributes[:metadata]
end
def destroy

View file

@ -15,6 +15,9 @@ module Fog
attribute :access_control_allow_origin, :aliases => ['Access-Control-Allow-Origin']
attribute :origin, :aliases => ['Origin']
attr_accessor :directory
attr_writer :public
def body
attributes[:body] ||= if last_modified
collection.get(identity).body
@ -27,10 +30,6 @@ module Fog
attributes[:body] = new_body
end
def directory
@directory
end
def copy(target_directory_key, target_file_key, options={})
requires :directory, :key
options['Content-Type'] ||= content_type if content_type
@ -47,10 +46,19 @@ module Fog
true
end
def metadata
@metadata ||= headers_to_metadata
def metadata=(hash)
if hash.is_a? Fog::Storage::Rackspace::Metadata
attributes[:metadata] = hash
else
attributes[:metadata] = Fog::Storage::Rackspace::Metadata.new(self, hash)
end
attributes[:metadata]
end
def metadata
attributes[:metadata] ||= Fog::Storage::Rackspace::Metadata.new(self)
end
def owner=(new_owner)
if new_owner
attributes[:owner] = {
@ -60,10 +68,6 @@ module Fog
end
end
def public=(new_public)
new_public
end
def public?
directory.public?
end
@ -86,72 +90,19 @@ module Fog
options['Content-Type'] = content_type if content_type
options['Access-Control-Allow-Origin'] = access_control_allow_origin if access_control_allow_origin
options['Origin'] = origin if origin
options.merge!(metadata_to_headers)
options.merge!(metadata.to_headers)
data = service.put_object(directory.key, key, body, options)
update_attributes_from(data)
refresh_metadata
self.content_length = Fog::Storage.get_body_size(body)
self.content_type ||= Fog::Storage.get_content_type(body)
true
end
private
def directory=(new_directory)
@directory = new_directory
end
def refresh_metadata
metadata.reject! {|k, v| v.nil? }
end
def headers_to_metadata
key_map = key_mapping
Hash[metadata_attributes.map {|k, v| [key_map[k], v] }]
end
def key_mapping
key_map = metadata_attributes
key_map.each_pair {|k, v| key_map[k] = header_to_key(k)}
end
def header_to_key(opt)
opt.gsub(metadata_prefix, '').split('-').map {|k| k[0, 1].downcase + k[1..-1]}.join('_').to_sym
end
def metadata_to_headers
hash = {}
metadata.each_pair do |k,v|
key = metakey(k,v)
hash[key] = v
end
hash
end
def metakey(key, value)
prefix = value.nil? ? "X-Remove-Object-Meta-" : "X-Object-Meta-"
prefix + key.to_s.split(/[-_]/).map(&:capitalize).join('-')
end
def metadata_attributes
if last_modified
headers = service.head_object(directory.key, self.key).headers
headers.reject! {|k, v| !metadata_attribute?(k)}
else
{}
end
end
def metadata_attribute?(key)
key.to_s =~ /^#{metadata_prefix}/
end
def metadata_prefix
"X-Object-Meta-"
end
def update_attributes_from(data)
merge_attributes(data.headers.reject {|key, value| ['Content-Length', 'Content-Type'].include?(key)})
end

View file

@ -55,10 +55,13 @@ module Fog
def get(key, &block)
requires :directory
data = service.get_object(directory.key, key, &block)
metadata = Metadata.from_headers(data.headers)
file_data = data.headers.merge({
:body => data.body,
:key => key
:key => key,
:metadata => metadata
})
new(file_data)
rescue Fog::Storage::Rackspace::NotFound
nil

View file

@ -4,21 +4,24 @@ module Fog
class Metadata
# META_PREFIX = "X-Object-Meta-"
# REMOVE_META_PREFIX = "X-Remove-Object-Meta-"
META_PREFIX = "X-Container-Meta-"
REMOVE_META_PREFIX = "X-Remove-Container-Meta-"
OBJECT_META_PREFIX = "X-Object-Meta-"
OBJECT_REMOVE_META_PREFIX = "X-Remove-Object-Meta-"
CONTAINER_META_PREFIX = "X-Container-Meta-"
CONTAINER_REMOVE_META_PREFIX = "X-Remove-Container-Meta-"
# Cloud Files will ignore headers without a value
DUMMY_VALUE = 1
KEY_REGEX = /^#{META_PREFIX}(.*)/
CONTAINER_KEY_REGEX = /^#{CONTAINER_META_PREFIX}(.*)/
OBJECT_KEY_REGEX = /^#{OBJECT_META_PREFIX}(.*)/
attr_reader :data
def initialize(hash={})
attr_reader :data, :parent
def initialize(parent, hash={})
@data = hash || {}
@deleted_hash = {}
@parent = parent
end
def delete(key)
@ -37,10 +40,10 @@ module Fog
headers
end
def self.from_headers(headers)
metadata = Metadata.new
def self.from_headers(parent, headers)
metadata = Metadata.new(parent)
headers.each_pair do |k, v|
key = Metadata.to_key(k)
key = metadata.send(:to_key, k)
next unless key
metadata.data[key] = Fog::JSON.decode(v)
end
@ -57,8 +60,38 @@ module Fog
private
def self.to_key(key)
m = key.match KEY_REGEX
def meta_prefix
if parent.is_a? Fog::Storage::Rackspace::Directory
CONTAINER_META_PREFIX
elsif parent.is_a? Fog::Storage::Rackspace::File
OBJECT_META_PREFIX
else
raise "Metadata prefix is unknown for #{parent.class}"
end
end
def remove_meta_prefix
if parent.is_a? Fog::Storage::Rackspace::Directory
CONTAINER_REMOVE_META_PREFIX
elsif parent.is_a? Fog::Storage::Rackspace::File
OBJECT_REMOVE_META_PREFIX
else
raise "Remove Metadata prefix is unknown for #{parent.class}"
end
end
def meta_prefix_regex
if parent.is_a? Fog::Storage::Rackspace::Directory
CONTAINER_KEY_REGEX
elsif parent.is_a? Fog::Storage::Rackspace::File
OBJECT_KEY_REGEX
else
raise "Metadata prefix is unknown for #{parent.class}"
end
end
def to_key(key)
m = key.match meta_prefix_regex
return nil unless m && m[1]
a = m[1].split('-')
@ -68,7 +101,7 @@ module Fog
end
def to_header_key(key, value)
prefix = value.nil? ? REMOVE_META_PREFIX : META_PREFIX
prefix = value.nil? ? remove_meta_prefix : meta_prefix
prefix + key.to_s.split(/[-_]/).collect(&:capitalize).join('-')
end

View file

@ -50,6 +50,12 @@ Shindo.tests('Fog::Rackspace::Storage | directory', ['rackspace']) do
returns(true) { dir.metadata[:list_test] }
end
tests("should reload metadata after calling reload").returns("42") do
@service.put_container @instance.key, "X-Container-Meta-Answer" => 42
@instance.reload
@instance.metadata[:answer]
end
end
end

View file

@ -35,7 +35,7 @@ Shindo.tests('Fog::Rackspace::Storage | file', ['rackspace']) do
model_tests(@directory.files, file_attributes, Fog.mocking?) do
tests("#metadata should load empty metadata").returns({}) do
@instance.metadata
@instance.metadata.data
end
tests('#save') do