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 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/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ === 0.0.1 / 2010-02-16
2
+
3
+ * First release
4
+
5
+
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ lib/osxscreenshot.rb
7
+ test/test_osxscreenshot.rb
8
+ vendor/webkit2png.py
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,12 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.spec 'osxscreenshot' do
7
+ developer('Geoffrey Grosenbach', 'boss@topfunky.com')
8
+
9
+ # self.rubyforge_name = 'osxscreenshotx' # if different than 'osxscreenshot'
10
+ end
11
+
12
+ # vim: syntax=ruby
@@ -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