mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
[ninefold|storage] File operations.
This commit is contained in:
parent
083f7b9038
commit
ef44cd0b38
9 changed files with 212 additions and 33 deletions
|
@ -13,20 +13,25 @@ module Fog
|
||||||
|
|
||||||
def all
|
def all
|
||||||
directory ? ns = directory.key : ns = ''
|
directory ? ns = directory.key : ns = ''
|
||||||
|
ns = ns + '/' unless ns =~ /\/$/
|
||||||
data = connection.get_namespace(ns).body[:DirectoryList]
|
data = connection.get_namespace(ns).body[:DirectoryList]
|
||||||
data = {:DirectoryEntry => []} if data.kind_of? String
|
data = {:DirectoryEntry => []} if data.kind_of? String
|
||||||
data[:DirectoryEntry] = [data[:DirectoryEntry]] if data[:DirectoryEntry].kind_of? Hash
|
data[:DirectoryEntry] = [data[:DirectoryEntry]] if data[:DirectoryEntry].kind_of? Hash
|
||||||
dirs = data[:DirectoryEntry].select {|de| de[:FileType] == 'directory'}
|
dirs = data[:DirectoryEntry].select {|de| de[:FileType] == 'directory'}
|
||||||
dirs.each {|d| d[:Filename] = ns + '/' + d[:Filename] if directory}
|
dirs.each do |d|
|
||||||
load(data[:DirectoryEntry].select {|de| de[:FileType] == 'directory'})
|
d[:Filename] = ns + d[:Filename] if directory
|
||||||
|
d[:Filename] += '/' unless d[:Filename] =~ /\/$/
|
||||||
|
end
|
||||||
|
load(dirs)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(key, options = {})
|
def get(key, options = {})
|
||||||
return nil if key == '' # Root dir shouldn't be retrieved like this.
|
return nil if key == '' # Root dir shouldn't be retrieved like this.
|
||||||
res = connection.get_namespace key
|
key =~ /\/$/ ? ns = key : ns = key + '/'
|
||||||
|
res = connection.get_namespace ns
|
||||||
emc_meta = res.headers['x-emc-meta']
|
emc_meta = res.headers['x-emc-meta']
|
||||||
obj_id = emc_meta.scan(/objectid=(\w+),/).flatten[0]
|
obj_id = emc_meta.scan(/objectid=(\w+),/).flatten[0]
|
||||||
new(:objectid => obj_id, :key => key)
|
new(:objectid => obj_id, :key => ns)
|
||||||
rescue Fog::Storage::Ninefold::NotFound
|
rescue Fog::Storage::Ninefold::NotFound
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,14 +28,19 @@ module Fog
|
||||||
end
|
end
|
||||||
|
|
||||||
def save
|
def save
|
||||||
self.key = attributes[:directory].key + '/' + key if attributes[:directory]
|
self.key = attributes[:directory].key + key if attributes[:directory]
|
||||||
|
self.key = key + '/' unless key =~ /\/$/
|
||||||
res = connection.post_namespace key
|
res = connection.post_namespace key
|
||||||
reload
|
reload
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy(opts={})
|
def destroy(opts={})
|
||||||
if opts[:recursive]
|
if opts[:recursive]
|
||||||
directories.each { |d| d.destroy(opts) }
|
files.each {|f| f.destroy }
|
||||||
|
directories.each do |d|
|
||||||
|
d.files.each {|f| f.destroy }
|
||||||
|
d.destroy(opts)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
connection.delete_namespace key
|
connection.delete_namespace key
|
||||||
end
|
end
|
||||||
|
|
91
lib/fog/storage/models/ninefold/file.rb
Normal file
91
lib/fog/storage/models/ninefold/file.rb
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
require 'fog/core/model'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Storage
|
||||||
|
class Ninefold
|
||||||
|
|
||||||
|
class File < Fog::Model
|
||||||
|
|
||||||
|
identity :key, :aliases => :Filename
|
||||||
|
|
||||||
|
attribute :content_length, :aliases => ['bytes', 'Content-Length'], :type => :integer
|
||||||
|
attribute :content_type, :aliases => ['content_type', 'Content-Type']
|
||||||
|
attribute :objectid, :aliases => :ObjectID
|
||||||
|
|
||||||
|
def body
|
||||||
|
attributes[:body] ||= if last_modified
|
||||||
|
collection.get(identity).body
|
||||||
|
else
|
||||||
|
''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def body=(new_body)
|
||||||
|
attributes[:body] = new_body
|
||||||
|
end
|
||||||
|
|
||||||
|
def directory
|
||||||
|
@directory
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
requires :directory, :key
|
||||||
|
connection.delete_namespace(directory.key + key)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
# def owner=(new_owner)
|
||||||
|
# if new_owner
|
||||||
|
# attributes[:owner] = {
|
||||||
|
# :display_name => new_owner['DisplayName'],
|
||||||
|
# :id => new_owner['ID']
|
||||||
|
# }
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
def public=(new_public)
|
||||||
|
# NOOP - we don't need to flag files as public, getting the public URL for a file handles it.
|
||||||
|
end
|
||||||
|
|
||||||
|
# By default, expire in 5 years
|
||||||
|
def public_url(expires = (Time.now + 5 * 365 * 24 * 60 * 60))
|
||||||
|
requires :objectid
|
||||||
|
# TODO - more efficient method to get this?
|
||||||
|
storage = Fog::Storage.new(:provider => 'Ninefold')
|
||||||
|
uri = URI::HTTP.build(:scheme => Fog::Storage::Ninefold::STORAGE_SCHEME, :host => Fog::Storage::Ninefold::STORAGE_HOST, :port => Fog::Storage::Ninefold::STORAGE_PORT.to_i, :path => "/rest/objects/#{objectid}" )
|
||||||
|
Fog::Storage.new(:provider => 'Ninefold').uid
|
||||||
|
|
||||||
|
|
||||||
|
sb = "GET\n"
|
||||||
|
sb += uri.path.downcase + "\n"
|
||||||
|
sb += storage.uid + "\n"
|
||||||
|
sb += String(expires.to_i())
|
||||||
|
|
||||||
|
signature = storage.sign( sb )
|
||||||
|
uri.query = "uid=#{CGI::escape(storage.uid)}&expires=#{expires.to_i()}&signature=#{CGI::escape(signature)}"
|
||||||
|
uri.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def save(options = {})
|
||||||
|
requires :body, :directory, :key
|
||||||
|
directory.kind_of?(Directory) ? ns = directory.key : ns = directory
|
||||||
|
ns += key
|
||||||
|
options['Content-Type'] = content_type if content_type
|
||||||
|
data = connection.post_namespace(ns, :body => body)
|
||||||
|
#p data
|
||||||
|
self.objectid = data.headers['location'].split('/')[-1]
|
||||||
|
merge_attributes(data.headers)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def directory=(new_directory)
|
||||||
|
@directory = new_directory
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
72
lib/fog/storage/models/ninefold/files.rb
Normal file
72
lib/fog/storage/models/ninefold/files.rb
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
require 'fog/core/collection'
|
||||||
|
require 'fog/storage/models/ninefold/file'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Storage
|
||||||
|
class Ninefold
|
||||||
|
|
||||||
|
class Files < Fog::Collection
|
||||||
|
|
||||||
|
attribute :directory
|
||||||
|
attribute :limit
|
||||||
|
attribute :marker
|
||||||
|
attribute :path
|
||||||
|
attribute :prefix
|
||||||
|
|
||||||
|
model Fog::Storage::Ninefold::File
|
||||||
|
|
||||||
|
def all(options = {})
|
||||||
|
requires :directory
|
||||||
|
directory ? ns = directory.key : ns = ''
|
||||||
|
ns = ns + '/' unless ns =~ /\/$/
|
||||||
|
data = connection.get_namespace(ns).body[:DirectoryList]
|
||||||
|
data = {:DirectoryEntry => []} if data.kind_of? String
|
||||||
|
data[:DirectoryEntry] = [data[:DirectoryEntry]] if data[:DirectoryEntry].kind_of? Hash
|
||||||
|
files = data[:DirectoryEntry].select {|de| de[:FileType] == 'regular'}
|
||||||
|
files.each do |s|
|
||||||
|
s[:directory] = directory
|
||||||
|
end
|
||||||
|
# TODO - Load additional file meta?
|
||||||
|
load(files)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(key, &block)
|
||||||
|
requires :directory
|
||||||
|
data = connection.get_namespace(directory.key + key, :parse => false)#, &block)
|
||||||
|
file_data = data.headers.merge({
|
||||||
|
:body => data.body,
|
||||||
|
:key => key
|
||||||
|
})
|
||||||
|
new(file_data)
|
||||||
|
rescue Fog::Storage::Ninefold::NotFound
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_url(key)
|
||||||
|
requires :directory
|
||||||
|
if self.directory.public_url
|
||||||
|
"#{self.directory.public_url}/#{key}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def head(key, options = {})
|
||||||
|
requires :directory
|
||||||
|
data = connection.head_object(directory.key, key)
|
||||||
|
file_data = data.headers.merge({
|
||||||
|
:key => key
|
||||||
|
})
|
||||||
|
new(file_data)
|
||||||
|
rescue Fog::Storage::Rackspace::NotFound
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def new(attributes = {})
|
||||||
|
requires :directory
|
||||||
|
super({ :directory => directory }.merge!(attributes))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -14,8 +14,8 @@ module Fog
|
||||||
model_path 'fog/storage/models/ninefold'
|
model_path 'fog/storage/models/ninefold'
|
||||||
model :directory
|
model :directory
|
||||||
collection :directories
|
collection :directories
|
||||||
# model :file
|
model :file
|
||||||
# collection :files
|
collection :files
|
||||||
|
|
||||||
request_path 'fog/storage/requests/ninefold'
|
request_path 'fog/storage/requests/ninefold'
|
||||||
# request :delete_container
|
# request :delete_container
|
||||||
|
@ -54,6 +54,15 @@ module Fog
|
||||||
@connection = Fog::Connection.new("#{Fog::Storage::Ninefold::STORAGE_SCHEME}://#{Fog::Storage::Ninefold::STORAGE_HOST}:#{Fog::Storage::Ninefold::STORAGE_PORT}", true) # persistent
|
@connection = Fog::Connection.new("#{Fog::Storage::Ninefold::STORAGE_SCHEME}://#{Fog::Storage::Ninefold::STORAGE_HOST}:#{Fog::Storage::Ninefold::STORAGE_PORT}", true) # persistent
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def uid
|
||||||
|
@ninefold_storage_token#.split('/')[-1]
|
||||||
|
end
|
||||||
|
|
||||||
|
def sign(string)
|
||||||
|
value = ::HMAC::SHA1.digest( @ninefold_storage_secret_decoded, string )
|
||||||
|
Base64.encode64( value ).chomp()
|
||||||
|
end
|
||||||
|
|
||||||
def reload
|
def reload
|
||||||
@connection.reset
|
@connection.reset
|
||||||
end
|
end
|
||||||
|
@ -89,7 +98,7 @@ module Fog
|
||||||
|
|
||||||
signstring += "/rest/" + URI.unescape( req_path ).downcase
|
signstring += "/rest/" + URI.unescape( req_path ).downcase
|
||||||
query_str = params[:query].map{|k,v| "#{k}=#{v}"}.join('&')
|
query_str = params[:query].map{|k,v| "#{k}=#{v}"}.join('&')
|
||||||
signstring += '?' + params[:query] unless query_str.empty?
|
signstring += '?' + query_str unless query_str.empty?
|
||||||
signstring += "\n"
|
signstring += "\n"
|
||||||
|
|
||||||
customheaders = {}
|
customheaders = {}
|
||||||
|
|
|
@ -4,14 +4,13 @@ module Fog
|
||||||
class Real
|
class Real
|
||||||
|
|
||||||
def delete_namespace(namespace = '', options = {})
|
def delete_namespace(namespace = '', options = {})
|
||||||
namespace = namespace + '/' unless namespace =~ /\/$/
|
|
||||||
options = options.reject {|key, value| value.nil?}
|
options = options.reject {|key, value| value.nil?}
|
||||||
request(
|
request({
|
||||||
:expects => 204,
|
:expects => 204,
|
||||||
:method => 'DELETE',
|
:method => 'DELETE',
|
||||||
:path => "namespace/" + namespace,
|
:path => "namespace/" + namespace,
|
||||||
:query => options
|
:query => options
|
||||||
)
|
}.merge(options))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,15 +4,14 @@ module Fog
|
||||||
class Real
|
class Real
|
||||||
|
|
||||||
def get_namespace(namespace = '', options = {})
|
def get_namespace(namespace = '', options = {})
|
||||||
namespace = namespace + '/' unless namespace =~ /\/$/
|
|
||||||
options = options.reject {|key, value| value.nil?}
|
options = options.reject {|key, value| value.nil?}
|
||||||
request(
|
request({
|
||||||
:expects => 200,
|
:expects => 200,
|
||||||
:method => 'GET',
|
:method => 'GET',
|
||||||
:path => "namespace/" + namespace,
|
:path => "namespace/" + namespace,
|
||||||
:query => options,
|
:query => {},
|
||||||
:parse => true
|
:parse => true
|
||||||
)
|
}.merge(options))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,15 +4,14 @@ module Fog
|
||||||
class Real
|
class Real
|
||||||
|
|
||||||
def post_namespace(namespace = '', options = {})
|
def post_namespace(namespace = '', options = {})
|
||||||
namespace = namespace + '/' unless namespace =~ /\/$/
|
|
||||||
options = options.reject {|key, value| value.nil?}
|
options = options.reject {|key, value| value.nil?}
|
||||||
request(
|
request({
|
||||||
:expects => 201,
|
:expects => 201,
|
||||||
:method => 'POST',
|
:method => 'POST',
|
||||||
:path => "namespace/" + namespace,
|
:path => "namespace/" + namespace,
|
||||||
:query => options,
|
:query => {},
|
||||||
:parse => true
|
:parse => true
|
||||||
)
|
}.merge(options))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ if storage_providers.keys.include? :ninefold
|
||||||
ninefold.directories.get('sub').directories.count
|
ninefold.directories.get('sub').directories.count
|
||||||
end
|
end
|
||||||
|
|
||||||
tests("create a directory in a sub dir").returns('sub/path/newdir') do
|
tests("create a directory in a sub dir").returns('sub/path/newdir/') do
|
||||||
ninefold.directories.get('sub/path').directories.create(:key => 'newdir').identity
|
ninefold.directories.get('sub/path').directories.create(:key => 'newdir').identity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue