optipng-r 0.3.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ae2746c1c99c904df57c35636d53453bf61b2b2
4
+ data.tar.gz: 9bcbfa525a8802e3e95fedab1606b080dbc12fea
5
+ SHA512:
6
+ metadata.gz: c60ec8b4c63d3cfd767d15ddb5606612c936bdaf900e78d7dc6af49fe8fb59cfeadd44fb5e352404d96d1d2319f7fb644db8166ff128f77f9d081234985f696b
7
+ data.tar.gz: 35dc03267e5766850e482c227d30107897ae3c568e4c48fb1c308d0a887cb4c5c11b22567b290a36adecfd83c9518d193c39e862341ea2592a3955a43ac0f7fa
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ gem "command-builder", ">= 0.2.0"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "bundler", ">= 1.0.0"
10
+ gem "jeweler", ">= 1.5.2"
11
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,22 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ command-builder (0.2.0)
5
+ hash-utils (>= 0.18.0)
6
+ pipe-run (>= 0.2.1)
7
+ git (1.2.5)
8
+ hash-utils (0.18.0)
9
+ jeweler (1.6.4)
10
+ bundler (~> 1.0)
11
+ git (>= 1.2.5)
12
+ rake
13
+ pipe-run (0.2.1)
14
+ rake (0.9.2)
15
+
16
+ PLATFORMS
17
+ ruby
18
+
19
+ DEPENDENCIES
20
+ bundler (>= 1.0.0)
21
+ command-builder (>= 0.2.0)
22
+ jeweler (>= 1.5.2)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ Optipng
2
+ =======
3
+
4
+ **Optipng** provides Ruby interface to the [`optipng`][1] tool.
5
+ Some examples follow: (for details, see module documentation)
6
+
7
+ require "optipng"
8
+
9
+ Optipng.available? # will return true (or false)
10
+
11
+ Optipng.optimize(["foo.png", "empty.png", "nonexist.png"], { :level => 5 })
12
+
13
+ # will run 'optipng -o 5 foo.png bar.png empty.png'
14
+ # and then will return for example:
15
+ # '#<struct Optipng::Result succeed={"foo.png => -22.1}}, errors=[["empty.png", "Unrecognized image file format"], ["nonexist.png", "Can't open the input file"]]>
16
+
17
+ It can be also run asynchronously by non-blocking way (with [`eventmachine`][4])
18
+ simply by giving block with one argument to `#optimize`. See documentation.
19
+
20
+ ### Call Result
21
+
22
+ Result contains members `:success` and `:errors`. Sucess member contains
23
+ hash of successfully optimized files with ratio as value. Zero or
24
+ positive percent ratio means the same as file has been skipped so
25
+ already optimized. It's negative number against the number reported by
26
+ `optipng` so it means new size against the old size.
27
+
28
+ Errors contains array with pairs where first member of the pair is
29
+ filename and second the message. First one can be null if message isn't
30
+ strictly associated with concrete file. (But fortunately usually it is.)
31
+
32
+ Contributing
33
+ ------------
34
+
35
+ 1. Fork it.
36
+ 2. Create a branch (`git checkout -b 20101220-my-change`).
37
+ 3. Commit your changes (`git commit -am "Added something"`).
38
+ 4. Push to the branch (`git push origin 20101220-my-change`).
39
+ 5. Create an [Issue][2] with a link to your branch.
40
+ 6. Enjoy a refreshing Orange Juice and wait.
41
+
42
+ Copyright
43
+ ---------
44
+
45
+ This gem was originaly developed by [Martin Kozák][https://github.com/martinkozak/optipng].
46
+ But original gem is broken, so this is the rebirth of it.
47
+
48
+ Copyright &copy; 2015 [Artyom Fedenko][3]. See `LICENSE.txt` for
49
+ further details.
50
+
51
+ [1]: http://optipng.sourceforge.net/
52
+ [2]: https://github.com/Artie18/optipng/issues
53
+ [3]: http://rubyeventmachine.com/
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+
13
+ require 'rake'
14
+ require 'jeweler'
15
+
16
+ Jeweler::Tasks.new do |gem|
17
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
18
+ gem.name = "optipng-i"
19
+ gem.homepage = "https://github.com/Artie18/optipng"
20
+ gem.license = "MIT"
21
+ gem.summary = "Ruby interface to 'optipng' tool."
22
+ gem.email = "artyomfedenko@hotmail.com"
23
+ gem.authors = ["Artyom Fedenko"]
24
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
25
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
26
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
27
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
28
+ end
29
+ Jeweler::RubygemsDotOrgTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
data/lib/optipng.rb ADDED
@@ -0,0 +1,138 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+ # (c) 2015 Artyom Fedenko (artyomfedenko@hotmail.com)
4
+
5
+ require 'command-builder'
6
+ require 'mkmf'
7
+
8
+ ##
9
+ # The +optipng+ tool command frontend.
10
+ # @see http://optipng.sourceforge.net/
11
+ #
12
+
13
+ module Optipng
14
+
15
+ ##
16
+ # Holds +optipng+ command.
17
+ #
18
+
19
+ COMMAND = :optipng
20
+
21
+ ##
22
+ # Result structure.
23
+ #
24
+
25
+ Result = Struct::new(:succeed, :errors)
26
+
27
+ ##
28
+ # Holds output matchers.
29
+ #
30
+
31
+ MATCHERS = [
32
+ /^Processing\:\s*(.*)/,
33
+ /^Error:\s*(.*)/,
34
+ /(\d+\.\d+)%/,
35
+ /already optimized\.$/,
36
+ ]
37
+
38
+ ##
39
+ # Checks if +jpegoptim+ is available.
40
+ # @return [Boolean] +true+ if it is, +false+ in otherwise
41
+ #
42
+
43
+ def self.available?
44
+ find_executable(self::COMMAND.to_s).nil? ? false : true
45
+ end
46
+
47
+ ##
48
+ # Performs optimizations above file or set of files.
49
+ #
50
+ # If block is given, runs +optipng+ asynchronously. In that case,
51
+ # +em-pipe-run+ file must be already required.
52
+ #
53
+ # @param [String, Array] paths file path or array of paths for optimizing
54
+ # @param [Hash] options options
55
+ # @param [Proc] block block for giving back the results
56
+ # @option options [Integer] :level optimization level (0-7)
57
+ # @option options [Boolean] :debug turn on debugging mode, so command will be put out to the +STDERR+
58
+ # @return [Struct] see {Result}
59
+ #
60
+
61
+ def self.optimize(paths, options = { }, &block)
62
+
63
+ # Command
64
+ cmd = CommandBuilder::new(self::COMMAND)
65
+
66
+ # Max
67
+ if options[:level].kind_of? Integer
68
+ cmd.arg(:o, options[:level].to_i)
69
+ end
70
+
71
+ # Files
72
+ if paths.kind_of? String
73
+ paths = [paths]
74
+ end
75
+
76
+ # Runs the command
77
+ cmd << paths
78
+
79
+ if options[:debug] == true
80
+ STDERR.write cmd.to_s + "\n"
81
+ end
82
+
83
+ # Blocking
84
+ if block.nil?
85
+ output = cmd.execute!
86
+
87
+ # Parses output
88
+ succeed, errors = __parse_output(output)
89
+ return self::Result::new(succeed, errors)
90
+
91
+ # Non-blocking
92
+ else
93
+ cmd.execute do |output|
94
+ succeed, errors = __parse_output(output)
95
+ block.call(self::Result::new(succeed, errors))
96
+ end
97
+ end
98
+
99
+ end
100
+
101
+
102
+ private
103
+
104
+ ##
105
+ # Parses output.
106
+ #
107
+
108
+ def self.__parse_output(output)
109
+ errors = [ ]
110
+ succeed = { }
111
+
112
+ output.split("**").each do |section|
113
+ section.strip!
114
+ if section.start_with? "Processing:"
115
+
116
+ # Scans each line
117
+ filename = nil
118
+
119
+ section.each_line do |line|
120
+ if m = line.match(self::MATCHERS[0])
121
+ filename = m[1]
122
+ elsif m = line.match(self::MATCHERS[1])
123
+ errors << [filename, m[1]]
124
+ next
125
+ elsif m = line.match(self::MATCHERS[2])
126
+ succeed[filename] = -1 * m[1].to_f
127
+ next
128
+ elsif m = line.match(self::MATCHERS[3])
129
+ succeed[filename] = 0.0
130
+ end
131
+ end
132
+
133
+ end
134
+ end
135
+
136
+ return [succeed, errors]
137
+ end
138
+ end
data/optipng.gemspec ADDED
@@ -0,0 +1,53 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{optipng-r}
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{Artyom Fedenko}]
12
+ s.date = %q{2015-09-30}
13
+ s.email = %q{artyomfedenko@hotmail.com}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE.txt",
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE.txt",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/optipng.rb",
27
+ "optipng.gemspec",
28
+ "test"
29
+ ]
30
+ s.homepage = %q{https://github.com/martinkozak/optipng}
31
+ s.licenses = [%q{MIT}]
32
+ s.require_paths = [%q{lib}]
33
+ s.rubygems_version = %q{2.4.8}
34
+ s.summary = %q{Ruby interface to 'optipng' tool.}
35
+
36
+ if s.respond_to? :specification_version then
37
+ s.specification_version = 3
38
+
39
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
40
+ s.add_runtime_dependency(%q<command-builder>, [">= 0.2.0"])
41
+ s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
42
+ s.add_development_dependency(%q<jeweler>, [">= 1.5.2"])
43
+ else
44
+ s.add_dependency(%q<command-builder>, [">= 0.2.0"])
45
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
46
+ s.add_dependency(%q<jeweler>, [">= 1.5.2"])
47
+ end
48
+ else
49
+ s.add_dependency(%q<command-builder>, [">= 0.2.0"])
50
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
51
+ s.add_dependency(%q<jeweler>, [">= 1.5.2"])
52
+ end
53
+ end
data/test ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ $:.push("./lib")
5
+ require "optipng"
6
+ require "em-pipe-run"
7
+
8
+ EM::run do
9
+ puts Optipng.available?.inspect
10
+ Optipng.optimize(["1.png", "4.png", "mp.png"], :level => 7, :debug => true) do |result|
11
+ puts result.inspect
12
+ end
13
+
14
+ puts "xxx"
15
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: optipng-r
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Artyom Fedenko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: command-builder
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: jeweler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 1.5.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.5.2
55
+ description:
56
+ email: artyomfedenko@hotmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files:
60
+ - LICENSE.txt
61
+ - README.md
62
+ files:
63
+ - ".document"
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - VERSION
70
+ - lib/optipng.rb
71
+ - optipng.gemspec
72
+ - test
73
+ homepage: https://github.com/martinkozak/optipng
74
+ licenses:
75
+ - MIT
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.4.8
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Ruby interface to 'optipng' tool.
97
+ test_files: []
98
+ has_rdoc: