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 +21 -0
- data/LICENSE +27 -0
- data/README.rdoc +106 -0
- data/bin/snapurl +7 -0
- data/lib/core/application.rb +96 -0
- data/lib/core/camera.rb +225 -0
- data/lib/snapurl.rb +28 -0
- data/test/test_snapurl.rb +0 -0
- metadata +74 -0
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,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
|
data/lib/core/camera.rb
ADDED
|
@@ -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
|