lipa-web 0.1.1
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/NEWS.md +3 -0
- data/README.md +65 -0
- data/Rakefile +23 -0
- data/examples/hello_word.rb +13 -0
- data/examples/universe.rb +50 -0
- data/lib/lipa/web.rb +49 -0
- data/lib/lipa/web/application.rb +61 -0
- data/lib/lipa/web/helpers.rb +3 -0
- data/lib/lipa/web/helpers/html_helper.rb +38 -0
- data/lib/lipa/web/helpers/node_helper.rb +82 -0
- data/lib/lipa/web/helpers/response_helper.rb +128 -0
- data/lib/lipa/web/server.rb +58 -0
- data/lib/lipa/web/version.rb +30 -0
- data/spec/application_spec.rb +100 -0
- data/spec/server_spec.rb +50 -0
- metadata +199 -0
data/NEWS.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
LipaWeb [](http://travis-ci.org/flipback/lipa-web)
|
2
|
+
=======================================================
|
3
|
+
LipaWeb - micro webframework based on [Lipa](http://lipa.flipbacl.new) for web access to treelike structures
|
4
|
+
|
5
|
+
Features
|
6
|
+
----------------------------------------------------
|
7
|
+
- Based on Rack and Lipa
|
8
|
+
- Support HTML,JSON and text format response
|
9
|
+
- Support ERB templates with layouts
|
10
|
+
|
11
|
+
Example
|
12
|
+
----------------------------------------------------
|
13
|
+
|
14
|
+
require 'lipa-web'
|
15
|
+
srv = root :universe do
|
16
|
+
kind :planet_system do
|
17
|
+
num_planet run{
|
18
|
+
count = 0
|
19
|
+
children.values.each do |planet|
|
20
|
+
count += 1 if planet.kind == :planet
|
21
|
+
end
|
22
|
+
count
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
kind :planet do
|
27
|
+
has_live false
|
28
|
+
has_water false
|
29
|
+
number 0
|
30
|
+
end
|
31
|
+
|
32
|
+
planet_system :sun_system do
|
33
|
+
planet :mercury do
|
34
|
+
number 1
|
35
|
+
radius 46_001_210
|
36
|
+
end
|
37
|
+
|
38
|
+
planet :venus do
|
39
|
+
number 2
|
40
|
+
radius 107_476_259
|
41
|
+
end
|
42
|
+
|
43
|
+
planet :earth do
|
44
|
+
number 3
|
45
|
+
radius 147_098_074
|
46
|
+
has_live true
|
47
|
+
has_water true
|
48
|
+
|
49
|
+
node :moon, :radius => 363_104
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
srv.run! #Run server
|
55
|
+
# GET http://127.0.0.1:9292
|
56
|
+
|
57
|
+
Installation
|
58
|
+
-----------------------------------------------------
|
59
|
+
`gem install lipa-web`
|
60
|
+
|
61
|
+
Reference
|
62
|
+
----------------------------------
|
63
|
+
Home page: https://github.com/flipback/lipa-web
|
64
|
+
|
65
|
+
Lipa home page: http://lipa.flipback.net
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rake'
|
14
|
+
require 'rspec/core'
|
15
|
+
require 'rspec/core/rake_task'
|
16
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
17
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'yard'
|
21
|
+
YARD::Rake::YardocTask.new
|
22
|
+
|
23
|
+
task :default => :spec
|
@@ -0,0 +1,50 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'../lib')
|
2
|
+
require 'lipa/web'
|
3
|
+
|
4
|
+
un = root :universe do
|
5
|
+
views File.join(File.dirname(__FILE__), "views")
|
6
|
+
layout "base.html.erb"
|
7
|
+
|
8
|
+
kind :planet_system do
|
9
|
+
num_planet run{
|
10
|
+
count = 0
|
11
|
+
children.values.each do |planet|
|
12
|
+
count += 1 if planet.kind == :planet
|
13
|
+
end
|
14
|
+
count
|
15
|
+
}
|
16
|
+
|
17
|
+
html erb("planet_system.html.erb")
|
18
|
+
end
|
19
|
+
|
20
|
+
kind :planet do
|
21
|
+
has_live false
|
22
|
+
has_water false
|
23
|
+
number 0
|
24
|
+
|
25
|
+
html erb("planet.html.erb")
|
26
|
+
end
|
27
|
+
|
28
|
+
planet_system :sun_system do
|
29
|
+
planet :mercury do
|
30
|
+
number 1
|
31
|
+
radius 46_001_210
|
32
|
+
end
|
33
|
+
|
34
|
+
planet :venus do
|
35
|
+
number 2
|
36
|
+
radius 107_476_259
|
37
|
+
end
|
38
|
+
|
39
|
+
planet :earth do
|
40
|
+
number 3
|
41
|
+
radius 147_098_074
|
42
|
+
has_live true
|
43
|
+
has_water true
|
44
|
+
|
45
|
+
node :moon, :radius => 363_104
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
un.run!
|
data/lib/lipa/web.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
=begin
|
2
|
+
Web access to Lipa
|
3
|
+
|
4
|
+
Copyright (c) 2011 Aleksey Timin
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
'Software'), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
require "lipa/web/version"
|
27
|
+
require "lipa/web/helpers"
|
28
|
+
require "lipa/web/application"
|
29
|
+
require "lipa/web/server"
|
30
|
+
|
31
|
+
class Lipa::Node
|
32
|
+
include Lipa::Web::NodeHelper
|
33
|
+
end
|
34
|
+
|
35
|
+
def root(name, &block)
|
36
|
+
#default options
|
37
|
+
|
38
|
+
root = Lipa::Root.new(name) do
|
39
|
+
port 9292
|
40
|
+
server :webrick
|
41
|
+
debug false
|
42
|
+
views File.join(File.absolute_path("."), "views")
|
43
|
+
end
|
44
|
+
|
45
|
+
root.instance_eval &block if block_given?
|
46
|
+
root.extend(Lipa::Web::Server)
|
47
|
+
root
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
=begin
|
2
|
+
Web access to Lipa
|
3
|
+
|
4
|
+
Copyright (c) 2011 Aleksey Timin
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
'Software'), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
require "lipa"
|
27
|
+
require "rack"
|
28
|
+
require "erb"
|
29
|
+
|
30
|
+
module Lipa
|
31
|
+
module Web
|
32
|
+
# Rack application
|
33
|
+
class Application
|
34
|
+
include ResponseHelper
|
35
|
+
|
36
|
+
# Init app
|
37
|
+
#
|
38
|
+
# @param root [Lipa::Root] Lipa structure
|
39
|
+
def initialize(root)
|
40
|
+
@root = root
|
41
|
+
end
|
42
|
+
|
43
|
+
def call(env)
|
44
|
+
path, format = env['PATH_INFO'].split(".")
|
45
|
+
node = @root[path]
|
46
|
+
if node
|
47
|
+
respond(node, format)
|
48
|
+
else
|
49
|
+
[ 500,
|
50
|
+
|
51
|
+
{"Content-Type" => "text/html"},
|
52
|
+
[
|
53
|
+
"Node is not existence"
|
54
|
+
]
|
55
|
+
]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
=begin
|
2
|
+
Web access to Lipa
|
3
|
+
|
4
|
+
Copyright (c) 2011 Aleksey Timin
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
'Software'), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
module Lipa
|
27
|
+
module Web
|
28
|
+
module HtmlHelper
|
29
|
+
# Make link for node
|
30
|
+
#
|
31
|
+
# @param node [Lipa::Node] linking node
|
32
|
+
# @return [String] html <a href='path/to/node'>name_of_node</a>
|
33
|
+
def link_to(node)
|
34
|
+
%(<a href="#{node.full_name}">#{node.name}</a>)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
=begin
|
2
|
+
Web access to Lipa
|
3
|
+
|
4
|
+
Copyright (c) 2011 Aleksey Timin
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
'Software'), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
module Lipa
|
27
|
+
module Web
|
28
|
+
module NodeHelper
|
29
|
+
|
30
|
+
# Assignment erb template fot html response
|
31
|
+
#
|
32
|
+
# @param path [String] path about views directory
|
33
|
+
#
|
34
|
+
# @examnple
|
35
|
+
# node :page_1 do
|
36
|
+
# html erb("page.html.erb")
|
37
|
+
# end
|
38
|
+
def erb(path)
|
39
|
+
{ :render => :erb, :template => File.join(root.attrs[:views], path) }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Assignment text for html response
|
43
|
+
#
|
44
|
+
# @param msg [String] text message
|
45
|
+
#
|
46
|
+
# @examnple
|
47
|
+
# node :page_1 do
|
48
|
+
# html text("Hello World!")
|
49
|
+
# end
|
50
|
+
def text(msg)
|
51
|
+
{ :render => :text, :msg => msg }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Definition html response
|
55
|
+
#
|
56
|
+
# @see NodeHelpers#erb
|
57
|
+
# @see NodeHelpers#text
|
58
|
+
def html(opts=nil)
|
59
|
+
if opts.nil?
|
60
|
+
@html
|
61
|
+
else
|
62
|
+
@html = opts
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Definition json response
|
67
|
+
#
|
68
|
+
# @example
|
69
|
+
# node :josn_1 do
|
70
|
+
# json { |j| j[:name] = name }
|
71
|
+
# end
|
72
|
+
# # => { "name":"json_1" }
|
73
|
+
def json(&block)
|
74
|
+
if block_given?
|
75
|
+
@json = {:block => block}
|
76
|
+
else
|
77
|
+
@json
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
=begin
|
2
|
+
Web access to Lipa
|
3
|
+
|
4
|
+
Copyright (c) 2011 Aleksey Timin
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
'Software'), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
require "json"
|
27
|
+
|
28
|
+
module Lipa
|
29
|
+
module Web
|
30
|
+
module ResponseHelper
|
31
|
+
# Rendering node data in format
|
32
|
+
#
|
33
|
+
# @param node [Lipa::Node] node for rendering
|
34
|
+
# @param format of rendering
|
35
|
+
def respond(node, format)
|
36
|
+
case format.to_s
|
37
|
+
when "json"
|
38
|
+
json_format(node)
|
39
|
+
else
|
40
|
+
html_format(node)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def context(node)
|
46
|
+
node.instance_eval("def binding_for(#{node.attrs.keys.join(",")}) binding; end")
|
47
|
+
node.extend(HtmlHelper)
|
48
|
+
block = block_given? ? Proc.new : nil
|
49
|
+
node.binding_for(*node.eval_attrs.values, &block)
|
50
|
+
end
|
51
|
+
|
52
|
+
def read_template(path)
|
53
|
+
File.open(path).read
|
54
|
+
end
|
55
|
+
|
56
|
+
def default_template
|
57
|
+
path = File.join(File.dirname(__FILE__), '..', 'views', 'node.html.erb') # default path
|
58
|
+
read_template(path)
|
59
|
+
end
|
60
|
+
|
61
|
+
def render_erb(node)
|
62
|
+
template = read_template(node.html[:template])
|
63
|
+
root = node.root
|
64
|
+
if root.layout
|
65
|
+
layout = read_template(File.join(root.views, root.layout))
|
66
|
+
ERB.new(layout).result(context(node) { ERB.new(template).result(context(node)) })
|
67
|
+
else
|
68
|
+
ERB.new(template).result(context(node))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def html_format(node)
|
73
|
+
status = 200
|
74
|
+
header = {}
|
75
|
+
body = ""
|
76
|
+
|
77
|
+
if node.html
|
78
|
+
case node.html[:render]
|
79
|
+
when :erb
|
80
|
+
body = render_erb(node)
|
81
|
+
header["Content-Type"] = "text/html"
|
82
|
+
when :text
|
83
|
+
body = node.html[:msg]
|
84
|
+
header["Content-Type"] = "text/plain"
|
85
|
+
end
|
86
|
+
else
|
87
|
+
body = ERB.new(default_template).result(context(node))
|
88
|
+
end
|
89
|
+
|
90
|
+
[ status, header, [body]]
|
91
|
+
end
|
92
|
+
|
93
|
+
def json_format(node)
|
94
|
+
status = 200
|
95
|
+
header = {}
|
96
|
+
body = ""
|
97
|
+
|
98
|
+
if node.json
|
99
|
+
j = {}
|
100
|
+
node.json[:block].call(j)
|
101
|
+
body = j.to_json
|
102
|
+
else
|
103
|
+
body = render_default_json(node)
|
104
|
+
end
|
105
|
+
|
106
|
+
header["Content-Type"] = "application/json"
|
107
|
+
[ status, header, [body]]
|
108
|
+
end
|
109
|
+
|
110
|
+
def render_default_json(node)
|
111
|
+
j = {}
|
112
|
+
j[:name] = node.name
|
113
|
+
j[:full_name] = node.full_name
|
114
|
+
j[:parent] = json_link_to(node.parent)
|
115
|
+
j[:children] = node.children.values.each.map {|ch| json_link_to(ch) }
|
116
|
+
node.eval_attrs.each_pair do |k,v|
|
117
|
+
j[k] = v.kind_of?(Lipa::Node) ? json_link_to(v) : v
|
118
|
+
end
|
119
|
+
|
120
|
+
j.to_json
|
121
|
+
end
|
122
|
+
|
123
|
+
def json_link_to(node)
|
124
|
+
{ :name => node.name, :full_name => node.full_name }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
=begin
|
2
|
+
Web access to Lipa
|
3
|
+
|
4
|
+
Copyright (c) 2011 Aleksey Timin
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
'Software'), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
require "lipa"
|
27
|
+
require "rack"
|
28
|
+
|
29
|
+
module Lipa
|
30
|
+
module Web
|
31
|
+
module Server
|
32
|
+
# Run HTTP server
|
33
|
+
#
|
34
|
+
# @param port [Integer] listener port (default 9292)
|
35
|
+
# @param host [String] host of server (default 127.0.0.1)
|
36
|
+
# @param server [Symbol,String] server name (:webbrick, :thin, :cgi and everything what Rack supports) ( default :webrick)
|
37
|
+
# @param debug [Boolean] debug mode (default false)
|
38
|
+
# @param views [String] path to views directory (default "./views")
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# srv root :srv do
|
42
|
+
# # Server params
|
43
|
+
# port 3456
|
44
|
+
# host '127.0.0.1'
|
45
|
+
# server :webrick
|
46
|
+
# debug false
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# srv.run!
|
50
|
+
def run!
|
51
|
+
Rack::Server.start :app => Application.new(self),
|
52
|
+
:Port => port,
|
53
|
+
:server => server.to_s,
|
54
|
+
:debug => debug
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
=begin
|
2
|
+
Web access to Lipa
|
3
|
+
|
4
|
+
Copyright (c) 2011 Aleksey Timin
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
'Software'), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
module Lipa
|
27
|
+
module Web
|
28
|
+
VERSION = "0.1.1"
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "lipa/web"
|
2
|
+
require "rack/test"
|
3
|
+
|
4
|
+
describe Lipa::Web::Application do
|
5
|
+
include Rack::Test::Methods
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@srv = root :srv do
|
9
|
+
views File.join(File.dirname(__FILE__), "views")
|
10
|
+
layout "layout.html.erb"
|
11
|
+
|
12
|
+
node :group do
|
13
|
+
node :test_node do
|
14
|
+
param_int 20
|
15
|
+
param_bool false
|
16
|
+
param_float 32.2
|
17
|
+
param_string "Hello"
|
18
|
+
param_time Time.new(2000,"jan",1,20,15,1,0)
|
19
|
+
param_proc run{5+3}
|
20
|
+
param_ref ref("../node_with_template")
|
21
|
+
|
22
|
+
node :child_1
|
23
|
+
node :child_2
|
24
|
+
end
|
25
|
+
|
26
|
+
node :node_with_template do
|
27
|
+
html erb("./my_template.html.erb")
|
28
|
+
json { |j| j[:name] = name }
|
29
|
+
end
|
30
|
+
|
31
|
+
node :node_greater do
|
32
|
+
html text("Hello world!")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def app
|
39
|
+
Lipa::Web::Application.new(@srv)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should get good to root' do
|
43
|
+
get "/"
|
44
|
+
last_response.should be_ok
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should get good response' do
|
48
|
+
get "/group"
|
49
|
+
last_response.should be_ok
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should get error for nonexistence node' do
|
53
|
+
get "/nonexistence_node"
|
54
|
+
last_response.should_not be_ok
|
55
|
+
last_response.status.should eql(500)
|
56
|
+
last_response.body.should eql("Node is not existence")
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should render default html template' do
|
60
|
+
get "/group/test_node"
|
61
|
+
|
62
|
+
last_response.header['Content-Type'].should eql( "text/html")
|
63
|
+
last_response.body.gsub(/^\s*\n/, '').should == fixture("node.html")
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should render user html template' do
|
67
|
+
get "/group/node_with_template"
|
68
|
+
|
69
|
+
last_response.header['Content-Type'].should eql("text/html")
|
70
|
+
last_response.body.gsub(/^\s*\n/, '').should == fixture("node_with_template.html")
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should render text' do
|
74
|
+
get "/group/node_greater"
|
75
|
+
|
76
|
+
last_response.header['Content-Type'].should eql("text/plain")
|
77
|
+
last_response.body.should == "Hello world!"
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should response in default json format' do
|
81
|
+
get "group/test_node.json"
|
82
|
+
|
83
|
+
last_response.header['Content-Type'].should eql("application/json")
|
84
|
+
last_response.body.gsub(/\s*/,'').should == fixture("node.json").gsub(/\s*/,'')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should response in default json format' do
|
88
|
+
get "group/node_with_template.json"
|
89
|
+
|
90
|
+
last_response.header['Content-Type'].should eql("application/json")
|
91
|
+
last_response.body.should == '{"name":"node_with_template"}'
|
92
|
+
end
|
93
|
+
|
94
|
+
def fixture(name)
|
95
|
+
path = File.join(File.dirname(__FILE__), "fixtures", name)
|
96
|
+
File.open(path).read.gsub(/^\s*\n/,'')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require "lipa/web"
|
2
|
+
|
3
|
+
describe Lipa::Web::Server do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@srv = root :srv do
|
7
|
+
node :test_node
|
8
|
+
end
|
9
|
+
|
10
|
+
app = mock('Rack application')
|
11
|
+
Lipa::Web::Application.stub!(:new).and_return(app)
|
12
|
+
@default_opts = {
|
13
|
+
:app => app,
|
14
|
+
:Port => 9292,
|
15
|
+
:server => "webrick",
|
16
|
+
:debug => false
|
17
|
+
}
|
18
|
+
|
19
|
+
Rack::Server.stub!(:start).and_return(nil)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should run whith default options' do
|
23
|
+
test_server(@srv, @default_opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should have #port option' do
|
27
|
+
@srv.port = 9999
|
28
|
+
test_server(@srv, @default_opts.merge(:Port => 9999))
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should have #server option' do
|
32
|
+
@srv.server = 'thin'
|
33
|
+
test_server(@srv, @default_opts.merge(:server => 'thin'))
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should have #debug option' do
|
37
|
+
@srv.debug = true
|
38
|
+
test_server(@srv, @default_opts.merge(:debug => true))
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should default path to dir of views eql "./views"' do
|
42
|
+
@srv.run!
|
43
|
+
@srv.views.should eql(File.join(File.absolute_path("."), "views"))
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_server(srv, opts)
|
47
|
+
Rack::Server.should_receive(:start).with(opts).and_return(nil)
|
48
|
+
srv.run!
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lipa-web
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- A.Timin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-11-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: lipa
|
16
|
+
requirement: &71011880 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *71011880
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rack
|
27
|
+
requirement: &71011620 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.3.5
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *71011620
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: json
|
38
|
+
requirement: &71011360 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.6.1
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *71011360
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: &71010610 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.9.2.2
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *71010610
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: bundler
|
60
|
+
requirement: &71010290 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *71010290
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: &71009740 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.7.0
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *71009740
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: yard
|
82
|
+
requirement: &71009510 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *71009510
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rdiscount
|
93
|
+
requirement: &71009170 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *71009170
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: pry
|
104
|
+
requirement: &71008760 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *71008760
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: notes
|
115
|
+
requirement: &71008270 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: *71008270
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: rack-test
|
126
|
+
requirement: &71007960 !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ~>
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.6.1
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: *71007960
|
135
|
+
- !ruby/object:Gem::Dependency
|
136
|
+
name: guard-rspec
|
137
|
+
requirement: &71007580 !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: *71007580
|
146
|
+
description:
|
147
|
+
email: atimin@gmail.com
|
148
|
+
executables: []
|
149
|
+
extensions: []
|
150
|
+
extra_rdoc_files:
|
151
|
+
- README.md
|
152
|
+
- NEWS.md
|
153
|
+
files:
|
154
|
+
- lib/lipa/web/application.rb
|
155
|
+
- lib/lipa/web/version.rb
|
156
|
+
- lib/lipa/web/helpers/html_helper.rb
|
157
|
+
- lib/lipa/web/helpers/response_helper.rb
|
158
|
+
- lib/lipa/web/helpers/node_helper.rb
|
159
|
+
- lib/lipa/web/helpers.rb
|
160
|
+
- lib/lipa/web/server.rb
|
161
|
+
- lib/lipa/web.rb
|
162
|
+
- spec/server_spec.rb
|
163
|
+
- spec/application_spec.rb
|
164
|
+
- examples/universe.rb
|
165
|
+
- examples/hello_word.rb
|
166
|
+
- Rakefile
|
167
|
+
- README.md
|
168
|
+
- NEWS.md
|
169
|
+
homepage: http://lipa.flipback.net
|
170
|
+
licenses: []
|
171
|
+
post_install_message:
|
172
|
+
rdoc_options:
|
173
|
+
- --title
|
174
|
+
- Lipa
|
175
|
+
- --inline-source
|
176
|
+
- --main
|
177
|
+
- README.md
|
178
|
+
require_paths:
|
179
|
+
- lib
|
180
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
181
|
+
none: false
|
182
|
+
requirements:
|
183
|
+
- - ! '>='
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: 1.9.2
|
186
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
|
+
none: false
|
188
|
+
requirements:
|
189
|
+
- - ! '>='
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: '0'
|
192
|
+
requirements: []
|
193
|
+
rubyforge_project:
|
194
|
+
rubygems_version: 1.8.10
|
195
|
+
signing_key:
|
196
|
+
specification_version: 3
|
197
|
+
summary: LipaWeb - micro webframework for web access to treelike structures
|
198
|
+
test_files: []
|
199
|
+
has_rdoc:
|