img-kit 1.3.9.1

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: 06110885384e166f0c19be2cd296d9259c88487c
4
+ data.tar.gz: a5c794145d084b19878bf91625c23ed3cd0ab7af
5
+ SHA512:
6
+ metadata.gz: 1fd97dddc1a97022742b2cb9f2638f8035d0f3bb712358faa9a57afbe17774ba74d7158527c42c60b5e1a14ffa83804d8fce3f15b6dec7b8cc00cf38a712b70b
7
+ data.tar.gz: c08b9f4b965e74d72a71809d53c428729ddc9666399220e79d7f1ae632ebc3c28e55a93009035b0670a65e8ede5ed35342c7a70263fe9b5bbdae2865c06c89d2
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,6 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ test.sh
5
+ .rvmrc
6
+ vendor
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "rake"
7
+ gem "rspec", "~> 2"
8
+ gem "rspec-core", "~> 2"
9
+ gem "mocha"
10
+ gem "rack"
11
+ gem "ruby-debug19", :platforms => :mri_19
12
+ gem "ruby-debug", :platforms => :mri_18
13
+ end
@@ -0,0 +1,55 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ img-kit (1.3.9.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ archive-tar-minitar (0.5.2)
10
+ columnize (0.3.4)
11
+ diff-lcs (1.1.2)
12
+ linecache (0.46)
13
+ rbx-require-relative (> 0.0.4)
14
+ linecache19 (0.5.12)
15
+ ruby_core_source (>= 0.1.4)
16
+ mocha (0.9.12)
17
+ rack (1.3.0)
18
+ rake (0.9.2.2)
19
+ rbx-require-relative (0.0.5)
20
+ rspec (2.6.0)
21
+ rspec-core (~> 2.6.0)
22
+ rspec-expectations (~> 2.6.0)
23
+ rspec-mocks (~> 2.6.0)
24
+ rspec-core (2.6.4)
25
+ rspec-expectations (2.6.0)
26
+ diff-lcs (~> 1.1.2)
27
+ rspec-mocks (2.6.0)
28
+ ruby-debug (0.10.4)
29
+ columnize (>= 0.1)
30
+ ruby-debug-base (~> 0.10.4.0)
31
+ ruby-debug-base (0.10.4)
32
+ linecache (>= 0.3)
33
+ ruby-debug-base19 (0.11.25)
34
+ columnize (>= 0.3.1)
35
+ linecache19 (>= 0.5.11)
36
+ ruby_core_source (>= 0.1.4)
37
+ ruby-debug19 (0.11.6)
38
+ columnize (>= 0.3.1)
39
+ linecache19 (>= 0.5.11)
40
+ ruby-debug-base19 (>= 0.11.19)
41
+ ruby_core_source (0.1.5)
42
+ archive-tar-minitar (>= 0.5.2)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ img-kit!
49
+ mocha
50
+ rack
51
+ rake
52
+ rspec (~> 2)
53
+ rspec-core (~> 2)
54
+ ruby-debug
55
+ ruby-debug19
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ This is a derivative work.
2
+
3
+ Original Copyright (c) 2009 jdpace
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.
@@ -0,0 +1,12 @@
1
+ ******************************************************************
2
+
3
+ Now install wkhtmltoimage binaries:
4
+ Global: sudo `which imgkit` --install-wkhtmltoimage
5
+ rvmsudo imgkit --install-wkhtmltoimage
6
+ (installs to default /usr/local/bin/wkhtmltoimage)
7
+
8
+ inside RVM folder: export TO=`which imgkit | sed 's:/imgkit:/wkhtmltoimage:'` && imgkit --install-wkhtmltoimage
9
+ (you'll have to configure the location of the binary if you do this!)
10
+
11
+ (run imgkit --help to see more options)
12
+ ******************************************************************
@@ -0,0 +1,15 @@
1
+ # IMGKit
2
+
3
+ Cloned from [csquared](http://github.com/csquared/IMGKit) to fix these bugs:
4
+
5
+ 1. Don't **spawn** new `wkhtmltoimage` and continue execution: wait for them to terminate!
6
+
7
+ 2. Recognize that `TempFile` is a file.
8
+
9
+ The problem with 1. was that, while `wkhtmltoimage` was still running, the
10
+ (only partially) rendered image was being uploaded to S3, causing broken images.
11
+
12
+ The problem with 2. was that, since `wkhtmltoimage` [does not work with HTML in STDIN](http://code.google.com/p/wkhtmltopdf/issues/detail?id=534),
13
+ the HTML must be stored in a temporary file, and the original IMGKit thinks that
14
+ [Tempfile instances are not files](https://github.com/csquared/IMGKit/blob/master/lib/imgkit/source.rb#L14).
15
+
@@ -0,0 +1,15 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+ Bundler.require
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'Default: run specs.'
7
+ task :default => :spec
8
+
9
+ desc "Run specs"
10
+ RSpec::Core::RakeTask.new do |t|
11
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
12
+ # Put spec opts in a file named .rspec in root
13
+ end
14
+
15
+ task :specs => :spec
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'optparse'
4
+ require 'rbconfig'
5
+ require 'open-uri'
6
+ require 'imgkit/configuration'
7
+ require 'imgkit/version'
8
+
9
+ GOOGLE_CODE_URL = ENV['GOOGLE_CODE_URL'] || "http://code.google.com/p/wkhtmltopdf/downloads/list?can=1"
10
+
11
+ def detect_architecture
12
+ case arch = Config::CONFIG['arch']
13
+ when /x86_64-linux/i
14
+ 'amd64'
15
+ when /linux/i
16
+ 'i386'
17
+ when /darwin/i
18
+ 'OSX'
19
+ else
20
+ cant_find_binaries(arch)
21
+ end
22
+ end
23
+
24
+ def cant_find_binaries(arch)
25
+ puts "Sorry, I couldn't find the binary for your architecture (#{arch}) \n at #{GOOGLE_CODE_URL}"
26
+ puts "Please go to that page, unzip the appropriate binary, and install"
27
+ exit(1)
28
+ end
29
+
30
+ def cleanup(install_to)
31
+ `rm -rf wkhtmltoimage*` rescue nil
32
+ `rm #{install_to}` rescue nil
33
+ end
34
+
35
+ def download_wkhtmltoimage(arch)
36
+ if ENV['BZIP']
37
+ download = "wkhtmltoimage-0.10.0_beta4-static-#{arch}.tar.bz2"
38
+ url = "http://wkhtmltopdf.googlecode.com/files/wkhtmltoimage-0.10.0_beta4-static-#{arch}.tar.bz2"
39
+ else
40
+ page = open(GOOGLE_CODE_URL).read
41
+ download = page.match(/href=".*name=(.*wkhtmltoimage-.*#{arch}.*?)&/) or cant_find_binaries(arch)
42
+ download = download[1]
43
+ url = "http://wkhtmltopdf.googlecode.com/files/#{download}"
44
+ end
45
+ puts "Downloading #{download} from #{url}"
46
+
47
+ `curl #{url} > #{download}`
48
+ download
49
+ end
50
+
51
+ def install(download, arch, install_to)
52
+ puts "Installing #{download} to #{install_to}"
53
+ if download =~ /.tar.bz2$/
54
+ `tar xjvf #{download}`
55
+ `mv wkhtmltoimage #{install_to}`
56
+ elsif download =~ /.tar.lzma$/
57
+ raise "couldn't extract archive: lzcat not found" unless system("which lzcat > /dev/null 2>/dev/null")
58
+ puts "Warning: lzcat is broken on Ubuntu. Re-run with --use-bzip to install alternate version"
59
+ `lzcat #{download} | tar x`
60
+ `mv wkhtmltoimage-#{arch} #{install_to}`
61
+ else
62
+ `mv #{download} #{install_to}`
63
+ end
64
+ `chmod +x #{install_to}`
65
+ end
66
+
67
+ @command = Proc.new { puts "Nothing to do: use --help"}
68
+
69
+ OptionParser.new do |parser|
70
+ parser.banner = "IMGKit\n\nOptions are:"
71
+
72
+ parser.on("--use-bzip", "Force bzip download for Ubuntu because lzcat is broken") do
73
+ ENV['BZIP'] = 'true'
74
+ end
75
+
76
+ parser.on("--install-wkhtmltoimage", "Install wkhtmltoimage binaries (TO=/usr/local/bin ARCHITECTURE=i386)") do
77
+ @command = Proc.new do
78
+ architecture = ENV['ARCHITECTURE'] || detect_architecture
79
+ install_to = ENV['TO'] ? ENV['TO']+'/wkhtmltoimage' : IMGKit.configuration.wkhtmltoimage
80
+
81
+ Dir.chdir '/tmp'
82
+
83
+ cleanup(install_to)
84
+ download = download_wkhtmltoimage(architecture)
85
+ install(download, architecture, install_to)
86
+ end
87
+ end
88
+
89
+ parser.on("--version", "Show Version.") do
90
+ @command = Proc.new do
91
+ puts IMGKit::VERSION
92
+ end
93
+ end
94
+
95
+ parser.on("-h", "--help", "Show this.") { puts parser; exit }
96
+ end.parse!
97
+
98
+ @command.call
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "imgkit/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "img-kit"
7
+ s.version = IMGKit::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["csquared"]
10
+ s.email = %q{christopher.continanza@gmail.com}
11
+ s.homepage = "http://github.com/topspin/imgkit"
12
+ s.summary = %q{HTML+CSS -> JPG}
13
+ s.description = %q{Uses wkhtmltoimage to create Images using HTML}
14
+ s.post_install_message = File.read('POST_INSTALL')
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'open3'
3
+ require 'imgkit/source'
4
+ require 'imgkit/imgkit'
5
+ require 'imgkit/configuration'
6
+ require 'imgkit/version'
@@ -0,0 +1,35 @@
1
+ class IMGKit
2
+ class Configuration
3
+ attr_accessor :meta_tag_prefix, :wkhtmltoimage, :default_options, :default_format
4
+
5
+ def initialize
6
+ @meta_tag_prefix = 'imgkit-'
7
+ @default_options = {:height => 1000}
8
+ @default_format = :jpg
9
+ @wkhtmltoimage ||= (defined?(Bundler::GemfileError) ? `bundle exec which wkhtmltoimage` : `which wkhtmltoimage`).chomp
10
+ @wkhtmltoimage = '/usr/local/bin/wkhtmltoimage' if @wkhtmltoimage.strip.empty? # Fallback
11
+ end
12
+ end
13
+
14
+ class << self
15
+ attr_accessor :configuration
16
+ end
17
+
18
+ # Configure IMGKit someplace sensible,
19
+ # like config/initializers/imgkit.rb
20
+ #
21
+ # @example
22
+ # IMGKit.configure do |config|
23
+ # config.wkhtmltoimage = '/usr/bin/wkhtmltoimage'
24
+ # end
25
+
26
+ def self.configuration
27
+ @configuration ||= Configuration.new
28
+ end
29
+
30
+
31
+ def self.configure
32
+ self.configuration
33
+ yield(configuration)
34
+ end
35
+ end
@@ -0,0 +1,199 @@
1
+ class IMGKit
2
+ KNOWN_FORMATS = [:jpg, :jpeg, :png, :tiff, :tif]
3
+
4
+ class NoExecutableError < StandardError
5
+ def initialize
6
+ msg = "No wkhtmltoimage executable found at #{IMGKit.configuration.wkhtmltoimage}\n"
7
+ msg << ">> Install wkhtmltoimage by hand or try running `imgkit --install-wkhtmltoimage`"
8
+ super(msg)
9
+ end
10
+ end
11
+
12
+ class ImproperSourceError < StandardError
13
+ def initialize(msg)
14
+ super("Improper Source: #{msg}")
15
+ end
16
+ end
17
+
18
+ class CommandFailedError < RuntimeError
19
+ attr_reader :command, :stderr
20
+ def initialize(command, stderr)
21
+ @command = command
22
+ @stderr = stderr
23
+ super("Command failed: #{command}: #{stderr}")
24
+ end
25
+ end
26
+
27
+ class UnknownFormatError < StandardError
28
+ def initialize(format)
29
+ super("Unknown Format: #{format}")
30
+ end
31
+ end
32
+
33
+ attr_accessor :source, :stylesheets
34
+ attr_reader :options
35
+
36
+ def initialize(url_file_or_html, options = {})
37
+ @source = Source.new(url_file_or_html)
38
+
39
+ @stylesheets = []
40
+
41
+ @options = IMGKit.configuration.default_options.merge(options)
42
+ @options.merge! find_options_in_meta(url_file_or_html) unless source.url?
43
+
44
+ raise NoExecutableError.new unless File.exists?(IMGKit.configuration.wkhtmltoimage)
45
+ end
46
+
47
+ def command
48
+ args = [executable]
49
+ args += normalize_options(@options).to_a.flatten.compact
50
+
51
+ if @source.html?
52
+ html_file = Tempfile.open ['file', '.html']
53
+ html_file.write @source.to_s
54
+ html_file.close
55
+ args << html_file.path
56
+ else
57
+ args << @source.to_s
58
+ end
59
+
60
+ args << '-' # Read IMG from stdout
61
+ args
62
+ end
63
+
64
+ def executable
65
+ default = IMGKit.configuration.wkhtmltoimage
66
+ return default if default !~ /^\// # its not a path, so nothing we can do
67
+ if File.exist?(default)
68
+ default
69
+ else
70
+ default.split('/').last
71
+ end
72
+ end
73
+
74
+ if Open3.respond_to? :capture3
75
+ def capture3(*opts)
76
+ Open3.capture3 *opts
77
+ end
78
+ else
79
+ # Lifted from ruby 1.9.2-p290 sources for ruby 1.8 compatibility
80
+ # and modified to work on 1.8
81
+ def capture3(*cmd, &block)
82
+ if Hash === cmd.last
83
+ opts = cmd.pop.dup
84
+ else
85
+ opts = {}
86
+ end
87
+
88
+ stdin_data = opts.delete(:stdin_data) || ''
89
+ binmode = opts.delete(:binmode)
90
+
91
+ Open3.popen3(*cmd) {|i, o, e|
92
+ if binmode
93
+ i.binmode
94
+ o.binmode
95
+ e.binmode
96
+ end
97
+ out_reader = Thread.new { o.read }
98
+ err_reader = Thread.new { e.read }
99
+ i.write stdin_data
100
+ i.close
101
+ [out_reader.value, err_reader.value]
102
+ }
103
+ end
104
+ end
105
+
106
+ def to_img(format = nil)
107
+ append_stylesheets
108
+ set_format(format)
109
+
110
+ result = `#{command.join ' '}`
111
+ result.force_encoding("ASCII-8BIT") if result.respond_to? :force_encoding
112
+
113
+ raise CommandFailedError.new(command.join(' '), '') if result.size == 0
114
+ result
115
+ end
116
+
117
+ def to_file(path)
118
+ format = File.extname(path).gsub(/^\./,'').to_sym
119
+ set_format(format)
120
+ File.open(path,'w:ASCII-8BIT') {|file| file << self.to_img}
121
+ end
122
+
123
+ def method_missing(name, *args, &block)
124
+ if(m = name.to_s.match(/^to_(\w+)/))
125
+ self.send(:to_img, m[1].to_sym)
126
+ else
127
+ super
128
+ end
129
+ end
130
+
131
+ protected
132
+
133
+ def find_options_in_meta(body)
134
+ imgkit_meta_tags(body).inject({}) do |found, tag|
135
+ name = tag.attributes["name"].sub(/^#{IMGKit.configuration.meta_tag_prefix}/, '').to_sym
136
+ found.merge(name => tag.attributes["content"])
137
+ end
138
+ end
139
+
140
+ def imgkit_meta_tags(body)
141
+ require 'rexml/document'
142
+ xml_body = REXML::Document.new(body)
143
+ found = []
144
+ xml_body.elements.each("html/head/meta") do |tag|
145
+ found << tag if tag.attributes['name'].to_s =~ /^#{IMGKit.configuration.meta_tag_prefix}/
146
+ end
147
+ found
148
+ rescue # rexml random crash on invalid xml
149
+ []
150
+ end
151
+
152
+ def style_tag_for(stylesheet)
153
+ "<style>#{stylesheet.respond_to?(:read) ? stylesheet.read : File.read(stylesheet)}</style>"
154
+ end
155
+
156
+ def append_stylesheets
157
+ raise ImproperSourceError.new('Stylesheets may only be added to an HTML source') if stylesheets.any? && !@source.html?
158
+
159
+ stylesheets.each do |stylesheet|
160
+ if @source.to_s.match(/<\/head>/)
161
+ @source.to_s.gsub!(/(<\/head>)/, style_tag_for(stylesheet)+'\1')
162
+ else
163
+ @source.to_s.insert(0, style_tag_for(stylesheet))
164
+ end
165
+ end
166
+ end
167
+
168
+ def normalize_options(options)
169
+ normalized_options = {}
170
+
171
+ options.each do |key, value|
172
+ next if !value
173
+ normalized_key = "--#{normalize_arg key}"
174
+ normalized_options[normalized_key] = normalize_value(value)
175
+ end
176
+ normalized_options
177
+ end
178
+
179
+ def normalize_arg(arg)
180
+ arg.to_s.downcase.gsub(/[^a-z0-9]/,'-')
181
+ end
182
+
183
+ def normalize_value(value)
184
+ case value
185
+ when TrueClass
186
+ nil
187
+ when Array
188
+ value
189
+ else
190
+ value.to_s
191
+ end
192
+ end
193
+
194
+ def set_format(format)
195
+ format = IMGKit.configuration.default_format unless format
196
+ @options.merge!(:format => format.to_s) unless @options[:format]
197
+ raise UnknownFormatError.new(format) unless KNOWN_FORMATS.include?(@options[:format].to_sym)
198
+ end
199
+ end
@@ -0,0 +1,27 @@
1
+ class IMGKit
2
+
3
+ class Source
4
+
5
+ def initialize(url_file_or_html)
6
+ @source = url_file_or_html
7
+ end
8
+
9
+ def url?
10
+ @source.is_a?(String) && @source.match(/\Ahttp/)
11
+ end
12
+
13
+ def file?
14
+ @source.kind_of?(File) || @source.kind_of?(Tempfile)
15
+ end
16
+
17
+ def html?
18
+ !(url? || file?)
19
+ end
20
+
21
+ def to_s
22
+ file? ? @source.path : @source
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,3 @@
1
+ class IMGKit
2
+ VERSION = "1.3.9.1"
3
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+ echo 'I have a problem' > /dev/stderr
3
+ exit 1
@@ -0,0 +1 @@
1
+ body { font-size: 20px; }
@@ -0,0 +1,5 @@
1
+ <html>
2
+ <body>
3
+ <h1>Oh Hai!</h1>
4
+ </body>
5
+ </html>
@@ -0,0 +1,301 @@
1
+ require 'spec_helper'
2
+
3
+ describe IMGKit do
4
+ context "initialization" do
5
+ it "should accept HTML as the source" do
6
+ imgkit = IMGKit.new('<h1>Oh Hai</h1>')
7
+ imgkit.source.should be_html
8
+ imgkit.source.to_s.should == '<h1>Oh Hai</h1>'
9
+ end
10
+
11
+ it "should accept a URL as the source" do
12
+ imgkit = IMGKit.new('http://google.com')
13
+ imgkit.source.should be_url
14
+ imgkit.source.to_s.should == 'http://google.com'
15
+ end
16
+
17
+ it "should accept a File as the source" do
18
+ file_path = File.join(SPEC_ROOT,'fixtures','example.html')
19
+ imgkit = IMGKit.new(File.new(file_path))
20
+ imgkit.source.should be_file
21
+ imgkit.source.to_s.should == file_path
22
+ end
23
+
24
+ it "should provide no default options" do
25
+ end
26
+
27
+ it "should set a default height" do
28
+ imgkit = IMGKit.new('<h1>Oh Hai</h1>')
29
+ imgkit.options.length.should be 1
30
+ imgkit.options[:height].should be 1000
31
+ end
32
+
33
+
34
+ =begin
35
+ it "should default to 'UTF-8' encoding" do
36
+ imgkit = IMGKit.new('Captación')
37
+ end
38
+ =end
39
+
40
+ it "should not have any stylesheet by default" do
41
+ imgkit = IMGKit.new('<h1>Oh Hai</h1>')
42
+ imgkit.stylesheets.should be_empty
43
+ end
44
+ end
45
+
46
+ context "command" do
47
+ it "should contstruct the correct command" do
48
+ imgkit = IMGKit.new('html')
49
+ imgkit.command[0].should include('wkhtmltoimage')
50
+ imgkit.command.should include('-')
51
+ end
52
+
53
+ it "should parse the options into a cmd line friedly format" do
54
+ imgkit = IMGKit.new('html', :quality => 75)
55
+ imgkit.command.should include('--quality')
56
+ end
57
+
58
+ it "will not include default options it is told to omit" do
59
+ imgkit = IMGKit.new('html')
60
+ imgkit = IMGKit.new('html', :disable_smart_shrinking => false)
61
+ imgkit.command.should_not include('--disable-smart-shrinking')
62
+ end
63
+ it "should encapsulate string arguments in quotes" do
64
+ imgkit = IMGKit.new('html', :header_center => "foo [page]")
65
+ imgkit.command[imgkit.command.index('--header-center') + 1].should == 'foo [page]'
66
+ end
67
+
68
+ it "should properly handle multi-part arguments" do
69
+ imgkit = IMGKit.new('html', :custom_header => ['User-Agent', 'some user agent'])
70
+ imgkit.command[imgkit.command.index('--custom-header') + 1].should == 'User-Agent'
71
+ imgkit.command[imgkit.command.index('--custom-header') + 2].should == 'some user agent'
72
+ end
73
+
74
+ it "read the source from a temporary file if it is html" do
75
+ imgkit = IMGKit.new('html')
76
+ imgkit.command[-2].should_not == '-'
77
+ end
78
+
79
+ it "specify the URL to the source if it is a url" do
80
+ imgkit = IMGKit.new('http://google.com')
81
+ imgkit.command[-2..-1].should == ['http://google.com', '-']
82
+ end
83
+
84
+ it "should specify the path to the source if it is a file" do
85
+ file_path = File.join(SPEC_ROOT,'fixtures','example.html')
86
+ imgkit = IMGKit.new(File.new(file_path))
87
+ imgkit.command[-2..-1].should == [file_path, '-']
88
+ end
89
+
90
+ it "should detect special imgkit meta tags" do
91
+ body = %{
92
+ <html>
93
+ <head>
94
+ <meta name="imgkit-page_size" content="Legal"/>
95
+ <meta name="imgkit-orientation" content="Landscape"/>
96
+ <meta name="imgkit-crop-h" content="900"/>
97
+ </head>
98
+ </html>
99
+ }
100
+ imgkit = IMGKit.new(body)
101
+ imgkit.command[imgkit.command.index('--page-size') + 1].should == 'Legal'
102
+ imgkit.command[imgkit.command.index('--orientation') + 1].should == 'Landscape'
103
+ imgkit.command[imgkit.command.index('--crop-h') + 1].should == '900'
104
+ end
105
+ end
106
+
107
+ context "#to_img(format = nil)" do
108
+ def filetype_of(img)
109
+ result = nil
110
+ tmpfile = Tempfile.new('imgkit')
111
+ File.open(tmpfile.path, 'w') { |f| f << img }
112
+ result = `file #{tmpfile.path}`
113
+ tmpfile.unlink()
114
+ result
115
+ end
116
+
117
+ it "should generate a IMG of the HTML" do
118
+ imgkit = IMGKit.new('html')
119
+ img = imgkit.to_img
120
+ filetype_of(img).should include('JPEG')
121
+ end
122
+
123
+ it "should generate an Image with a numerical parameter" do
124
+ imgkit = IMGKit.new('html', :quality => 50)
125
+ img = imgkit.to_img
126
+ filetype_of(img).should include('JPEG')
127
+ end
128
+
129
+ it "should generate an Image with a symbol parameter" do
130
+ imgkit = IMGKit.new('html', :username => 'chris')
131
+ img = imgkit.to_img
132
+ filetype_of(img).should include('JPEG')
133
+ end
134
+
135
+ it "should have the stylesheet added to the head if it has one" do
136
+ imgkit = IMGKit.new("<html><head></head><body>Hai!</body></html>")
137
+ css = File.join(SPEC_ROOT,'fixtures','example.css')
138
+ imgkit.stylesheets << css
139
+ imgkit.to_img
140
+ imgkit.source.to_s.should include("<style>#{File.read(css)}</style>")
141
+ end
142
+
143
+ it "should accept stylesheet as an object which responds to #read" do
144
+ imgkit = IMGKit.new("<html><head></head><body>Hai!</body></html>")
145
+ css = StringIO.new( File.read(File.join(SPEC_ROOT,'fixtures','example.css')) )
146
+ imgkit.stylesheets << css
147
+ imgkit.to_img
148
+ imgkit.source.to_s.should include("<style>#{css.string}</style>")
149
+ end
150
+
151
+ it "should prepend style tags if the HTML doesn't have a head tag" do
152
+ imgkit = IMGKit.new("<html><body>Hai!</body></html>")
153
+ css = File.join(SPEC_ROOT,'fixtures','example.css')
154
+ imgkit.stylesheets << css
155
+ imgkit.to_img
156
+ imgkit.source.to_s.should include("<style>#{File.read(css)}</style><html>")
157
+ end
158
+
159
+ it "should throw an error if the source is not html and stylesheets have been added" do
160
+ imgkit = IMGKit.new('http://google.com')
161
+ css = File.join(SPEC_ROOT,'fixtures','example.css')
162
+ imgkit.stylesheets << css
163
+ lambda { imgkit.to_img }.should raise_error(IMGKit::ImproperSourceError)
164
+ end
165
+
166
+ def set_wkhtmltoimage_binary(binary)
167
+ spec_dir = File.dirname(__FILE__)
168
+ IMGKit.configuration.should_receive(:wkhtmltoimage).at_least(1).times.and_return(File.join(spec_dir, binary))
169
+ end
170
+
171
+ it "should throw an error if the wkhtmltoimage command fails" do
172
+ set_wkhtmltoimage_binary 'error_binary'
173
+ imgkit = IMGKit.new('http://www.example.com')
174
+ lambda { imgkit.to_img }.should raise_error(IMGKit::CommandFailedError)
175
+ end
176
+
177
+ it "should be able to handle lots of error output" do
178
+ set_wkhtmltoimage_binary 'warning_binary'
179
+ imgkit = IMGKit.new("<html><body>Hai!</body></html>")
180
+ imgkit.to_img.should == "result\n"
181
+ end
182
+
183
+ context "when there is no format" do
184
+ it "should fallback to jpg" do
185
+ IMGKit.new("Hello, world").to_img.should be_a(:jpg)
186
+ end
187
+
188
+ context "when a default_format has been configured" do
189
+ before do
190
+ IMGKit.configure do |config|
191
+ config.default_format = :png
192
+ end
193
+ end
194
+
195
+ after do
196
+ IMGKit.configure do |config|
197
+ config.default_format = :jpg
198
+ end
199
+ end
200
+
201
+ it "should use the configured format" do
202
+ IMGKit.new("Oh hai!").to_img.should be_a(:png)
203
+ end
204
+ end
205
+ end
206
+
207
+ context "when format = :jpg" do
208
+ it "should create a jpg" do
209
+ IMGKit.new("Hello, world").to_img(:jpg).should be_a(:jpg)
210
+ end
211
+ end
212
+
213
+ context "when format is a known format" do
214
+ it "should create an image with that format" do
215
+ IMGKit::KNOWN_FORMATS.each do |format|
216
+ IMGKit.new("Hello, world").to_img(format).should be_a(format)
217
+ end
218
+ end
219
+ end
220
+
221
+ context "when format is unknown" do
222
+ it "should raise an UnknownFormatError" do
223
+ lambda { IMGKit.new("Hello, world").to_img(:blah) }.should raise_error(IMGKit::UnknownFormatError)
224
+ end
225
+ end
226
+ end
227
+
228
+ context "#to_<known_format>" do
229
+ IMGKit::KNOWN_FORMATS.each do |format|
230
+ describe "#to_#{format}" do
231
+ it "should create a #{format}" do
232
+ IMGKit.new("Hello").send("to_#{format}").should be_a(format)
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ context "#to_<unkown_format>" do
239
+ it "should raise and UnknownFormatError" do
240
+ lambda { IMGKit.new("Hello, world").to_blah }.should raise_error(IMGKit::UnknownFormatError)
241
+ end
242
+ end
243
+
244
+ context "#to_file" do
245
+ before do
246
+ @file_path = File.join(SPEC_ROOT,'fixtures','test.jpg')
247
+ File.delete(@file_path) if File.exist?(@file_path)
248
+ end
249
+
250
+ after do
251
+ File.delete(@file_path) if File.exist?(@file_path)
252
+ end
253
+
254
+ it "should create a file with the result of :to_img as content" do
255
+ imgkit = IMGKit.new('html', :quality => 50)
256
+ imgkit.expects(:to_img).returns('CONTENT')
257
+ file = imgkit.to_file(@file_path)
258
+ file.should be_instance_of(File)
259
+ File.read(file.path).should == 'CONTENT'
260
+ end
261
+
262
+ IMGKit::KNOWN_FORMATS.each do |format|
263
+ it "should use the extension #{format} as the format" do
264
+ @file_path = File.join(SPEC_ROOT,'fixtures',"test.#{format}")
265
+ imgkit = IMGKit.new('html', :quality => 50)
266
+ file = imgkit.to_file(@file_path)
267
+ file.should be_instance_of(File)
268
+ File.open(file.path, "r:ASCII-8BIT") { |f| f.read.should be_a(format) }
269
+ end
270
+ end
271
+
272
+ it "should raise UnknownFormatError when format is unknown" do
273
+ kit = IMGKit.new("html")
274
+ lambda {
275
+ kit.to_file("file.bad_format")
276
+ }.should raise_error(IMGKit::UnknownFormatError)
277
+ end
278
+
279
+ it "should not create the file if format is unknown" do
280
+ kit = IMGKit.new("html")
281
+ kit.to_file("file.bad_format") rescue nil
282
+ File.exist?("file.bad_format").should be_false
283
+ end
284
+ end
285
+
286
+ context "security" do
287
+ before do
288
+ @test_path = File.join(SPEC_ROOT,'fixtures','security-oops')
289
+ File.delete(@test_path) if File.exist?(@test_path)
290
+ end
291
+
292
+ after do
293
+ File.delete(@test_path) if File.exist?(@test_path)
294
+ end
295
+
296
+ it "should not allow shell injection in options" do
297
+ imgkit = IMGKit.new('html', :password => "blah\"; touch #{@test_path} #")
298
+ lambda { imgkit.to_img }.should raise_error(IMGKit::CommandFailedError)
299
+ end
300
+ end
301
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe IMGKit::Source do
4
+
5
+ describe "#url?" do
6
+ it "should return true if passed a url like string" do
7
+ source = IMGKit::Source.new('http://google.com')
8
+ source.should be_url
9
+ end
10
+
11
+ it "should return false if passed a file" do
12
+ source = IMGKit::Source.new(File.new(__FILE__))
13
+ source.should_not be_url
14
+ end
15
+
16
+ it "should return false if passed HTML" do
17
+ source = IMGKit::Source.new('<blink>Oh Hai!</blink>')
18
+ source.should_not be_url
19
+ end
20
+
21
+ it "should return false if passed HTML with a line starting with 'http'" do
22
+ source = IMGKit::Source.new("<blink>Oh Hai!</blink>\nhttp://google.com")
23
+ source.should_not be_url
24
+ end
25
+ end
26
+
27
+ describe "#file?" do
28
+ it "should return true if passed a file" do
29
+ source = IMGKit::Source.new(File.new(__FILE__))
30
+ source.should be_file
31
+ end
32
+
33
+ it "should return true if passed a temporary file" do
34
+ source = IMGKit::Source.new(Tempfile.new 'temp_file')
35
+ source.should be_file
36
+ end
37
+
38
+ it "should return false if passed a url like string" do
39
+ source = IMGKit::Source.new('http://google.com')
40
+ source.should_not be_file
41
+ end
42
+
43
+ it "should return false if passed HTML" do
44
+ source = IMGKit::Source.new('<blink>Oh Hai!</blink>')
45
+ source.should_not be_file
46
+ end
47
+ end
48
+
49
+ describe "#html?" do
50
+ it "should return true if passed HTML" do
51
+ source = IMGKit::Source.new('<blink>Oh Hai!</blink>')
52
+ source.should be_html
53
+ end
54
+
55
+ it "should return false if passed a file" do
56
+ source = IMGKit::Source.new(File.new(__FILE__))
57
+ source.should_not be_html
58
+ end
59
+
60
+ it "should return false if passed a url like string" do
61
+ source = IMGKit::Source.new('http://google.com')
62
+ source.should_not be_html
63
+ end
64
+ end
65
+
66
+ describe "#to_s" do
67
+ it "should return the HTML if passed HTML" do
68
+ source = IMGKit::Source.new('<blink>Oh Hai!</blink>')
69
+ source.to_s.should == '<blink>Oh Hai!</blink>'
70
+ end
71
+
72
+ it "should return a path if passed a file" do
73
+ source = IMGKit::Source.new(File.new(__FILE__))
74
+ source.to_s.should == __FILE__
75
+ end
76
+
77
+ it "should return the url if passed a url like string" do
78
+ source = IMGKit::Source.new('http://google.com')
79
+ source.to_s.should == 'http://google.com'
80
+ end
81
+ end
82
+
83
+ end
@@ -0,0 +1,48 @@
1
+ SPEC_ROOT = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift(SPEC_ROOT)
3
+ $LOAD_PATH.unshift(File.join(SPEC_ROOT, '..', 'lib'))
4
+ require 'imgkit'
5
+ require 'rspec'
6
+ require 'rspec/autorun'
7
+ require 'mocha'
8
+ require 'rack'
9
+ require 'tempfile'
10
+
11
+ RSpec.configure do |config|
12
+ config.before do
13
+ IMGKit.any_instance.stubs(:wkhtmltoimage).returns(
14
+ File.join(SPEC_ROOT,'..','bin','wkhtmltoimage-proxy')
15
+ )
16
+ end
17
+ end
18
+
19
+ module MagicNumber
20
+ extend self
21
+ JPG = "\xFF\xD8\xFF\xE0"
22
+ JPEG = JPG
23
+ PNG = "\x89\x50\x4e\x47"
24
+ TIFF = "\x49\x49\x2a\x00"
25
+ TIF = TIFF
26
+ GIF = "\x47\x49\x46\x38"
27
+
28
+
29
+ if "".respond_to?(:force_encoding)
30
+ constants.each { |c| const_get(c).force_encoding("ASCII-8BIT") }
31
+ end
32
+
33
+ def read(string)
34
+ string[0,4]
35
+ end
36
+ end
37
+
38
+ RSpec::Matchers.define :be_a do |expected|
39
+ match do |actual|
40
+ @expected = MagicNumber.const_get(expected.to_s.upcase)
41
+ MagicNumber.read(actual) == @expected
42
+ end
43
+
44
+ failure_message_for_should do |actual|
45
+ actual = MagicNumber.read(actual)
46
+ "expctected #{actual.inspect},#{actual.encoding} to equal #{@expected.inspect},#{@expected.encoding}"
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+
3
+ for i in {1..1000}; do
4
+ echo "Some kind of a long error message so that the operating system buffer gets filled" > /dev/stderr
5
+ done
6
+
7
+ echo "result"
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: img-kit
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.9.1
5
+ platform: ruby
6
+ authors:
7
+ - csquared
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-20 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Uses wkhtmltoimage to create Images using HTML
14
+ email: christopher.continanza@gmail.com
15
+ executables:
16
+ - imgkit
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - .document
21
+ - .gitignore
22
+ - .rspec
23
+ - .rvmrc
24
+ - Gemfile
25
+ - Gemfile.lock
26
+ - LICENSE
27
+ - POST_INSTALL
28
+ - README.md
29
+ - Rakefile
30
+ - bin/imgkit
31
+ - imgkit.gemspec
32
+ - lib/imgkit.rb
33
+ - lib/imgkit/configuration.rb
34
+ - lib/imgkit/imgkit.rb
35
+ - lib/imgkit/source.rb
36
+ - lib/imgkit/version.rb
37
+ - spec/error_binary
38
+ - spec/fixtures/example.css
39
+ - spec/fixtures/example.html
40
+ - spec/imgkit_spec.rb
41
+ - spec/source_spec.rb
42
+ - spec/spec_helper.rb
43
+ - spec/warning_binary
44
+ homepage: http://github.com/topspin/imgkit
45
+ licenses: []
46
+ metadata: {}
47
+ post_install_message: |
48
+ ******************************************************************
49
+
50
+ Now install wkhtmltoimage binaries:
51
+ Global: sudo `which imgkit` --install-wkhtmltoimage
52
+ rvmsudo imgkit --install-wkhtmltoimage
53
+ (installs to default /usr/local/bin/wkhtmltoimage)
54
+
55
+ inside RVM folder: export TO=`which imgkit | sed 's:/imgkit:/wkhtmltoimage:'` && imgkit --install-wkhtmltoimage
56
+ (you'll have to configure the location of the binary if you do this!)
57
+
58
+ (run imgkit --help to see more options)
59
+ ******************************************************************
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 2.1.0
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: HTML+CSS -> JPG
79
+ test_files:
80
+ - spec/error_binary
81
+ - spec/fixtures/example.css
82
+ - spec/fixtures/example.html
83
+ - spec/imgkit_spec.rb
84
+ - spec/source_spec.rb
85
+ - spec/spec_helper.rb
86
+ - spec/warning_binary
87
+ has_rdoc: