couch_photo 0.0.5 → 0.0.6
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 +46 -2
- data/VERSION +1 -0
- data/couch_photo.gemspec +19 -0
- data/lib/couch_photo/couch_photo.rb +57 -7
- data/lib/couch_photo/variations.rb +27 -5
- metadata +81 -24
data/README.markdown
CHANGED
@@ -116,13 +116,19 @@ Let's go back to our original image example:
|
|
116
116
|
i.save
|
117
117
|
|
118
118
|
We can access our variations in one of three ways:
|
119
|
-
- the `variations` method, which
|
119
|
+
- the `variations` method, which will allow you to iterate over the variation_name/variation pairs via the `each` method
|
120
120
|
- the `variation.<variation_name>` method, which returns a specific variation
|
121
121
|
- the `variation("<variation_name>")`, which also returns a specific variation
|
122
122
|
|
123
123
|
For example:
|
124
124
|
|
125
|
-
i.variations
|
125
|
+
i.variations.each do |variation_name, variation_image|
|
126
|
+
puts variation_name
|
127
|
+
puts variation.name
|
128
|
+
puts variation.filename
|
129
|
+
# etc...
|
130
|
+
end
|
131
|
+
|
126
132
|
i.variation.small
|
127
133
|
i.variation "large"
|
128
134
|
|
@@ -135,3 +141,41 @@ Once you've got a variation, you can call several methods on it:
|
|
135
141
|
i.variation.small.filetype # ==> "jpg"
|
136
142
|
i.variation.small.mimetype # ==> "image/jpg"
|
137
143
|
i.variation.small.data # ==> BINARY BLOB
|
144
|
+
|
145
|
+
## Creating Custom Variations
|
146
|
+
|
147
|
+
If you'd like to add a variation to your image document that's not predefined / autogenerated, you can use the add_variation method:
|
148
|
+
|
149
|
+
i = Image.new
|
150
|
+
i.original = "somefile.jpg"
|
151
|
+
i.add_variation "variation_name.jpg", :file => "filename.jpg"
|
152
|
+
i.add_variation "variation/name.jpg", :blob => File.read("filename.jpg")
|
153
|
+
|
154
|
+
These images would be accessible via the following urls :
|
155
|
+
|
156
|
+
http://your_couch_server/your_image_database/somefile.jpg/original.jpg
|
157
|
+
http://your_couch_server/your_image_database/somefile.jpg/variations/variation_name.jpg
|
158
|
+
http://your_couch_server/your_image_database/somefile.jpg/variations/variation/name.jpg
|
159
|
+
|
160
|
+
## XMP Metadata
|
161
|
+
Need to access XMP Metadata? It's as simple as adding xmp_metadata! into your document definition.
|
162
|
+
|
163
|
+
class Image < CouchRest::Model::Base
|
164
|
+
use_database IMAGE_DB
|
165
|
+
include CouchPhoto
|
166
|
+
|
167
|
+
xmp_metadata!
|
168
|
+
override_id! # the id of the document will be the basename of the original image file
|
169
|
+
|
170
|
+
variations do
|
171
|
+
small "20x20"
|
172
|
+
medium "100x100"
|
173
|
+
large "500x500"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
i = Image.new
|
178
|
+
i.original = "avatar.jpg"
|
179
|
+
i.save
|
180
|
+
|
181
|
+
Now you can access your image's XMP metadata by calling i.metadata.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.6
|
data/couch_photo.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "couch_photo"
|
3
|
+
s.version = File.read "VERSION"
|
4
|
+
s.authors = "Matt Parker"
|
5
|
+
s.homepage = "http://github.com/moonmaster9000/couch_photo"
|
6
|
+
s.summary = "A handy Ruby mixin for managing images in CouchDB / couchrest_model"
|
7
|
+
s.description = "Manage an image and all of its variations and xmp metadata in a single document."
|
8
|
+
s.email = "moonmaster9000@gmail.com"
|
9
|
+
s.files = Dir["lib/**/*"] << "VERSION" << "README.markdown" << "couch_photo.gemspec"
|
10
|
+
s.test_files = Dir["feature/**/*"]
|
11
|
+
|
12
|
+
s.add_development_dependency "cucumber"
|
13
|
+
s.add_development_dependency "rspec"
|
14
|
+
s.add_development_dependency "couchrest_model_config"
|
15
|
+
|
16
|
+
s.add_dependency "couchrest", "1.0.1"
|
17
|
+
s.add_dependency "mini_magick"
|
18
|
+
s.add_dependency "couchrest_model", "~> 1.0.0"
|
19
|
+
end
|
@@ -13,8 +13,7 @@ module CouchPhoto
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def variations
|
16
|
-
@variations
|
17
|
-
@variations.variations.values
|
16
|
+
@variations = Variations.new self
|
18
17
|
end
|
19
18
|
|
20
19
|
def original
|
@@ -27,15 +26,30 @@ module CouchPhoto
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def variation(variation_name=nil)
|
30
|
-
variation_name ?
|
29
|
+
variation_name ? variations.send(variation_name) : variations
|
31
30
|
end
|
32
31
|
|
33
32
|
def original=(*args)#filepath, blob=nil
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
if args[0].kind_of?(Array)
|
34
|
+
filepath, blob = args[0].first, args[0].last
|
35
|
+
else
|
36
|
+
filepath = args[0]
|
37
|
+
blob = nil
|
38
|
+
end
|
39
|
+
image_format = filetype(filepath)
|
40
|
+
filename = File.basename filepath
|
41
|
+
basename = File.basename(filepath, "." + "#{image_format}")
|
42
|
+
|
43
|
+
if self.class.xmp_metadata?
|
44
|
+
File.open(filepath, 'w') { |f| f.write blob } if !blob.nil?
|
45
|
+
`convert #{filepath} /tmp/#{basename}.xmp`
|
46
|
+
self.metadata = Hash.from_xml File.read("/tmp/#{basename}.xmp")
|
47
|
+
File.delete("/tmp/#{basename}.xmp")
|
48
|
+
end
|
49
|
+
|
50
|
+
self["_id"] = filename if self.class.override_id?
|
51
|
+
self.original_filename = filename
|
37
52
|
blob ||= File.read filepath
|
38
|
-
image_format = filepath.match(/^.*\.([^\.]*)$/)[1]
|
39
53
|
attachment_name = "original.#{image_format}"
|
40
54
|
attachment = {:name => attachment_name, :file => Attachment.new(blob, attachment_name)}
|
41
55
|
update_or_create_attachment attachment
|
@@ -43,6 +57,20 @@ module CouchPhoto
|
|
43
57
|
update_or_create_attachment :name => "variations/#{variation_name}.#{image_format}", :file => Attachment.new(variation_blob, attachment_name)
|
44
58
|
end
|
45
59
|
end
|
60
|
+
|
61
|
+
def add_variation(variation_name, opt={})
|
62
|
+
if opt[:file]
|
63
|
+
blob = File.read("#{opt[:file]}")
|
64
|
+
elsif opt[:blob]
|
65
|
+
blob = opt[:blob]
|
66
|
+
end
|
67
|
+
update_or_create_attachment :name => "variations/#{variation_name}", :file => Attachment.new(blob, variation_name)
|
68
|
+
variations.add_variation variation_name
|
69
|
+
end
|
70
|
+
|
71
|
+
def filetype(filename)
|
72
|
+
filename.match(/^.*\.([^\.]*)$/)[1]
|
73
|
+
end
|
46
74
|
|
47
75
|
module ClassMethods
|
48
76
|
def variations(&block)
|
@@ -53,6 +81,15 @@ module CouchPhoto
|
|
53
81
|
def override_id!
|
54
82
|
@override_id = true
|
55
83
|
end
|
84
|
+
|
85
|
+
def xmp_metadata!
|
86
|
+
@xmp_metadata = true
|
87
|
+
self.property :metadata, Hash
|
88
|
+
end
|
89
|
+
|
90
|
+
def xmp_metadata?
|
91
|
+
@xmp_metadata
|
92
|
+
end
|
56
93
|
|
57
94
|
def override_id?
|
58
95
|
@override_id
|
@@ -62,4 +99,17 @@ module CouchPhoto
|
|
62
99
|
@variation_definitions ||= VariationDefinitions.new
|
63
100
|
end
|
64
101
|
end
|
102
|
+
|
103
|
+
module_function
|
104
|
+
def variation_short_name(variation_path)
|
105
|
+
variation_path.gsub(/(?:variations\/)?(.+)\.[^\.]+/) {$1}
|
106
|
+
end
|
107
|
+
|
108
|
+
def variation_short_name_from_path(variation_path)
|
109
|
+
variation_path.gsub(/(?:variations\/)?(.+)/) {$1}
|
110
|
+
end
|
111
|
+
|
112
|
+
def variation_file_extension(variation_path)
|
113
|
+
variation_path.gsub(/(?:variations\/)?.+\.([^\.]+)/) {$1}
|
114
|
+
end
|
65
115
|
end
|
@@ -1,5 +1,9 @@
|
|
1
1
|
module CouchPhoto
|
2
|
+
|
3
|
+
|
2
4
|
class VariationDefinitions
|
5
|
+
attr_reader :variations
|
6
|
+
|
3
7
|
def initialize
|
4
8
|
@variations = {}
|
5
9
|
end
|
@@ -38,21 +42,39 @@ module CouchPhoto
|
|
38
42
|
end
|
39
43
|
|
40
44
|
class Variations
|
41
|
-
attr_reader :variations
|
45
|
+
attr_reader :variations, :document
|
42
46
|
|
43
47
|
def initialize(document)
|
48
|
+
@document = document
|
44
49
|
@variations = {}
|
45
50
|
attachments = document["_attachments"] || {}
|
46
51
|
attachments.keys.select {|name| name.match /variations\//}.each do |variation_name|
|
47
|
-
|
48
|
-
|
52
|
+
if document.class.variation_definitions.variations.keys.include?(CouchPhoto.variation_short_name(variation_name).to_sym)
|
53
|
+
variation_key = CouchPhoto.variation_short_name(variation_name)
|
54
|
+
else
|
55
|
+
variation_key = CouchPhoto.variation_short_name_from_path(variation_name)
|
56
|
+
end
|
57
|
+
@variations[variation_key] = Variation.new document, variation_name
|
49
58
|
end
|
50
59
|
end
|
60
|
+
|
61
|
+
def each(&block)
|
62
|
+
@variations.each &block
|
63
|
+
end
|
64
|
+
|
65
|
+
def count
|
66
|
+
attachments = self.document["_attachments"] || {}
|
67
|
+
attachments.keys.count {|name| name.match /variations\//}
|
68
|
+
end
|
51
69
|
|
52
70
|
def method_missing(method_name, *args, &block)
|
53
71
|
raise "Unknown variation '#{method_name}'" unless @variations[method_name.to_s]
|
54
72
|
@variations[method_name.to_s]
|
55
73
|
end
|
74
|
+
|
75
|
+
def add_variation(variation_name)
|
76
|
+
@variations[variation_name] = Variation.new document, "variations/#{variation_name}"
|
77
|
+
end
|
56
78
|
end
|
57
79
|
|
58
80
|
class Variation
|
@@ -62,11 +84,11 @@ module CouchPhoto
|
|
62
84
|
@path = "/" + [document.database.name, document.id, attachment_name].join("/")
|
63
85
|
@url = [document.database.to_s, document.id, attachment_name].join "/"
|
64
86
|
@attachment_name = attachment_name
|
65
|
-
@name =
|
87
|
+
@name = CouchPhoto.variation_short_name attachment_name
|
66
88
|
@filename = attachment_name
|
67
89
|
@basename = File.basename attachment_name
|
68
90
|
@document = document
|
69
|
-
@filetype =
|
91
|
+
@filetype = CouchPhoto.variation_file_extension attachment_name
|
70
92
|
@mimetype = document["_attachments"][attachment_name]["content_type"]
|
71
93
|
end
|
72
94
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couch_photo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 6
|
10
|
+
version: 0.0.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matt Parker
|
@@ -15,55 +15,112 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
19
|
-
default_executable:
|
18
|
+
date: 2011-09-16 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
21
|
+
name: cucumber
|
23
22
|
prerelease: false
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
25
|
requirements:
|
27
|
-
- -
|
26
|
+
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rspec
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
30
43
|
segments:
|
31
|
-
- 1
|
32
44
|
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: couchrest_model_config
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
33
58
|
- 0
|
34
|
-
version:
|
59
|
+
version: "0"
|
60
|
+
type: :development
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: couchrest
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - "="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 21
|
71
|
+
segments:
|
72
|
+
- 1
|
73
|
+
- 0
|
74
|
+
- 1
|
75
|
+
version: 1.0.1
|
35
76
|
type: :runtime
|
36
|
-
version_requirements: *
|
77
|
+
version_requirements: *id004
|
37
78
|
- !ruby/object:Gem::Dependency
|
38
79
|
name: mini_magick
|
39
80
|
prerelease: false
|
40
|
-
requirement: &
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
type: :runtime
|
91
|
+
version_requirements: *id005
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: couchrest_model
|
94
|
+
prerelease: false
|
95
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
41
96
|
none: false
|
42
97
|
requirements:
|
43
98
|
- - ~>
|
44
99
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
100
|
+
hash: 23
|
46
101
|
segments:
|
47
|
-
- 3
|
48
102
|
- 1
|
49
|
-
|
103
|
+
- 0
|
104
|
+
- 0
|
105
|
+
version: 1.0.0
|
50
106
|
type: :runtime
|
51
|
-
version_requirements: *
|
52
|
-
description:
|
107
|
+
version_requirements: *id006
|
108
|
+
description: Manage an image and all of its variations and xmp metadata in a single document.
|
53
109
|
email: moonmaster9000@gmail.com
|
54
110
|
executables: []
|
55
111
|
|
56
112
|
extensions: []
|
57
113
|
|
58
|
-
extra_rdoc_files:
|
59
|
-
|
114
|
+
extra_rdoc_files: []
|
115
|
+
|
60
116
|
files:
|
61
|
-
- lib/couch_photo.rb
|
62
117
|
- lib/couch_photo/attachment.rb
|
63
118
|
- lib/couch_photo/couch_photo.rb
|
64
119
|
- lib/couch_photo/variations.rb
|
120
|
+
- lib/couch_photo.rb
|
121
|
+
- VERSION
|
65
122
|
- README.markdown
|
66
|
-
|
123
|
+
- couch_photo.gemspec
|
67
124
|
homepage: http://github.com/moonmaster9000/couch_photo
|
68
125
|
licenses: []
|
69
126
|
|
@@ -93,9 +150,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
150
|
requirements: []
|
94
151
|
|
95
152
|
rubyforge_project:
|
96
|
-
rubygems_version: 1.
|
153
|
+
rubygems_version: 1.8.10
|
97
154
|
signing_key:
|
98
155
|
specification_version: 3
|
99
|
-
summary:
|
156
|
+
summary: A handy Ruby mixin for managing images in CouchDB / couchrest_model
|
100
157
|
test_files: []
|
101
158
|
|