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 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.6
1
+ 0.7.7
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dragonfly}
8
- s.version = "0.7.6"
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-09-12}
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",
@@ -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.
@@ -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
@@ -1,3 +1,5 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
1
3
  require File.dirname(__FILE__) + '/lib/dragonfly'
2
4
  APP = Dragonfly[:images].configure_with(:rmagick)
3
5
 
@@ -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
- File.new(path),
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), 'w') do |f|
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(File.read(path)) : {}
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 = Tempfile.new('dragonfly')
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
- f.close
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, 'w'){|f| f.write(initialized_data) }
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 = Tempfile.new('dragonfly')
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
- file.read.should == 'hey dog'
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
- def have_keys(*keys)
4
- simple_matcher("have keys #{keys.join(', ')}") do |given|
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
@@ -1,8 +1,8 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  # Matchers
4
- def match_steps(steps)
5
- simple_matcher("match steps #{steps.inspect}") do |given|
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
@@ -22,14 +22,20 @@ def image_properties(image)
22
22
  }
23
23
  end
24
24
 
25
- def have_width(width)
26
- simple_matcher("have width #{width}"){|given| width.should === image_properties(given)[:width].to_i }
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
- def have_height(height)
30
- simple_matcher("have height #{height}"){|given| height.should === image_properties(given)[:height].to_i }
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
- def have_format(format)
34
- simple_matcher("have format #{format}"){|given| image_properties(given)[:format].should == format }
37
+ Spec::Matchers.define :have_format do |format|
38
+ match do |given|
39
+ image_properties(given)[:format].should == format
40
+ end
35
41
  end
@@ -1,5 +1,5 @@
1
- def match_url(url)
2
- simple_matcher("match url #{url}") do |given|
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
- def be_an_empty_directory
11
- simple_matcher("be empty") do |given|
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
- def match_ar_error(string)
18
- simple_matcher("match activerecord error") do |given|
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
- def include_hash(hash)
25
- simple_matcher("include hash #{hash.inspect}") do |given|
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
- def leak_memory
36
- simple_matcher("leak memory") do |given|
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
- - 6
9
- version: 0.7.6
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-09-12 00:00:00 +01:00
17
+ date: 2010-10-31 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency