wunderbar 0.14.7 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -107,6 +107,7 @@ module Wunderbar
107
107
  def initialize(args)
108
108
  @_scope = args.delete(:scope)
109
109
  @_builder = SpacedMarkup.new(args)
110
+ @_pdf = false
110
111
  end
111
112
 
112
113
  # forward to Wunderbar, XmlMarkup, or @_scope
@@ -148,6 +149,14 @@ module Wunderbar
148
149
  end
149
150
  end
150
151
 
152
+ def pdf=(value)
153
+ @_pdf = value
154
+ end
155
+
156
+ def pdf?
157
+ @_pdf
158
+ end
159
+
151
160
  # execute a system command, echoing stdin, stdout, and stderr
152
161
  def system(command, opts={})
153
162
  if command.respond_to? :join
@@ -1,10 +1,10 @@
1
1
  require 'digest/md5'
2
2
 
3
3
  module Wunderbar
4
- module CGI
4
+ class CGI
5
5
 
6
6
  # produce json
7
- def self.json(scope, &block)
7
+ def json(scope, &block)
8
8
  headers = { 'type' => 'application/json', 'Cache-Control' => 'no-cache' }
9
9
  builder = JsonBuilder.new(scope)
10
10
  output = builder.encode(&block)
@@ -18,7 +18,7 @@ module Wunderbar
18
18
  end
19
19
 
20
20
  # produce text
21
- def self.text(scope, &block)
21
+ def text(scope, &block)
22
22
  headers = {'type' => 'text/plain', 'charset' => 'UTF-8'}
23
23
  builder = TextBuilder.new(scope)
24
24
  output = builder.encode(&block)
@@ -31,7 +31,7 @@ module Wunderbar
31
31
  end
32
32
 
33
33
  # Conditionally provide output, based on ETAG
34
- def self.out?(scope, headers, &block)
34
+ def out?(scope, headers, &block)
35
35
  content = block.call
36
36
  etag = Digest::MD5.hexdigest(content)
37
37
 
@@ -49,16 +49,53 @@ module Wunderbar
49
49
  Wunderbar.fatal exception.inspect
50
50
  end
51
51
 
52
+ def html2pdf(input=nil, &block)
53
+ require 'thread'
54
+ require 'open3'
55
+ require 'stringio'
56
+
57
+ display=":#{rand(999)+1}"
58
+ pid = fork do
59
+ # close open files
60
+ STDIN.reopen '/dev/null'
61
+ STDOUT.reopen '/dev/null', 'a'
62
+ STDERR.reopen STDOUT
63
+
64
+ Process.setsid
65
+ Wunderbar.error Process.exec("Xvfb #{display}")
66
+ Process.exit
67
+ end
68
+ Process.detach(pid)
69
+
70
+ ENV['DISPLAY']=display
71
+ input ||= block.call
72
+ output = StringIO.new
73
+
74
+ Open3.popen3('wkhtmltopdf - -') do |pin, pout, perr|
75
+ [
76
+ Thread.new { pin.write input; pin.close },
77
+ Thread.new { IO.copy_stream(pout, output) },
78
+ Thread.new { perr.readpartial(4096) until perr.eof? }
79
+ ].map(&:join)
80
+ end
81
+
82
+ output.string
83
+ ensure
84
+ Process.kill 'INT', pid rescue nil
85
+ end
86
+
52
87
  # produce html/xhtml
53
- def self.html(scope, *args, &block)
88
+ def html(scope, *args, &block)
54
89
  headers = { 'type' => 'text/html', 'charset' => 'UTF-8' }
55
90
  headers['type'] = 'application/xhtml+xml' if @xhtml
56
91
 
57
92
  x = HtmlMarkup.new(scope)
58
93
 
59
94
  begin
60
- if @xhtml
61
- output = x.xhtml *args, &block
95
+ if @pdf
96
+ x._.pdf = true if @pdf
97
+ headers = { 'type' => 'application/pdf' }
98
+ output = html2pdf {x.html *args, &block}
62
99
  else
63
100
  output = x.html *args, &block
64
101
  end
@@ -80,23 +117,32 @@ module Wunderbar
80
117
  end
81
118
 
82
119
  def self.call(scope)
120
+ new.call(scope)
121
+ end
122
+
123
+ def call(scope)
83
124
  env = scope.env
84
- accept = env['HTTP_ACCEPT'].to_s
85
- request_uri = env['REQUEST_URI'].to_s
125
+ accept = env['HTTP_ACCEPT'].to_s
126
+ path_info = env['PATH_INFO'].to_s
86
127
 
87
128
  # implied request types
88
129
  xhr_json = Wunderbar::Options::XHR_JSON || (accept =~ /json/)
89
130
  text = Wunderbar::Options::TEXT ||
90
131
  (accept =~ /plain/ and accept !~ /html/)
91
132
  @xhtml = (accept =~ /xhtml/ or accept == '')
92
-
93
- # overrides via the uri query parameter
94
- xhr_json ||= (request_uri =~ /\?json$/)
95
- text ||= (request_uri =~ /\?text$/)
133
+ @pdf = (accept =~ /pdf/)
96
134
 
97
135
  # overrides via the command line
98
136
  xhtml_override = ARGV.include?('--xhtml')
99
137
  html_override = ARGV.include?('--html')
138
+ @pdf ||= ARGV.include?('--pdf')
139
+
140
+ # overrides via the uri query parameter
141
+ xhr_json ||= (path_info.end_with? '.json')
142
+ text ||= (path_info.end_with? '.text')
143
+ @pdf ||= (path_info.end_with? '.pdf')
144
+ xhtml_override ||= (path_info.end_with? '.xhtml')
145
+ html_override ||= (path_info.end_with? '.html')
100
146
 
101
147
  # disable conneg if only one handler is provided
102
148
  if Wunderbar.queue.length == 1
@@ -16,12 +16,6 @@ module Wunderbar
16
16
  def initialize(scope)
17
17
  @_scope = scope
18
18
  @x = XmlMarkup.new :scope => scope, :indent => 2, :target => []
19
- @xthml = false
20
- end
21
-
22
- def xhtml(*args, &block)
23
- @xhtml = true
24
- html(*args, &block)
25
19
  end
26
20
 
27
21
  def html(*args, &block)
@@ -50,15 +44,6 @@ module Wunderbar
50
44
  html(*args, &block)
51
45
  end
52
46
 
53
- def _xhtml(*args, &block)
54
- @xhtml = true
55
- html(*args, &block)
56
- end
57
-
58
- def xhtml?
59
- @xhtml
60
- end
61
-
62
47
  def method_missing(name, *args, &block)
63
48
  if name.to_s =~ /^_(\w+)(!|\?|)$/
64
49
  name, flag = $1, $2
@@ -1,8 +1,8 @@
1
1
  module Wunderbar
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 14
5
- TINY = 7
4
+ MINOR = 15
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/wunderbar.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "wunderbar"
5
- s.version = "0.14.7"
5
+ s.version = "0.15.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Sam Ruby"]
9
- s.date = "2012-05-11"
9
+ s.date = "2012-05-13"
10
10
  s.description = " Wunderbar makes it easy to produce valid HTML5, wellformed XHTML, Unicode\n (utf-8), consistently indented, readable applications. This includes\n output that conforms to the Polyglot specification and the emerging\n results from the XML Error Recovery Community Group.\n"
11
11
  s.email = "rubys@intertwingly.net"
12
12
  s.files = ["wunderbar.gemspec", "README.md", "COPYING", "lib/wunderbar.rb", "lib/wunderbar", "lib/wunderbar/installation.rb", "lib/wunderbar/html-methods.rb", "lib/wunderbar/job-control.rb", "lib/wunderbar/server.rb", "lib/wunderbar/logger.rb", "lib/wunderbar/rack.rb", "lib/wunderbar/builder.rb", "lib/wunderbar/websocket.rb", "lib/wunderbar/sinatra.rb", "lib/wunderbar/environment.rb", "lib/wunderbar/rails.rb", "lib/wunderbar/cgi-methods.rb", "lib/wunderbar/cssproxy.rb", "lib/wunderbar/version.rb"]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wunderbar
3
3
  version: !ruby/object:Gem::Version
4
- hash: 41
4
+ hash: 35
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 14
9
- - 7
10
- version: 0.14.7
8
+ - 15
9
+ - 0
10
+ version: 0.15.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sam Ruby
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-05-11 00:00:00 Z
18
+ date: 2012-05-13 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: builder