Class: Thumbshooter

Inherits:
Object
  • Object
show all
Defined in:
lib/thumbshooter.rb,
lib/webkit2png.rb

Overview

Binding for webkit2png

Constant Summary collapse

IMAGE_TYPE =
'png'
CHECK_LOADING_STATUS_INTERVAL =
0.1
WEBKIT2PNG =
File.dirname(__FILE__) + '/webkit2png.rb'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Thumbshooter

screen: dimension of the view part (w * h) i.e. 800x800 resize: resize thumbshot (w * h) i.e. 160x160 format: png (any others?) timeout: timeout for the page to load



23
24
25
26
27
28
29
30
# File 'lib/thumbshooter.rb', line 23

def initialize
  @timeout     = 30
  @state       = 'waiting'
  @progress    = 0
  @started_at  = nil
  @output      = nil
  self.screen_size = '1024x768'
end

Instance Attribute Details

#timeoutObject

Returns the value of attribute timeout.



26
27
28
# File 'lib/webkit2png.rb', line 26

def timeout
  @timeout
end

Class Method Details

.use_xvfbObject

use X window virtual framebuffer?



12
13
14
# File 'lib/thumbshooter.rb', line 12

def self.use_xvfb
  @use_xvfb
end

.use_xvfb=(value) ⇒ Object

use X window virtual framebuffer?



7
8
9
# File 'lib/thumbshooter.rb', line 7

def self.use_xvfb=(value)
  @use_xvfb = value
end

Instance Method Details

#create(url, output = nil) ⇒ Object

creates a thumbshot returns it if no output-path given



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/thumbshooter.rb', line 50

def create(url, output=nil)
  args = @args
  args << "--output=#{output}" if output

  # execute webkit2png-script and save stdout
  command = ''
  if self.class.use_xvfb
    # calculate screen size
    screen = @screen.split('x').collect{|i|i.to_i+100}.join("x") 
    # add xvfb wrapper
    command << "xvfb-run -a --server-args='-screen 0, #{screen}x24' "
  end

  command << "#{WEBKIT2PNG} '#{url}' #{args}"

  img    = `#{command} 2>&1`
  status = $?.to_i
  pos    = img.index("\211PNG")

  if status != 0 || !pos
    raise "#{WEBKIT2PNG} failed with status #{status}: #{img}"
  end

  # strip beginning rubish
  img = img[pos..-1]

  if @resize
    width,height = geometry(@resize)
    img = resize(img,width,height)
  end

  if @crop
    width,height = geometry(@crop)
    img = crop(img,width,height)
  end

  img
end

#create_by_html(html) ⇒ Object

creates a thumb from direct html using a temporary file



90
91
92
93
94
95
96
97
98
99
100
# File 'lib/thumbshooter.rb', line 90

def create_by_html(html)
  tmp_file = Tempfile.new('thumbshot.html')
  tmp_file.write(html)
  tmp_file.close

  begin
    create(tmp_file.path)
  ensure
    tmp_file.close!
  end
end

#generate(url) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/webkit2png.rb', line 42

def generate(url)
  app     = Qt::Application.new(ARGV)
  webview = Qt::WebView.new()
  
  webview.connect(SIGNAL("loadStarted()")) do
    @started_at = Time.now.to_i
  end
  
  webview.connect(SIGNAL('loadFinished(bool)')) do |result|
    if result
      @state = 'finished-success'
    else
      @state = 'finished-fail'
      @progress = false
    end
    suspend_thread # Give it enough time to switch to the sentinel thread and avoid an empty exec loop
  end
  
  webview.connect(SIGNAL("loadProgress(int)")) do |progress|
    @progress = progress
    suspend_thread if has_reached_time_out?
  end
  
  # Hide the scrollbars
  mainFrame = webview.page.mainFrame
  mainFrame.setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff)
  mainFrame.setScrollBarPolicy(Qt::Vertical,   Qt::ScrollBarAlwaysOff)
  
  webview.load(Qt::Url.new(url))
  webview.resize(@screen_size)
  webview.show
  render_page_thread = Thread.new do
    app.exec
  end
  
  check_status_thread = Thread.new do
    while true do
      sleep CHECK_LOADING_STATUS_INTERVAL
      if @state =~ /^finished/ || has_reached_time_out?
        # Save a screenshot if page finished loaded or it has timed out with 50%+ completion
        if @state == 'finished-success' || (@progress && @progress >= 50)
          save_screenshot(webview)
        end
        render_page_thread.kill
        break
      end
    end
  end
  
  check_status_thread.join
  render_page_thread.join
  
  # percentage of completion
  @progress
end

#outputObject



98
99
100
# File 'lib/webkit2png.rb', line 98

def output
  @output
end

#progressObject



102
103
104
# File 'lib/webkit2png.rb', line 102

def progress
  @progress
end

#screen_size=(value) ⇒ Object

Raises:

  • (ArgumentError)


37
38
39
40
# File 'lib/webkit2png.rb', line 37

def screen_size=(value)
  raise ArgumentError, "invalid size: #{value}" unless value =~ /^(\d+)x(\d+$)/
  @screen_size = Qt::Size.new($~[1].to_i, $~[2].to_i)
end