amber-kit 0.0.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.
- 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
|