tiny_png 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -18,8 +18,15 @@ this API was introduced, TinyPNG could only be used from their [web interface](h
18
18
  And while their homepage is cool and all, manually uploading and saving files is a less-than-enjoyable
19
19
  process. The kind of process a computer was made to do for you. Ergo this gem.
20
20
 
21
+ **TinyPNG's API service is currently in private beta. You will need to request an API key to use this gem.**
22
+ [See here](https://twitter.com/tinypng/status/256049113852944384) for details.
23
+
21
24
  This gem interacts with TinyPNG's API to replace a given PNG with its shrunken counterpart.
22
25
 
26
+ When you pass a full path into the `shrink` method, it will replace the source image with the image
27
+ returned by TinyPNG. If this process fails for whatever reason, the original image will be restored.
28
+ On success, the original image is completely overwritten and is no longer available.
29
+
23
30
  ## Installation
24
31
 
25
32
  If you're using bundler, just add the following to your Gemfile:
@@ -30,28 +37,50 @@ gem 'tiny_png'
30
37
 
31
38
  ## Usage
32
39
 
33
- Create an instance of the `TinyPng::Shrink` class, passing in your API key:
40
+ Create an instance of the `TinyPng::Client` class, passing in your API key:
34
41
 
35
42
  ```ruby
36
- @tiny = TinyPng::Shrink.new API_KEY
43
+ @client = TinyPng::Client.new API_KEY
37
44
  ```
38
45
 
39
46
  If you want to work with a list of images, and want to silently suppress exceptions, just pass that in the options field:
40
47
 
41
48
  ```ruby
42
- @tiny = TinyPng::Shrink.new API_KEY, { :suppress_exceptions => true }
49
+ @client = TinyPng::Client.new API_KEY, { :suppress_exceptions => true }
43
50
  ```
44
51
 
45
- Next, pass in the full path to the image you want to shrink
52
+ Next, pass in the full paths to the images you want to shrink (you can also pass in whole directories)
53
+
54
+ ```ruby
55
+ @client.shrink '/FULL/PATH/TO/IMAGE.png'
56
+ ```
46
57
 
47
58
  ```ruby
48
- @tiny.shrink '/FULL/PATH/TO/IMAGE.png'
59
+ @client.shrink '/FULL/PATH/TO/image.png', '/FULL/PATH/TO/ANOTHER/image.png', '/DIRECTORY/WITH/LOTS/OF/IMAGES'
49
60
  ```
50
61
 
51
- The shrunken image will be saved in the same path, effectively overwriting the old file.
62
+ The `shrink` method will return a hash of arrays letting you know which paths were successfully overwritten and which
63
+ ones failed:
64
+
65
+ ```
66
+ {
67
+ :success => [
68
+ '/THIS/ONE/WAS/overwritten.png',
69
+ '/THIS/ONE/WAS/ALSO/overwritten.png'
70
+ ],
71
+ :failure => [
72
+ '/THIS/FAILED/AND/WAS/reverted.png',
73
+ '/THIS/ISNT/A/png.gif'
74
+ ]
75
+ }
76
+ ```
77
+
78
+ Each successfully shrunken image will overwrite the original file.
52
79
 
53
80
  **NOTE:**
54
81
 
82
+ For each image path analyzed (whether sent in directly or picked out of a folder):
83
+
55
84
  - There must be a file already at the specified path
56
85
  - That file must be readable and writeable
57
86
  - The file name *must* end in `.png`
data/lib/tiny_png.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module TinyPng
2
2
  end
3
3
 
4
- require File.join File.dirname(__FILE__), 'tiny_png', 'tiny_png'
4
+ require File.join File.dirname(__FILE__), 'tiny_png', 'client'
@@ -0,0 +1,32 @@
1
+ require 'base64'
2
+ require 'httparty'
3
+ require File.join File.dirname(__FILE__), 'exceptions'
4
+ require File.join File.dirname(__FILE__), 'shrink'
5
+ require File.join File.dirname(__FILE__), 'exception_handling'
6
+
7
+ module TinyPng
8
+ class Client
9
+ include TinyPng::ExceptionHandling
10
+ include TinyPng::Shrink
11
+
12
+ include HTTParty
13
+ base_uri 'api.tinypng.org'
14
+
15
+ #
16
+ # Create a new instance of the TinyPng::Shrink class
17
+ #
18
+ # Arguments:
19
+ # - api_key (String)
20
+ # - options (Hash)
21
+ # - :suppress_exceptions (Boolean)
22
+ # Default: false
23
+ # If false (the default), exceptions will be raised when the process fails. If suppression is turned on, exceptions will not be raised, but a false value will be returned if shrinking fails for any reason.
24
+ #
25
+ # Returns: TinyPng::Client instance
26
+ #
27
+ def initialize api_key, options={}
28
+ @options = { :suppress_exceptions => false }.merge options
29
+ @auth = { :username => 'api', :password => api_key }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,66 @@
1
+ module TinyPng::Shrink
2
+ #
3
+ # Replace an image at a given path with its shrunken version
4
+ #
5
+ # The image at the given path will be submitted to TinyPNG and the new version will overwrite the original. If this process fails for any reason, the original file will be rolled back.
6
+ #
7
+ # Arguments:
8
+ # - shrinkwrap (any number of objects to be shrunk)
9
+ # You can pass in a directory, or individual files that should be shrunk. All should be absolute paths.
10
+ #
11
+ # If you send in a path to a specific file, it must end in `.png` or it will not be sent to TinyPNG for processing.
12
+ #
13
+ # Likewise, when traversing through a directory, only files that end in `.png` will be processed.
14
+ #
15
+ # All paths to specific files (whether sent in directly or picked out from the directory) need to be readable and writeable.
16
+ #
17
+ # Returns: Hash { :success => [Array, Of, Paths, Successfully, Overwrittern], :failure => [Array, Of, Paths, Left, Unchanged] }
18
+ #
19
+
20
+ def shrink *shrinkwrap
21
+ results = { :success => [], :failure => [] }
22
+ [shrinkwrap].flatten.each do |shrinkable|
23
+ if File.directory? shrinkable
24
+ Dir.glob("#{shrinkable.gsub(/\/$/,'')}/**/*.png") do |image_path|
25
+ key = self.shrink_in_place(image_path) ? :success : :failure
26
+ results[key].push image_path
27
+ end
28
+ else
29
+ key = shrink_in_place(shrinkable) ? :success : :failure
30
+ results[key].push shrinkable
31
+ end
32
+ end
33
+ results
34
+ end
35
+
36
+ protected
37
+
38
+ def shrink_in_place image_path
39
+ # check to make sure everything looks kosher before sending data to TinyPNG
40
+ return raise_exception InvalidFileType, 'The file must be a PNG' unless image_path.downcase.match(/\.png$/)
41
+ return raise_exception FileDoesntExist, "Can't find a file at the specified path" unless File.exists? image_path
42
+ return raise_exception FileNotReadable, "Can't read the requested file" unless File.readable? image_path
43
+ return raise_exception FileNotWriteable, "Can't write to the specifed file" unless File.writable? image_path
44
+
45
+ # store current content in case we need to rollback later
46
+ current_content = File.read image_path
47
+
48
+ # passes our quick checks, so let's fire off the request
49
+ response = self.class.post('/api/shrink', :basic_auth => @auth, :body => current_content.force_encoding('BINARY'))
50
+
51
+ # abort unless TinyPNG successfully did its thing
52
+ return raise_exception ShrinkingFailed, response.message unless response.code == 200
53
+
54
+ # only overwrite if the new file is smaller than the old
55
+ if response['output']['ratio'] < 1
56
+ begin
57
+ open(image_path, 'wb') { |f| f.write HTTParty.get(response['output']['url']).parsed_response }
58
+ rescue # if the writing process fails for whatever reason, rollback and raise custom error
59
+ open(image_path, 'wb') { |f| f.write current_content }
60
+ return raise_exception ShrinkingFailed, "Couldn't write new content"
61
+ end
62
+ end
63
+
64
+ true
65
+ end
66
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiny_png
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-10 00:00:00.000000000 Z
12
+ date: 2012-10-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty
16
- requirement: &2152385040 !ruby/object:Gem::Requirement
16
+ requirement: &2152072180 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,21 +21,23 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2152385040
24
+ version_requirements: *2152072180
25
25
  description: Use the TinyPNG service to minimize the size of your image files.
26
26
  email: chris@thesturgills.com
27
27
  executables: []
28
28
  extensions: []
29
29
  extra_rdoc_files: []
30
30
  files:
31
+ - lib/tiny_png/client.rb
31
32
  - lib/tiny_png/exception_handling.rb
32
33
  - lib/tiny_png/exceptions.rb
33
- - lib/tiny_png/tiny_png.rb
34
+ - lib/tiny_png/shrink.rb
34
35
  - lib/tiny_png.rb
35
36
  - LICENSE
36
37
  - README.md
37
- homepage: http://chris.thesturgills.com
38
- licenses: []
38
+ homepage: https://github.com/sturgill/tiny_png
39
+ licenses:
40
+ - MIT
39
41
  post_install_message:
40
42
  rdoc_options: []
41
43
  require_paths:
@@ -1,74 +0,0 @@
1
- require 'base64'
2
- require 'httparty'
3
- require File.join File.dirname(__FILE__), 'exceptions'
4
- require File.join File.dirname(__FILE__), 'exception_handling'
5
-
6
- module TinyPng
7
- class Shrink
8
- include TinyPng::ExceptionHandling
9
-
10
- include HTTParty
11
- base_uri 'api.tinypng.org'
12
-
13
- #
14
- # Create a new instance of the TinyPng::Shrink class
15
- #
16
- # Arguments:
17
- # - api_key (String)
18
- # - options (Hash)
19
- # - :suppress_exceptions (Boolean)
20
- # Default: false
21
- # If false (the default), exceptions will be raised when the process fails. If suppression is turned on, exceptions will not be raised, but a false value will be returned if shrinking fails for any reason.
22
- #
23
- # Returns: TinyPng::Shrink instance
24
- #
25
- def initialize api_key, options={}
26
- @options = { :suppress_exceptions => false }.merge options
27
- @auth = { :username => 'api', :password => api_key }
28
- end
29
-
30
- #
31
- # Replace an image at a given path with its shrunken version
32
- #
33
- # The image at the given path will be submitted to TinyPNG and the new version will overwrite the original. If this process fails for any reason, the original file will be rolled back.
34
- #
35
- # Arguments:
36
- # - image_path (String)
37
- # The full path to the image that should be shrunk. Requirements:
38
- # - Must be the full and absolute path (not a relative path)
39
- # - Path must end in `.png`
40
- # - Path must be readable
41
- # - Path must be writeable
42
- #
43
- # Returns: Boolean (whether or not the action was successful)
44
- #
45
- def shrink image_path
46
- # check to make sure everything looks kosher before sending data to TinyPNG
47
- return raise_exception InvalidFileType, 'The file must be a PNG' unless image_path.downcase.match(/\.png$/)
48
- return raise_exception FileDoesntExist, "Can't find a file at the specified path" unless File.exists? image_path
49
- return raise_exception FileNotReadable, "Can't read the requested file" unless File.readable? image_path
50
- return raise_exception FileNotWriteable, "Can't write to the specifed file" unless File.writable? image_path
51
-
52
- # store current content in case we need to rollback later
53
- current_content = File.read image_path
54
-
55
- # passes our quick checks, so let's fire off the request
56
- response = self.class.post('/api/shrink', :basic_auth => @auth, :body => current_content.force_encoding('BINARY'))
57
-
58
- # abort unless TinyPNG successfully did its thing
59
- return raise_exception ShrinkingFailed, response.message unless response.code == 200
60
-
61
- # only overwrite if the new file is smaller than the old
62
- if response['output']['ratio'] < 1
63
- begin
64
- open(image_path, 'wb') { |f| f.write HTTParty.get(response['output']['url']).parsed_response }
65
- rescue # if the writing process fails for whatever reason, rollback and raise custom error
66
- open(image_path, 'wb') { |f| f.write current_content }
67
- return raise_exception ShrinkingFailed, "Couldn't write new content"
68
- end
69
- end
70
-
71
- true
72
- end
73
- end
74
- end