osxscreenshot 0.0.1
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/.autotest +23 -0
- data/History.txt +5 -0
- data/Manifest.txt +8 -0
- data/README.txt +60 -0
- data/Rakefile +12 -0
- data/lib/osxscreenshot.rb +86 -0
- data/test/test_osxscreenshot.rb +29 -0
- data/vendor/webkit2png.py +285 -0
- metadata +97 -0
data/.autotest
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
|
5
|
+
# Autotest.add_hook :initialize do |at|
|
6
|
+
# at.extra_files << "../some/external/dependency.rb"
|
7
|
+
#
|
8
|
+
# at.libs << ":../some/external"
|
9
|
+
#
|
10
|
+
# at.add_exception 'vendor'
|
11
|
+
#
|
12
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
13
|
+
# at.files_matching(/test_.*rb$/)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# %w(TestA TestB).each do |klass|
|
17
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# Autotest.add_hook :run_command do |at|
|
22
|
+
# system "rake build"
|
23
|
+
# end
|
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
= osxscreenshot
|
2
|
+
|
3
|
+
* http://gemcutter.org/gems/osxscreenshot
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Wrapper around webkit2png.py to easily and programmatically capture
|
8
|
+
screenshots, crop, and resize them on Mac OS X.
|
9
|
+
|
10
|
+
== FEATURES/PROBLEMS:
|
11
|
+
|
12
|
+
* Uses the Python built-in to Mac OS X.
|
13
|
+
* You may be able to use snapurl instead of webkit2png.py: http://gemcutter.org/gems/snapurl
|
14
|
+
|
15
|
+
== REQUIREMENTS:
|
16
|
+
|
17
|
+
* Uses Python's Cocoa support (standard in Mac OS X).
|
18
|
+
|
19
|
+
== INSTALL:
|
20
|
+
|
21
|
+
* gem install osxscreenshot
|
22
|
+
|
23
|
+
== DEVELOPERS:
|
24
|
+
|
25
|
+
Call the +capture+ method with the desired URL and some (optional) options.
|
26
|
+
|
27
|
+
output_screenshot_path =
|
28
|
+
OSX::Screenshot.capture(my_url, {
|
29
|
+
:tmp => "#{Sinatra::Application.root}/tmp",
|
30
|
+
:webkit2png => "#{Sinatra::Application.root}/bin/webkit2png.py",
|
31
|
+
:mogrify => "/opt/local/bin/mogrify",
|
32
|
+
:width => 220,
|
33
|
+
:height => 270
|
34
|
+
})
|
35
|
+
system "mv #{output_screenshot_path} #{local_path}"
|
36
|
+
|
37
|
+
== LICENSE:
|
38
|
+
|
39
|
+
(The MIT License)
|
40
|
+
|
41
|
+
Copyright (c) 2010 Topfunky Corporation
|
42
|
+
|
43
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
44
|
+
a copy of this software and associated documentation files (the
|
45
|
+
'Software'), to deal in the Software without restriction, including
|
46
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
47
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
48
|
+
permit persons to whom the Software is furnished to do so, subject to
|
49
|
+
the following conditions:
|
50
|
+
|
51
|
+
The above copyright notice and this permission notice shall be
|
52
|
+
included in all copies or substantial portions of the Software.
|
53
|
+
|
54
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
55
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
56
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
57
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
58
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
59
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
60
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
module OSX
|
2
|
+
module Screenshot
|
3
|
+
VERSION = '0.0.1'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Takes a screenshot of a website, optionally resizes it, and writes
|
7
|
+
# it to a temporary directory. Returns the file path to the
|
8
|
+
# temporary file.
|
9
|
+
#
|
10
|
+
# It's assumed that you will move the file to a permanent
|
11
|
+
# destination or store it in a database.
|
12
|
+
#
|
13
|
+
# Options include:
|
14
|
+
#
|
15
|
+
# tmpdir:: Path to tmp directory where files will be stored
|
16
|
+
# webkit2png:: Path to webkit2png.py command
|
17
|
+
# mogrify:: Path to mogrify command
|
18
|
+
#
|
19
|
+
# Usage:
|
20
|
+
#
|
21
|
+
# output_screenshot_path =
|
22
|
+
# OSX::Screenshot.capture(article_url, {
|
23
|
+
# :tmpdir => "#{Sinatra::Application.root}/tmp",
|
24
|
+
# :webkit2png => "#{Sinatra::Application.root}/bin/webkit2png.py",
|
25
|
+
# :mogrify => "/opt/local/bin/mogrify",
|
26
|
+
# :width => 220,
|
27
|
+
# :height => 270
|
28
|
+
# })
|
29
|
+
# system "mv #{output_screenshot_path} #{local_path}"
|
30
|
+
|
31
|
+
def self.capture(url, options={})
|
32
|
+
vendored_webkit2png = File.expand_path(File.join(File.dirname(__FILE__),
|
33
|
+
"..",
|
34
|
+
"vendor",
|
35
|
+
"webkit2png.py"))
|
36
|
+
options = {
|
37
|
+
:tmpdir => "/tmp",
|
38
|
+
:webkit2png => vendored_webkit2png,
|
39
|
+
:mogrify => "mogrify",
|
40
|
+
:width => 320,
|
41
|
+
:height => 480
|
42
|
+
}.merge(options)
|
43
|
+
|
44
|
+
random_id = [url.length, Time.now.to_i.to_s, rand(10000)].join('-')
|
45
|
+
tmp_abs_filename = File.join(options[:tmpdir], "#{random_id}-full.png")
|
46
|
+
tmp_dir = File.dirname(tmp_abs_filename)
|
47
|
+
FileUtils.mkdir_p(tmp_dir)
|
48
|
+
|
49
|
+
webkit2png_command = options[:webkit2png]
|
50
|
+
|
51
|
+
system(*[webkit2png_command,
|
52
|
+
"--full",
|
53
|
+
"--filename", random_id,
|
54
|
+
"--dir", options[:tmpdir],
|
55
|
+
url
|
56
|
+
])
|
57
|
+
|
58
|
+
# Example: mogrify -resize 320x peepcodecom-full.png -crop 320x480 peepcodecom-full.png
|
59
|
+
mogrify_command = options[:mogrify]
|
60
|
+
target_width = options[:width]
|
61
|
+
target_height = options[:height]
|
62
|
+
system(*[mogrify_command,
|
63
|
+
"-resize", "#{target_width}x",
|
64
|
+
tmp_abs_filename,
|
65
|
+
"-crop", "#{target_width}x#{target_height}",
|
66
|
+
tmp_abs_filename
|
67
|
+
])
|
68
|
+
|
69
|
+
output_filename = if File.exist?(tmp_abs_filename)
|
70
|
+
# Add full width and height to image
|
71
|
+
system(*[mogrify_command,
|
72
|
+
"-extent", "#{target_width}x#{target_height}",
|
73
|
+
tmp_abs_filename])
|
74
|
+
tmp_abs_filename
|
75
|
+
elsif File.exist?(tmp_abs_filename.gsub(/\.png/, '-0.png'))
|
76
|
+
# Remove extra file generated by cropping.
|
77
|
+
FileUtils.rm(tmp_abs_filename.gsub(/\.png/, '-1.png'))
|
78
|
+
tmp_abs_filename.gsub(/\.png/, '-0.png')
|
79
|
+
end
|
80
|
+
return output_filename
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "osxscreenshot"
|
3
|
+
|
4
|
+
class TestOsxscreenshot < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_loads_url
|
7
|
+
@tmpfile = OSX::Screenshot.capture("http://example.com")
|
8
|
+
assert_not_nil @tmpfile
|
9
|
+
assert File.exist?(@tmpfile)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_loads_tall_url
|
13
|
+
@tmpfile = OSX::Screenshot.capture("http://blog.peepcode.com/archives")
|
14
|
+
|
15
|
+
extra_file_name = @tmpfile.gsub(/-0\.png$/, "-1.png")
|
16
|
+
assert !File.exist?(extra_file_name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_uses_custom_tmpdir
|
20
|
+
@tmpfile = OSX::Screenshot.capture("http://example.com", :tmpdir => "./tmp")
|
21
|
+
assert_match /^\.\/tmp/, @tmpfile
|
22
|
+
assert File.exist?(@tmpfile)
|
23
|
+
end
|
24
|
+
|
25
|
+
def teardown
|
26
|
+
FileUtils.rm @tmpfile
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,285 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
# webkit2png - makes screenshots of webpages
|
4
|
+
# http://www.paulhammond.org/webkit2png
|
5
|
+
|
6
|
+
__version__ = "0.5"
|
7
|
+
|
8
|
+
# Copyright (c) 2009 Paul Hammond
|
9
|
+
#
|
10
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
11
|
+
# of this software and associated documentation files (the "Software"), to deal
|
12
|
+
# in the Software without restriction, including without limitation the rights
|
13
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14
|
+
# copies of the Software, and to permit persons to whom the Software is
|
15
|
+
# furnished to do so, subject to the following conditions:
|
16
|
+
#
|
17
|
+
# The above copyright notice and this permission notice shall be included in
|
18
|
+
# all copies or substantial portions of the Software.
|
19
|
+
#
|
20
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
26
|
+
# THE SOFTWARE.
|
27
|
+
#
|
28
|
+
|
29
|
+
import sys
|
30
|
+
import optparse
|
31
|
+
|
32
|
+
try:
|
33
|
+
import Foundation
|
34
|
+
import WebKit
|
35
|
+
import AppKit
|
36
|
+
import objc
|
37
|
+
except ImportError:
|
38
|
+
print "Cannot find pyobjc library files. Are you sure it is installed?"
|
39
|
+
sys.exit()
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
class AppDelegate (Foundation.NSObject):
|
44
|
+
# what happens when the app starts up
|
45
|
+
def applicationDidFinishLaunching_(self, aNotification):
|
46
|
+
webview = aNotification.object().windows()[0].contentView()
|
47
|
+
webview.frameLoadDelegate().getURL(webview)
|
48
|
+
self.performSelector_withObject_afterDelay_( "timeout:", None, 60 )
|
49
|
+
|
50
|
+
def timeout_(self, obj):
|
51
|
+
NSLog("timed out!")
|
52
|
+
NSApplication.sharedApplication().terminate_(None)
|
53
|
+
|
54
|
+
class WebkitLoad (Foundation.NSObject, WebKit.protocols.WebFrameLoadDelegate):
|
55
|
+
|
56
|
+
# what happens if something goes wrong while loading
|
57
|
+
def webView_didFailLoadWithError_forFrame_(self,webview,error,frame):
|
58
|
+
print " ... something went wrong: "+error.localizedDescription()
|
59
|
+
self.getURL(webview)
|
60
|
+
|
61
|
+
def webView_didFailProvisionalLoadWithError_forFrame_(self,webview,error,frame):
|
62
|
+
print " ... something went wrong: "+error.localizedDescription()
|
63
|
+
self.getURL(webview)
|
64
|
+
|
65
|
+
def makeFilename(self,URL,options):
|
66
|
+
# make the filename
|
67
|
+
if options.filename:
|
68
|
+
filename = options.filename
|
69
|
+
elif options.md5:
|
70
|
+
try:
|
71
|
+
import md5
|
72
|
+
except ImportError:
|
73
|
+
print "--md5 requires python md5 library"
|
74
|
+
AppKit.NSApplication.sharedApplication().terminate_(None)
|
75
|
+
filename = md5.new(URL).hexdigest()
|
76
|
+
else:
|
77
|
+
import re
|
78
|
+
filename = re.sub('\W','',URL);
|
79
|
+
filename = re.sub('^http','',filename);
|
80
|
+
if options.datestamp:
|
81
|
+
import time
|
82
|
+
now = time.strftime("%Y%m%d")
|
83
|
+
filename = now + "-" + filename
|
84
|
+
import os
|
85
|
+
dir = os.path.abspath(os.path.expanduser(options.dir))
|
86
|
+
return os.path.join(dir,filename)
|
87
|
+
|
88
|
+
def saveImages(self,bitmapdata,filename,options):
|
89
|
+
# save the fullsize png
|
90
|
+
if options.fullsize:
|
91
|
+
bitmapdata.representationUsingType_properties_(AppKit.NSPNGFileType,None).writeToFile_atomically_(filename + "-full.png",objc.YES)
|
92
|
+
|
93
|
+
if options.thumb or options.clipped:
|
94
|
+
# work out how big the thumbnail is
|
95
|
+
width = bitmapdata.pixelsWide()
|
96
|
+
height = bitmapdata.pixelsHigh()
|
97
|
+
thumbWidth = (width * options.scale)
|
98
|
+
thumbHeight = (height * options.scale)
|
99
|
+
|
100
|
+
# make the thumbnails in a scratch image
|
101
|
+
scratch = AppKit.NSImage.alloc().initWithSize_(
|
102
|
+
Foundation.NSMakeSize(thumbWidth,thumbHeight))
|
103
|
+
scratch.lockFocus()
|
104
|
+
AppKit.NSGraphicsContext.currentContext().setImageInterpolation_(
|
105
|
+
AppKit.NSImageInterpolationHigh)
|
106
|
+
thumbRect = Foundation.NSMakeRect(0.0, 0.0, thumbWidth, thumbHeight)
|
107
|
+
clipRect = Foundation.NSMakeRect(0.0,
|
108
|
+
thumbHeight-options.clipheight,
|
109
|
+
options.clipwidth, options.clipheight)
|
110
|
+
bitmapdata.drawInRect_(thumbRect)
|
111
|
+
thumbOutput = AppKit.NSBitmapImageRep.alloc().initWithFocusedViewRect_(thumbRect)
|
112
|
+
clipOutput = AppKit.NSBitmapImageRep.alloc().initWithFocusedViewRect_(clipRect)
|
113
|
+
scratch.unlockFocus()
|
114
|
+
|
115
|
+
# save the thumbnails as pngs
|
116
|
+
if options.thumb:
|
117
|
+
thumbOutput.representationUsingType_properties_(
|
118
|
+
AppKit.NSPNGFileType,None
|
119
|
+
).writeToFile_atomically_(filename + "-thumb.png",objc.YES)
|
120
|
+
if options.clipped:
|
121
|
+
clipOutput.representationUsingType_properties_(
|
122
|
+
AppKit.NSPNGFileType,None
|
123
|
+
).writeToFile_atomically_(filename + "-clipped.png",objc.YES)
|
124
|
+
|
125
|
+
def getURL(self,webview):
|
126
|
+
if self.urls:
|
127
|
+
if self.urls[0] == '-':
|
128
|
+
url = sys.stdin.readline().rstrip()
|
129
|
+
if not url: AppKit.NSApplication.sharedApplication().terminate_(None)
|
130
|
+
else:
|
131
|
+
url = self.urls.pop(0)
|
132
|
+
else:
|
133
|
+
AppKit.NSApplication.sharedApplication().terminate_(None)
|
134
|
+
print "Fetching", url, "..."
|
135
|
+
self.resetWebview(webview)
|
136
|
+
webview.mainFrame().loadRequest_(Foundation.NSURLRequest.requestWithURL_(Foundation.NSURL.URLWithString_(url)))
|
137
|
+
if not webview.mainFrame().provisionalDataSource():
|
138
|
+
print " ... not a proper url?"
|
139
|
+
self.getURL(webview)
|
140
|
+
|
141
|
+
def resetWebview(self,webview):
|
142
|
+
rect = Foundation.NSMakeRect(0,0,self.options.initWidth,self.options.initHeight)
|
143
|
+
webview.window().setContentSize_((self.options.initWidth,self.options.initHeight))
|
144
|
+
webview.setFrame_(rect)
|
145
|
+
|
146
|
+
def resizeWebview(self,view):
|
147
|
+
view.window().display()
|
148
|
+
view.window().setContentSize_(view.bounds().size)
|
149
|
+
view.setFrame_(view.bounds())
|
150
|
+
|
151
|
+
def captureView(self,view):
|
152
|
+
view.lockFocus()
|
153
|
+
bitmapdata = AppKit.NSBitmapImageRep.alloc()
|
154
|
+
bitmapdata.initWithFocusedViewRect_(view.bounds())
|
155
|
+
view.unlockFocus()
|
156
|
+
return bitmapdata
|
157
|
+
|
158
|
+
# what happens when the page has finished loading
|
159
|
+
def webView_didFinishLoadForFrame_(self,webview,frame):
|
160
|
+
# don't care about subframes
|
161
|
+
if (frame == webview.mainFrame()):
|
162
|
+
Foundation.NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_( self.options.delay, self, self.doGrab, webview, False)
|
163
|
+
|
164
|
+
def doGrab(self,timer):
|
165
|
+
webview = timer.userInfo()
|
166
|
+
view = webview.mainFrame().frameView().documentView()
|
167
|
+
|
168
|
+
self.resizeWebview(view)
|
169
|
+
|
170
|
+
URL = webview.mainFrame().dataSource().initialRequest().URL().absoluteString()
|
171
|
+
filename = self.makeFilename(URL, self.options)
|
172
|
+
|
173
|
+
bitmapdata = self.captureView(view)
|
174
|
+
self.saveImages(bitmapdata,filename,self.options)
|
175
|
+
|
176
|
+
print " ... done"
|
177
|
+
self.getURL(webview)
|
178
|
+
|
179
|
+
|
180
|
+
def main():
|
181
|
+
|
182
|
+
# parse the command line
|
183
|
+
usage = """%prog [options] [http://example.net/ ...]
|
184
|
+
|
185
|
+
examples:
|
186
|
+
%prog http://google.com/ # screengrab google
|
187
|
+
%prog -W 1000 -H 1000 http://google.com/ # bigger screengrab of google
|
188
|
+
%prog -T http://google.com/ # just the thumbnail screengrab
|
189
|
+
%prog -TF http://google.com/ # just thumbnail and fullsize grab
|
190
|
+
%prog -o foo http://google.com/ # save images as "foo-thumb.png" etc
|
191
|
+
%prog - # screengrab urls from stdin
|
192
|
+
%prog -h | less # full documentation"""
|
193
|
+
|
194
|
+
cmdparser = optparse.OptionParser(usage,version=("webkit2png "+__version__))
|
195
|
+
# TODO: add quiet/verbose options
|
196
|
+
cmdparser.add_option("-W", "--width",type="float",default=800.0,
|
197
|
+
help="initial (and minimum) width of browser (default: 800)")
|
198
|
+
cmdparser.add_option("-H", "--height",type="float",default=600.0,
|
199
|
+
help="initial (and minimum) height of browser (default: 600)")
|
200
|
+
cmdparser.add_option("--clipwidth",type="float",default=200.0,
|
201
|
+
help="width of clipped thumbnail (default: 200)",
|
202
|
+
metavar="WIDTH")
|
203
|
+
cmdparser.add_option("--clipheight",type="float",default=150.0,
|
204
|
+
help="height of clipped thumbnail (default: 150)",
|
205
|
+
metavar="HEIGHT")
|
206
|
+
cmdparser.add_option("-s", "--scale",type="float",default=0.25,
|
207
|
+
help="scale factor for thumbnails (default: 0.25)")
|
208
|
+
cmdparser.add_option("-m", "--md5", action="store_true",
|
209
|
+
help="use md5 hash for filename (like del.icio.us)")
|
210
|
+
cmdparser.add_option("-o", "--filename", type="string",default="",
|
211
|
+
metavar="NAME", help="save images as NAME-full.png,NAME-thumb.png etc")
|
212
|
+
cmdparser.add_option("-F", "--fullsize", action="store_true",
|
213
|
+
help="only create fullsize screenshot")
|
214
|
+
cmdparser.add_option("-T", "--thumb", action="store_true",
|
215
|
+
help="only create thumbnail sreenshot")
|
216
|
+
cmdparser.add_option("-C", "--clipped", action="store_true",
|
217
|
+
help="only create clipped thumbnail screenshot")
|
218
|
+
cmdparser.add_option("-d", "--datestamp", action="store_true",
|
219
|
+
help="include date in filename")
|
220
|
+
cmdparser.add_option("-D", "--dir",type="string",default="./",
|
221
|
+
help="directory to place images into")
|
222
|
+
cmdparser.add_option("--delay",type="float",default=0,
|
223
|
+
help="delay between page load finishing and screenshot")
|
224
|
+
cmdparser.add_option("--noimages", action="store_true",
|
225
|
+
help="don't load images")
|
226
|
+
cmdparser.add_option("--debug", action="store_true",
|
227
|
+
help=optparse.SUPPRESS_HELP)
|
228
|
+
(options, args) = cmdparser.parse_args()
|
229
|
+
if len(args) == 0:
|
230
|
+
cmdparser.print_usage()
|
231
|
+
return
|
232
|
+
if options.filename:
|
233
|
+
if len(args) != 1 or args[0] == "-":
|
234
|
+
print "--filename option requires exactly one url"
|
235
|
+
return
|
236
|
+
if options.scale == 0:
|
237
|
+
cmdparser.error("scale cannot be zero")
|
238
|
+
# make sure we're outputing something
|
239
|
+
if not (options.fullsize or options.thumb or options.clipped):
|
240
|
+
options.fullsize = True
|
241
|
+
options.thumb = True
|
242
|
+
options.clipped = True
|
243
|
+
# work out the initial size of the browser window
|
244
|
+
# (this might need to be larger so clipped image is right size)
|
245
|
+
options.initWidth = (options.clipwidth / options.scale)
|
246
|
+
options.initHeight = (options.clipheight / options.scale)
|
247
|
+
if options.width>options.initWidth:
|
248
|
+
options.initWidth = options.width
|
249
|
+
if options.height>options.initHeight:
|
250
|
+
options.initHeight = options.height
|
251
|
+
|
252
|
+
app = AppKit.NSApplication.sharedApplication()
|
253
|
+
|
254
|
+
# create an app delegate
|
255
|
+
delegate = AppDelegate.alloc().init()
|
256
|
+
AppKit.NSApp().setDelegate_(delegate)
|
257
|
+
|
258
|
+
# create a window
|
259
|
+
rect = Foundation.NSMakeRect(0,0,100,100)
|
260
|
+
win = AppKit.NSWindow.alloc()
|
261
|
+
win.initWithContentRect_styleMask_backing_defer_ (rect,
|
262
|
+
AppKit.NSBorderlessWindowMask, 2, 0)
|
263
|
+
if options.debug:
|
264
|
+
win.orderFrontRegardless()
|
265
|
+
# create a webview object
|
266
|
+
webview = WebKit.WebView.alloc()
|
267
|
+
webview.initWithFrame_(rect)
|
268
|
+
# turn off scrolling so the content is actually x wide and not x-15
|
269
|
+
webview.mainFrame().frameView().setAllowsScrolling_(objc.NO)
|
270
|
+
|
271
|
+
webview.setPreferencesIdentifier_('webkit2png')
|
272
|
+
webview.preferences().setLoadsImagesAutomatically_(not options.noimages)
|
273
|
+
|
274
|
+
# add the webview to the window
|
275
|
+
win.setContentView_(webview)
|
276
|
+
|
277
|
+
# create a LoadDelegate
|
278
|
+
loaddelegate = WebkitLoad.alloc().init()
|
279
|
+
loaddelegate.options = options
|
280
|
+
loaddelegate.urls = args
|
281
|
+
webview.setFrameLoadDelegate_(loaddelegate)
|
282
|
+
|
283
|
+
app.run()
|
284
|
+
|
285
|
+
if __name__ == '__main__' : main()
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: osxscreenshot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Geoffrey Grosenbach
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-16 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rubyforge
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.3
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: gemcutter
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.0
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: hoe
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.5.0
|
44
|
+
version:
|
45
|
+
description: |-
|
46
|
+
Wrapper around webkit2png.py to easily and programmatically capture
|
47
|
+
screenshots, crop, and resize them on Mac OS X.
|
48
|
+
email:
|
49
|
+
- boss@topfunky.com
|
50
|
+
executables: []
|
51
|
+
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
extra_rdoc_files:
|
55
|
+
- History.txt
|
56
|
+
- Manifest.txt
|
57
|
+
- README.txt
|
58
|
+
files:
|
59
|
+
- .autotest
|
60
|
+
- History.txt
|
61
|
+
- Manifest.txt
|
62
|
+
- README.txt
|
63
|
+
- Rakefile
|
64
|
+
- lib/osxscreenshot.rb
|
65
|
+
- test/test_osxscreenshot.rb
|
66
|
+
- vendor/webkit2png.py
|
67
|
+
has_rdoc: true
|
68
|
+
homepage: http://gemcutter.org/gems/osxscreenshot
|
69
|
+
licenses: []
|
70
|
+
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options:
|
73
|
+
- --main
|
74
|
+
- README.txt
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: "0"
|
82
|
+
version:
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: "0"
|
88
|
+
version:
|
89
|
+
requirements: []
|
90
|
+
|
91
|
+
rubyforge_project: osxscreenshot
|
92
|
+
rubygems_version: 1.3.5
|
93
|
+
signing_key:
|
94
|
+
specification_version: 3
|
95
|
+
summary: Wrapper around webkit2png.py to easily and programmatically capture screenshots, crop, and resize them on Mac OS X.
|
96
|
+
test_files:
|
97
|
+
- test/test_osxscreenshot.rb
|