fog-external 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.travis.yml +1 -0
- data/Gemfile +6 -0
- data/README.md +32 -0
- data/Rakefile +11 -0
- data/Watchrfile +37 -0
- data/examples/ernie.conf +4 -0
- data/examples/example.rb +36 -0
- data/examples/fog.rb +102 -0
- data/fog-external.gemspec +24 -0
- data/lib/fog/external/models/storage/directories.rb +27 -0
- data/lib/fog/external/models/storage/directory.rb +44 -0
- data/lib/fog/external/models/storage/file.rb +79 -0
- data/lib/fog/external/models/storage/files.rb +54 -0
- data/lib/fog/external/storage.rb +31 -0
- data/lib/fog-external.rb +29 -0
- data/spec/boot.rb +9 -0
- data/spec/fog/external/storage_spec.rb +157 -0
- data/spec/service_mock.rb +34 -0
- data/spec/spec_helper.rb +2 -0
- metadata +102 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm: 1.9.2
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Fog-External
|
2
|
+
With `fog-external`, you can use arbitrary Ruby objects as backend for `Fog::Storage`. This can mean a custom-written local-storage backend, or, without any more configuration, a BERT-RPC (or any other RPC implementation) remote call.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
gem install fog-external
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
require 'fog/external/storage'
|
9
|
+
|
10
|
+
storage = Fog::Storage.new({
|
11
|
+
:provider => 'External',
|
12
|
+
:delegate => BERTRPC::Service.new('localhost', 9999).call.fog
|
13
|
+
})
|
14
|
+
|
15
|
+
You can then use `storage` just like any other Fog::Storage object, see [the Fog docs](http://fog.io/1.1.1/storage/) for what's possible.. The API is compatible to the one of `Fog::Local`.
|
16
|
+
|
17
|
+
The delegate must respond to a number of backend methods. The delegate in the above-example uses [BERT-RPC][1] to call a server on localhost:9999, using the `fog` module name.
|
18
|
+
See `examples/example.rb` for a complete example *including a Ernie-powered BERT-RPC backend*.
|
19
|
+
|
20
|
+
## Copyright
|
21
|
+
|
22
|
+
(The MIT License)
|
23
|
+
|
24
|
+
Copyright © 2011 Jonas Schneider
|
25
|
+
|
26
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
27
|
+
|
28
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
29
|
+
|
30
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
31
|
+
|
32
|
+
[1]: https://github.com/mojombo/bertrpc
|
data/Rakefile
ADDED
data/Watchrfile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# vim:set filetype=ruby:
|
2
|
+
def run(cmd)
|
3
|
+
puts cmd
|
4
|
+
system cmd
|
5
|
+
end
|
6
|
+
|
7
|
+
def run_spec(args)
|
8
|
+
run("spin push #{args}")
|
9
|
+
#run("bundle exec rspec --fail-fast #{args}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def spec(file)
|
13
|
+
if File.exists?(file)
|
14
|
+
run_spec(file)
|
15
|
+
else
|
16
|
+
puts("Spec: #{file} does not exist.")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
watch("spec/.*/*_spec\.rb") do |match|
|
21
|
+
puts(match[0])
|
22
|
+
spec(match[0])
|
23
|
+
end
|
24
|
+
|
25
|
+
watch("lib/(.*/*)\.rb") do |match|
|
26
|
+
puts(match[0])
|
27
|
+
if File.exists?(p = "spec/"+match[1]+"_spec.rb")
|
28
|
+
spec(p)
|
29
|
+
else
|
30
|
+
spec("spec/fog/external/storage_spec.rb")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
watch("spec/service_mock\.rb") do |match|
|
35
|
+
puts(match[0])
|
36
|
+
spec("spec/fog/external/storage_spec.rb")
|
37
|
+
end
|
data/examples/ernie.conf
ADDED
data/examples/example.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'fog/external/storage'
|
4
|
+
require "bertrpc"
|
5
|
+
|
6
|
+
ROOT = '/tmp/fog-external-example-root'
|
7
|
+
Dir.chdir File.join(File.dirname(__FILE__), '..')
|
8
|
+
|
9
|
+
Dir.mkdir(ROOT) unless File.exists?(ROOT)
|
10
|
+
|
11
|
+
def run(cmd)
|
12
|
+
puts "=> #{cmd}"
|
13
|
+
system cmd
|
14
|
+
end
|
15
|
+
|
16
|
+
puts "Starting ernie on localhost:8000"
|
17
|
+
run "ernie -d -c examples/ernie.conf -P examples/ernie.pid -a /tmp/ernie.log"
|
18
|
+
|
19
|
+
puts "Ernie running."
|
20
|
+
|
21
|
+
storage = Fog::Storage.new({
|
22
|
+
:provider => 'External',
|
23
|
+
:delegate => BERTRPC::Service.new('localhost', 8000).call.fog
|
24
|
+
})
|
25
|
+
|
26
|
+
puts "Known directories: "
|
27
|
+
puts storage.directories.all.inspect
|
28
|
+
|
29
|
+
puts "Creating directory mydir/ ..."
|
30
|
+
puts storage.directories.create(key: 'mydir').save
|
31
|
+
|
32
|
+
puts "Known directories: "
|
33
|
+
puts storage.directories.all.inspect
|
34
|
+
|
35
|
+
puts "Stopping ernie on localhost:8000"
|
36
|
+
run "kill `cat examples/ernie.pid`"
|
data/examples/fog.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'ernie'
|
2
|
+
ROOT = '/tmp/fog-external-example-root'
|
3
|
+
# ported from Fog's Local storage
|
4
|
+
|
5
|
+
module Fog
|
6
|
+
def create_directory(key)
|
7
|
+
if ::File.directory?(path_to(key))
|
8
|
+
false
|
9
|
+
else
|
10
|
+
Dir.mkdir path_to(key)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def list_directories
|
15
|
+
data = Dir.entries(ROOT).select do |entry|
|
16
|
+
entry[0...1] != '.' && ::File.directory?(path_to(entry))
|
17
|
+
end.map do |entry|
|
18
|
+
{:key => entry}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_directory(key)
|
23
|
+
if ::File.directory?(path_to(key))
|
24
|
+
{ key: key }
|
25
|
+
else
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy_directory(key)
|
31
|
+
if ::File.directory?(path_to(key))
|
32
|
+
Dir.rmdir(path_to(key))
|
33
|
+
true
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def list_files(dir_key)
|
41
|
+
Dir.chdir(path_to(dir_key)) do
|
42
|
+
data = Dir.glob('**/*').reject do |file|
|
43
|
+
::File.directory?(file)
|
44
|
+
end.map do |key|
|
45
|
+
path = file_path(key)
|
46
|
+
{
|
47
|
+
:content_length => ::File.size(path),
|
48
|
+
:key => key,
|
49
|
+
:last_modified => ::File.mtime(path)
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
data
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_file(key)
|
57
|
+
path = path_to(key)
|
58
|
+
if ::File.exists?(path)
|
59
|
+
{
|
60
|
+
:content_length => ::File.size(path),
|
61
|
+
:key => key,
|
62
|
+
:last_modified => ::File.mtime(path),
|
63
|
+
:body => ::File.read(path)
|
64
|
+
}
|
65
|
+
else
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def destroy_file(key)
|
71
|
+
path = path_to(key)
|
72
|
+
|
73
|
+
if ::File.exists?(path)
|
74
|
+
::File.delete(path)
|
75
|
+
true
|
76
|
+
else
|
77
|
+
false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def save_file(key, body)
|
82
|
+
file = ::File.new(path, 'wb')
|
83
|
+
if body.is_a?(String)
|
84
|
+
file.write(body)
|
85
|
+
else
|
86
|
+
file.write(body.read)
|
87
|
+
end
|
88
|
+
file.close
|
89
|
+
|
90
|
+
::File.mtime(path)
|
91
|
+
rescue
|
92
|
+
false
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def path_to(entry)
|
98
|
+
::File.join(ROOT, entry)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
Ernie.expose(:fog, Fog)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "fog-external"
|
6
|
+
s.version = "0.0.1"
|
7
|
+
s.authors = ["Jonas Schneider"]
|
8
|
+
s.email = ["mail@jonasschneider.com"]
|
9
|
+
s.homepage = ""
|
10
|
+
s.summary = %q{Fog::Storage with a consistent API}
|
11
|
+
s.description = %q{Use a custom backend (such as BERTRPC) with Fog:Storage.}
|
12
|
+
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
# specify any dependencies here; for example:
|
20
|
+
s.add_development_dependency('rake')
|
21
|
+
s.add_development_dependency "rspec"
|
22
|
+
|
23
|
+
s.add_runtime_dependency "fog"
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/external/models/storage/directory'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Storage
|
6
|
+
class External
|
7
|
+
|
8
|
+
class Directories < Fog::Collection
|
9
|
+
model Fog::Storage::External::Directory
|
10
|
+
|
11
|
+
def all
|
12
|
+
load(connection.remote.list_directories)
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(id)
|
16
|
+
data = connection.remote.get_directory(id)
|
17
|
+
if data
|
18
|
+
new(data)
|
19
|
+
else
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'fog/core/model'
|
2
|
+
require 'fog/external/models/storage/files'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Storage
|
6
|
+
class External
|
7
|
+
|
8
|
+
class Directory < Fog::Model
|
9
|
+
identity :key
|
10
|
+
|
11
|
+
def destroy
|
12
|
+
requires :key
|
13
|
+
|
14
|
+
connection.remote.destroy_directory(identity)
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def files
|
19
|
+
@files ||= begin
|
20
|
+
Fog::Storage::External::Files.new(
|
21
|
+
:directory => self,
|
22
|
+
:connection => connection
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def public=(new_public)
|
28
|
+
new_public
|
29
|
+
end
|
30
|
+
|
31
|
+
def public_url
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def save
|
36
|
+
requires :key
|
37
|
+
|
38
|
+
connection.remote.create_directory(identity)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'fog/core/model'
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Storage
|
5
|
+
class External
|
6
|
+
|
7
|
+
class File < Fog::Model
|
8
|
+
identity :key, :aliases => 'Key'
|
9
|
+
|
10
|
+
attribute :content_length, :aliases => 'Content-Length', :type => :integer
|
11
|
+
attribute :last_modified, :aliases => 'Last-Modified'
|
12
|
+
|
13
|
+
def directory
|
14
|
+
@directory
|
15
|
+
end
|
16
|
+
|
17
|
+
def directory=(new_directory)
|
18
|
+
@directory = new_directory
|
19
|
+
end
|
20
|
+
|
21
|
+
def content_type
|
22
|
+
@content_type ||= begin
|
23
|
+
unless (mime_types = ::MIME::Types.of(key)).empty?
|
24
|
+
mime_types.first.content_type
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def body
|
30
|
+
attributes[:body] ||= if last_modified
|
31
|
+
directory.files.get(identity).body
|
32
|
+
else
|
33
|
+
''
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def body=(new_body)
|
38
|
+
attributes[:body] = new_body
|
39
|
+
end
|
40
|
+
|
41
|
+
def destroy
|
42
|
+
requires :key, :directory
|
43
|
+
|
44
|
+
connection.remote.destroy_file(full_key)
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
def public=(new_public)
|
49
|
+
new_public
|
50
|
+
end
|
51
|
+
|
52
|
+
def public_url
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def save
|
57
|
+
requires :body, :directory, :key
|
58
|
+
|
59
|
+
if res = connection.remote.save_file(full_key, body)
|
60
|
+
merge_attributes(
|
61
|
+
:content_length => Fog::Storage.get_body_size(body),
|
62
|
+
:last_modified => res
|
63
|
+
)
|
64
|
+
true
|
65
|
+
else
|
66
|
+
false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def full_key
|
73
|
+
::File.join(directory.key, key)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/external/models/storage/file'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module Storage
|
6
|
+
class External
|
7
|
+
|
8
|
+
class Files < Fog::Collection
|
9
|
+
attribute :directory
|
10
|
+
model Fog::Storage::External::File
|
11
|
+
|
12
|
+
def all
|
13
|
+
requires :directory
|
14
|
+
|
15
|
+
load(connection.remote.list_files(directory.key))
|
16
|
+
end
|
17
|
+
|
18
|
+
def get(id)
|
19
|
+
requires :directory
|
20
|
+
|
21
|
+
data = connection.remote.get_file(file_key(id))
|
22
|
+
if data
|
23
|
+
new(data)
|
24
|
+
else
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def head(id) # hackish!
|
30
|
+
requires :directory
|
31
|
+
real_key = file_key(id)
|
32
|
+
if data = connection.remote.list_files(directory.key).detect{|c|c[:key] == real_key}
|
33
|
+
new(data)
|
34
|
+
else
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def new(attributes = {})
|
40
|
+
requires :directory
|
41
|
+
super({ :directory => directory }.merge!(attributes))
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def file_key(id)
|
48
|
+
::File.join(directory.key, id)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'fog'
|
2
|
+
require 'fog/storage'
|
3
|
+
|
4
|
+
require 'fog-external'
|
5
|
+
|
6
|
+
module Fog
|
7
|
+
module Storage
|
8
|
+
class External < Fog::Service
|
9
|
+
|
10
|
+
requires :delegate
|
11
|
+
|
12
|
+
model_path 'fog/external/models/storage'
|
13
|
+
collection :directories
|
14
|
+
model :directory
|
15
|
+
collection :files
|
16
|
+
model :file
|
17
|
+
|
18
|
+
class Real
|
19
|
+
def initialize(options={})
|
20
|
+
require 'mime/types'
|
21
|
+
@delegate = options[:delegate]
|
22
|
+
end
|
23
|
+
|
24
|
+
def remote
|
25
|
+
@delegate
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/fog-external.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Fog
|
2
|
+
module Storage
|
3
|
+
def self.new(attributes) # monkey patch to add :external
|
4
|
+
attributes = attributes.dup # prevent delete from having side effects
|
5
|
+
case provider = attributes.delete(:provider).to_s.downcase.to_sym
|
6
|
+
when :aws
|
7
|
+
require 'fog/aws/storage'
|
8
|
+
Fog::Storage::AWS.new(attributes)
|
9
|
+
when :google
|
10
|
+
require 'fog/google/storage'
|
11
|
+
Fog::Storage::Google.new(attributes)
|
12
|
+
when :local
|
13
|
+
require 'fog/local/storage'
|
14
|
+
Fog::Storage::Local.new(attributes)
|
15
|
+
when :ninefold
|
16
|
+
require 'fog/ninefold/storage'
|
17
|
+
Fog::Storage::Ninefold.new(attributes)
|
18
|
+
when :rackspace
|
19
|
+
require 'fog/rackspace/storage'
|
20
|
+
Fog::Storage::Rackspace.new(attributes)
|
21
|
+
when :external
|
22
|
+
require 'fog/external/storage'
|
23
|
+
Fog::Storage::External.new(attributes)
|
24
|
+
else
|
25
|
+
raise ArgumentError.new("#{provider} is not a recognized storage provider")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/boot.rb
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
|
2
|
+
|
3
|
+
require 'fog/external/storage'
|
4
|
+
|
5
|
+
describe "fog-external" do
|
6
|
+
let(:storage) do
|
7
|
+
storage = Fog::Storage.new({
|
8
|
+
:provider => 'External',
|
9
|
+
:delegate => service_mock
|
10
|
+
})
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:service_mock) do
|
14
|
+
ServiceMock.new
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#directories" do
|
18
|
+
it "#create creates a directory" do
|
19
|
+
service_mock.should_receive(:create_directory).with('mykey')
|
20
|
+
directory = storage.directories.create key: 'mykey'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "#all lists directories" do
|
24
|
+
service_mock.should_receive(:list_directories) { [{:key => 'mykey'}] }
|
25
|
+
storage.directories.all.first.key.should == 'mykey'
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#get" do
|
29
|
+
it "gets a directory" do
|
30
|
+
service_mock.should_receive(:get_directory).with('mykey') { {:key => 'mykey'} }
|
31
|
+
x = storage.directories.get('mykey')
|
32
|
+
x.should be_kind_of(Fog::Storage::External::Directory)
|
33
|
+
x.key.should == 'mykey'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns nil for unknown directory keys" do
|
37
|
+
service_mock.should_receive(:get_directory).with('something_strange') { nil }
|
38
|
+
x = storage.directories.get('something_strange')
|
39
|
+
x.should be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "::Directory" do
|
45
|
+
let(:dir) { Fog::Storage::External::Directory.new connection: storage, key: 'mykey' }
|
46
|
+
|
47
|
+
it "#files" do
|
48
|
+
dir.files.should be_kind_of(Fog::Storage::External::Files)
|
49
|
+
dir.files.directory.should == dir
|
50
|
+
dir.files.connection.should == storage
|
51
|
+
end
|
52
|
+
|
53
|
+
it "#destroy" do
|
54
|
+
service_mock.should_receive(:destroy_directory).with('mykey')
|
55
|
+
dir.destroy
|
56
|
+
end
|
57
|
+
|
58
|
+
it "#public=" do
|
59
|
+
(dir.public = :a).should == :a
|
60
|
+
end
|
61
|
+
|
62
|
+
it "#public_url" do
|
63
|
+
dir.public_url.should be_nil
|
64
|
+
end
|
65
|
+
|
66
|
+
it "#save" do
|
67
|
+
service_mock.should_receive(:create_directory).with('mykey')
|
68
|
+
dir.save
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "::Files" do
|
73
|
+
let(:dir) { Fog::Storage::External::Directory.new connection: storage, key: 'mykey' }
|
74
|
+
let(:files) { dir.files }
|
75
|
+
|
76
|
+
it "#all" do
|
77
|
+
service_mock.should_receive(:list_files).with("mykey") { [{:key => 'mykey/a'}] }
|
78
|
+
res = files.all
|
79
|
+
res.first.key.should == 'mykey/a'
|
80
|
+
end
|
81
|
+
|
82
|
+
it "#get" do
|
83
|
+
data = {:key => 'mykey/a', :content_length => 5, :last_modified => Time.now, :body => 'asdf' }
|
84
|
+
service_mock.should_receive(:get_file).with("mykey/a") { data }
|
85
|
+
res = files.get('a')
|
86
|
+
|
87
|
+
res.key.should == 'mykey/a'
|
88
|
+
res.content_length.should == 5
|
89
|
+
res.body.should == 'asdf'
|
90
|
+
end
|
91
|
+
|
92
|
+
it "#head" do
|
93
|
+
service_mock.should_receive(:list_files).twice.with("mykey") { [{:key => 'mykey/a'}] }
|
94
|
+
|
95
|
+
res = files.head('a')
|
96
|
+
|
97
|
+
res.key.should == 'mykey/a'
|
98
|
+
res.content_length.should be_nil
|
99
|
+
|
100
|
+
files.head('b').should be_nil
|
101
|
+
end
|
102
|
+
|
103
|
+
it "#new" do
|
104
|
+
files.new(:key => 'hai').directory.should == dir
|
105
|
+
files.new(:key => 'hai').key.should == 'hai'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "::Files" do
|
110
|
+
let(:dir) { Fog::Storage::External::Directory.new connection: storage, key: 'mykey' }
|
111
|
+
let(:file) { Fog::Storage::External::File.new connection: storage, last_modified: Time.now, key: 'a', directory: dir }
|
112
|
+
|
113
|
+
it "#body when the body is not set" do
|
114
|
+
data = {:key => 'mykey/a', :content_length => 5, :last_modified => Time.now, :body => 'asdf' }
|
115
|
+
service_mock.should_receive(:get_file).with("mykey/a") { data }
|
116
|
+
file.body.should == 'asdf'
|
117
|
+
end
|
118
|
+
|
119
|
+
it "#body when the body is set" do
|
120
|
+
file = Fog::Storage::External::File.new connection: storage, key: 'a', directory: dir, body: 'b'
|
121
|
+
file.body.should == 'b'
|
122
|
+
end
|
123
|
+
|
124
|
+
it "#body= sets the body" do
|
125
|
+
file.body = 'new'
|
126
|
+
file.body.should == 'new'
|
127
|
+
end
|
128
|
+
|
129
|
+
it "#directory" do
|
130
|
+
file.directory.should == dir
|
131
|
+
end
|
132
|
+
|
133
|
+
it "#content_type" do
|
134
|
+
file.key = 'a.txt'
|
135
|
+
file.content_type.should == 'text/plain'
|
136
|
+
end
|
137
|
+
|
138
|
+
it "#destroy" do
|
139
|
+
service_mock.should_receive(:destroy_file).with("mykey/a")
|
140
|
+
file.destroy
|
141
|
+
end
|
142
|
+
|
143
|
+
it "#public=" do
|
144
|
+
(file.public = :a).should == :a
|
145
|
+
end
|
146
|
+
|
147
|
+
it "#public_url" do
|
148
|
+
file.public_url.should be_nil
|
149
|
+
end
|
150
|
+
|
151
|
+
it "#save" do
|
152
|
+
service_mock.should_receive(:save_file).with("mykey/a", "test")
|
153
|
+
file.body = "test"
|
154
|
+
file.save
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class ServiceMock
|
2
|
+
def create_directory(key)
|
3
|
+
true
|
4
|
+
end
|
5
|
+
|
6
|
+
def list_directories
|
7
|
+
[{:key => 'mykey'}]
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_directory(key)
|
11
|
+
{:key => 'mykey'} || nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def destroy_directory(key)
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def list_files(dir_key)
|
20
|
+
[{:key => 'mykey/a', :content_length => 5, :last_modified => Time.now}]
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_file(key)
|
24
|
+
{:key => 'mykey/a', :content_length => 5, :last_modified => Time.now, :body => 'asdf'} || nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def destroy_file(key)
|
28
|
+
true || false
|
29
|
+
end
|
30
|
+
|
31
|
+
def save_file(key, body)
|
32
|
+
mtime || false
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fog-external
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jonas Schneider
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-03 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &76776280 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *76776280
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &76776070 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *76776070
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: fog
|
38
|
+
requirement: &76775860 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *76775860
|
47
|
+
description: Use a custom backend (such as BERTRPC) with Fog:Storage.
|
48
|
+
email:
|
49
|
+
- mail@jonasschneider.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- .travis.yml
|
56
|
+
- Gemfile
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- Watchrfile
|
60
|
+
- examples/ernie.conf
|
61
|
+
- examples/example.rb
|
62
|
+
- examples/fog.rb
|
63
|
+
- fog-external.gemspec
|
64
|
+
- lib/fog-external.rb
|
65
|
+
- lib/fog/external/models/storage/directories.rb
|
66
|
+
- lib/fog/external/models/storage/directory.rb
|
67
|
+
- lib/fog/external/models/storage/file.rb
|
68
|
+
- lib/fog/external/models/storage/files.rb
|
69
|
+
- lib/fog/external/storage.rb
|
70
|
+
- spec/boot.rb
|
71
|
+
- spec/fog/external/storage_spec.rb
|
72
|
+
- spec/service_mock.rb
|
73
|
+
- spec/spec_helper.rb
|
74
|
+
homepage: ''
|
75
|
+
licenses: []
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.8.10
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Fog::Storage with a consistent API
|
98
|
+
test_files:
|
99
|
+
- spec/boot.rb
|
100
|
+
- spec/fog/external/storage_spec.rb
|
101
|
+
- spec/service_mock.rb
|
102
|
+
- spec/spec_helper.rb
|