wunderbar 0.14.7 → 0.15.0

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.
@@ -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