geetarista (owner)

Fork Of

Revisions

gist: 94711 Download_button fork
public
Public Clone URL: git://gist.github.com/94711.git
Embed All Files: show embed
Ruby #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env macruby
#
# DarkRoom
# Takes fullsize screenshots of a web page.
# Copyright (c) 2007 Justin Palmer.
# Rewrote for MacRuby by Laurent Sansonetti.
#
# Released under an MIT LICENSE
#
# Usage
# ====
# ruby ./darkroom.rb http://activereload.net
# ruby ./darkroom.rb --output=google.png http://google.com
# ruby ./darkroom.rb --width=400 --delay=5 http://yahoo.com
#
 
require 'optparse'
require 'pp'
framework 'WebKit'
 
module ActiveReload
  module DarkRoom
    USER_AGENT = "DarkRoom/0.1"
    class Photographer
      def initialize
        options = {}
        opts = OptionParser.new do |opts|
          opts.banner = "Usage: #$0 [options] URL"
      
          opts.on('-w', '--width=[WIDTH]', Integer, 'Force width of the screenshot') do |v|
            options[:width] = v
          end
      
          opts.on('-h', '--height=[HEIGHT]', Integer, 'Force height of screenshot') do |v|
            options[:height] = v
          end
          
          opts.on('-o', '--output=[FILENAME]', String, 'Specify filename for saving') do |v|
            options[:output] = v
          end
          
          opts.on('-d', '--delay=[DELAY]', Integer, 'Delay in seconds to give web page assets time to load') do |v|
            options[:delay] = v
          end
      
          opts.on_tail('-h', '--help', 'Display this message and exit') do
            puts opts
            exit
          end
        end.parse!
        options[:width] ||= 1024
        options[:height] ||= 0
        options[:website] = ARGV.first || 'http://ruby-lang.org'
        Camera.shoot(options)
      end
    end
 
    class Camera
      def self.shoot(options)
        app = NSApplication.sharedApplication
        delegate = Processor.new
        delegate.options = options
        app.delegate = delegate
        app.run
      end
    end
 
    class Processor
      attr_accessor :options, :web_view
  
      def initialize
        rect = [-16000.0, -16000.0, 100, 100]
        win = NSWindow.alloc.initWithContentRect rect,
          styleMask:NSBorderlessWindowMask,
          backing:2,
          defer:0
    
        @web_view = WebView.alloc.initWithFrame rect
        @web_view.mainFrame.frameView.allowsScrolling = false
        @web_view.applicationNameForUserAgent = USER_AGENT
        @web_view.frameLoadDelegate = self
    
        NSNotificationCenter.defaultCenter.addObserver(self, selector:'webview_finished_loading:', name:WebViewProgressFinishedNotification, object:@web_view)
        
        win.contentView = @web_view
      end
      
      def webview_finished_loading(sender)
        puts "WOOT"
      end
      
      def applicationDidFinishLaunching(notification)
        @options[:output] ||= "#{Time.now.strftime('%m-%d-%y-%H%I%S')}.png"
        @web_view.window.contentSize = [@options[:width], @options[:height]]
        @web_view.frameSize = [@options[:width], @options[:height]]
        @web_view.mainFrame.loadRequest NSURLRequest.requestWithURL NSURL.URLWithString @options[:website]
      end
  
      def webView(web_view, didFinishLoadForFrame:frame)
        viewport = frame.frameView.documentView
 
        # if viewport.bounds.size.height == 0
        # viewport = web_view.mainFrame.childFrames[0].frameView.documentView
        # end
        
        viewport.window.orderFront(nil)
        viewport.window.display
        
        viewport.window.contentSize = [@options[:width], (@options[:height] > 0 ? @options[:height] : viewport.bounds.size.height)]
        viewport.frame = viewport.bounds
        sleep(@options[:delay]) if @options[:delay]
        capture_and_save viewport
      end
  
      def capture_and_save(view)
        # bounds = view.bounds
        # if bounds.size.height == 0
        # bounds = NSMakeRect(0,0,1024,800)
        # view.setFrame(bounds)
        # end
        
        view.lockFocus
          bitmap = NSBitmapImageRep.alloc.initWithFocusedViewRect view.bounds
        view.unlockFocus
    
        repr = bitmap.representationUsingType NSPNGFileType, properties:nil
        repr.writeToFile @options[:output], atomically:true
        NSApplication.sharedApplication.terminate nil
      end
    end
  end
end
 
ActiveReload::DarkRoom::Photographer.new