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 +35 -6
- data/lib/tiny_png.rb +1 -1
- data/lib/tiny_png/client.rb +32 -0
- data/lib/tiny_png/shrink.rb +66 -0
- metadata +9 -7
- data/lib/tiny_png/tiny_png.rb +0 -74
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::
|
40
|
+
Create an instance of the `TinyPng::Client` class, passing in your API key:
|
34
41
|
|
35
42
|
```ruby
|
36
|
-
@
|
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
|
-
@
|
49
|
+
@client = TinyPng::Client.new API_KEY, { :suppress_exceptions => true }
|
43
50
|
```
|
44
51
|
|
45
|
-
Next, pass in the full
|
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
|
-
@
|
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
|
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
@@ -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.
|
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-
|
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: &
|
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: *
|
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/
|
34
|
+
- lib/tiny_png/shrink.rb
|
34
35
|
- lib/tiny_png.rb
|
35
36
|
- LICENSE
|
36
37
|
- README.md
|
37
|
-
homepage:
|
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:
|
data/lib/tiny_png/tiny_png.rb
DELETED
@@ -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
|