snapurl 0.0.3

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.
data/History ADDED
@@ -0,0 +1,21 @@
1
+ === 0.0.3 / 2009-10-19
2
+
3
+ * Added install-cocoa script.
4
+ * Moved to jeweler for package/project management
5
+ (http://github.com/technicalpickles/jeweler)
6
+ * Added support for file:// urls - thanks to Joel Chippindale
7
+ (http://blog.monkeysthumb.org)
8
+ * Added dependency to thoughtbot-shoulda
9
+ (http://thoughtbot.com/projects/shoulda)
10
+ * Gem name is now jurisgalang-snapurl
11
+ * No longer uses Hoe
12
+
13
+ === 0.0.2 / 2009-04-04
14
+
15
+ * Light house-keeping.
16
+ * Merged changes by Michael Kohl (http://citizen428.net)
17
+ * Added RubyCocoa source package and installation task.
18
+
19
+ === 0.0.1 / 2009-02-08
20
+
21
+ * Birthday!
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2008, 2009 Juris Galang
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ Except as contained in this notice, the name(s) of the above
16
+ copyright holders shall not be used in advertising or otherwise to
17
+ promote the sale, use or other dealings in this Software without
18
+ prior written authorization.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,106 @@
1
+ = snapurl
2
+
3
+ Take snapshots of web pages. This is a Ruby/RubyCocoa port of the webkit2png.py script by Paul Hammond (http://www.paulhammond.org/webkit2png/) with some minor modifications.
4
+
5
+ See also: http://www.jurisgalang.com/articles/show/SnapUrl
6
+
7
+
8
+ == Requirements:
9
+
10
+ * OS X only.
11
+ * RubyCocoa (Leopard and Snow Leopard will already have this installed)
12
+ * Ruby 1.8.7 (Ruby 1.9.x wont play with RubyCocoa)
13
+
14
+ If you intend to work with the source and do your own builds, the project expects that you have the following gems installed:
15
+
16
+ * gemcutter
17
+ * jeweler
18
+ * rcov
19
+ * thoughtbot-shoulda
20
+
21
+
22
+ == Installation
23
+
24
+ $ sudo gem install snapurl
25
+
26
+ This gem is published at gemcutter (http://gemcutter.org), so you'll need to add it as a gem source (unless you already have):
27
+
28
+ $ gem sources -a http://gemcutter.org
29
+
30
+ Alternatively you can build the gem from source and install:
31
+
32
+ $ git clone git://github.com/jurisgalang/snapurl.git
33
+ $ cd snapurl
34
+ $ rake gemspec install
35
+
36
+ To build and install a specific tag:
37
+
38
+ $ git clone git://github.com/jurisgalang/snapurl.git
39
+ $ cd snapurl
40
+ $ git checkout -f -b `whoami`-snapurl v0.0.3
41
+ $ rake gemspec install
42
+
43
+
44
+ == Install RubyCocoa
45
+
46
+ If you have a custom Ruby installation then you'll also need to do a custom build and install of RubyCocoa. I've bundled the latest release source and a script to do this for you:
47
+
48
+ $ cd snapurl
49
+ $ ./thirdparty/install-cocoa
50
+
51
+ NOTE: Your custom Ruby installation must have had --enable-shared flag on when you built it.
52
+
53
+
54
+ == Usage
55
+
56
+ Just pass a list of URLs to the snapurl script and it will take a snapshot of the pages found in those URLs:
57
+
58
+ $ snapurl http://artists.gawker.com/ # takes a snapshot of gawker artists
59
+ $ snapurl http://io9.com/ http://artists.gawker.com/ # ... and io9 websites.
60
+
61
+ By default snapurl generates a set of files per URL that it processes: thumbnail, clipped, and full-sized view of the web pages in PNG format.
62
+
63
+
64
+ == Note on Patches/Pull Requests
65
+
66
+ * Fork the project.
67
+ * Make your feature addition or bug fix.
68
+ * Add tests for it. This is important so I don't break it in a
69
+ future version unintentionally.
70
+ * Commit, do not mess with rakefile, version, or history.
71
+ (if you want to have your own version, that is fine but
72
+ bump version in a commit by itself I can ignore when I pull)
73
+ * Send me a pull request. Bonus points for topic branches.
74
+
75
+
76
+ == License
77
+
78
+ (The MIT License)
79
+
80
+ Copyright (c) 2008, 2009 Juris Galang
81
+
82
+ Permission is hereby granted, free of charge, to any person
83
+ obtaining a copy of this software and associated documentation
84
+ files (the "Software"), to deal in the Software without
85
+ restriction, including without limitation the rights to use,
86
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
87
+ copies of the Software, and to permit persons to whom the
88
+ Software is furnished to do so, subject to the following
89
+ conditions:
90
+
91
+ The above copyright notice and this permission notice shall be
92
+ included in all copies or substantial portions of the Software.
93
+
94
+ Except as contained in this notice, the name(s) of the above
95
+ copyright holders shall not be used in advertising or otherwise to
96
+ promote the sale, use or other dealings in this Software without
97
+ prior written authorization.
98
+
99
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
100
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
101
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
102
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
103
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
104
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
105
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
106
+ OTHER DEALINGS IN THE SOFTWARE.
data/bin/snapurl ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File::join(File::dirname(__FILE__), '..', 'lib')
4
+ require 'rubygems'
5
+ require 'snapurl'
6
+
7
+ SnapUrl::Application::run(ARGV)
@@ -0,0 +1,96 @@
1
+ =begin
2
+ * Name: SnapUrl
3
+ * Description:
4
+ * This is a Ruby/RubyCocoa port of the webkit2png.py script by Paul Hammond
5
+ * (http://www.paulhammond.org/webkit2png/) with some minor modifications.
6
+ * Author: Juris Galang (http://www.JurisGalang.com)
7
+ * Date: 09/15/08
8
+ * License:
9
+ =end
10
+ module SnapUrl
11
+ class Application
12
+ def Application::run(args)
13
+ config = Application.parse(args)
14
+ Camera::snap(config[:urls], config[:options])
15
+ end
16
+
17
+ # TODO: add option to control log-level
18
+ # TODO: add implementation for verbose run
19
+ # TODO: set --include-format = true if more than one format
20
+ def Application::parse(args)
21
+ options = Camera::DEFAULT_OPTIONS
22
+ begin
23
+ opts = OptionParser.new do |opts|
24
+ opts.banner = <<-EOF
25
+ Usage: #{opts.program_name} url0 [url1] [url2]... [options]
26
+
27
+ #{opts.program_name} is a command line tool that creates PNG screenshots of webpages.
28
+ With tall or wide pages that would normally require scrolling, it takes
29
+ screenshots of the whole webpage, not just the area that would be visible
30
+ in a browser window.
31
+
32
+ It is a Ruby/RubyCocoa port of the webkit2png.py script by Paul Hammond
33
+ (http://www.paulhammond.org/webkit2png/)
34
+ EOF
35
+ opts.banner.gsub!(/ /, '')
36
+
37
+ opts.separator ' '
38
+ opts.separator 'Specific Options:'
39
+ opts.on('--width [WIDTH]', Float, "initial and minimum browser width (default: #{options[:browser][:width].to_i})") { |n| options[:browser][:width] = n }
40
+ opts.on('--height [HEIGHT]', Float, "initial and minimum browser height (default: #{options[:browser][:height].to_i})") { |n| options[:browser][:height] = n }
41
+
42
+ opts.separator ' '
43
+ opts.on('--[no-]fullsize', "create fullsize screenshot") { |n| n ? options[:snapFormat] << :fullsize : options[:snapFormat].delete(:fullsize) }
44
+ opts.on('--[no-]thumbnail', "create thumbnail") { |n| n ? options[:snapFormat] << :thumbnail : options[:snapFormat].delete(:thumbnail) }
45
+ opts.on('--[no-]clip', "create clip of thumbnail") { |n| n ? options[:snapFormat] << :clip : options[:snapFormat].delete(:clip) }
46
+
47
+ opts.separator ' '
48
+ opts.on('--scale [SCALE]', Float, "scale factor for thumbnails (default: #{options[:scaleFactor]})") { |n| options[:scaleFactor] = n }
49
+
50
+ opts.separator ' '
51
+ opts.on('--clipwidth [WIDTH]', Float, "width of clipped thumbnail (default: #{options[:clip][:width].to_i})") { |n| options[:clip][:width] = n }
52
+ opts.on('--clipheight [HEIGHT]', Float, "height of clipped thumbnail (default: #{options[:clip][:height].to_i})") { |n| options[:clip][:height] = n }
53
+
54
+ opts.separator ' '
55
+ opts.on('-f', '--filename [NAME]', "use NAME as part of filename (derived from url if not specified)") { |n| options[:filename] = n }
56
+
57
+ opts.on('--use-md5hash', "use md5 hash for filename (overriden by --filename)") { |n| options[:useHashForFilename?] = n }
58
+ opts.on('--include-datestamp', "include date in filename") { |n| options[:datestampInFilename?] = n }
59
+ opts.on('--include-timestamp', "include time in filename") { |n| options[:timestampInFilename?] = n }
60
+ opts.on('--include-size', "include image size in filename") { |n| options[:sizeInFilename?] = n }
61
+ opts.on('--include-format', "include image format in filename") { |n| options[:snapFormatInFilename?] = n }
62
+
63
+ opts.separator ' '
64
+ opts.on('-d', '--output-dir [DIRNAME]', "directory to place images into (default: #{options[:outputDirectory]})") { |n| options[:outputDirectory] = n }
65
+
66
+ opts.separator ' '
67
+ opts.separator 'Common Options:'
68
+ opts.on('-v', "--[no-]verbose", "Run verbosely") { |n| options[:verbose?] = n }
69
+ opts.on_tail("-h", "--help", "Show this message") do
70
+ puts opts.help
71
+ exit
72
+ end
73
+
74
+ opts.on_tail("--version", "Show version") do
75
+ puts opts.ver
76
+ exit
77
+ end
78
+ end
79
+
80
+ urls = opts.permute!(args)
81
+
82
+ raise OptionParser::MissingArgument.new('you need to supply at least one URL') if urls.empty?
83
+ raise OptionParser::InvalidArgument.new('you can only use the filename option if there is only one URL') if (urls.size > 1) && !options[:filename].empty?
84
+ raise OptionParser::InvalidArgument.new('scale cannot be zero') if options[:scaleFactor] < 0.0
85
+ # width and height cannot be zero or less than minimum
86
+ # clipwidth and clipheight cannot be zero or less than minimum
87
+ raise OptionParser::AmbiguousArgument.new('you need to allow at least one format') if options[:snapFormat].empty?
88
+
89
+ return { :urls => urls, :options => options }
90
+ rescue OptionParser::ParseError => e
91
+ puts "#{e.message.capitalize}"
92
+ exit(1)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,225 @@
1
+ =begin
2
+ * Name: SnapUrl
3
+ * Description:
4
+ * This is a Ruby/RubyCocoa port of the webkit2png.py script by Paul Hammond
5
+ * (http://www.paulhammond.org/webkit2png/) with some minor modifications.
6
+ * Author: Juris Galang (http://www.JurisGalang.com)
7
+ * Date: 09/15/08
8
+ * License:
9
+ =end
10
+
11
+ module SnapUrl
12
+ module Camera
13
+ DEFAULT_OPTIONS = {
14
+ :browser => {:width => 800.0, :height => 600.0},
15
+ :clip => {:width => 200.0, :height => 150.0},
16
+ :snapFormat => [:fullsize, :thumbnail, :clip],
17
+ :scaleFactor => 0.25,
18
+ :filename => '',
19
+ :datestampInFilename? => false,
20
+ :timestampInFilename? => false,
21
+ :sizeInFilename? => false,
22
+ :snapFormatInFilename? => false,
23
+ :useHashForFilename? => false,
24
+ :outputDirectory => Dir.pwd,
25
+ :verbose? => false
26
+ }
27
+
28
+ def Camera::snap(urls, options = {})
29
+ # create context
30
+ OSX::NSApplication.sharedApplication
31
+
32
+ # create an app delegate
33
+ delegate = AppDelegate.alloc.init
34
+ OSX::NSApp.setDelegate(delegate)
35
+
36
+ # create a webview object
37
+ rect = OSX::NSMakeRect(-16000, -16000, 100, 100)
38
+ webview = OSX::WebView.alloc.initWithFrame(rect)
39
+ webview.setMediaStyle('screen')
40
+ webview.mainFrame.frameView.setAllowsScrolling(false)
41
+
42
+ # make sure we don't save any of the prefs that we change.
43
+ webview.preferences.setAutosaves(false)
44
+ webview.preferences.setShouldPrintBackgrounds(true)
45
+ webview.preferences.setJavaScriptCanOpenWindowsAutomatically(false)
46
+ webview.preferences.setAllowsAnimatedImages(false)
47
+
48
+ # create a window and set view
49
+ win = OSX::NSWindow.alloc
50
+ win.initWithContentRect_styleMask_backing_defer(rect, OSX::NSBorderlessWindowMask, OSX::NSBackingStoreBuffered, false)
51
+ win.setContentView(webview)
52
+
53
+ # create load delegate
54
+ loader = LoadDelegate.alloc.init
55
+ loader.urls = urls
56
+ loader.options = DEFAULT_OPTIONS.merge(options)
57
+ webview.setFrameLoadDelegate(loader)
58
+
59
+ # now run
60
+ OSX::NSApp.run
61
+ end
62
+
63
+ class AppDelegate < OSX::NSObject
64
+ def applicationDidFinishLaunching(aNotification)
65
+ webview = aNotification.object.windows.objectAtIndex(0).contentView
66
+ webview.frameLoadDelegate.fetchUrl(webview)
67
+ end
68
+ end
69
+
70
+ class LoadDelegate < OSX::NSObject
71
+ attr_accessor :options, :urls, :logger
72
+
73
+ def urls=(urls)
74
+ @urls = urls.to_a
75
+ end
76
+
77
+ def options=(options)
78
+ # adjust configs
79
+ options[:snapFormatInFilename?] = true if (options[:snapFormat].size > 1) && !options[:snapFormatInFilename?]
80
+
81
+ w = options[:clip][:width] / options[:scaleFactor]
82
+ h = options[:clip][:height] / options[:scaleFactor]
83
+ options[:browser][:width] = w unless w < options[:browser][:width]
84
+ options[:browser][:height] = h unless h < options[:browser][:height]
85
+
86
+ @options = options
87
+ end
88
+
89
+ def init
90
+ @logger = Logger.new(STDOUT)
91
+ self
92
+ end
93
+
94
+ def webView_didFailLoadWithError_forFrame(webview, error, frame)
95
+ @logger.warn "#{error.localizedDescription}"
96
+ fetchUrl(webview)
97
+ end
98
+
99
+ def webView_didFailProvisionalLoadWithError_forFrame(webview, error, frame)
100
+ @logger.warn "#{error.localizedDescription}"
101
+ fetchUrl(webview)
102
+ end
103
+
104
+ def webView_didFinishLoadForFrame(webview, frame)
105
+ # don't care about subframes
106
+ return unless (frame == webview.mainFrame)
107
+ docview = frame.frameView.documentView
108
+ resizeWebView(docview)
109
+
110
+ @logger.info "Capturing..."
111
+ url = frame.dataSource.initialRequest.URL.absoluteString
112
+ bitmap = captureView(docview)
113
+ saveImages(url, bitmap)
114
+
115
+ @logger.info "Done!"
116
+ fetchUrl(webview)
117
+ end
118
+
119
+ def resetWebView(view)
120
+ rect = OSX::NSMakeRect(0, 0, browser[:width], browser[:height])
121
+ view.window.setContentSize([browser[:width], browser[:height]])
122
+ view.setFrame(rect)
123
+ end
124
+
125
+ def resizeWebView(view)
126
+ view.setNeedsDisplay(true)
127
+ view.displayIfNeeded
128
+ view.window.setContentSize(view.bounds.size)
129
+ view.setFrame(view.bounds)
130
+ end
131
+
132
+ def captureView(view)
133
+ view.lockFocus
134
+ bitmap = OSX::NSBitmapImageRep.alloc
135
+ bitmap.initWithFocusedViewRect(view.bounds)
136
+ view.unlockFocus
137
+ bitmap
138
+ end
139
+
140
+ def fetchUrl(webview)
141
+ OSX::NSApplication.sharedApplication.terminate(self) if @urls.empty?
142
+
143
+ url = String.new(@urls.shift)
144
+
145
+ url.gsub!(/^/, "http:\/\/") unless url =~ /^(http(s)?|file):\/\//
146
+ @logger.info "Fetching #{url}..."
147
+
148
+ resetWebView(webview)
149
+ webview.mainFrame.loadRequest(OSX::NSURLRequest.requestWithURL(OSX::NSURL.URLWithString(url)))
150
+
151
+ return if webview.mainFrame.provisionalDataSource
152
+ fetchUrl(webview)
153
+ end
154
+
155
+ def makeFilename(url, bitmap, format)
156
+ if !filename.empty?
157
+ name = filename
158
+
159
+ elsif useHashForFilename?
160
+ name = Digest::MD5.new.hexdigest(url)
161
+
162
+ else
163
+ name = String.new(url)
164
+ name.gsub!(/\W/, '');
165
+ name.gsub!(/^http(s)?/i, '');
166
+ name.gsub!(/\//, '.');
167
+ end
168
+
169
+ name = "#{Time.now.strftime('%H%M%S')}-#{name}" if timestampInFilename?
170
+ name = "#{Time.now.strftime('%Y%m%d')}-#{name}" if datestampInFilename?
171
+ name = "#{name}-#{bitmap.pixelsWide}x#{bitmap.pixelsHigh}" if sizeInFilename?
172
+ name = "#{name}-#{format}" if snapFormatInFilename?
173
+
174
+ name = "#{name}.png"
175
+
176
+ name = File.join(File.expand_path(outputDirectory), name) unless outputDirectory.empty?
177
+ name
178
+ end
179
+
180
+ def saveImages(url, bitmap)
181
+ writeToFile(url, bitmap, :fullsize) if snapFormat.include?(:fullsize)
182
+
183
+ if snapFormat.include?(:thumbnail) || snapFormat.include?(:clip)
184
+ # work out how big the thumbnail is
185
+ thumbWidth = bitmap.pixelsWide * scaleFactor
186
+ thumbHeight = bitmap.pixelsHigh * scaleFactor
187
+
188
+ # make the thumbnails in a scratch image
189
+ scratch = OSX::NSImage.alloc.initWithSize(OSX::NSMakeSize(thumbWidth, thumbHeight))
190
+ scratch.lockFocus
191
+ OSX::NSGraphicsContext.currentContext.setImageInterpolation(OSX::NSImageInterpolationHigh)
192
+ thumbRect = OSX::NSMakeRect(0.0, 0.0, thumbWidth, thumbHeight)
193
+ clipRect = OSX::NSMakeRect(0.0, thumbHeight - clip[:height], clip[:width], clip[:height])
194
+ bitmap.drawInRect(thumbRect)
195
+ thumbnail = OSX::NSBitmapImageRep.alloc.initWithFocusedViewRect(thumbRect)
196
+ clipping = OSX::NSBitmapImageRep.alloc.initWithFocusedViewRect(clipRect)
197
+ scratch.unlockFocus
198
+
199
+ # save the thumbnails as pngs
200
+ writeToFile(url, thumbnail, :thumbnail) if snapFormat.include?(:thumbnail)
201
+ writeToFile(url, clipping, :clip) if snapFormat.include?(:clip)
202
+ end
203
+ end
204
+
205
+ def writeToFile(url, bitmap, format)
206
+ name = makeFilename(url, bitmap, format)
207
+ FileUtils.mkdir_p File.dirname(name)
208
+ bitmap.representationUsingType_properties(OSX::NSPNGFileType, nil).writeToFile_atomically(name, true)
209
+ end
210
+
211
+ def ping(url)
212
+ open(url) rescue nil
213
+ end
214
+
215
+ def method_missing(name, *args)
216
+ if args.empty?
217
+ k = name.to_sym
218
+ super(name, args) unless @options.keys.include?(k)
219
+ return @options[k]
220
+ end
221
+ super(name, args)
222
+ end
223
+ end
224
+ end
225
+ end
data/lib/snapurl.rb ADDED
@@ -0,0 +1,28 @@
1
+ =begin
2
+ * Name: SnapUrl
3
+ * Description:
4
+ * This is a Ruby/RubyCocoa port of the webkit2png.py script by Paul Hammond
5
+ * (http://www.paulhammond.org/webkit2png/) with some minor modifications.
6
+ * Author: Juris Galang (http://www.JurisGalang.com)
7
+ * Date: 09/15/08
8
+ * License:
9
+ =end
10
+ require 'digest/md5'
11
+ require 'fileutils'
12
+ require 'logger'
13
+ require 'optparse'
14
+ require 'ostruct'
15
+ require 'open-uri'
16
+
17
+ require 'osx/cocoa'
18
+ OSX.require_framework 'WebKit'
19
+
20
+ require 'core/camera'
21
+ require 'core/application'
22
+
23
+ Version = "0.0.2"
24
+ Release = "alpha"
25
+
26
+ module SnapUrl
27
+ VERSION = Version
28
+ end
File without changes
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: snapurl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Juris Galang
8
+ - Michael Kohl
9
+ - Joel Chippindale
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-10-20 00:00:00 -07:00
15
+ default_executable: snapurl
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: thoughtbot-shoulda
19
+ type: :development
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: "0"
26
+ version:
27
+ description: "\n Take snapshots of websites. This is a Ruby/RubyCocoa port of the \n webkit2png.py script by Paul Hammond \n (http://www.paulhammond.org/webkit2png/) with some minor modifications -\n Generates a set of image files representing the thumbnail, clipped, \n and full-sized view of a web page in PNG format. "
28
+ email: jurisgalang@gmail.com
29
+ executables:
30
+ - snapurl
31
+ extensions: []
32
+
33
+ extra_rdoc_files:
34
+ - LICENSE
35
+ - README.rdoc
36
+ files:
37
+ - History
38
+ - README.rdoc
39
+ - bin/snapurl
40
+ - lib/core/application.rb
41
+ - lib/core/camera.rb
42
+ - lib/snapurl.rb
43
+ - test/test_snapurl.rb
44
+ - LICENSE
45
+ has_rdoc: true
46
+ homepage: http://github.com/jurisgalang/snapurl
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.5
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Take snapshots of websites.
73
+ test_files:
74
+ - test/test_snapurl.rb