dragonfly 0.7.6 → 0.7.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dragonfly might be problematic. Click here for more details.
- data/History.md +12 -0
- data/README.md +4 -2
- data/VERSION +1 -1
- data/dragonfly.gemspec +2 -2
- data/extra_docs/DataStorage.md +2 -0
- data/extra_docs/Index.md +4 -2
- data/irbrc.rb +2 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +5 -3
- data/lib/dragonfly/data_storage/mongo_data_store.rb +15 -2
- data/lib/dragonfly/temp_object.rb +17 -10
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +6 -1
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +21 -1
- data/spec/dragonfly/function_manager_spec.rb +2 -2
- data/spec/dragonfly/job_spec.rb +2 -2
- data/spec/dragonfly/temp_object_spec.rb +4 -1
- data/spec/image_matchers.rb +12 -6
- data/spec/simple_matchers.rb +10 -10
- metadata +3 -3
data/History.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
0.7.7 (2010-10-31)
|
2
|
+
==================
|
3
|
+
Features
|
4
|
+
--------
|
5
|
+
- Added username/password authentication to mongo data store
|
6
|
+
|
7
|
+
Fixes
|
8
|
+
-----
|
9
|
+
- Fixes for Windows, inc. tempfile binmode and closing files
|
10
|
+
- "IOError: closed stream" fix (hopefully!)
|
11
|
+
|
12
|
+
|
1
13
|
0.7.6 (2010-09-12)
|
2
14
|
==================
|
3
15
|
Features
|
data/README.md
CHANGED
@@ -65,6 +65,10 @@ It's highly customizable, and works with any data type (not just images).
|
|
65
65
|
|
66
66
|
For more info, consult the <a href="http://markevans.github.com/dragonfly"><big><strong>DOCUMENTATION</strong></big></a>
|
67
67
|
|
68
|
+
Add-ons
|
69
|
+
=======
|
70
|
+
For third-party add-ons, see [the Add-ons wiki](http://github.com/markevans/dragonfly/wiki/Dragonfly-add-ons)
|
71
|
+
|
68
72
|
Issues
|
69
73
|
======
|
70
74
|
Please use the <a href="http://github.com/markevans/dragonfly/issues">github issue tracker</a> if you have any issues.
|
@@ -77,8 +81,6 @@ Credits
|
|
77
81
|
=======
|
78
82
|
- [Mark Evans](http://github.com/markevans) (author)
|
79
83
|
|
80
|
-
|
81
84
|
Copyright
|
82
85
|
========
|
83
|
-
|
84
86
|
Copyright (c) 2009-2010 Mark Evans. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.7
|
data/dragonfly.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dragonfly}
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Mark Evans"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-10-31}
|
13
13
|
s.email = %q{mark@new-bamboo.co.uk}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE",
|
data/extra_docs/DataStorage.md
CHANGED
@@ -79,6 +79,8 @@ It won't normally need configuring, but if you wish to:
|
|
79
79
|
c.host = 'http://egg.heads:5000' # defaults to localhost
|
80
80
|
c.port = '27018' # defaults to mongo default (27017)
|
81
81
|
c.database = 'my_database' # defaults to 'dragonfly'
|
82
|
+
c.username = 'some_user' # only needed if mongo is running in auth mode
|
83
|
+
c.password = 'some_password' # only needed if mongo is running in auth mode
|
82
84
|
end
|
83
85
|
|
84
86
|
You can also pass these options to `MongoDataStore.new` as an options hash.
|
data/extra_docs/Index.md
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
Dragonfly Documentation
|
2
|
-
=======================
|
3
1
|
Dragonfly is a {http://rack.rubyforge.org Rack} framework for on-the-fly image handling in Ruby.
|
4
2
|
|
5
3
|
It is suitable for using with web frameworks such as Rails(2.3 and 3), Sinatra, etc.
|
@@ -16,6 +14,10 @@ Installation
|
|
16
14
|
|
17
15
|
gem install dragonfly
|
18
16
|
|
17
|
+
Add-ons
|
18
|
+
-------
|
19
|
+
For third-party add-ons, see [the Add-ons wiki](http://github.com/markevans/dragonfly/wiki/Dragonfly-add-ons)
|
20
|
+
|
19
21
|
Issues
|
20
22
|
------
|
21
23
|
Please use the <a href="http://github.com/markevans/dragonfly/issues">github issue tracker</a>.
|
data/irbrc.rb
CHANGED
@@ -34,8 +34,10 @@ module Dragonfly
|
|
34
34
|
|
35
35
|
def retrieve(relative_path)
|
36
36
|
path = absolute(relative_path)
|
37
|
+
file = File.new(path)
|
38
|
+
file.close
|
37
39
|
[
|
38
|
-
|
40
|
+
file,
|
39
41
|
retrieve_extra_data(path)
|
40
42
|
]
|
41
43
|
rescue Errno::ENOENT => e
|
@@ -81,14 +83,14 @@ module Dragonfly
|
|
81
83
|
end
|
82
84
|
|
83
85
|
def store_extra_data(data_path, temp_object)
|
84
|
-
File.open(extra_data_path(data_path), '
|
86
|
+
File.open(extra_data_path(data_path), 'wb') do |f|
|
85
87
|
f.write Marshal.dump(temp_object.attributes)
|
86
88
|
end
|
87
89
|
end
|
88
90
|
|
89
91
|
def retrieve_extra_data(data_path)
|
90
92
|
path = extra_data_path(data_path)
|
91
|
-
File.exist?(path) ? Marshal.load(
|
93
|
+
File.exist?(path) ? File.open(path,'rb'){|f| Marshal.load(f.read) } : {}
|
92
94
|
end
|
93
95
|
|
94
96
|
def prepare_path(path)
|
@@ -10,6 +10,8 @@ module Dragonfly
|
|
10
10
|
configurable_attr :host
|
11
11
|
configurable_attr :port
|
12
12
|
configurable_attr :database, 'dragonfly'
|
13
|
+
configurable_attr :username
|
14
|
+
configurable_attr :password
|
13
15
|
|
14
16
|
# Mongo gem deprecated ObjectID in favour of ObjectId
|
15
17
|
OBJECT_ID = defined?(BSON::ObjectId) ? BSON::ObjectId : BSON::ObjectID
|
@@ -19,9 +21,12 @@ module Dragonfly
|
|
19
21
|
self.host = opts[:host]
|
20
22
|
self.port = opts[:port]
|
21
23
|
self.database = opts[:database] if opts[:database]
|
24
|
+
self.username = opts[:username]
|
25
|
+
self.password = opts[:password]
|
22
26
|
end
|
23
27
|
|
24
28
|
def store(temp_object, opts={})
|
29
|
+
ensure_authenticated!
|
25
30
|
temp_object.file do |f|
|
26
31
|
mongo_id = grid.put(f, :metadata => marshal_encode(temp_object.attributes))
|
27
32
|
mongo_id.to_s
|
@@ -29,6 +34,7 @@ module Dragonfly
|
|
29
34
|
end
|
30
35
|
|
31
36
|
def retrieve(uid)
|
37
|
+
ensure_authenticated!
|
32
38
|
grid_io = grid.get(bson_id(uid))
|
33
39
|
extra = marshal_decode(grid_io.metadata)
|
34
40
|
extra[:meta].merge!(:stored_at => grid_io.upload_date)
|
@@ -41,13 +47,12 @@ module Dragonfly
|
|
41
47
|
end
|
42
48
|
|
43
49
|
def destroy(uid)
|
50
|
+
ensure_authenticated!
|
44
51
|
grid.delete(bson_id(uid))
|
45
52
|
rescue Mongo::GridFileNotFound, INVALID_OBJECT_ID => e
|
46
53
|
raise DataNotFound, "#{e} - #{uid}"
|
47
54
|
end
|
48
55
|
|
49
|
-
private
|
50
|
-
|
51
56
|
def connection
|
52
57
|
@connection ||= Mongo::Connection.new(host, port)
|
53
58
|
end
|
@@ -60,6 +65,14 @@ module Dragonfly
|
|
60
65
|
@grid ||= Mongo::Grid.new(db)
|
61
66
|
end
|
62
67
|
|
68
|
+
private
|
69
|
+
|
70
|
+
def ensure_authenticated!
|
71
|
+
if username
|
72
|
+
@authenticated ||= db.authenticate(username, password)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
63
76
|
def bson_id(uid)
|
64
77
|
OBJECT_ID.from_string(uid)
|
65
78
|
end
|
@@ -48,7 +48,7 @@ module Dragonfly
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def data
|
51
|
-
@data ||= initialized_data || file.read
|
51
|
+
@data ||= initialized_data || file{|f| f.read }
|
52
52
|
end
|
53
53
|
|
54
54
|
def tempfile
|
@@ -56,23 +56,22 @@ module Dragonfly
|
|
56
56
|
case initialized_with
|
57
57
|
when :tempfile
|
58
58
|
@tempfile = initialized_tempfile
|
59
|
+
@tempfile.close
|
59
60
|
when :data
|
60
|
-
@tempfile =
|
61
|
-
@tempfile.binmode
|
62
|
-
@tempfile.write(initialized_data)
|
61
|
+
@tempfile = new_tempfile(initialized_data)
|
63
62
|
when :file
|
64
63
|
@tempfile = copy_to_tempfile(initialized_file.path)
|
65
64
|
end
|
66
|
-
@tempfile.close
|
67
65
|
@tempfile
|
68
66
|
end
|
69
67
|
end
|
70
68
|
|
71
69
|
def file(&block)
|
72
70
|
f = tempfile.open
|
71
|
+
tempfile.binmode
|
73
72
|
if block_given?
|
74
73
|
ret = yield f
|
75
|
-
|
74
|
+
tempfile.close
|
76
75
|
else
|
77
76
|
ret = f
|
78
77
|
end
|
@@ -117,16 +116,16 @@ module Dragonfly
|
|
117
116
|
|
118
117
|
def to_file(path)
|
119
118
|
if initialized_data
|
120
|
-
File.open(path, '
|
119
|
+
File.open(path, 'wb'){|f| f.write(initialized_data) }
|
121
120
|
else
|
122
121
|
FileUtils.cp(self.path, path)
|
123
122
|
end
|
124
|
-
File.new(path)
|
123
|
+
File.new(path, 'rb')
|
125
124
|
end
|
126
125
|
|
127
126
|
def to_io(&block)
|
128
127
|
if initialized_data
|
129
|
-
StringIO.open(initialized_data, &block)
|
128
|
+
StringIO.open(initialized_data, 'rb', &block)
|
130
129
|
else
|
131
130
|
file(&block)
|
132
131
|
end
|
@@ -197,7 +196,7 @@ module Dragonfly
|
|
197
196
|
end
|
198
197
|
|
199
198
|
def copy_to_tempfile(path)
|
200
|
-
tempfile =
|
199
|
+
tempfile = new_tempfile
|
201
200
|
FileUtils.cp File.expand_path(path), tempfile.path
|
202
201
|
tempfile
|
203
202
|
end
|
@@ -208,5 +207,13 @@ module Dragonfly
|
|
208
207
|
raise ArgumentError, "Unrecognised options #{invalid_keys.inspect}" if invalid_keys.any?
|
209
208
|
end
|
210
209
|
|
210
|
+
def new_tempfile(content=nil)
|
211
|
+
tempfile = Tempfile.new('dragonfly')
|
212
|
+
tempfile.binmode
|
213
|
+
tempfile.write(content) if content
|
214
|
+
tempfile.close
|
215
|
+
tempfile
|
216
|
+
end
|
217
|
+
|
211
218
|
end
|
212
219
|
end
|
@@ -136,11 +136,16 @@ describe Dragonfly::DataStorage::FileDataStore do
|
|
136
136
|
end
|
137
137
|
|
138
138
|
describe "retrieve" do
|
139
|
+
it "should return a closed file" do
|
140
|
+
uid = @data_store.store(@temp_object)
|
141
|
+
file, extra = @data_store.retrieve(uid)
|
142
|
+
file.should be_closed
|
143
|
+
end
|
139
144
|
it "should be able to retrieve any file, stored or not (and without extra data)" do
|
140
145
|
FileUtils.mkdir_p("#{@data_store.root_path}/jelly_beans/are")
|
141
146
|
File.open("#{@data_store.root_path}/jelly_beans/are/good", 'w'){|f| f.write('hey dog') }
|
142
147
|
file, meta = @data_store.retrieve("jelly_beans/are/good")
|
143
|
-
|
148
|
+
File.read(file.path).should == 'hey dog'
|
144
149
|
meta.should == {}
|
145
150
|
end
|
146
151
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
3
|
require File.dirname(__FILE__) + '/data_store_spec'
|
3
4
|
require 'mongo'
|
@@ -10,9 +11,28 @@ describe Dragonfly::DataStorage::MongoDataStore do
|
|
10
11
|
rescue Mongo::ConnectionFailure => e
|
11
12
|
pending "You need to start mongo on localhost:27017 to test the MongoDataStore"
|
12
13
|
end
|
13
|
-
@data_store = Dragonfly::DataStorage::MongoDataStore.new
|
14
|
+
@data_store = Dragonfly::DataStorage::MongoDataStore.new :database => 'dragonfly_test'
|
14
15
|
end
|
15
16
|
|
16
17
|
it_should_behave_like 'data_store'
|
18
|
+
|
19
|
+
describe "authenticating" do
|
20
|
+
before(:each) do
|
21
|
+
@temp_object = Dragonfly::TempObject.new('Feijão verde')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not attempt to authenticate if a username is not given" do
|
25
|
+
@data_store.db.should_not_receive(:authenticate)
|
26
|
+
@data_store.store(@temp_object)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should attempt to authenticate once if a username is given" do
|
30
|
+
@data_store.username = 'terry'
|
31
|
+
@data_store.password = 'butcher'
|
32
|
+
@data_store.db.should_receive(:authenticate).exactly(:once).with('terry','butcher').and_return(true)
|
33
|
+
uid = @data_store.store(@temp_object)
|
34
|
+
@data_store.retrieve(uid)
|
35
|
+
end
|
36
|
+
end
|
17
37
|
|
18
38
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
Spec::Matchers.define :have_keys do |*keys|
|
4
|
+
match do |given|
|
5
5
|
given.keys.map{|sym| sym.to_s }.sort == keys.map{|sym| sym.to_s }.sort
|
6
6
|
end
|
7
7
|
end
|
data/spec/dragonfly/job_spec.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
2
|
|
3
3
|
# Matchers
|
4
|
-
|
5
|
-
|
4
|
+
Spec::Matchers.define :match_steps do |steps|
|
5
|
+
match do |given|
|
6
6
|
given.map{|step| step.class } == steps
|
7
7
|
end
|
8
8
|
end
|
@@ -80,6 +80,10 @@ describe Dragonfly::TempObject do
|
|
80
80
|
'doogie'
|
81
81
|
end.should == 'doogie'
|
82
82
|
end
|
83
|
+
it "should enable reading the file twice" do
|
84
|
+
@temp_object.file{|f| f.read }.should == "HELLO"
|
85
|
+
@temp_object.file{|f| f.read }.should == "HELLO"
|
86
|
+
end
|
83
87
|
end
|
84
88
|
|
85
89
|
describe "tempfile" do
|
@@ -170,7 +174,6 @@ describe Dragonfly::TempObject do
|
|
170
174
|
end
|
171
175
|
end
|
172
176
|
|
173
|
-
|
174
177
|
end
|
175
178
|
|
176
179
|
describe "initializing from a string" do
|
data/spec/image_matchers.rb
CHANGED
@@ -22,14 +22,20 @@ def image_properties(image)
|
|
22
22
|
}
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
Spec::Matchers.define :have_width do |width|
|
26
|
+
match do |given|
|
27
|
+
width.should === image_properties(given)[:width].to_i
|
28
|
+
end
|
27
29
|
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
+
Spec::Matchers.define :have_height do |height|
|
32
|
+
match do |given|
|
33
|
+
height.should === image_properties(given)[:height].to_i
|
34
|
+
end
|
31
35
|
end
|
32
36
|
|
33
|
-
|
34
|
-
|
37
|
+
Spec::Matchers.define :have_format do |format|
|
38
|
+
match do |given|
|
39
|
+
image_properties(given)[:format].should == format
|
40
|
+
end
|
35
41
|
end
|
data/spec/simple_matchers.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
Spec::Matchers.define :match_url do |url|
|
2
|
+
match do |given|
|
3
3
|
given_path, given_query_string = given.split('?')
|
4
4
|
path, query_string = url.split('?')
|
5
5
|
|
@@ -7,22 +7,22 @@ def match_url(url)
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
Spec::Matchers.define :be_an_empty_directory do
|
11
|
+
match do |given|
|
12
12
|
Dir.entries(given) == ['.','..']
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
# The reason we need this is that ActiveRecord 2.x returns just a string/nil, whereas AR 3 always returns an array
|
17
|
-
|
18
|
-
|
17
|
+
Spec::Matchers.define :match_ar_error do |string|
|
18
|
+
match do |given|
|
19
19
|
error = given.is_a?(Array) ? given.first : given
|
20
20
|
error == string
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
Spec::Matchers.define :include_hash do |hash|
|
25
|
+
match do |given|
|
26
26
|
given.merge(hash) == given
|
27
27
|
end
|
28
28
|
end
|
@@ -32,8 +32,8 @@ def memory_usage
|
|
32
32
|
`ps -o rss= -p #{$$}`.strip.to_i
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
Spec::Matchers.define :leak_memory do
|
36
|
+
match do |given|
|
37
37
|
memory_before = memory_usage
|
38
38
|
given.call
|
39
39
|
memory_after = memory_usage
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 7
|
8
|
-
-
|
9
|
-
version: 0.7.
|
8
|
+
- 7
|
9
|
+
version: 0.7.7
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mark Evans
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-10-31 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|