wunderbar 0.8.4 → 0.8.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|