wunderbar 0.8.4 → 0.8.5
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.
- data/README +39 -0
- data/lib/wunderbar/cgi-methods.rb +4 -2
- data/lib/wunderbar/environment.rb +1 -1
- data/lib/wunderbar/html-methods.rb +20 -57
- data/lib/wunderbar/installation.rb +27 -2
- data/lib/wunderbar/version.rb +1 -1
- data/wunderbar.gemspec +2 -2
- metadata +4 -4
data/README
CHANGED
|
@@ -4,6 +4,45 @@ Wunder provides a number of globals, helper methods, and monkey patches which
|
|
|
4
4
|
simplify the development of single page applications in the form of CGI
|
|
5
5
|
scripts.
|
|
6
6
|
|
|
7
|
+
Basic interface
|
|
8
|
+
===============
|
|
9
|
+
|
|
10
|
+
A typical main program produces one or more of HTML, JSON, or plain text
|
|
11
|
+
output. This is accomplished by providing one or more of the following:
|
|
12
|
+
|
|
13
|
+
Wunderbar.html do
|
|
14
|
+
code
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
Wunderbar.json do
|
|
18
|
+
expression
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Wunderbar.text do
|
|
22
|
+
code
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Arbitrary Ruby code can be placed in each.
|
|
26
|
+
|
|
27
|
+
== Methods provided to Wunderbar.html
|
|
28
|
+
|
|
29
|
+
Invoking methods that start with a Unicode "low line" character ("_") will
|
|
30
|
+
generate a HTML tag. As with builder on which this library is based, these
|
|
31
|
+
tags can have text content and attributes. Tags can also be nested. Logic
|
|
32
|
+
can be freely intermixed.
|
|
33
|
+
|
|
34
|
+
Wunderbar knows which HTML tags need to be explicitly closed with separate end
|
|
35
|
+
tags (example: textarea), and which should never be closed with separate end
|
|
36
|
+
tags (example: br). It also takes care of HTML quoting and escaping of
|
|
37
|
+
arguments and text.
|
|
38
|
+
|
|
39
|
+
The "_" method serves a number of purposes. Calling it with a single argument
|
|
40
|
+
produces text nodes. Inserting markup verbatim is done by "_ << text". A
|
|
41
|
+
number of other convenience methods are defined:
|
|
42
|
+
|
|
43
|
+
_.post? -- was this invoked via HTTP POST?
|
|
44
|
+
_.system -- invokes a shell command, captures stdin, stdout, and stderr
|
|
45
|
+
|
|
7
46
|
== Globals provided
|
|
8
47
|
* $cgi - Common Gateway Interface
|
|
9
48
|
* $param - Access to parameters (read-only OpenStruct like interface)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# produce json
|
|
2
|
-
def $cgi.json
|
|
2
|
+
def $cgi.json(&block)
|
|
3
3
|
return unless $XHR_JSON
|
|
4
|
-
|
|
4
|
+
$param.each {|key,value| instance_variable_set "@#{key}", value.first}
|
|
5
|
+
output = instance_eval(&block)
|
|
5
6
|
rescue Exception => exception
|
|
6
7
|
Kernel.print "Status: 500 Internal Error\r\n"
|
|
7
8
|
output = {
|
|
@@ -38,6 +39,7 @@ def $cgi.text &block
|
|
|
38
39
|
def $cgi.print(line=nil)
|
|
39
40
|
@output << line
|
|
40
41
|
end
|
|
42
|
+
$param.each {|key,value| instance_variable_set "@#{key}", value.first}
|
|
41
43
|
self.instance_eval &block
|
|
42
44
|
rescue Exception => exception
|
|
43
45
|
Kernel.print "Status: 500 Internal Error\r\n"
|
|
@@ -72,7 +72,7 @@ $USER = ENV['REMOTE_USER'] || ENV['USER'] ||
|
|
|
72
72
|
|
|
73
73
|
ENV['REMOTE_USER'] ||= $USER
|
|
74
74
|
|
|
75
|
-
$HOME
|
|
75
|
+
$HOME = ENV['HOME'] ||= File.expand_path('~' + $USER)
|
|
76
76
|
$SERVER = ENV['HTTP_HOST'] || `hostname`.chomp
|
|
77
77
|
|
|
78
78
|
# more implied request types
|
|
@@ -1,58 +1,32 @@
|
|
|
1
|
-
# smart style, knows that the content is indented text/data
|
|
2
|
-
def $x.style!(text)
|
|
3
|
-
text.slice! /^\n/
|
|
4
|
-
text.slice! /[ ]+\z/
|
|
5
|
-
$x.style :type => "text/css" do
|
|
6
|
-
if $XHTML
|
|
7
|
-
indented_text! text
|
|
8
|
-
else
|
|
9
|
-
indented_data! text
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# smart script, knows that the content is indented text/data
|
|
15
|
-
def $x.script!(text)
|
|
16
|
-
text.slice! /^\n/
|
|
17
|
-
text.slice! /[ ]+\z/
|
|
18
|
-
$x.script :lang => "text/javascript" do
|
|
19
|
-
if $XHTML
|
|
20
|
-
indented_text! text
|
|
21
|
-
else
|
|
22
|
-
indented_data! text
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
1
|
# execute a system command, echoing stdin, stdout, and stderr
|
|
28
|
-
def $x.system
|
|
29
|
-
require 'open3'
|
|
2
|
+
def $x.system(command, opts={})
|
|
3
|
+
::Kernel.require 'open3'
|
|
30
4
|
output_class = opts[:class] || {}
|
|
31
|
-
stdin = output_class[:stdin] || '
|
|
32
|
-
stdout = output_class[:stdout] || '
|
|
33
|
-
stderr = output_class[:stderr] || '
|
|
5
|
+
stdin = output_class[:stdin] || '_stdin'
|
|
6
|
+
stdout = output_class[:stdout] || '_stdout'
|
|
7
|
+
stderr = output_class[:stderr] || '_stderr'
|
|
34
8
|
|
|
35
9
|
$x.pre command, :class=>stdin unless opts[:echo] == false
|
|
36
10
|
|
|
37
|
-
require 'thread'
|
|
38
|
-
semaphore = Mutex.new
|
|
39
|
-
Open3.popen3(command) do |pin, pout, perr|
|
|
11
|
+
::Kernel.require 'thread'
|
|
12
|
+
semaphore = ::Mutex.new
|
|
13
|
+
::Open3.popen3(command) do |pin, pout, perr|
|
|
40
14
|
[
|
|
41
|
-
Thread.new do
|
|
15
|
+
::Thread.new do
|
|
42
16
|
until pout.eof?
|
|
43
17
|
out_line = pout.readline.chomp
|
|
44
18
|
semaphore.synchronize { $x.pre out_line, :class=>stdout }
|
|
45
19
|
end
|
|
46
20
|
end,
|
|
47
21
|
|
|
48
|
-
Thread.new do
|
|
22
|
+
::Thread.new do
|
|
49
23
|
until perr.eof?
|
|
50
24
|
err_line = perr.readline.chomp
|
|
51
25
|
semaphore.synchronize { $x.pre err_line, :class=>stderr }
|
|
52
26
|
end
|
|
53
27
|
end,
|
|
54
28
|
|
|
55
|
-
Thread.new do
|
|
29
|
+
::Thread.new do
|
|
56
30
|
if opts[:stdin].respond_to? :read
|
|
57
31
|
require 'fileutils'
|
|
58
32
|
FileUtils.copy_stream opts[:stdin], pin
|
|
@@ -65,25 +39,9 @@ def $x.system!(command, opts={})
|
|
|
65
39
|
end
|
|
66
40
|
end
|
|
67
41
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
traceback_style ||= 'background-color:#ff0; margin: 1em 0; padding: 1em; ' +
|
|
72
|
-
'border: 4px solid red; border-radius: 1em'
|
|
73
|
-
$x.body(args) do
|
|
74
|
-
begin
|
|
75
|
-
yield
|
|
76
|
-
rescue ::Exception => exception
|
|
77
|
-
text = exception.inspect
|
|
78
|
-
exception.backtrace.each {|frame| text += "\n #{frame}"}
|
|
79
|
-
|
|
80
|
-
if traceback_class
|
|
81
|
-
$x.pre text, :class=>traceback_class
|
|
82
|
-
else
|
|
83
|
-
$x.pre text, :style=>traceback_style
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
42
|
+
# was this invoked via HTTP POST?
|
|
43
|
+
def $x.post?
|
|
44
|
+
$HTTP_POST
|
|
87
45
|
end
|
|
88
46
|
|
|
89
47
|
# Wrapper class that understands HTML
|
|
@@ -101,7 +59,12 @@ class HtmlMarkup
|
|
|
101
59
|
end
|
|
102
60
|
|
|
103
61
|
def html(*args, &block)
|
|
104
|
-
@x.html(*args)
|
|
62
|
+
@x.html(*args) do
|
|
63
|
+
$param.each do |key,value|
|
|
64
|
+
instance_variable_set "@#{key}", value.first if key =~ /^\w+$/
|
|
65
|
+
end
|
|
66
|
+
instance_exec(@x, &block)
|
|
67
|
+
end
|
|
105
68
|
end
|
|
106
69
|
|
|
107
70
|
def method_missing(name, *args, &block)
|
|
@@ -40,10 +40,35 @@ if install and ARGV.delete(install)
|
|
|
40
40
|
file.puts "Dir.chdir #{File.dirname(main).inspect}"
|
|
41
41
|
|
|
42
42
|
# Optional data from the script (after __END__)
|
|
43
|
-
|
|
43
|
+
if Object.const_defined? :DATA
|
|
44
|
+
data = DATA.read
|
|
45
|
+
|
|
46
|
+
# process argument overrides
|
|
47
|
+
data.scan(/^\s*([A-Z]\w*)\s*=\s*(['"]).*\2$/).each do |name, q|
|
|
48
|
+
override = ARGV.find {|arg| arg =~ /--#{name}=(.*)/}
|
|
49
|
+
data[/^\s*#{name}\s*=\s*(.*)/,1] = $1.inspect if override
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
file.puts "\n#{data}\n"
|
|
53
|
+
end
|
|
44
54
|
|
|
45
55
|
# Load script
|
|
46
|
-
|
|
56
|
+
require = "require #{"./#{File.basename(main).sub(/\.rb$/,'')}".inspect}"
|
|
57
|
+
if ARGV.delete('--rescue') or ARGV.delete('--backtrace')
|
|
58
|
+
file.puts <<-EOF.gsub(/^ {8}/,'')
|
|
59
|
+
begin
|
|
60
|
+
#{require}
|
|
61
|
+
rescue ::Exception => exception
|
|
62
|
+
print "Content-Type: text/plain\\r\\n\\r\\n"
|
|
63
|
+
puts exception.inspect
|
|
64
|
+
exception.backtrace.each do |frame|
|
|
65
|
+
puts " \#{frame}"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
EOF
|
|
69
|
+
else
|
|
70
|
+
file.puts require
|
|
71
|
+
end
|
|
47
72
|
end
|
|
48
73
|
|
|
49
74
|
# Mark wrapper as executable
|
data/lib/wunderbar/version.rb
CHANGED
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.8.
|
|
5
|
+
s.version = "0.8.5"
|
|
6
6
|
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
|
8
8
|
s.authors = ["Sam Ruby"]
|
|
9
|
-
s.date = "2012-02-
|
|
9
|
+
s.date = "2012-02-18"
|
|
10
10
|
s.description = " Provides a number of globals, helper methods, and monkey patches which\n simplify the generation of HTML and the development of CGI scripts.\n"
|
|
11
11
|
s.email = "rubys@intertwingly.net"
|
|
12
12
|
s.extra_rdoc_files = ["COPYING", "README", "lib/wunderbar.rb", "lib/wunderbar/builder.rb", "lib/wunderbar/cgi-methods.rb", "lib/wunderbar/environment.rb", "lib/wunderbar/html-methods.rb", "lib/wunderbar/installation.rb", "lib/wunderbar/job-control.rb", "lib/wunderbar/logger.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:
|
|
4
|
+
hash: 53
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 8
|
|
9
|
-
-
|
|
10
|
-
version: 0.8.
|
|
9
|
+
- 5
|
|
10
|
+
version: 0.8.5
|
|
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-02-
|
|
18
|
+
date: 2012-02-18 00:00:00 Z
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
21
21
|
name: builder
|