osxscreenshot 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -4,13 +4,15 @@
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- Wrapper around webkit2png.py to easily and programmatically capture
8
- screenshots of websites, then crop and resize them. Mac OS X only.
7
+ A Ruby wrapper around webkit2png.py to easily and programmatically
8
+ capture screenshots of websites, then crop and resize them. Mac OS X
9
+ only.
9
10
 
10
11
  == FEATURES/PROBLEMS:
11
12
 
12
13
  * Uses the Python built-in to Mac OS X.
13
14
  * You may be able to use snapurl instead of webkit2png.py: http://gemcutter.org/gems/snapurl
15
+ * See examples in use at http://blog.peepcode.com/archives and http://news.peepcode.com/
14
16
 
15
17
  == REQUIREMENTS:
16
18
 
@@ -32,7 +34,7 @@ Or, pass some (optional) options.
32
34
 
33
35
  file_path =
34
36
  OSX::Screenshot.capture(my_url, {
35
- :tmp => "#{Sinatra::Application.root}/tmp",
37
+ :tmpdir => "#{Sinatra::Application.root}/tmp",
36
38
  :webkit2png => "#{Sinatra::Application.root}/bin/webkit2png.py",
37
39
  :mogrify => "/opt/local/bin/mogrify",
38
40
  :width => 220,
data/Rakefile CHANGED
@@ -5,7 +5,9 @@ require 'hoe'
5
5
 
6
6
  Hoe.spec 'osxscreenshot' do
7
7
  developer('Geoffrey Grosenbach', 'boss@topfunky.com')
8
-
8
+
9
+ extra_deps << ['open4']
10
+
9
11
  # self.rubyforge_name = 'osxscreenshotx' # if different than 'osxscreenshot'
10
12
  end
11
13
 
data/lib/osxscreenshot.rb CHANGED
@@ -1,6 +1,8 @@
1
+ require 'open4'
2
+
1
3
  module OSX
2
- module Screenshot
3
- VERSION = '0.0.2'
4
+ class Screenshot
5
+ VERSION = '0.0.3'
4
6
 
5
7
  ##
6
8
  # Takes a screenshot of a website, optionally resizes it, and writes
@@ -29,55 +31,88 @@ module OSX
29
31
  # system "mv #{output_screenshot_path} #{local_path}"
30
32
 
31
33
  def self.capture(url, options={})
34
+ obj = new(url, options)
35
+ obj.capture
36
+ end
37
+
38
+ def initialize(url, options)
32
39
  vendored_webkit2png = File.expand_path(File.join(File.dirname(__FILE__),
33
40
  "..",
34
41
  "vendor",
35
42
  "webkit2png.py"))
36
- options = {
43
+ @url = url
44
+ @options = {
37
45
  :tmpdir => "/tmp",
38
46
  :webkit2png => vendored_webkit2png,
39
47
  :mogrify => "mogrify",
40
48
  :width => 320,
41
- :height => 480
49
+ :height => 480,
50
+ :timeout => 30
42
51
  }.merge(options)
52
+ end
43
53
 
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")
54
+ def capture
55
+ random_id = [@url.length, Time.now.to_i.to_s, rand(10000)].join('-')
56
+ tmp_abs_filename = File.join(@options[:tmpdir], "#{random_id}-full.png")
46
57
  tmp_dir = File.dirname(tmp_abs_filename)
47
58
  FileUtils.mkdir_p(tmp_dir)
48
59
 
49
- webkit2png_command = options[:webkit2png]
60
+ webkit2png_command = [@options[:webkit2png],
61
+ "--full",
62
+ "--filename", random_id,
63
+ "--dir", @options[:tmpdir],
64
+ @url
65
+ ].join(' ')
50
66
 
51
- system(*[webkit2png_command,
52
- "--full",
53
- "--filename", random_id,
54
- "--dir", options[:tmpdir],
55
- url
56
- ])
67
+ run_command(webkit2png_command) do
68
+ return resize(tmp_abs_filename, @options[:width], @options[:height])
69
+ end
70
+ end
57
71
 
72
+ def resize(tmp_abs_filename, width, height)
58
73
  # 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
74
 
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
75
+ mogrify_command = [@options[:mogrify],
76
+ "-resize", "#{width}x",
77
+ tmp_abs_filename,
78
+ "-crop", "#{width}x#{height}",
79
+ tmp_abs_filename
80
+ ].join(' ')
81
+ run_command(mogrify_command) do
82
+ output_filename = if File.exist?(tmp_abs_filename)
83
+ # Add full width and height to image
84
+ extent_command = [@options[:mogrify],
85
+ "-extent", "#{width}x#{height}",
86
+ tmp_abs_filename].join(' ')
87
+ run_command(extent_command) { return tmp_abs_filename }
88
+ elsif File.exist?(tmp_abs_filename.gsub(/\.png/, '-0.png'))
89
+ # Remove extra file generated by cropping.
90
+ FileUtils.rm(tmp_abs_filename.gsub(/\.png/, '-1.png'))
91
+ tmp_abs_filename.gsub(/\.png/, '-0.png')
92
+ end
93
+ return output_filename
94
+ end
95
+ end
96
+
97
+ def run_command(cmd, &block)
98
+ pid = nil
99
+ status = nil
100
+
101
+ Timeout.timeout(@options[:timeout]) {
102
+ pid, i, o, e = open4(cmd)
103
+ ignored, status = Process::waitpid2 pid
104
+ }
105
+
106
+ # Success
107
+ if (status.exitstatus == 0)
108
+ return yield
109
+ end
110
+
111
+ # Error
112
+ system "kill -9 #{pid}"
113
+ raise "Command failed: #{cmd}"
114
+ rescue Timeout::Error => e
115
+ return nil
81
116
  end
82
117
 
83
118
  end
@@ -2,7 +2,7 @@ require "test/unit"
2
2
  require "osxscreenshot"
3
3
 
4
4
  class TestOsxscreenshot < Test::Unit::TestCase
5
-
5
+
6
6
  def test_loads_url
7
7
  @tmpfile = OSX::Screenshot.capture("http://example.com")
8
8
  assert_not_nil @tmpfile
@@ -15,15 +15,25 @@ class TestOsxscreenshot < Test::Unit::TestCase
15
15
  extra_file_name = @tmpfile.gsub(/-0\.png$/, "-1.png")
16
16
  assert !File.exist?(extra_file_name)
17
17
  end
18
-
18
+
19
19
  def test_uses_custom_tmpdir
20
20
  @tmpfile = OSX::Screenshot.capture("http://example.com", :tmpdir => "./tmp")
21
21
  assert_match(/^\.\/tmp/, @tmpfile)
22
22
  assert File.exist?(@tmpfile)
23
23
  end
24
-
24
+
25
+ def test_handles_timeout
26
+ @tmpfile = OSX::Screenshot.capture("http://example.com", {
27
+ :timeout => 1,
28
+ :webkit2png => "sleep 5 &&"
29
+ })
30
+ assert_nil @tmpfile
31
+ end
32
+
25
33
  def teardown
26
- FileUtils.rm @tmpfile
34
+ if @tmpfile
35
+ FileUtils.rm @tmpfile
36
+ end
27
37
  end
28
38
 
29
39
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: osxscreenshot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoffrey Grosenbach
@@ -9,9 +9,19 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-16 00:00:00 -08:00
12
+ date: 2010-02-18 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: open4
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
15
25
  - !ruby/object:Gem::Dependency
16
26
  name: rubyforge
17
27
  type: :development
@@ -43,8 +53,9 @@ dependencies:
43
53
  version: 2.5.0
44
54
  version:
45
55
  description: |-
46
- Wrapper around webkit2png.py to easily and programmatically capture
47
- screenshots of websites, then crop and resize them. Mac OS X only.
56
+ A Ruby wrapper around webkit2png.py to easily and programmatically
57
+ capture screenshots of websites, then crop and resize them. Mac OS X
58
+ only.
48
59
  email:
49
60
  - boss@topfunky.com
50
61
  executables: []
@@ -92,6 +103,6 @@ rubyforge_project: osxscreenshot
92
103
  rubygems_version: 1.3.5
93
104
  signing_key:
94
105
  specification_version: 3
95
- summary: Wrapper around webkit2png.py to easily and programmatically capture screenshots of websites, then crop and resize them
106
+ summary: A Ruby wrapper around webkit2png.py to easily and programmatically capture screenshots of websites, then crop and resize them
96
107
  test_files:
97
108
  - test/test_osxscreenshot.rb