griddle 0.0.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +112 -0
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/griddle.gemspec +16 -8
- data/lib/griddle/attachment.rb +208 -37
- data/lib/griddle/has_grid_attachment.rb +10 -6
- data/lib/griddle/processor/image_magick.rb +74 -0
- data/lib/griddle/processor.rb +23 -0
- data/lib/griddle.rb +21 -2
- data/test/attachment_test.rb +5 -3
- data/test/fixtures/baboon.jpg +0 -0
- data/test/fixtures/climenole.jpeg +0 -0
- data/test/fixtures/squid.png +0 -0
- data/test/has_attachment_test.rb +224 -12
- data/test/models.rb +10 -13
- data/test/mongo_mapper_models.rb +46 -0
- data/test/processor_test.rb +56 -0
- data/test/style_test.rb +8 -0
- data/test/test_helper.rb +11 -3
- metadata +44 -15
- data/README.rdoc +0 -17
data/README.markdown
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
Griddle: GridFileSystem made simple
|
2
|
+
=======================================
|
3
|
+
|
4
|
+
Griddle is a file attachment gem for use with `mongo-ruby-driver`.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------------
|
8
|
+
|
9
|
+
Install the gem:
|
10
|
+
|
11
|
+
gem install griddle
|
12
|
+
|
13
|
+
|
14
|
+
Usage
|
15
|
+
---------------------------------------
|
16
|
+
|
17
|
+
A class with a grid attachment:
|
18
|
+
|
19
|
+
class Document
|
20
|
+
|
21
|
+
include Griddle::HasGridAttachment
|
22
|
+
|
23
|
+
has_grid_attachment :image, :styles=>{
|
24
|
+
:thumb => "50x50#"
|
25
|
+
}
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
Or, alternately if you're using an object model
|
30
|
+
|
31
|
+
class Document
|
32
|
+
|
33
|
+
include MongoMapper::Document
|
34
|
+
include Griddle::HasGridAttachment
|
35
|
+
|
36
|
+
has_grid_attachment :image, :styles=>{
|
37
|
+
:thumb => "50x50#"
|
38
|
+
}
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
Create a document:
|
43
|
+
|
44
|
+
@document = Document.new
|
45
|
+
@document.image = File.new("attached_file.jpg", 'rb')
|
46
|
+
@document.save_attached_files
|
47
|
+
|
48
|
+
Or, if you're using an object model, `saved_attached_files` is called `after_save`:
|
49
|
+
|
50
|
+
image = File.new("attached_file.jpg", 'rb')
|
51
|
+
@document = Document.new(:image => image)
|
52
|
+
@document.save
|
53
|
+
|
54
|
+
Retrieving A File
|
55
|
+
-----------------
|
56
|
+
|
57
|
+
The contents of a file stored in GridFileSystem can be retrieved using `Mongo::GridIO` accessed by the `file` method:
|
58
|
+
|
59
|
+
@document.image.file
|
60
|
+
=> <#Mongo::GridIO>
|
61
|
+
|
62
|
+
@document.image.file.read
|
63
|
+
=> contents of file
|
64
|
+
|
65
|
+
Some other methods that may be helpful to know:
|
66
|
+
|
67
|
+
# does the attachment exist?
|
68
|
+
@document.image.exist?
|
69
|
+
=> true
|
70
|
+
|
71
|
+
# attachment file name
|
72
|
+
@document.image.file_name
|
73
|
+
=> attached_file.jpg
|
74
|
+
|
75
|
+
# attachment grid key
|
76
|
+
@document.image.grid_key
|
77
|
+
=> document/12345/image/attached_file.jpg
|
78
|
+
|
79
|
+
Styles
|
80
|
+
------
|
81
|
+
|
82
|
+
Griddle makes use of `ImageMagik` processor to fit and/or crop images and store different image `styles`:
|
83
|
+
|
84
|
+
@document.image.styles
|
85
|
+
=> {:thumb => '50x50#'}
|
86
|
+
|
87
|
+
Each style is saved as a `Griddle::Attachment` as well:
|
88
|
+
|
89
|
+
@document.image.thumb.exist?
|
90
|
+
=> true
|
91
|
+
|
92
|
+
@document.image.thumb.file_name
|
93
|
+
=> attached_file.jpg
|
94
|
+
|
95
|
+
@document.image.thumb.grid_key
|
96
|
+
=> documents/12345/images/attached_file.jpg
|
97
|
+
|
98
|
+
Note on Patches/Pull Requests
|
99
|
+
-----------------------------
|
100
|
+
|
101
|
+
* Fork the project.
|
102
|
+
* Make your feature addition or bug fix.
|
103
|
+
* Add tests for it. This is important so I don't break it in a
|
104
|
+
future version unintentionally.
|
105
|
+
* Commit, do not mess with rakefile, version, or history.
|
106
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
107
|
+
* Send me a pull request. Bonus points for topic branches.
|
108
|
+
|
109
|
+
Copyright
|
110
|
+
---------
|
111
|
+
|
112
|
+
Copyright (c) 2010 Matt Matt san Mongeau. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -9,9 +9,9 @@ begin
|
|
9
9
|
gem.description = %Q{GridFS made simple...}
|
10
10
|
gem.email = "matt@toastyapps.com"
|
11
11
|
gem.homepage = "http://github.com/toastyapps/griddle"
|
12
|
-
gem.authors = ["Matt Mongeau"]
|
12
|
+
gem.authors = ["Matt Mongeau","meanmarcus"]
|
13
13
|
gem.add_development_dependency "shoulda", ">= 0"
|
14
|
-
gem.
|
14
|
+
gem.add_development_dependency "mongo_mapper", ">= 0"
|
15
15
|
end
|
16
16
|
Jeweler::GemcutterTasks.new
|
17
17
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.2
|
data/griddle.gemspec
CHANGED
@@ -5,37 +5,43 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{griddle}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["Matt Mongeau"]
|
12
|
-
s.date = %q{2010-
|
11
|
+
s.authors = ["Matt Mongeau", "meanmarcus"]
|
12
|
+
s.date = %q{2010-05-30}
|
13
13
|
s.description = %q{GridFS made simple...}
|
14
14
|
s.email = %q{matt@toastyapps.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
"README.
|
17
|
+
"README.markdown"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".gitignore",
|
22
22
|
"LICENSE",
|
23
|
-
"README.
|
23
|
+
"README.markdown",
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
26
|
"griddle.gemspec",
|
27
27
|
"lib/griddle.rb",
|
28
28
|
"lib/griddle/attachment.rb",
|
29
29
|
"lib/griddle/has_grid_attachment.rb",
|
30
|
+
"lib/griddle/processor.rb",
|
31
|
+
"lib/griddle/processor/image_magick.rb",
|
30
32
|
"lib/griddle/style.rb",
|
31
33
|
"lib/griddle/upfile.rb",
|
32
34
|
"rails/init.rb",
|
33
35
|
"test/attachment_test.rb",
|
34
36
|
"test/fixtures/baboon.jpg",
|
37
|
+
"test/fixtures/climenole.jpeg",
|
35
38
|
"test/fixtures/fox.jpg",
|
36
39
|
"test/fixtures/sample.pdf",
|
40
|
+
"test/fixtures/squid.png",
|
37
41
|
"test/has_attachment_test.rb",
|
38
42
|
"test/models.rb",
|
43
|
+
"test/mongo_mapper_models.rb",
|
44
|
+
"test/processor_test.rb",
|
39
45
|
"test/style_test.rb",
|
40
46
|
"test/test_helper.rb",
|
41
47
|
"test/upfile_test.rb"
|
@@ -43,12 +49,14 @@ Gem::Specification.new do |s|
|
|
43
49
|
s.homepage = %q{http://github.com/toastyapps/griddle}
|
44
50
|
s.rdoc_options = ["--charset=UTF-8"]
|
45
51
|
s.require_paths = ["lib"]
|
46
|
-
s.rubygems_version = %q{1.3.
|
52
|
+
s.rubygems_version = %q{1.3.7}
|
47
53
|
s.summary = %q{GridFS made simple.}
|
48
54
|
s.test_files = [
|
49
55
|
"test/attachment_test.rb",
|
50
56
|
"test/has_attachment_test.rb",
|
51
57
|
"test/models.rb",
|
58
|
+
"test/mongo_mapper_models.rb",
|
59
|
+
"test/processor_test.rb",
|
52
60
|
"test/style_test.rb",
|
53
61
|
"test/test_helper.rb",
|
54
62
|
"test/upfile_test.rb"
|
@@ -58,9 +66,9 @@ Gem::Specification.new do |s|
|
|
58
66
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
59
67
|
s.specification_version = 3
|
60
68
|
|
61
|
-
if Gem::Version.new(Gem::
|
69
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
62
70
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
63
|
-
s.
|
71
|
+
s.add_development_dependency(%q<mongo_mapper>, [">= 0"])
|
64
72
|
else
|
65
73
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
66
74
|
s.add_dependency(%q<mongo_mapper>, [">= 0"])
|
data/lib/griddle/attachment.rb
CHANGED
@@ -1,71 +1,242 @@
|
|
1
1
|
module Griddle
|
2
2
|
class Attachment
|
3
|
-
include MongoMapper::Document
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
4
|
+
include Mongo
|
5
|
+
|
6
|
+
def self.attachment_for(options)
|
7
|
+
options = self.clean_options(options)
|
8
|
+
options_for_search = {:name => options[:name], :owner_type => options[:owner_type], :owner_id => options[:owner_id]}
|
9
|
+
record = collection.find_one(options_for_search)
|
10
|
+
return new(record) unless record.nil?
|
11
|
+
return new(options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.collection
|
15
|
+
@collection ||= Griddle.database.collection('griddle.attachments')
|
16
|
+
end
|
17
17
|
|
18
18
|
def self.for(name, owner, options = {})
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
attachment_for(options.merge({
|
20
|
+
:name => name,
|
21
|
+
:owner_type => owner.class,
|
22
|
+
:owner_id => owner.id
|
23
|
+
}))
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.valid_attributes
|
27
|
+
[:name, :owner_id, :owner_type, :file_name, :file_size, :content_type, :styles, :options]
|
28
|
+
end
|
29
|
+
# belongs_to :owner, :polymorphic => true
|
30
|
+
|
31
|
+
attr_accessor :attributes
|
32
|
+
|
33
|
+
def initialize(attributes = {})
|
34
|
+
@grid = GridFileSystem.new(Griddle.database)
|
35
|
+
@attributes = attributes.symbolize_keys
|
36
|
+
initialize_processor
|
37
|
+
initialize_styles
|
38
|
+
create_attachments_for_styles
|
39
|
+
end
|
40
|
+
|
41
|
+
def assign(uploaded_file)
|
42
|
+
if valid_assignment?(uploaded_file)
|
43
|
+
self.file = uploaded_file
|
44
|
+
self.dirty!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def attributes
|
49
|
+
@attributes
|
50
|
+
end
|
51
|
+
|
52
|
+
def attributes=(attributes)
|
53
|
+
@attributes.merge!(attributes).symbolize_keys
|
54
|
+
end
|
55
|
+
|
56
|
+
def collection
|
57
|
+
@collection ||= self.class.collection
|
58
|
+
end
|
59
|
+
|
60
|
+
def destroy
|
61
|
+
destroy_file
|
62
|
+
collection.remove({:name => name, :owner_type => owner_type, :owner_id => owner_id})
|
63
|
+
end
|
64
|
+
|
65
|
+
def method_missing(method, *args, &block)
|
66
|
+
key = method.to_s.gsub(/\=$/, '').to_sym
|
67
|
+
if self.class.valid_attributes.include?(key)
|
68
|
+
if key != method
|
69
|
+
@attributes[key] = args[0]
|
70
|
+
else
|
71
|
+
@attributes[key]
|
24
72
|
end
|
73
|
+
else
|
74
|
+
super
|
25
75
|
end
|
26
|
-
|
76
|
+
end
|
77
|
+
|
78
|
+
def destroy_file
|
79
|
+
@grid.delete(grid_key)
|
80
|
+
destroy_styles
|
81
|
+
end
|
82
|
+
|
83
|
+
def dirty?
|
84
|
+
@dirty ||= false
|
85
|
+
@dirty
|
86
|
+
end
|
87
|
+
|
88
|
+
def exists?
|
89
|
+
Griddle.database['fs.files'].find({'filename' => self.grid_key}).count > 0
|
27
90
|
end
|
28
91
|
|
29
92
|
def grid_key
|
30
|
-
|
93
|
+
"#{owner_type.tableize}/#{owner_id}/#{name}/#{self.file_name}".downcase
|
31
94
|
end
|
32
95
|
|
33
|
-
def
|
34
|
-
|
35
|
-
@tmp_file = uploaded_file
|
96
|
+
def file
|
97
|
+
@grid.open(grid_key, 'r') if exists?
|
36
98
|
end
|
37
99
|
|
38
100
|
def file=(new_file)
|
39
|
-
|
40
|
-
self.file_name =
|
41
|
-
self.file_size = File.size(new_file)
|
101
|
+
filename = clean_filename(new_file.respond_to?(:original_filename) ? new_file.original_filename : File.basename(new_file.path))
|
102
|
+
self.file_name = filename
|
103
|
+
self.file_size = File.size(new_file.path)
|
42
104
|
self.content_type = new_file.content_type
|
43
|
-
|
44
|
-
|
45
|
-
|
105
|
+
@tmp_file = new_file
|
106
|
+
end
|
107
|
+
|
108
|
+
def name= name
|
109
|
+
@attributes[:name] = name.to_sym
|
110
|
+
end
|
111
|
+
|
112
|
+
def owner_id= id
|
113
|
+
@attributes[:owner_id] = id.to_s
|
114
|
+
end
|
115
|
+
|
116
|
+
def owner_type= str
|
117
|
+
@attributes[:owner_type] = str.to_s
|
118
|
+
end
|
119
|
+
|
120
|
+
def processor
|
121
|
+
@processor
|
122
|
+
end
|
123
|
+
|
124
|
+
def processor= processor
|
125
|
+
@attributes[:processor] = processor
|
126
|
+
initialize_processor
|
127
|
+
end
|
128
|
+
|
129
|
+
def save
|
130
|
+
if valid?
|
131
|
+
destroy
|
132
|
+
save_file
|
133
|
+
collection.insert(valid_attributes(@attributes).stringify_keys)
|
46
134
|
end
|
47
135
|
end
|
48
136
|
|
49
|
-
def
|
50
|
-
|
137
|
+
def styles
|
138
|
+
@styles
|
51
139
|
end
|
52
140
|
|
53
|
-
def
|
54
|
-
|
141
|
+
def styles= styles
|
142
|
+
@attributes[:styles] = styles
|
143
|
+
initialize_styles
|
55
144
|
end
|
56
145
|
|
57
|
-
def
|
58
|
-
|
146
|
+
def valid?
|
147
|
+
dirty? && valid_assignment?(@tmp_file)
|
148
|
+
end
|
149
|
+
|
150
|
+
def valid_attributes(attributes)
|
151
|
+
Hash[*attributes.select{|key, value| self.class.valid_attributes.include?(key) }.flatten]
|
152
|
+
end
|
153
|
+
|
154
|
+
protected
|
155
|
+
|
156
|
+
def dirty!
|
157
|
+
@dirty = true
|
59
158
|
end
|
60
159
|
|
61
160
|
private
|
62
161
|
|
162
|
+
def self.clean_options(options)
|
163
|
+
options.symbolize_keys!
|
164
|
+
options.merge({
|
165
|
+
:name => options[:name].to_sym,
|
166
|
+
:owner_type => options[:owner_type].to_s,
|
167
|
+
:owner_id => options[:owner_id].to_s
|
168
|
+
})
|
169
|
+
end
|
170
|
+
|
171
|
+
def clean_filename str
|
172
|
+
tmp_file_reg = /\.([a-z]{2}[a-z0-9]{0,2})#{Time.now.strftime('%Y%m%d')}-.+/
|
173
|
+
str.gsub(tmp_file_reg,'.\1').gsub(/[?:\/*""<>|]+/,'_')
|
174
|
+
end
|
175
|
+
|
176
|
+
def create_attachments_for_styles
|
177
|
+
self.styles.each do |h|
|
178
|
+
create_style_attachment h[0]
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def create_style_attachment style_name
|
183
|
+
raise "Invalid style name :#{style_name}. #{style_name} is a reserved word." if respond_to?(style_name) || !attributes[style_name.to_sym].nil?
|
184
|
+
|
185
|
+
attrs = attributes.merge({
|
186
|
+
:name => "#{name}/#{style_name}",
|
187
|
+
:owner_id => @attributes[:owner_id].to_s,
|
188
|
+
:styles => {}
|
189
|
+
})
|
190
|
+
self.class_eval do
|
191
|
+
|
192
|
+
define_method(style_name) do |*args|
|
193
|
+
Attachment.attachment_for(attrs)
|
194
|
+
end
|
195
|
+
|
196
|
+
define_method("#{style_name}=") do |file|
|
197
|
+
Attachment.attachment_for(attrs).assign(file)
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def destroy_styles
|
204
|
+
styles.each{|s| send(s[0]).destroy }
|
205
|
+
end
|
206
|
+
|
207
|
+
def initialize_processor
|
208
|
+
@processor = Processor.new @attributes[:processor]
|
209
|
+
end
|
210
|
+
|
211
|
+
def initialize_styles
|
212
|
+
@styles = {}
|
213
|
+
if @attributes[:styles] && @attributes[:styles].is_a?(Hash)
|
214
|
+
@styles = @attributes[:styles].inject({}) do |h, value|
|
215
|
+
h[value.first.to_sym] = Style.new value.first, value.last, self
|
216
|
+
h
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
63
221
|
def save_file
|
64
|
-
|
222
|
+
@tmp_file.rewind
|
223
|
+
@grid.open(grid_key, 'w', :content_type => self.content_type) do |f|
|
224
|
+
f.write @tmp_file.read
|
225
|
+
end
|
226
|
+
save_styles
|
227
|
+
end
|
228
|
+
|
229
|
+
def save_styles
|
230
|
+
styles.each do |h|
|
231
|
+
processed_file = processor.process_image(@tmp_file, h[1])
|
232
|
+
style_attachment = send(h[0])
|
233
|
+
style_attachment.assign(processed_file)
|
234
|
+
style_attachment.save
|
235
|
+
end
|
65
236
|
end
|
66
237
|
|
67
238
|
def valid_assignment?(file)
|
68
|
-
|
239
|
+
(file.respond_to?(:original_filename) && file.respond_to?(:content_type))
|
69
240
|
end
|
70
241
|
|
71
242
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'mongo/gridfs'
|
2
1
|
module Griddle
|
3
2
|
module HasGridAttachment
|
4
3
|
def self.included(base)
|
@@ -13,14 +12,15 @@ module Griddle
|
|
13
12
|
write_inheritable_attribute(:attachment_definitions, {}) if attachment_definitions.nil?
|
14
13
|
attachment_definitions[name] = options
|
15
14
|
|
16
|
-
after_save :save_attached_files
|
15
|
+
after_save :save_attached_files if respond_to? :after_save
|
16
|
+
after_destroy :destroy_attached_files if respond_to? :after_destroy
|
17
17
|
|
18
18
|
define_method(name) do |*args|
|
19
|
-
attachment_for(name)
|
19
|
+
attachment_for(name, options)
|
20
20
|
end
|
21
21
|
|
22
22
|
define_method("#{name}=") do |file|
|
23
|
-
attachment_for(name).assign(file)
|
23
|
+
attachment_for(name, options).assign(file)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -31,9 +31,13 @@ module Griddle
|
|
31
31
|
|
32
32
|
module InstanceMethods
|
33
33
|
|
34
|
-
def attachment_for name
|
34
|
+
def attachment_for name, options = {}
|
35
35
|
@_gripster_attachments ||= {}
|
36
|
-
@_gripster_attachments[name] ||= Attachment.for(name, self)
|
36
|
+
@_gripster_attachments[name] ||= Attachment.for(name, self, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def destroy_attached_files
|
40
|
+
each_attachment{|name, attachment| attachment.destroy }
|
37
41
|
end
|
38
42
|
|
39
43
|
def each_attachment
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Griddle
|
2
|
+
class Processor
|
3
|
+
class ImageMagick
|
4
|
+
|
5
|
+
def crop
|
6
|
+
`convert #{File.expand_path(@destination_file.path)} -crop #{geometry} -gravity Center #{@destination_file.path}`
|
7
|
+
end
|
8
|
+
|
9
|
+
def crop?
|
10
|
+
@style.geometry =~ /#/
|
11
|
+
end
|
12
|
+
|
13
|
+
def file_width
|
14
|
+
file_dimensions.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def fit(geo = geometry)
|
18
|
+
`convert #{File.expand_path(@file.path)} -resize #{geo} #{@destination_file.path}`
|
19
|
+
end
|
20
|
+
|
21
|
+
def geometry
|
22
|
+
@geometry ||= @style.geometry.gsub(/#/,'')
|
23
|
+
end
|
24
|
+
|
25
|
+
def file_height
|
26
|
+
file_dimensions.last
|
27
|
+
end
|
28
|
+
|
29
|
+
def height
|
30
|
+
dimensions.last
|
31
|
+
end
|
32
|
+
|
33
|
+
def process_image file, style
|
34
|
+
@style = style
|
35
|
+
@file = file
|
36
|
+
@destination_file = Tempfile.new @file.original_filename
|
37
|
+
if crop?
|
38
|
+
fit(resize_geometry_for_crop)
|
39
|
+
crop
|
40
|
+
else
|
41
|
+
fit
|
42
|
+
end
|
43
|
+
@destination_file
|
44
|
+
end
|
45
|
+
|
46
|
+
def width
|
47
|
+
dimensions.first
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def dimensions
|
53
|
+
@dimensions ||= dimensions_for(geometry)
|
54
|
+
end
|
55
|
+
|
56
|
+
def dimensions_for geo
|
57
|
+
geo.scan(/([0-9]*)x([0-9]*)/).flatten.collect{|v|v.to_f}
|
58
|
+
end
|
59
|
+
|
60
|
+
def file_dimensions
|
61
|
+
@file_dimensions ||= dimensions_for(`identify -format "%[fx:w]x%[fx:h]" #{File.expand_path(@file.path)}`)
|
62
|
+
end
|
63
|
+
|
64
|
+
def resize_for_width?
|
65
|
+
file_height*(width/file_width) >= height
|
66
|
+
end
|
67
|
+
|
68
|
+
def resize_geometry_for_crop
|
69
|
+
resize_for_width? ? "#{width}x" : "x#{height}"
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Griddle
|
2
|
+
class Processor
|
3
|
+
|
4
|
+
attr_accessor :klass
|
5
|
+
|
6
|
+
def initialize( processor_class = :ImageMagick )
|
7
|
+
processor_class = :ImageMagick unless valid_processors.include? processor_class
|
8
|
+
self.klass = self.class.const_get "#{processor_class}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def process_image file, style
|
12
|
+
processor = self.klass.new
|
13
|
+
raise "Define in subclass" unless processor.respond_to? :process_image
|
14
|
+
processor.process_image(file, style)
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
def valid_processors
|
19
|
+
[:ImageMagick]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/griddle.rb
CHANGED
@@ -3,16 +3,35 @@ if RUBY_VERSION =~ /1.9.[0-9]/
|
|
3
3
|
else
|
4
4
|
require 'ftools'
|
5
5
|
end
|
6
|
+
require 'rubygems'
|
6
7
|
require 'mime/types'
|
8
|
+
require 'tempfile'
|
7
9
|
require 'griddle/has_grid_attachment'
|
8
10
|
require 'griddle/attachment'
|
9
11
|
require 'griddle/upfile'
|
10
12
|
require 'griddle/style'
|
13
|
+
require 'griddle/processor/image_magick'
|
14
|
+
require 'griddle/processor'
|
11
15
|
|
12
16
|
module Griddle
|
17
|
+
|
13
18
|
def self.version
|
14
|
-
|
19
|
+
@version ||= File.read(File.join(File.dirname(__FILE__), "..", "VERSION")).chomp
|
15
20
|
end
|
21
|
+
|
22
|
+
def self.database
|
23
|
+
@database ||= if(defined?(MongoMapper))
|
24
|
+
MongoMapper.database
|
25
|
+
else
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.database=(database)
|
31
|
+
@database = database
|
32
|
+
end
|
33
|
+
|
16
34
|
end
|
17
35
|
|
18
|
-
File.send(:include, Griddle::Upfile)
|
36
|
+
File.send(:include, Griddle::Upfile)
|
37
|
+
|
data/test/attachment_test.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
require "models"
|
3
3
|
|
4
|
+
include Mongo
|
5
|
+
|
4
6
|
class AttachmentTest < Test::Unit::TestCase
|
5
7
|
|
6
8
|
context "An Attachment" do
|
@@ -19,8 +21,8 @@ class AttachmentTest < Test::Unit::TestCase
|
|
19
21
|
should "#assign a valid assignment" do
|
20
22
|
@attachment.assign(@image)
|
21
23
|
@attachment.save
|
22
|
-
|
23
|
-
assert
|
24
|
+
assert_kind_of Mongo::GridIO, @attachment.file
|
25
|
+
assert @attachment.exists?
|
24
26
|
end
|
25
27
|
|
26
28
|
context "with a file" do
|
@@ -31,7 +33,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
31
33
|
|
32
34
|
should "#destroy_file" do
|
33
35
|
@attachment.destroy_file
|
34
|
-
assert
|
36
|
+
assert !@attachment.exists?
|
35
37
|
end
|
36
38
|
|
37
39
|
end
|
data/test/fixtures/baboon.jpg
CHANGED
Binary file
|
Binary file
|
Binary file
|
data/test/has_attachment_test.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
require "models"
|
3
|
+
include Mongo
|
3
4
|
|
4
5
|
class HasAttachmentTest < Test::Unit::TestCase
|
5
6
|
context "A Doc that has_grid_attachment :image" do
|
@@ -28,20 +29,83 @@ class HasAttachmentTest < Test::Unit::TestCase
|
|
28
29
|
should "should return an Attachment" do
|
29
30
|
assert_equal(Griddle::Attachment, @document.image.class)
|
30
31
|
end
|
31
|
-
|
32
|
+
|
32
33
|
should "read file from grid store" do
|
33
34
|
assert_equal "image/jpeg", @file_system.find_one(:filename => @document.image.grid_key)['contentType']
|
34
35
|
end
|
36
|
+
|
37
|
+
should "exist" do
|
38
|
+
assert @document.image.exists?
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when assigned a new file" do
|
42
|
+
|
43
|
+
setup do
|
44
|
+
@new_file = File.new("#{@dir}/climenole.jpeg", 'rb')
|
45
|
+
@document.image = @new_file
|
46
|
+
@document.save!
|
47
|
+
@document = Doc.find(@document.id)
|
48
|
+
end
|
49
|
+
|
50
|
+
should "be the new file" do
|
51
|
+
assert_equal "climenole.jpeg", @document.image.file_name
|
52
|
+
@new_file.rewind
|
53
|
+
assert_equal @new_file.read.length, @document.image.file.read.length
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when save is called without a new file" do
|
59
|
+
|
60
|
+
setup do
|
61
|
+
@document = Doc.find(@document.id)
|
62
|
+
@document.save!
|
63
|
+
end
|
64
|
+
|
65
|
+
should "be the original image" do
|
66
|
+
assert @document.image.exists?
|
67
|
+
assert_equal "baboon.jpg", @document.image.file_name
|
68
|
+
@image.rewind
|
69
|
+
assert_equal @image.read.length, @document.image.file.read.length
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
35
73
|
|
36
74
|
end
|
37
75
|
|
76
|
+
context "when assigned nil" do
|
77
|
+
|
78
|
+
setup do
|
79
|
+
@document.image = nil
|
80
|
+
@document.save!
|
81
|
+
end
|
82
|
+
|
83
|
+
should "not exist" do
|
84
|
+
assert !@document.image.exists?
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when assigned blank" do
|
90
|
+
|
91
|
+
setup do
|
92
|
+
@document.image = ""
|
93
|
+
@document.save!
|
94
|
+
end
|
95
|
+
|
96
|
+
should "not exist" do
|
97
|
+
assert !@document.image.exists?
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
38
102
|
context "with styles" do
|
39
103
|
|
40
104
|
setup do
|
41
105
|
@document = DocWithStyles.new
|
42
106
|
end
|
43
107
|
|
44
|
-
context "when assigned
|
108
|
+
context "when assigned an image" do
|
45
109
|
|
46
110
|
setup do
|
47
111
|
@document.image = @image
|
@@ -50,23 +114,171 @@ class HasAttachmentTest < Test::Unit::TestCase
|
|
50
114
|
|
51
115
|
should "have a styles" do
|
52
116
|
assert_kind_of Hash, @document.image.styles
|
53
|
-
end
|
117
|
+
end
|
118
|
+
|
119
|
+
should "have a method for each style" do
|
120
|
+
assert @document.image.respond_to? :cropped_wide
|
121
|
+
end
|
122
|
+
|
123
|
+
should "be a kind of attachment" do
|
124
|
+
assert_kind_of Griddle::Attachment, @document.image.cropped_wide
|
125
|
+
end
|
126
|
+
|
127
|
+
should "style should have a grid_key for cropped" do
|
128
|
+
assert_equal "doc_with_styles/#{@document.id}/image/cropped_wide/baboon.jpg", @document.image.cropped_wide.grid_key
|
129
|
+
end
|
130
|
+
|
131
|
+
should "style should have a file for cropped" do
|
132
|
+
assert @document.image.cropped_wide.exists?
|
133
|
+
assert !@document.image.cropped_wide.file.read.blank?
|
134
|
+
end
|
135
|
+
|
136
|
+
should "delete an image and its styles" do
|
137
|
+
grid_keys = @document.image.styles.inject([]) do |a,style|
|
138
|
+
a << @document.image.send(style[0]).grid_key
|
139
|
+
a
|
140
|
+
end
|
141
|
+
|
142
|
+
grid_keys << @document.image.grid_key
|
143
|
+
|
144
|
+
@document.image.destroy
|
145
|
+
|
146
|
+
grid_keys.each do |grid_key|
|
147
|
+
assert Griddle.database['fs.files'].find({'filename' => grid_key}).count == 0
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
image_varations = {
|
154
|
+
"wider than taller" => {
|
155
|
+
:file_name => "baboon.jpg",
|
156
|
+
:expected_dimensions => {
|
157
|
+
:resized => "150 x 100",
|
158
|
+
:fitted => "150 x 114",
|
159
|
+
:cropped_wide => '60 x 50',
|
160
|
+
:cropped_tall => '50 x 60',
|
161
|
+
:cropped_square => '50 x 50'
|
162
|
+
}
|
163
|
+
},
|
164
|
+
"taller than wider" => {
|
165
|
+
:file_name =>"climenole.jpeg",
|
166
|
+
:expected_dimensions => {
|
167
|
+
:resized => "150 x 100",
|
168
|
+
:fitted => "94 x 150",
|
169
|
+
:cropped_wide => '60 x 50',
|
170
|
+
:cropped_tall => '50 x 60',
|
171
|
+
:cropped_square => '50 x 50'
|
172
|
+
}
|
173
|
+
},
|
174
|
+
"square" => {
|
175
|
+
:file_name => "squid.png",
|
176
|
+
:expected_dimensions => {
|
177
|
+
:resized => "150 x 100",
|
178
|
+
:fitted => "150 x 150",
|
179
|
+
:cropped_wide => '60 x 50',
|
180
|
+
:cropped_tall => '50 x 60',
|
181
|
+
:cropped_square => '50 x 50'
|
182
|
+
}
|
183
|
+
},
|
184
|
+
}
|
185
|
+
|
186
|
+
image_varations.each do |variant|
|
187
|
+
description, variant = variant
|
188
|
+
|
189
|
+
context "when assigned an image that is #{description}" do
|
190
|
+
|
191
|
+
setup do
|
192
|
+
@document.image = File.new("#{@dir}/#{variant[:file_name]}", 'rb')
|
193
|
+
@document.save!
|
194
|
+
end
|
195
|
+
|
196
|
+
variant[:expected_dimensions].each do |style|
|
197
|
+
style_name, dimensions = style
|
198
|
+
|
199
|
+
should "have the correct dimensions for #{style_name}" do
|
200
|
+
temp = Tempfile.new "#{style[0]}.jpg"
|
201
|
+
style_attachment = @document.image.send(style_name)
|
202
|
+
|
203
|
+
file_path = File.dirname(temp.path) + '/' + style_attachment.file_name
|
204
|
+
File.open(file_path, 'w') do |f|
|
205
|
+
f.write style_attachment.file.read
|
206
|
+
end
|
207
|
+
cmd = %Q[identify -format "%[fx:w] x %[fx:h]" #{file_path}]
|
208
|
+
assert_equal dimensions, `#{cmd}`.chomp
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
54
214
|
|
55
215
|
end
|
56
216
|
|
57
217
|
end
|
58
|
-
|
59
|
-
context "
|
218
|
+
|
219
|
+
context "with a invalid style name" do
|
220
|
+
|
60
221
|
setup do
|
61
|
-
@
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
222
|
+
@document = DocWithInvalidStyles.new
|
223
|
+
end
|
224
|
+
|
225
|
+
should "raise an error indicating an invalid style name" do
|
226
|
+
assert_raise RuntimeError do
|
227
|
+
@document.image = @image
|
228
|
+
end
|
67
229
|
end
|
230
|
+
|
68
231
|
end
|
69
|
-
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
context "A Document with multiple attachments" do
|
236
|
+
|
237
|
+
setup do
|
238
|
+
@document = DocWithMultipleAttachments.new
|
239
|
+
@dir = File.dirname(__FILE__) + '/fixtures'
|
240
|
+
@document.image = File.open("#{@dir}/baboon.jpg", 'r')
|
241
|
+
@document.pdf = File.open("#{@dir}/sample.pdf", 'r')
|
242
|
+
@document.save
|
243
|
+
|
244
|
+
@grid_keys = [@document.image.grid_key, @document.pdf.grid_key]
|
245
|
+
end
|
246
|
+
|
247
|
+
should "destroy_attached_files" do
|
248
|
+
@document.destroy_attached_files
|
249
|
+
@grid_keys.each do |grid_key|
|
250
|
+
assert Griddle.database['fs.files'].find({'filename' => grid_key}).count == 0
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
should "destroy on after_destroy" do
|
255
|
+
@document.destroy
|
256
|
+
@grid_keys.each do |grid_key|
|
257
|
+
assert Griddle.database['fs.files'].find({'filename' => grid_key}).count == 0
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
262
|
+
|
263
|
+
context "A Document with no object model" do
|
264
|
+
|
265
|
+
setup do
|
266
|
+
@document = Document.new
|
267
|
+
@dir = File.dirname(__FILE__) + '/fixtures'
|
268
|
+
@image = File.open("#{@dir}/baboon.jpg", 'r')
|
269
|
+
end
|
270
|
+
|
271
|
+
should "have a method for save_attached_files" do
|
272
|
+
assert @document.respond_to? :save_attached_files
|
273
|
+
end
|
274
|
+
|
275
|
+
should "save_attached_files" do
|
276
|
+
@document.save_attached_files
|
277
|
+
attachment = Griddle::Attachment.for(:image, @document)
|
278
|
+
attachment.attributes.delete(:_id)
|
279
|
+
assert_equal @document.image.attributes, attachment.attributes
|
280
|
+
end
|
281
|
+
|
70
282
|
end
|
71
283
|
|
72
284
|
end
|
data/test/models.rb
CHANGED
@@ -1,19 +1,16 @@
|
|
1
|
-
class
|
2
|
-
include MongoMapper::Document
|
3
|
-
include Griddle::HasGridAttachment
|
4
|
-
has_grid_attachment :image
|
5
|
-
end
|
6
|
-
|
7
|
-
class DocNoAttachment
|
8
|
-
include MongoMapper::Document
|
9
|
-
end
|
10
|
-
|
11
|
-
class DocWithStyles
|
12
|
-
include MongoMapper::Document
|
1
|
+
class Document
|
13
2
|
include Griddle::HasGridAttachment
|
14
3
|
|
15
4
|
has_grid_attachment :image, :styles => {
|
16
|
-
:
|
5
|
+
:resized => "150x100!",
|
6
|
+
:fitted => "150x150",
|
7
|
+
:cropped_wide => '60x50#',
|
8
|
+
:cropped_tall => '50x60#',
|
9
|
+
:cropped_square => '50x50#'
|
17
10
|
}
|
18
11
|
|
12
|
+
def id
|
13
|
+
object_id
|
14
|
+
end
|
15
|
+
|
19
16
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
MongoMapper.database = Griddle.database.name
|
2
|
+
|
3
|
+
class Doc
|
4
|
+
include MongoMapper::Document
|
5
|
+
include Griddle::HasGridAttachment
|
6
|
+
has_grid_attachment :image
|
7
|
+
end
|
8
|
+
|
9
|
+
class DocNoAttachment
|
10
|
+
include MongoMapper::Document
|
11
|
+
end
|
12
|
+
|
13
|
+
class DocWithStyles
|
14
|
+
include MongoMapper::Document
|
15
|
+
include Griddle::HasGridAttachment
|
16
|
+
|
17
|
+
has_grid_attachment :image, :styles => {
|
18
|
+
:resized => "150x100!",
|
19
|
+
:fitted => "150x150",
|
20
|
+
:cropped_wide => '60x50#',
|
21
|
+
:cropped_tall => '50x60#',
|
22
|
+
:cropped_square => '50x50#'
|
23
|
+
}
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
# invalid because one of the styles is a reserved word
|
28
|
+
class DocWithInvalidStyles
|
29
|
+
include MongoMapper::Document
|
30
|
+
include Griddle::HasGridAttachment
|
31
|
+
|
32
|
+
has_grid_attachment :image, :styles => {
|
33
|
+
:file => "50x50#",
|
34
|
+
:thumb => '50x50#'
|
35
|
+
}
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
class DocWithMultipleAttachments
|
40
|
+
include MongoMapper::Document
|
41
|
+
include Griddle::HasGridAttachment
|
42
|
+
|
43
|
+
has_grid_attachment :image
|
44
|
+
has_grid_attachment :pdf
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "models"
|
3
|
+
|
4
|
+
class ProcessorTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "A Processor" do
|
7
|
+
|
8
|
+
setup do
|
9
|
+
@processor = Griddle::Processor.new
|
10
|
+
end
|
11
|
+
|
12
|
+
should "be a type of processor" do
|
13
|
+
assert_kind_of Griddle::Processor, @processor
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
context "An Attachment" do
|
19
|
+
|
20
|
+
setup do
|
21
|
+
@dir = File.dirname(__FILE__) + '/fixtures'
|
22
|
+
@image = File.open("#{@dir}/baboon.jpg", 'r')
|
23
|
+
@options = {
|
24
|
+
:processor => :ImageMagick
|
25
|
+
}
|
26
|
+
@doc = DocNoAttachment.create
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context "without processor options" do
|
31
|
+
|
32
|
+
setup do
|
33
|
+
@attachment = Griddle::Attachment.for(:image, @doc)
|
34
|
+
end
|
35
|
+
|
36
|
+
should "have default to processor ImageMagick" do
|
37
|
+
assert_equal Griddle::Processor::ImageMagick, @attachment.processor.klass
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context "and a file" do
|
43
|
+
|
44
|
+
setup do
|
45
|
+
@attachment = Griddle::Attachment.for(:image, @doc, @options)
|
46
|
+
end
|
47
|
+
|
48
|
+
should "have a processor of ImageMagick" do
|
49
|
+
assert_equal Griddle::Processor::ImageMagick, @attachment.processor.klass
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/test/style_test.rb
CHANGED
@@ -44,6 +44,14 @@ class StyleTest < Test::Unit::TestCase
|
|
44
44
|
assert_equal @options[:styles][:thumb], @attachment.styles[:thumb].geometry
|
45
45
|
end
|
46
46
|
|
47
|
+
should "save styles with the attachment" do
|
48
|
+
@attachment.save
|
49
|
+
options = {:name => @attachment.name, :owner_id => @attachment.owner_id, :owner_type => @attachment.owner_type }
|
50
|
+
record = Griddle::Attachment.collection.find_one(options)
|
51
|
+
attachment = Griddle::Attachment.new record
|
52
|
+
assert_equal @attachment.styles[:thumb][:geometry], attachment.styles[:thumb][:geometry]
|
53
|
+
end
|
54
|
+
|
47
55
|
end
|
48
56
|
|
49
57
|
end
|
data/test/test_helper.rb
CHANGED
@@ -2,17 +2,22 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'mongo_mapper'
|
5
|
+
require 'mongo'
|
6
|
+
gem 'activesupport', '2.3.5'
|
7
|
+
require 'active_support'
|
5
8
|
require 'griddle'
|
6
9
|
require 'test/unit'
|
7
10
|
require 'shoulda'
|
11
|
+
require 'tempfile'
|
12
|
+
require 'rack'
|
8
13
|
|
9
14
|
TEST_DB = 'griddle-test' unless Object.const_defined?("TEST_DB")
|
10
15
|
|
11
|
-
|
16
|
+
Griddle.database = Mongo::Connection.new.db(TEST_DB)
|
12
17
|
|
13
18
|
class Test::Unit::TestCase
|
14
19
|
def teardown
|
15
|
-
|
20
|
+
Griddle.database.collections.each do |coll|
|
16
21
|
coll.remove
|
17
22
|
end
|
18
23
|
end
|
@@ -24,4 +29,7 @@ class Test::Unit::TestCase
|
|
24
29
|
super
|
25
30
|
end
|
26
31
|
end
|
27
|
-
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'models'
|
35
|
+
require 'mongo_mapper_models'
|
metadata
CHANGED
@@ -1,37 +1,52 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: griddle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 31
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Matt Mongeau
|
14
|
+
- meanmarcus
|
8
15
|
autorequire:
|
9
16
|
bindir: bin
|
10
17
|
cert_chain: []
|
11
18
|
|
12
|
-
date: 2010-
|
19
|
+
date: 2010-05-30 00:00:00 -04:00
|
13
20
|
default_executable:
|
14
21
|
dependencies:
|
15
22
|
- !ruby/object:Gem::Dependency
|
16
23
|
name: shoulda
|
17
|
-
|
18
|
-
|
19
|
-
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
20
27
|
requirements:
|
21
28
|
- - ">="
|
22
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
23
33
|
version: "0"
|
24
|
-
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
25
36
|
- !ruby/object:Gem::Dependency
|
26
37
|
name: mongo_mapper
|
27
|
-
|
28
|
-
|
29
|
-
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
30
41
|
requirements:
|
31
42
|
- - ">="
|
32
43
|
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
33
47
|
version: "0"
|
34
|
-
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
35
50
|
description: GridFS made simple...
|
36
51
|
email: matt@toastyapps.com
|
37
52
|
executables: []
|
@@ -40,27 +55,33 @@ extensions: []
|
|
40
55
|
|
41
56
|
extra_rdoc_files:
|
42
57
|
- LICENSE
|
43
|
-
- README.
|
58
|
+
- README.markdown
|
44
59
|
files:
|
45
60
|
- .document
|
46
61
|
- .gitignore
|
47
62
|
- LICENSE
|
48
|
-
- README.
|
63
|
+
- README.markdown
|
49
64
|
- Rakefile
|
50
65
|
- VERSION
|
51
66
|
- griddle.gemspec
|
52
67
|
- lib/griddle.rb
|
53
68
|
- lib/griddle/attachment.rb
|
54
69
|
- lib/griddle/has_grid_attachment.rb
|
70
|
+
- lib/griddle/processor.rb
|
71
|
+
- lib/griddle/processor/image_magick.rb
|
55
72
|
- lib/griddle/style.rb
|
56
73
|
- lib/griddle/upfile.rb
|
57
74
|
- rails/init.rb
|
58
75
|
- test/attachment_test.rb
|
59
76
|
- test/fixtures/baboon.jpg
|
77
|
+
- test/fixtures/climenole.jpeg
|
60
78
|
- test/fixtures/fox.jpg
|
61
79
|
- test/fixtures/sample.pdf
|
80
|
+
- test/fixtures/squid.png
|
62
81
|
- test/has_attachment_test.rb
|
63
82
|
- test/models.rb
|
83
|
+
- test/mongo_mapper_models.rb
|
84
|
+
- test/processor_test.rb
|
64
85
|
- test/style_test.rb
|
65
86
|
- test/test_helper.rb
|
66
87
|
- test/upfile_test.rb
|
@@ -74,21 +95,27 @@ rdoc_options:
|
|
74
95
|
require_paths:
|
75
96
|
- lib
|
76
97
|
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
77
99
|
requirements:
|
78
100
|
- - ">="
|
79
101
|
- !ruby/object:Gem::Version
|
102
|
+
hash: 3
|
103
|
+
segments:
|
104
|
+
- 0
|
80
105
|
version: "0"
|
81
|
-
version:
|
82
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
83
108
|
requirements:
|
84
109
|
- - ">="
|
85
110
|
- !ruby/object:Gem::Version
|
111
|
+
hash: 3
|
112
|
+
segments:
|
113
|
+
- 0
|
86
114
|
version: "0"
|
87
|
-
version:
|
88
115
|
requirements: []
|
89
116
|
|
90
117
|
rubyforge_project:
|
91
|
-
rubygems_version: 1.3.
|
118
|
+
rubygems_version: 1.3.7
|
92
119
|
signing_key:
|
93
120
|
specification_version: 3
|
94
121
|
summary: GridFS made simple.
|
@@ -96,6 +123,8 @@ test_files:
|
|
96
123
|
- test/attachment_test.rb
|
97
124
|
- test/has_attachment_test.rb
|
98
125
|
- test/models.rb
|
126
|
+
- test/mongo_mapper_models.rb
|
127
|
+
- test/processor_test.rb
|
99
128
|
- test/style_test.rb
|
100
129
|
- test/test_helper.rb
|
101
130
|
- test/upfile_test.rb
|
data/README.rdoc
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
= griddle
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Note on Patches/Pull Requests
|
6
|
-
|
7
|
-
* Fork the project.
|
8
|
-
* Make your feature addition or bug fix.
|
9
|
-
* Add tests for it. This is important so I don't break it in a
|
10
|
-
future version unintentionally.
|
11
|
-
* Commit, do not mess with rakefile, version, or history.
|
12
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
-
* Send me a pull request. Bonus points for topic branches.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2010 Matt Matt san Mongeau. See LICENSE for details.
|