imagery 1.0.0.rc2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 617d676eaacd1c4f9d90ef5f091c133be23b7046
4
+ data.tar.gz: 73c33e7af9d03b6c049d8821e01630bc788a694d
5
+ SHA512:
6
+ metadata.gz: 8803b9dab1271092fdcc1a559488796f7e5eaaafd6becb14aad8f72dd6be0e42e19283c00e7831dfd83cbceefac91dc94e2b86590fa6eb34b003205da1663188
7
+ data.tar.gz: d31402d450fed4979743ede359de64195a68a9be0f5c21a4f6152fdda61b7d6252b08839a2759707f10667fbf462e325b345f90ae41cc02bffda8eb6022e134b
@@ -1,211 +1,76 @@
1
1
  Imagery
2
2
  =======
3
3
 
4
- ## Image manipulation should be simple. It should be customizable. It should allow for flexibility. Imagery attempts to solve these.
5
-
6
- ### Imagery favors:
7
-
8
- 1. Simplicity and explicitness over magic DSLs.
9
- 2. OOP principles such as inheritance and composition.
10
- 3. Flexibility and extensibility.
11
- 4. Not being tied to any form of ORM.
12
-
13
- 1. Simplicity and Explicitness
14
- ------------------------------
15
- To get started using Imagery you only need GraphicsMagick, ruby and Imagery of
16
- course.
17
-
18
- # on debian based systems
19
- sudo apt-get install graphicsmagick
20
- # or maybe using homebrew
21
- brew install graphicsmagick
22
- [sudo] gem install imagery
23
-
24
- Then you may proceed using it.
25
-
26
- require 'rubygems'
27
- require 'imagery'
28
-
29
- i = Imagery.new(:photo, "1001", thumb: ["48x48^", "48x48"])
30
- i.save(File.open('/some/path/to/image.jpg'))
31
-
32
- File.exist?('public/photo/1001/thumb.jpg')
33
- # => true
34
-
35
- File.exist?('public/photo/1001/original.jpg')
36
- # => true
37
-
38
- 2. OOP Principles (that we already know)
39
- ----------------------------------------
40
-
41
- ### Ohm example (See [http://ohm.keyvalue.org](http://ohm.keyvalue.org))
42
-
43
- class User < Ohm::Model
44
- include Ohm::Callbacks
45
-
46
- after :save, :write_avatar
47
-
48
- def avatar=(fp)
49
- @avatar_fp = fp
50
- end
51
-
52
- def avatar
53
- Imagery.new :avatar, id,
54
- :thumb => ["48x48^", "48x48"],
55
- :medium => ["120x120"]
56
- end
57
-
58
- protected
59
- def write_avatar
60
- avatar.save(@avatar_fp[:tempfile]) if @avatar_fp
61
- end
62
- end
63
-
64
- # Since we're using composition, we can customize the dimensions on an
65
- # instance level.
66
- class Collage < Ohm::Model
67
- attribute :width
68
- attribute :height
69
-
70
- def photo
71
- Imagery.new :photo, id, :thumb => ["%sx%s" % [width, height]]
72
- end
73
- end
74
-
75
- # For cases where we want to use S3 for some and normal filesystem for others
76
- class S3Photo < Imagery
77
- include Imagery::S3
78
-
79
- s3_bucket "my-bucket"
80
- end
81
-
82
- # then maybe some other files are using cloudfront
83
- class CloudfrontPhoto < Imagery
84
- include Imagery::S3
85
-
86
- s3_bucket "my-bucket"
87
- s3_distribution_domain "assets.site.com"
88
- end
89
-
90
- # some might be using S3 EU, in which case you can specify the s3_host
91
- class CustomS3Host < Imagery::Model
92
- include Imagery::S3
93
- s3_host "http://my.custom.host"
94
- s3_bucket "my-bucket-name"
95
- end
96
-
97
- 3. Flexibility and Extensibility
98
- --------------------------------
99
- ### Existing plugins: Faking and S3
100
-
101
- #### Imagery::S3
102
-
103
- As was shown in some examples above you can easily do S3 integration.
104
- The access credentials are assumed to be stored in
105
-
106
- ENV["AMAZON_ACCESS_KEY_ID"]
107
- ENV["AMAZON_SECRET_ACCESS_KEY"]
108
-
109
- you can do this by setting it on your .bash_profile / .bashrc or just
110
- manually setting them somewhere in your appication
111
-
112
- ENV["AMAZON_ACCESS_KEY_ID"] = "_access_key_id_"
113
- ENV["AMAZON_SECRET_ACCESS_KEY"] = "_secret_access_key_"
114
-
115
- Now you can just start using it:
116
-
117
- class Imagery
118
- include Imagery::S3
119
- s3_bucket "my-bucket"
120
- end
121
-
122
- i = Imagery.new :photo, 1001
123
- i.save(File.open("/some/path/to/image.jpg"))
124
-
125
- #### Imagery::Faking
126
-
127
- When doing testing, you definitely don't want to run image
128
- resizing everytime. Enter Faking.
129
-
130
- # in your test_helper / spec_helper
131
- Imagery::Model.send :include, Imagery::Faking
132
- Imagery::Model.mode = :fake
133
-
134
- # but what if we want to run it for real on a case to case basis?
135
- # sure we can!
136
- Imagery::Model.real {
137
- # do some imagery testing here
138
- }
139
-
140
- #### Imagery::Test
141
-
142
- There is a module you can include in your test context to automate the pattern
143
- of testing / faking on an opt-in basis.
144
-
145
- # in your test_helper / spec_helper
146
- class Test::Unit::TestCase
147
- include Imagery::Test
148
- end
149
-
150
- # now when you do some testing... (User assumes the user example above)
151
- imagery do |enabled|
152
- user = User.new(:avatar => { tempfile: File.open("avatar.jpg") })
153
- user.save
154
-
155
- if enabled
156
- assert File.exist?(user.avatar.root("original.jpg"))
157
- end
158
- end
159
-
160
- Running your test suite:
161
-
162
- REAL_IMAGERY=true rake test
163
-
164
- It's off by default though, so you don't have to do anything to make sure
165
- Imagery doesn't run.
166
-
167
- ### Extending Imagery
168
- By making use of standard Ruby idioms, we can easily do lots with it.
169
- Exensibility is addressed via Ruby modules for example:
170
-
171
- class Imagery
172
- module MogileStore
173
- def self.included(base)
174
- class << base
175
- attr_accessor :mogile_config
176
- end
177
- end
178
-
179
- def save(io)
180
- if super
181
- # do some mogie FS stuff here
182
- end
183
- end
184
-
185
- def delete
186
- super
187
- # remove the mogile stuff here
188
- end
189
- end
190
- end
191
-
192
- # Now just include the module to use it.
193
- class Imagery
194
- include Imagery::MogileStore
195
- self.mogile_config = { :foo => :bar }
196
- end
197
-
198
-
199
- ### Note on Patches/Pull Requests
200
-
201
- * Fork the project.
202
- * Make your feature addition or bug fix.
203
- * Add tests for it. This is important so I don't break it in a
204
- future version unintentionally.
205
- * Commit, do not mess with rakefile, version, or history.
206
- (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)
207
- * Send me a pull request. Bonus points for topic branches.
208
-
209
- ### Copyright
4
+ Simple image resizing module.
5
+
6
+ ## Prerequisites
7
+
8
+ You should have graphicsmagick first:
9
+
10
+ ```bash
11
+ # on debian based systems
12
+ $ sudo apt-get install graphicsmagick
13
+
14
+ # or maybe using homebrew
15
+ $ brew install graphicsmagick
16
+ ```
17
+
18
+ ## Installing
19
+
20
+ ```bash
21
+ $ gem install imagery
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ```ruby
27
+ require 'imagery'
28
+
29
+ # - 48x48^ is the geometry string. This means we're resizing
30
+ # to a 48x48^ constrained image
31
+ # - 48x48 (second one) means we're cropping the image to an
32
+ # extent of 48x48 pixels.
33
+ i = Imagery.new(:photo, "1001", thumb: ["48x48^", "48x48"])
34
+ i.save(File.open('/some/path/to/image.jpg'))
35
+
36
+ File.exist?('public/photo/1001/thumb.jpg')
37
+ # => true
38
+
39
+ File.exist?('public/photo/1001/original.jpg')
40
+ # => true
41
+ ```
42
+
43
+ ## Advanced Usage (S3)
44
+
45
+ For cases where we want to use S3 for some and normal filesystem for others.
46
+
47
+ ```ruby
48
+ class S3Photo < Imagery
49
+ include Imagery::S3
50
+
51
+ s3_bucket "my-bucket"
52
+ end
53
+
54
+ # then maybe some other files are using cloudfront
55
+ class CloudfrontPhoto < Imagery
56
+ include Imagery::S3
57
+
58
+ s3_bucket "my-bucket"
59
+ s3_distribution_domain "assets.site.com"
60
+ end
61
+
62
+ # some might be using S3 EU, in which case you can specify the s3_host
63
+ class CustomS3Host < Imagery::Model
64
+ include Imagery::S3
65
+ s3_host "http://my.custom.host"
66
+ s3_bucket "my-bucket-name"
67
+ end
68
+ ```
69
+
70
+ ## Extending
71
+
72
+ You can check `Imagery::S3` to see an example of an extension.
73
+
74
+ ## Copyright
210
75
 
211
76
  Copyright (c) 2010 Cyril David. See LICENSE for details.
@@ -1,10 +1,10 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "imagery"
3
- s.version = "1.0.0.rc2"
4
- s.summary = "POROS + GraphicsMagick."
3
+ s.version = "1.0.0"
4
+ s.summary = "Simple image resizing"
5
5
  s.description = "Clean & light interface around GraphicsMagick."
6
6
  s.authors = ["Cyril David"]
7
- s.email = ["me@cyrildavid.com"]
7
+ s.email = ["cyx@cyx.is"]
8
8
  s.homepage = "http://github.com/cyx/imagery"
9
9
 
10
10
  s.files = Dir[
@@ -131,8 +131,9 @@ class Imagery
131
131
  module GM
132
132
  # -size tells GM to only read from a given dimension.
133
133
  # -resize is the target dimension, and understands geometry strings.
134
- # -quality we force it to 80, which is very reasonable and practical.
135
- CONVERT = "gm convert -size '%s' '%s' -resize '%s' %s -quality 80 '%s'"
134
+ # -quality we force it to 90, which is a bit aggressive, but
135
+ # we want beautiful photos don't we? :-)
136
+ CONVERT = "gm convert -size '%s' '%s' -resize '%s' %s -quality 90 '%s'"
136
137
 
137
138
  # 2 is the file descriptor for stderr, which `gm identify`
138
139
  # happily chucks out information to, regardless if the image
data/makefile CHANGED
@@ -1,2 +1,7 @@
1
1
  test:
2
- cutest tests/*.rb
2
+ cutest tests/*_test.rb
3
+
4
+ tests/%: .PHONY
5
+ cutest $@
6
+
7
+ .PHONY:
File without changes
@@ -20,7 +20,7 @@ end
20
20
 
21
21
  test "changes url to an S3 hosted one" do
22
22
  i = Imagery.new(:avatar)
23
-
23
+
24
24
  expect = "http://s3.amazonaws.com/cdn.site.com/missing/avatar/original.jpg"
25
25
  assert_equal expect, i.url
26
26
  end
@@ -30,7 +30,7 @@ test "allows an s3_host override" do
30
30
  Imagery.s3_host "https://foo.com"
31
31
 
32
32
  i = Imagery.new(:avatar)
33
-
33
+
34
34
  expect = "https://foo.com/cdn.site.com/missing/avatar/original.jpg"
35
35
  assert_equal expect, i.url
36
36
  ensure
@@ -41,7 +41,7 @@ end
41
41
  test "allows a distribution domain for cloudfront hosted buckets" do
42
42
  begin
43
43
  Imagery.s3_distribution_domain "https://cdn.site.com"
44
-
44
+
45
45
  i = Imagery.new(:avatar)
46
46
  expect = "https://cdn.site.com/missing/avatar/original.jpg"
47
47
  assert_equal expect, i.url
@@ -68,7 +68,7 @@ scope do
68
68
 
69
69
  test "saves all sizes to S3" do |im, io|
70
70
  im.save(io)
71
-
71
+
72
72
  cmds = Imagery::S3::Gateway.commands
73
73
 
74
74
  assert_equal [:store, "avatar/1001/original.jpg", "buck"], cmds.shift
@@ -80,7 +80,7 @@ scope do
80
80
 
81
81
  test "doesn't delete when passing same id" do |im, io|
82
82
  im.save(io, "1001")
83
-
83
+
84
84
  cmds = Imagery::S3::Gateway.commands
85
85
 
86
86
  assert_equal [:store, "avatar/1001/original.jpg", "buck"], cmds.shift
@@ -92,7 +92,7 @@ scope do
92
92
 
93
93
  test "deletes when passing a different id" do |im, io|
94
94
  im.save(io, "1002")
95
-
95
+
96
96
  cmds = Imagery::S3::Gateway.commands
97
97
 
98
98
  assert_equal [:delete, "avatar/1001/original.jpg", "buck"], cmds.shift
metadata CHANGED
@@ -1,51 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imagery
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc2
5
- prerelease: 6
4
+ version: 1.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Cyril David
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-07-04 00:00:00.000000000 Z
11
+ date: 2013-09-22 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: cutest
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: aws-s3
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  description: Clean & light interface around GraphicsMagick.
47
42
  email:
48
- - me@cyrildavid.com
43
+ - cyx@cyx.is
49
44
  executables: []
50
45
  extensions: []
51
46
  extra_rdoc_files: []
@@ -53,37 +48,33 @@ files:
53
48
  - LICENSE
54
49
  - README.markdown
55
50
  - makefile
56
- - lib/imagery/faking.rb
57
51
  - lib/imagery/s3.rb
58
- - lib/imagery/test.rb
59
52
  - lib/imagery.rb
60
53
  - imagery.gemspec
61
- - tests/faking.rb
62
54
  - tests/helper.rb
63
- - tests/imagery.rb
64
- - tests/s3.rb
55
+ - tests/imagery_test.rb
56
+ - tests/s3_test.rb
65
57
  homepage: http://github.com/cyx/imagery
66
58
  licenses: []
59
+ metadata: {}
67
60
  post_install_message:
68
61
  rdoc_options: []
69
62
  require_paths:
70
63
  - lib
71
64
  required_ruby_version: !ruby/object:Gem::Requirement
72
- none: false
73
65
  requirements:
74
- - - ! '>='
66
+ - - '>='
75
67
  - !ruby/object:Gem::Version
76
68
  version: '0'
77
69
  required_rubygems_version: !ruby/object:Gem::Requirement
78
- none: false
79
70
  requirements:
80
- - - ! '>'
71
+ - - '>='
81
72
  - !ruby/object:Gem::Version
82
- version: 1.3.1
73
+ version: '0'
83
74
  requirements: []
84
75
  rubyforge_project:
85
- rubygems_version: 1.8.23
76
+ rubygems_version: 2.0.3
86
77
  signing_key:
87
- specification_version: 3
88
- summary: POROS + GraphicsMagick.
78
+ specification_version: 4
79
+ summary: Simple image resizing
89
80
  test_files: []
@@ -1,90 +0,0 @@
1
- class Imagery
2
- module Faking
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- # Allows you to define the current mode. The only special value here is
9
- # `:fake`. If the mode is :fake, then Imagery::Model#save and
10
- # Imagery::Model#delete will not actually run.
11
- #
12
- # @example
13
- #
14
- # Photo = Class.new(Struct.new(:id))
15
- #
16
- # i = Imagery.new(Photo.new(1001))
17
- # i.root = '/tmp'
18
- #
19
- # Imagery::Model.faked {
20
- # assert i.save(File.open('/path/to/image.png'))
21
- # }
22
- #
23
- # @see Imagery::Test
24
- #
25
- attr_accessor :mode
26
-
27
- # Switches the current mode to :fake.
28
- #
29
- # @example
30
- # Imagery::Model.mode == nil
31
- # # => true
32
- #
33
- # Imagery::Model.faked {
34
- # Imagery::Model.mode == :fake
35
- # # => true
36
- # }
37
- #
38
- # Imagery::Model.mode = nil
39
- # # => true
40
- #
41
- def faked
42
- @omode, @mode = @mode, :fake
43
- yield
44
- ensure
45
- @mode = @omode
46
- end
47
-
48
- # Switches the current mode to nil. Useful for forcing real saves
49
- # in your test.
50
- #
51
- # You should do this at least once in your project just to know
52
- # that all your Imagery::Model#save and Imagery::Model#delete
53
- # operations actually work.
54
- #
55
- # @example
56
- # Imagery::Model.mode = :fake
57
- #
58
- # Imagery::Model.faked {
59
- # Imagery::Model.mode == nil
60
- # # => true
61
- # }
62
- #
63
- # Imagery::Model.mode = :fake
64
- # # => true
65
- #
66
- def real
67
- @omode, @mode = @mode, nil
68
- yield
69
- ensure
70
- @mode = @omode
71
- end
72
- end
73
-
74
- # Implement the stubbed version of save and skips actual operation
75
- # if Imagery::Model.mode == :fake
76
- def save(io, key = nil)
77
- return true if self.class.mode == :fake
78
-
79
- super
80
- end
81
-
82
- # Implement the stubbed version of save and skips actual operation
83
- # if Imagery::Model.mode == :fake
84
- def delete
85
- return true if self.class.mode == :fake
86
-
87
- super
88
- end
89
- end
90
- end
@@ -1,17 +0,0 @@
1
- class Imagery
2
- module Test
3
- def self.included(base)
4
- Imagery.send :include, Imagery::Faking
5
- Imagery.mode = :fake
6
- end
7
-
8
- protected
9
- def imagery
10
- if ENV["REAL_IMAGERY"]
11
- Imagery.real { yield true }
12
- else
13
- Imagery.faked { yield false }
14
- end
15
- end
16
- end
17
- end
@@ -1,71 +0,0 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
2
- require "stringio"
3
-
4
- # Imagery::Test hooks
5
- scope do
6
- setup do
7
- Object.send :include, Imagery::Test
8
- end
9
-
10
- test "auto-includes Imagery::Faking upon inclusion" do
11
- assert Imagery.ancestors.include?(Imagery::Faking)
12
- end
13
-
14
- test "auto-sets mode to :fake" do
15
- assert_equal :fake, Imagery.mode
16
- end
17
- end
18
-
19
-
20
- class Imagery
21
- include Faking
22
- end
23
-
24
- test "skips saving when faked" do
25
- Imagery.mode = :fake
26
-
27
- i = Imagery.new(:avatar, "1001")
28
- i.save(StringIO.new)
29
-
30
- assert ! File.exist?(Imagery.root("avatar", "1001"))
31
- end
32
-
33
- test "skips deleting when faked" do
34
- Imagery.mode = :fake
35
-
36
- FileUtils.mkdir_p(Imagery.root("avatar", "1001"))
37
-
38
- i = Imagery.new(:avatar, "1001")
39
- i.delete
40
-
41
- assert File.exist?(Imagery.root("avatar", "1001"))
42
- end
43
-
44
- # Imagery::Test
45
- scope do
46
- extend Imagery::Test
47
-
48
- test "yields true when REAL_IMAGERY is set" do
49
- ENV["REAL_IMAGERY"] = "true"
50
-
51
- enabled = nil
52
-
53
- imagery do |e|
54
- enabled = e
55
- end
56
-
57
- assert enabled
58
- end
59
-
60
- test "yields false when REAL_IMAGERY is not set" do
61
- ENV["REAL_IMAGERY"] = nil
62
-
63
- enabled = nil
64
-
65
- imagery do |e|
66
- enabled = e
67
- end
68
-
69
- assert_equal false, enabled
70
- end
71
- end