imager 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,17 +1,17 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in Imager.gemspec
4
- gemspec
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in Imager.gemspec
4
+ gemspec
@@ -1,22 +1,22 @@
1
- Copyright (c) 2013 TODO: Write your name
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2013 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,92 +1,104 @@
1
- # Imager
2
-
3
- Use with [ImagerServer](https://github.com/guilherme-otran/ImagerServer), a storange and resizer server for images.
4
- Check the test directory for know how the server works.
5
- You can save your images in other domain running ImagerServer.
6
-
7
- [![Build Status](https://travis-ci.org/guilherme-otran/Imager.png?branch=master)](https://travis-ci.org/guilherme-otran/Imager)
8
- [![Dependency Status](https://gemnasium.com/guilherme-otran/Imager.png)](https://gemnasium.com/guilherme-otran/Imager)
9
-
10
- ## Please contribute!
11
- A lot of the features are not implemented yet (except for the server)
12
-
13
- 1. Fork it
14
- 2. Create your feature branch (`git checkout -b my-new-feature`)
15
- 3. Commit your changes (`git commit -am 'Add some feature'`)
16
- 4. Push to the branch (`git push origin my-new-feature`)
17
- 5. Create new Pull Request
18
-
19
- ## Installation
20
-
21
- Add this line to your application's Gemfile:
22
-
23
- gem 'imager'
24
-
25
- And then execute:
26
-
27
- $ bundle
28
-
29
- Or install it yourself as:
30
-
31
- $ gem install imager
32
-
33
- ## Usage
34
-
35
- Imager.configure do |c|
36
- c.base_uri = "http://files.myserver.com"
37
- c.manager_path = "manager"
38
- c.collections_path = "images"
39
- c.auth_code = ""
40
- end
41
-
42
- c.auth_code is the `$YOUR_AUTH_CODE = '';` you setted in the [server] (https://github.com/guilherme-otran/ImagerServer).
43
- This is for post and delete authentication (manager).
44
-
45
- ### Sending the images
46
-
47
- Imager::ServerInterface.post("Collection", "Album", "test/image.png", small: { width: 100 })
48
-
49
- ### Removing the images
50
-
51
- Imager::ServerInterface.delete("Collection", "Album", "image")
52
-
53
- ### Using the images
54
-
55
- Imager::LinkHelper.link_for("Collection", "Album", "image", :small)
56
-
57
- Will return:
58
- "http://files.myserver.com/images/collection/album/image/small.jpg"
59
- Since the server ALWAYS save the images as jpg.
60
-
61
- You can use Collection as model name(product) and album as id(1) and get the result:
62
-
63
- "http://files.myserver.com/images/product/1/image/small.jpg"
64
- Just save as:
65
- `Imager::ServerInterface.post("product", "1", "test/image.png", small: { width: 100 })`
66
-
67
- ## Notes about saving and sizes
68
- Saving first as `"product", "1", "test/image.png", small: { width: 100 })` and after `"product", "1", "test/otherimage.png", small: { width: 90 })` don't changes the size of image. Beware!
69
-
70
- ### Sizes Explain:
71
- The server accepts the following combinations:
72
-
73
- ```
74
- YourSizeName: { width: 100 } # Will resize (maintein main aspect) the image for 100px of width
75
- YourSizeName: { height: 100 } # Will resize (maintein main aspect) the image for 100px of height
76
- YourSizeName: { width: 100, height: 150 } # Will resize to fit in 100x150 px
77
- YourSizeName: { original: :original } # Will save the original size. Don't worry. The server compress to 50% of quality.
78
- ```
79
-
80
- You can have many sizes when posting a image:
81
-
82
- ```
83
- sizes = [
84
- small: { width: 100 }
85
- gallery: { height: 300 }
86
- mini-home: { width: 50, height: 50 }
87
- original: :original
88
- ]
89
- ```
90
-
91
- ### Compression
92
- The images always are compressed to 70%. Except for the original size (50%).
1
+ # Imager
2
+
3
+ Use with [ImagerServer](https://github.com/guilherme-otran/ImagerServer), a storange and resizer server for images.
4
+ Check the test directory for know how the server works.
5
+ You can save your images in other domain running ImagerServer.
6
+
7
+ [![Build Status](https://travis-ci.org/guilherme-otran/Imager.png?branch=master)](https://travis-ci.org/guilherme-otran/Imager)
8
+ [![Dependency Status](https://gemnasium.com/guilherme-otran/Imager.png)](https://gemnasium.com/guilherme-otran/Imager)
9
+
10
+ ## Please contribute!
11
+ A lot of the features are not implemented yet (except for the server)
12
+
13
+ 1. Fork it
14
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
15
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
16
+ 4. Push to the branch (`git push origin my-new-feature`)
17
+ 5. Create new Pull Request
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ gem 'imager'
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install imager
32
+
33
+ ## Usage
34
+
35
+ Imager.configure do |c|
36
+ c.base_uri = "http://files.myserver.com"
37
+ c.manager_path = "manager"
38
+ c.collections_path = "images"
39
+ c.auth_code = ""
40
+ end
41
+
42
+ c.auth_code is the `$YOUR_AUTH_CODE = '';` you setted in the [server] (https://github.com/guilherme-otran/ImagerServer).
43
+ This is for post and delete authentication (manager).
44
+
45
+ ### Sending the images
46
+
47
+ Imager::ServerInterface.post("Collection", "Album", "test/imageid.png", small: { width: 100 })
48
+
49
+ Creates:
50
+
51
+ http://files.myserver.com/images/Collection/Album/imageid/small.jpg
52
+
53
+ And
54
+
55
+ Imager::ServerInterface.post("Collection", "Album", "test/image.png", small: { width: 100 }, "someimageid")
56
+
57
+ Creates
58
+
59
+ http://files.myserver.com/images/Collection/Album/someimageid/small.jpg
60
+
61
+ ### Removing the images
62
+
63
+ Imager::ServerInterface.delete("Collection", "Album", "imageid")
64
+
65
+ ### Using the images
66
+
67
+ Imager::LinkHelper.link_for("Collection", "Album", "imageid", :small)
68
+
69
+ Will return:
70
+ "http://files.myserver.com/images/collection/album/image/small.jpg"
71
+ Since the server ALWAYS save the images as jpg.
72
+
73
+ You can use Collection as model name(product) and album as id(1) and get the result:
74
+
75
+ "http://files.myserver.com/images/product/1/image/small.jpg"
76
+ Just save as:
77
+ `Imager::ServerInterface.post("product", "1", "test/image.png", small: { width: 100 })`
78
+
79
+ ## Notes about saving and sizes
80
+ Saving first as `"product", "1", "test/image.png", small: { width: 100 })` and after `"product", "1", "test/otherimage.png", small: { width: 90 })` don't changes the size of image. Beware!
81
+
82
+ ### Sizes Explain:
83
+ The server accepts the following combinations:
84
+
85
+ ```
86
+ YourSizeName: :original # Will save the original size. Don't worry. The server compress to 50% of quality.
87
+ YourSizeName: { width: 100 } # Will resize (maintein main aspect) the image for 100px of width
88
+ YourSizeName: { height: 100 } # Will resize (maintein main aspect) the image for 100px of height
89
+ YourSizeName: { width: 100, height: 150 } # Will resize to fit in 100x150 px
90
+ ```
91
+
92
+ You can have many sizes when posting a image:
93
+
94
+ ```
95
+ sizes = {
96
+ small: { width: 100 },
97
+ gallery: { height: 300 },
98
+ mini-home: { width: 50, height: 50 },
99
+ original: :original
100
+ }
101
+ ```
102
+
103
+ ### Compression
104
+ The images always are compressed to 70%. Except for the original size (50%).
@@ -1,29 +1,29 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'imager/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "imager"
8
- spec.version = Imager::VERSION
9
- spec.authors = ["Guilherme Otranto"]
10
- spec.email = ["guilherme_otran@hotmail.com"]
11
- spec.description = %q{A remote storange and resizer client for images.}
12
- spec.summary = %q{Imager Client API}
13
- spec.homepage = "https://github.com/guilherme-otran/Imager"
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
23
- spec.add_development_dependency "rspec"
24
- spec.add_development_dependency "webmock"
25
- spec.add_development_dependency "vcr"
26
- spec.add_development_dependency "turn"
27
- spec.add_dependency "httmultiparty", "~> 0.3.10"
28
- spec.add_dependency "json"
29
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'imager/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "imager"
8
+ spec.version = Imager::VERSION
9
+ spec.authors = ["Guilherme Otranto"]
10
+ spec.email = ["guilherme_otran@hotmail.com"]
11
+ spec.description = %q{A remote storange and resizer client for images.}
12
+ spec.summary = %q{Imager Client API}
13
+ spec.homepage = "https://github.com/guilherme-otran/Imager"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "webmock"
25
+ spec.add_development_dependency "vcr"
26
+ spec.add_development_dependency "turn"
27
+ spec.add_dependency "httmultiparty", "~> 0.3.10"
28
+ spec.add_dependency "json"
29
+ end
@@ -1,16 +1,16 @@
1
- require "imager/version"
2
- require "imager/server_client"
3
- require "imager/server_interface"
4
- require "imager/link_helper"
5
- require "imager/imager_error"
6
- module Imager
7
-
8
- class << self
9
- attr_accessor :manager_path, :collection_path, :auth_code, :base_uri
10
-
11
- def configure
12
- yield self
13
- end
14
- end
15
-
16
- end
1
+ require "imager/version"
2
+ require "imager/server_client"
3
+ require "imager/server_interface"
4
+ require "imager/link_helper"
5
+ require "imager/imager_error"
6
+ module Imager
7
+
8
+ class << self
9
+ attr_accessor :manager_path, :collection_path, :auth_code, :base_uri
10
+
11
+ def configure
12
+ yield self
13
+ end
14
+ end
15
+
16
+ end
@@ -1,5 +1,9 @@
1
1
  module Imager
2
2
  class LinkHelper
3
+ # @param [String] Collection for save the image
4
+ # @param [String] Album for save the image
5
+ # @param [String] File id
6
+ # @param [Symbol, String] Image Size name.
3
7
  def self.link_for(collection, album, image, size)
4
8
  size = size.to_s
5
9
  "#{Imager.base_uri}/#{Imager.collection_path}/#{collection}/#{album}/#{image}/#{size}.jpg"
@@ -1,7 +1,7 @@
1
- require 'httmultiparty'
2
-
3
- module Imager
4
- class ServerClient
5
- include HTTMultiParty
6
- end
1
+ require 'httmultiparty'
2
+
3
+ module Imager
4
+ class ServerClient
5
+ include HTTMultiParty
6
+ end
7
7
  end
@@ -1,95 +1,130 @@
1
- require 'openssl'
2
- require 'cgi'
3
- require 'json'
4
-
5
- module Imager
6
- class ServerInterface
7
- def self.post(collection, album, file, sizes)
8
- query = {}
9
- query[:collection] = collection
10
- query[:album] = album
11
- query[:sizes] = sizes
12
-
13
- auth = auth_token(query, file)
14
- query[:file] = File.new(file)
15
- query[:auth] = auth
16
-
17
- return parse(client.post('/post.php', { query: query }))
18
- end
19
-
20
- def self.delete(collection, album, file_id)
21
- query = {}
22
- query[:collection] = collection
23
- query[:album] = album
24
- query[:file_id] = file_id
25
- query[:auth] = auth_token(query)
26
-
27
- return parse(client.post('/delete.php', { query: query }), true)
28
- end
29
-
30
- def self.client
31
- unless Imager::ServerClient.base_uri
32
- Imager::ServerClient.base_uri Imager.base_uri + '/' + Imager.manager_path
33
- end
34
- Imager::ServerClient
35
- end
36
-
37
- private
38
-
39
- def self.parse(response, is_delete = false)
40
- case response.code
41
- when 204
42
- return true
43
- when 200..299
44
- parsed = begin
45
- !!JSON.parse(response.body)
46
- rescue
47
- false
48
- end
49
-
50
- return true if parsed
51
- # Something is wrong with the server
52
- raise ArgumentError, "The server send an invalid response.", caller
53
- when 400
54
- raise ImagerError, response.body, caller
55
- when 404
56
- # We are deleting something that doesn't exist
57
- if (is_delete && response.body == "Cannot find the file.")
58
- raise ImagerError, response.body, caller
59
- else
60
- raise ArgumentError, "The server return an unexpected 404.", caller
61
- end
62
- when 401
63
- # Authentication with the server failed
64
- raise ArgumentError, "Authentication failed: " + response.body, caller
65
- else
66
- raise ArgumentError, "The server returned an error: " + response.body, caller
67
- end
68
- end
69
-
70
- def self.auth_token(query, file=nil)
71
- query_hash = query.clone
72
- if file
73
- if !File.file?(file)
74
- raise ImagerError, "Invalid image file", caller
75
- end
76
- query_hash[:file_md5] = Digest::MD5.file(file)
77
- query_hash[:file_sha1] = Digest::SHA1.file(file)
78
- query_hash[:file_name] = File.basename(file)
79
- end
80
-
81
- query_hash = to_query(query_hash)
82
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('md5'), Imager.auth_code, query_hash)
83
- end
84
-
85
- def self.to_query(hash, namespace=false)
86
- if(hash.is_a? Hash)
87
- hash.collect do |k, v|
88
- to_query(v, namespace ? "#{namespace}[#{k}]" : k)
89
- end.join '&'
90
- else
91
- CGI.escape(namespace.to_s) + "=" + CGI.escape(hash.to_s)
92
- end
93
- end
94
- end
1
+ require 'openssl'
2
+ require 'cgi'
3
+ require 'json'
4
+
5
+ module Imager
6
+ class ServerInterface
7
+
8
+ # if file is a class that respond to original_filename (like UploadIO)
9
+ # the file id will be the original_filename.
10
+
11
+ # @param [String] Collection for save the image
12
+ # @param [String] Album for save the image
13
+ # @param [UploadIO, File, String] The image file or the path to it
14
+ # @param [Hash] Sizes you want to save. @see https://github.com/guilherme-otran/Imager#sizes-explain
15
+ # @param [String] File id. if passed file_id will be this instead of file.original_filename or File.basename(file).
16
+ # @return [void]
17
+ # @raise [ImagerError] if some server validation failed.
18
+ # @raise [ArgumentError] when something with server comunication is wrong
19
+ def self.post(collection, album, file, sizes, file_id = nil)
20
+ raise Imager::ImagerError "File is empty", caller unless file
21
+
22
+ if file.is_a?(String)
23
+ raise Imager::ImagerError, "File is not a file", caller unless File.file?(file)
24
+ file = File.new(file)
25
+ end
26
+
27
+ query = {}
28
+ query[:collection] = collection
29
+ query[:album] = album
30
+ query[:sizes] = sizes
31
+
32
+ query[:file_id] = file_id
33
+ query[:file_id] ||= file.original_filename if file.respond_to?(:original_filename)
34
+ query[:file_id] ||= File.basename(file)
35
+
36
+ # Remove file extension
37
+ query[:file_id].gsub!(/(\..{3,4})\z/i, '')
38
+
39
+ auth = auth_token(query, file)
40
+ query[:file] = file
41
+ query[:auth] = auth
42
+
43
+ return parse client.post('/post.php', query: query)
44
+ end
45
+
46
+ # @param [String] Collection for save the image
47
+ # @param [String] Album for save the image
48
+ # @param [String] File id
49
+ # @raise [ImagerError] if collection or album or file_id is wrong
50
+ # @raise [ArgumentError] when something with server comunication is wrong
51
+ def self.delete(collection, album, file_id)
52
+ query = {}
53
+ query[:collection] = collection
54
+ query[:album] = album
55
+ query[:file_id] = file_id
56
+ query[:auth] = auth_token(query)
57
+
58
+ return parse client.post('/delete.php', query: query), true
59
+ end
60
+
61
+ def self.client
62
+ unless Imager::ServerClient.base_uri
63
+ Imager::ServerClient.base_uri Imager.base_uri + '/' + Imager.manager_path
64
+ end
65
+ Imager::ServerClient
66
+ end
67
+
68
+ private
69
+
70
+ def self.parse(response, is_delete = false)
71
+ case response.code
72
+ when 204
73
+ return true
74
+ when 200..299
75
+ parsed = begin
76
+ !!JSON.parse(response.body)
77
+ rescue
78
+ false
79
+ end
80
+
81
+ return true if parsed
82
+ # Something is wrong with the server
83
+ raise ArgumentError, "The server send an invalid response.", caller
84
+ when 422
85
+ raise ImagerError, response.body, caller
86
+ when 404
87
+ # We are deleting something that doesn't exist
88
+ if (is_delete && response.body == "Cannot find the file.")
89
+ raise ImagerError, response.body, caller
90
+ else
91
+ raise ArgumentError, "The server return an unexpected 404.", caller
92
+ end
93
+ when 401
94
+ # Authentication with the server failed
95
+ raise ArgumentError, "Authentication failed: " + response.body, caller
96
+ else
97
+ raise ArgumentError, "The server returned an error: " + response.body, caller
98
+ end
99
+ end
100
+
101
+ def self.auth_token(query, file=nil)
102
+ query_hash = query.clone
103
+ if file
104
+ begin
105
+ query_hash[:file_md5] = Digest::MD5.file(file)
106
+ query_hash[:file_sha1] = Digest::SHA1.file(file)
107
+ rescue
108
+ raise Imager::ImagerError, "Cannot read the file", caller unless file.respond_to?(:read)
109
+
110
+ # Fix for rubinius
111
+ query_hash[:file_md5] = Digest::MD5.hexdigest(file.read)
112
+ query_hash[:file_sha1] = Digest::SHA1.hexdigest(file.read)
113
+ end
114
+ end
115
+
116
+ query_hash = to_query(query_hash)
117
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('md5'), Imager.auth_code, query_hash)
118
+ end
119
+
120
+ def self.to_query(hash, namespace=false)
121
+ if(hash.is_a? Hash)
122
+ hash.collect do |k, v|
123
+ to_query(v, namespace ? "#{namespace}[#{k}]" : k)
124
+ end.join '&'
125
+ else
126
+ CGI.escape(namespace.to_s) + "=" + CGI.escape(hash.to_s)
127
+ end
128
+ end
129
+ end
95
130
  end