amber-kit 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +0 -0
- data/amber.gemspec +49 -0
- data/bin/amber +55 -0
- data/lib/amber/controller.rb +5 -0
- data/lib/amber/data/array_data.rb +15 -0
- data/lib/amber/data/date_data.rb +15 -0
- data/lib/amber/data/float_data.rb +13 -0
- data/lib/amber/data/integer_data.rb +13 -0
- data/lib/amber/data/string_data.rb +13 -0
- data/lib/amber/data.rb +14 -0
- data/lib/amber/data_delegate.rb +9 -0
- data/lib/amber/http/request.rb +229 -0
- data/lib/amber/http/response.rb +80 -0
- data/lib/amber/http.rb +9 -0
- data/lib/amber/model.rb +89 -0
- data/lib/amber/route.rb +66 -0
- data/lib/amber/route_path.rb +39 -0
- data/lib/amber/server.rb +103 -0
- data/lib/amber/storage/json.rb +116 -0
- data/lib/amber/storage/remote_json.rb +103 -0
- data/lib/amber/storage.rb +8 -0
- data/lib/amber/switch/content/form_data.rb +43 -0
- data/lib/amber/switch/content/json.rb +35 -0
- data/lib/amber/switch/content/text.rb +22 -0
- data/lib/amber/switch/content.rb +38 -0
- data/lib/amber/switch/content_delegate.rb +9 -0
- data/lib/amber/switch/request/get.rb +5 -0
- data/lib/amber/switch/request/post.rb +7 -0
- data/lib/amber/switch/request.rb +16 -0
- data/lib/amber/switch/response.rb +10 -0
- data/lib/amber/switch.rb +71 -0
- data/lib/amber/view/json.rb +9 -0
- data/lib/amber/view.rb +9 -0
- data/lib/amber.rb +48 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5b2b0cde2d48a5f894ed730b36260d428de273da
|
4
|
+
data.tar.gz: df73ca4d62fb83e44fde411594a1d451a3448dbe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d0e02a5aa95e3fbfd6d2cf492fc333b9673a20c565e16452a99b711c3943343ac03f30279ef4bc65b30f2aa21131264bb602136d92afc858380f36f48d627d5c
|
7
|
+
data.tar.gz: b2c3db8bcb7203822e8f9604a7f288a35c7a082fb825372128ad651b8718d92e0eb8be1180d3ca1d79c56d2c4734ba779c59fd739c696fe04e699b432c20fb8f
|
data/Rakefile
ADDED
File without changes
|
data/amber.gemspec
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "amber-kit"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.authors = ["Jakit"]
|
5
|
+
s.date = "2017-06-03"
|
6
|
+
s.summary = "A glitter network toolkit"
|
7
|
+
s.description = "Useful network toolkit for create your application"
|
8
|
+
s.email = "jakit_liang@outlook.com"
|
9
|
+
s.files = [
|
10
|
+
"Rakefile",
|
11
|
+
"amber.gemspec",
|
12
|
+
"bin/amber",
|
13
|
+
"lib/amber.rb",
|
14
|
+
"lib/amber/controller.rb",
|
15
|
+
"lib/amber/data.rb",
|
16
|
+
"lib/amber/data/array_data.rb",
|
17
|
+
"lib/amber/data/date_data.rb",
|
18
|
+
"lib/amber/data/float_data.rb",
|
19
|
+
"lib/amber/data/integer_data.rb",
|
20
|
+
"lib/amber/data/string_data.rb",
|
21
|
+
"lib/amber/data_delegate.rb",
|
22
|
+
"lib/amber/http.rb",
|
23
|
+
"lib/amber/http/request.rb",
|
24
|
+
"lib/amber/http/response.rb",
|
25
|
+
"lib/amber/model.rb",
|
26
|
+
"lib/amber/route.rb",
|
27
|
+
"lib/amber/route_path.rb",
|
28
|
+
"lib/amber/server.rb",
|
29
|
+
"lib/amber/storage.rb",
|
30
|
+
"lib/amber/storage/json.rb",
|
31
|
+
"lib/amber/storage/remote_json.rb",
|
32
|
+
"lib/amber/switch.rb",
|
33
|
+
"lib/amber/switch/content.rb",
|
34
|
+
"lib/amber/switch/content/form_data.rb",
|
35
|
+
"lib/amber/switch/content/json.rb",
|
36
|
+
"lib/amber/switch/content/text.rb",
|
37
|
+
"lib/amber/switch/content_delegate.rb",
|
38
|
+
"lib/amber/switch/request.rb",
|
39
|
+
"lib/amber/switch/request/get.rb",
|
40
|
+
"lib/amber/switch/request/post.rb",
|
41
|
+
"lib/amber/switch/response.rb",
|
42
|
+
"lib/amber/view.rb",
|
43
|
+
"lib/amber/view/json.rb"
|
44
|
+
]
|
45
|
+
s.executables << 'amber'
|
46
|
+
s.require_paths = ["lib"]
|
47
|
+
s.homepage = "http://pingz.org.cn/amber"
|
48
|
+
s.license = "MIT"
|
49
|
+
end
|
data/bin/amber
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "amber"
|
4
|
+
|
5
|
+
run_operation = ARGV[0] ? ARGV[0] : "run"
|
6
|
+
run_parameter = ARGV[1] ? ARGV[0] : nil
|
7
|
+
|
8
|
+
current_path = Dir.pwd
|
9
|
+
|
10
|
+
# Add controller path if exist
|
11
|
+
controller_path = current_path + '/controller'
|
12
|
+
|
13
|
+
if File.exist? controller_path
|
14
|
+
$LOAD_PATH << controller_path
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add model path if exist
|
18
|
+
model_path = current_path + '/model'
|
19
|
+
|
20
|
+
if File.exist? model_path
|
21
|
+
$LOAD_PATH << model_path
|
22
|
+
end
|
23
|
+
|
24
|
+
# Add library path if exist
|
25
|
+
library_path = current_path + '/library'
|
26
|
+
|
27
|
+
if File.exist? library_path
|
28
|
+
$LOAD_PATH << library_path
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add view path if exist
|
32
|
+
view_path = current_path + '/view'
|
33
|
+
|
34
|
+
if File.exist? view_path
|
35
|
+
$LOAD_PATH << view_path
|
36
|
+
end
|
37
|
+
|
38
|
+
if run_operation
|
39
|
+
case run_operation
|
40
|
+
when /\w+.rb/
|
41
|
+
if File.exist? run_operation
|
42
|
+
if run_operation.slice(0, 1) == '/'
|
43
|
+
require run_operation
|
44
|
+
else
|
45
|
+
require_relative current_path + '/' + run_operation
|
46
|
+
end
|
47
|
+
end
|
48
|
+
when "run"
|
49
|
+
amber_instance = Amber.new
|
50
|
+
amber_instance.run
|
51
|
+
else
|
52
|
+
amber_instance = Amber.new
|
53
|
+
amber_instance.run
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Amber::Data::DateData < Amber::Data
|
2
|
+
include Amber::DataDelegate
|
3
|
+
|
4
|
+
def initialize(value = Time.new)
|
5
|
+
@delegate = self
|
6
|
+
|
7
|
+
self.assign(value)
|
8
|
+
end
|
9
|
+
|
10
|
+
def assign(value)
|
11
|
+
if (value.is_a?(Integer)) || (value.is_a?(Float))
|
12
|
+
@value = Time.at(value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/amber/data.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
class Amber::Data
|
2
|
+
def initialize
|
3
|
+
@value = nil
|
4
|
+
@delegate = nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def value
|
8
|
+
@delegate.fetch if @delegate.class.include?(Amber::DataDelegate)
|
9
|
+
end
|
10
|
+
|
11
|
+
def value=(value)
|
12
|
+
@delegate.assign(value) if @delegate.class.include?(Amber::DataDelegate)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
class Amber::Http::Request < Amber::Http
|
2
|
+
attr_reader :method, :url, :query, :protocol, :body
|
3
|
+
|
4
|
+
GET = "GET"
|
5
|
+
POST = "POST"
|
6
|
+
PUT = "PUT"
|
7
|
+
DELETE = "DELETE"
|
8
|
+
|
9
|
+
def initialize(socket)
|
10
|
+
super
|
11
|
+
|
12
|
+
@url = ""
|
13
|
+
@query = {}
|
14
|
+
@body = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def receive
|
18
|
+
unless self.receive_request
|
19
|
+
STDERR.puts "Bad request"
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
|
23
|
+
self.receive_header
|
24
|
+
|
25
|
+
# p @header
|
26
|
+
|
27
|
+
if @header.has_key?("Content-Length")
|
28
|
+
content_length = @header["Content-Length"].to_i
|
29
|
+
|
30
|
+
if content_length > 0
|
31
|
+
self.receive_body(content_length)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# p @body_raw_data
|
36
|
+
|
37
|
+
# p @body
|
38
|
+
|
39
|
+
return true
|
40
|
+
end
|
41
|
+
|
42
|
+
def receive_request
|
43
|
+
last_token = ""
|
44
|
+
data = ""
|
45
|
+
|
46
|
+
Timeout::timeout(30) {
|
47
|
+
while buffer = @socket.recv_nonblock(1)
|
48
|
+
if last_token == "\r" && buffer == "\n"
|
49
|
+
break
|
50
|
+
end
|
51
|
+
|
52
|
+
data << buffer
|
53
|
+
last_token = buffer
|
54
|
+
end
|
55
|
+
}
|
56
|
+
|
57
|
+
self.parse_request(data)
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse_request(data)
|
61
|
+
request_info = data.split(' ')
|
62
|
+
|
63
|
+
if request_info.length == 3
|
64
|
+
case request_info[0]
|
65
|
+
when GET
|
66
|
+
@method = GET
|
67
|
+
when POST
|
68
|
+
@method = POST
|
69
|
+
when PUT
|
70
|
+
@method = PUT
|
71
|
+
when DELETE
|
72
|
+
@method = DELETE
|
73
|
+
else
|
74
|
+
return false
|
75
|
+
end
|
76
|
+
|
77
|
+
self.parse_url request_info[1]
|
78
|
+
@protocol = request_info[2]
|
79
|
+
end
|
80
|
+
|
81
|
+
return true
|
82
|
+
end
|
83
|
+
|
84
|
+
def parse_url(url)
|
85
|
+
if url.include? "?"
|
86
|
+
url_info = url.split "?"
|
87
|
+
@url = url_info[0]
|
88
|
+
if url_info.length > 1
|
89
|
+
self.parse_query url_info[1]
|
90
|
+
end
|
91
|
+
return
|
92
|
+
end
|
93
|
+
@url = url
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse_query(query_string)
|
97
|
+
query_info = query_string.split "&"
|
98
|
+
query_info.each do |query_info_item|
|
99
|
+
query_item = query_info_item.split "="
|
100
|
+
if query_item.length == 2
|
101
|
+
query_item_key = query_item[0]
|
102
|
+
query_item_value = query_item[1]
|
103
|
+
@query[query_item_key] = query_item_value
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def receive_header
|
109
|
+
loop { break unless receive_header_item }
|
110
|
+
end
|
111
|
+
|
112
|
+
def receive_header_item
|
113
|
+
last_token = ""
|
114
|
+
data = ""
|
115
|
+
|
116
|
+
while buffer = @socket.recv_nonblock(1)
|
117
|
+
if last_token == "\r" && buffer == "\n"
|
118
|
+
break
|
119
|
+
end
|
120
|
+
|
121
|
+
data << buffer
|
122
|
+
last_token = buffer
|
123
|
+
end
|
124
|
+
|
125
|
+
if data == "\r"
|
126
|
+
return false
|
127
|
+
end
|
128
|
+
|
129
|
+
self.parse_header_item(data.chomp)
|
130
|
+
end
|
131
|
+
|
132
|
+
def parse_header_item(data)
|
133
|
+
header_item = data.split(": ")
|
134
|
+
|
135
|
+
if header_item.length == 2
|
136
|
+
@header[header_item[0]] = header_item[1]
|
137
|
+
end
|
138
|
+
|
139
|
+
return true
|
140
|
+
end
|
141
|
+
|
142
|
+
def receive_body(size)
|
143
|
+
data = @socket.recv(size)
|
144
|
+
self.parse_body(data)
|
145
|
+
end
|
146
|
+
|
147
|
+
def parse_body(data)
|
148
|
+
@body_raw_data = data
|
149
|
+
|
150
|
+
if @header.has_key?("Content-Type")
|
151
|
+
content_type = @header["Content-Type"]
|
152
|
+
|
153
|
+
if content_type.include? "application/x-www-form-urlencoded"
|
154
|
+
self.parse_form_body(data)
|
155
|
+
elsif content_type.include? "multipart/form-data"
|
156
|
+
content_type_info = content_type.split("; ")
|
157
|
+
content_type_info.each do |info|
|
158
|
+
if info.include? "boundary"
|
159
|
+
boundary_info = info.split('=')
|
160
|
+
|
161
|
+
if boundary_info.length == 2
|
162
|
+
boundary = boundary_info[1]
|
163
|
+
self.parse_multipart_form_body(boundary, data)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def parse_form_body(data)
|
172
|
+
form_items = data.split('&')
|
173
|
+
|
174
|
+
form_items.each do |item|
|
175
|
+
item_info = item.split('=')
|
176
|
+
if item_info.length == 2
|
177
|
+
@body[item_info[0]] = item_info[1]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def parse_multipart_form_body(boundary, data)
|
183
|
+
offset = 0
|
184
|
+
boundary_string = "--#{boundary}"
|
185
|
+
|
186
|
+
while offset = data.index(boundary_string, offset)
|
187
|
+
next_offset = data.index(boundary_string, offset + 1)
|
188
|
+
|
189
|
+
unless next_offset
|
190
|
+
break
|
191
|
+
end
|
192
|
+
|
193
|
+
data_part = data.slice(offset + boundary_string.length + 2, next_offset - offset - boundary_string.length - 4)
|
194
|
+
self.parse_form_part(data_part)
|
195
|
+
|
196
|
+
offset = next_offset
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def parse_form_part(data)
|
201
|
+
first_of_break = data.index("\r\n\r\n")
|
202
|
+
unless first_of_break === nil
|
203
|
+
content_info_data = data.slice(0, first_of_break)
|
204
|
+
content_info_data = content_info_data.gsub("\r\n", "; ")
|
205
|
+
content_info = content_info_data.split("; ")
|
206
|
+
content_disposition = ""
|
207
|
+
content_name = ""
|
208
|
+
|
209
|
+
content_info.each do |info|
|
210
|
+
if info.include? "Content-Disposition"
|
211
|
+
info_array = info.split(': ')
|
212
|
+
content_disposition = info_array[1] if info_array.length == 2
|
213
|
+
|
214
|
+
elsif info.include? "name="
|
215
|
+
info_array = info.split('=')
|
216
|
+
content_name = info_array[1] if info_array.length == 2
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
content_body = data.slice(first_of_break + 4, data.length - 4 - first_of_break - 2)
|
221
|
+
|
222
|
+
unless content_name.empty?
|
223
|
+
@body[content_name] = content_body
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
require "timeout"
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class Amber::Http::Response < Amber::Http
|
2
|
+
attr_reader :status, :header, :content_type, :body
|
3
|
+
|
4
|
+
TEXT_CONTENT = "text/plain"
|
5
|
+
HTML_CONTENT = "text/html"
|
6
|
+
JSON_CONTENT = "application/json"
|
7
|
+
|
8
|
+
def initialize(socket)
|
9
|
+
super
|
10
|
+
|
11
|
+
@status_table = {
|
12
|
+
"100" => "Continue",
|
13
|
+
"200" => "OK",
|
14
|
+
"300" => "Multiple Choices",
|
15
|
+
"301" => "Moved Permanently",
|
16
|
+
"400" => "Bad Request",
|
17
|
+
"401" => "Unauthorized",
|
18
|
+
"403" => "Forbidden",
|
19
|
+
"404" => "Not Found",
|
20
|
+
"500" => "Internal Server Error",
|
21
|
+
"502" => "Bad Gateway",
|
22
|
+
"503" => "Service Unavailable"
|
23
|
+
}
|
24
|
+
|
25
|
+
@mime_table = [
|
26
|
+
TEXT_CONTENT,
|
27
|
+
HTML_CONTENT,
|
28
|
+
JSON_CONTENT
|
29
|
+
]
|
30
|
+
|
31
|
+
@status = "200"
|
32
|
+
@header = {}
|
33
|
+
@content_type = HTML_CONTENT
|
34
|
+
@body = ""
|
35
|
+
end
|
36
|
+
|
37
|
+
def send
|
38
|
+
data = create_status_line
|
39
|
+
data << "Server: Amber/0.0.1\r\n"
|
40
|
+
@header.each do |key, value|
|
41
|
+
data << "#{key}: #{value}\r\n"
|
42
|
+
end
|
43
|
+
data << "Content-Type: #{@content_type}\r\n"
|
44
|
+
data << "Content-Length: #{@body.length}\r\n\r\n"
|
45
|
+
data << @body
|
46
|
+
|
47
|
+
@socket.sendmsg data, 0
|
48
|
+
end
|
49
|
+
|
50
|
+
def create_status_line
|
51
|
+
status_line = "HTTP/1.1 "
|
52
|
+
status_line << @status
|
53
|
+
status_line << ' '
|
54
|
+
status_line << @status_table[@status]
|
55
|
+
status_line << "\r\n"
|
56
|
+
status_line
|
57
|
+
end
|
58
|
+
|
59
|
+
def status=(status)
|
60
|
+
@status = status if @status_table.has_key?(status)
|
61
|
+
end
|
62
|
+
|
63
|
+
def header=(header)
|
64
|
+
if header.is_a? Hash
|
65
|
+
header.each do |key, value|
|
66
|
+
@header[key] = value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def content_type=(content_type)
|
72
|
+
@content_type = content_type if @mime_table.include?(content_type)
|
73
|
+
end
|
74
|
+
|
75
|
+
def body=(body)
|
76
|
+
if body.is_a? String
|
77
|
+
@body = body.bytes.to_a.pack("C*")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/amber/http.rb
ADDED
data/lib/amber/model.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
class Amber::Model
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
@data = {}
|
5
|
+
@data["id"] = Amber::Data::IntegerData.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](key)
|
9
|
+
if @data.has_key? key
|
10
|
+
return @data[key]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def has_key?(key)
|
15
|
+
@data.has_key? key
|
16
|
+
end
|
17
|
+
|
18
|
+
def []=(key, value)
|
19
|
+
if value.is_a? Amber::Data
|
20
|
+
@data[key] = value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def keys
|
25
|
+
@data.keys
|
26
|
+
end
|
27
|
+
|
28
|
+
def pack(map = nil)
|
29
|
+
data = {}
|
30
|
+
if map.is_a? Hash
|
31
|
+
map.each do |key, value|
|
32
|
+
if @data.has_key? key
|
33
|
+
data_item = @data[key]
|
34
|
+
data[value] = data_item.value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
@data.each do |key, value|
|
39
|
+
data[key] = value.value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
data
|
43
|
+
end
|
44
|
+
|
45
|
+
def unpack(data, map = nil)
|
46
|
+
if data.is_a? Hash
|
47
|
+
if map.is_a? Hash
|
48
|
+
map.each do |key, value|
|
49
|
+
if @data.has_key?(key) && data.has_key?(value)
|
50
|
+
data_item = @data[key]
|
51
|
+
data_item.value = data[value]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else
|
55
|
+
data.each do |key, value|
|
56
|
+
if @data.has_key? key
|
57
|
+
data_item = @data[key]
|
58
|
+
data_item.value = data[key]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def struct(map = nil, name_only = false)
|
66
|
+
struct = {}
|
67
|
+
if map.is_a? Hash
|
68
|
+
map.each do |key, value|
|
69
|
+
if @data.has_key? key
|
70
|
+
data_item = @data[key]
|
71
|
+
if name_only
|
72
|
+
struct[value] = data_item.class.to_s.match('\w+$').to_s
|
73
|
+
next
|
74
|
+
end
|
75
|
+
struct[value] = data_item.class.to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
else
|
79
|
+
@data.each do |key, value|
|
80
|
+
if name_only
|
81
|
+
struct[key] = value.class.to_s.match('\w+$').to_s
|
82
|
+
next
|
83
|
+
end
|
84
|
+
struct[key] = value.class.to_s
|
85
|
+
end
|
86
|
+
end
|
87
|
+
struct
|
88
|
+
end
|
89
|
+
end
|
data/lib/amber/route.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
class Amber::Route
|
2
|
+
attr_reader :root
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@root = Amber::RoutePath.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def map(url, method = nil, &callback)
|
9
|
+
layers = self.parse_url(url)
|
10
|
+
|
11
|
+
if layers.length > 0
|
12
|
+
layers.delete ""
|
13
|
+
current_layer = @root
|
14
|
+
|
15
|
+
layers.each do |layer|
|
16
|
+
if layer == layers.last
|
17
|
+
if current_layer.child.has_key? layer
|
18
|
+
path = current_layer.child[layer]
|
19
|
+
path.callback = callback
|
20
|
+
path.method = method if method
|
21
|
+
next
|
22
|
+
end
|
23
|
+
|
24
|
+
new_path = Amber::RoutePath.new
|
25
|
+
new_path.callback = callback
|
26
|
+
new_path.method = method if method
|
27
|
+
|
28
|
+
current_layer.add_child(layer, new_path)
|
29
|
+
else
|
30
|
+
if current_layer.child.has_key? layer
|
31
|
+
current_layer = current_layer.child[layer]
|
32
|
+
next
|
33
|
+
end
|
34
|
+
|
35
|
+
new_path = Amber::RoutePath.new
|
36
|
+
current_layer.add_child(layer, new_path)
|
37
|
+
current_layer = new_path
|
38
|
+
end
|
39
|
+
end
|
40
|
+
else
|
41
|
+
@root.callback = callback
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def find(url)
|
46
|
+
layers = self.parse_url(url)
|
47
|
+
current_layer = @root
|
48
|
+
|
49
|
+
if layers.length > 0
|
50
|
+
layers.delete ""
|
51
|
+
layers.each do |layer|
|
52
|
+
if current_layer.child.has_key? layer
|
53
|
+
current_layer = current_layer.child[layer]
|
54
|
+
else
|
55
|
+
return nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
current_layer
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_url(url)
|
64
|
+
url.split('/')
|
65
|
+
end
|
66
|
+
end
|