nekonote-framework 1.0.0.pre.beta7 → 1.0.0.pre.beta8
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 +4 -4
- data/README.md +1 -1
- data/data/structure/preference/development/route.yml +10 -19
- data/data/structure/preference/development/route_error.yml +12 -8
- data/data/structure/preference/development/route_include.yml +4 -5
- data/data/structure/preference/development/setting/welcome.yml +1 -0
- data/data/structure/template/welcome/index.tpl +7 -6
- data/lib/nekonote/exception/handler_error.rb +2 -1
- data/lib/nekonote/handler.rb +100 -90
- data/lib/nekonote/preference.rb +3 -62
- data/lib/nekonote/rack/url_mapper.rb +14 -67
- data/lib/nekonote/rackup.rb +2 -7
- data/lib/nekonote/request.rb +10 -143
- data/lib/nekonote/spec.rb +6 -11
- data/lib/nekonote/view.rb +2 -4
- data/lib/nekonote/yaml_access.rb +1 -1
- metadata +6 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c90694ebb2f95129d0cc03e078cf4be8584d1357cd1db9877105f7c93228d8e0
|
4
|
+
data.tar.gz: d782253bf9b884629c34f08467c31398cf4194aa5d2bc066c59ec3443b37b7e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8074f388ff578cd78239da26a6e8f7116927c33c375064152c26208fe7624ede71bc6dfef211774484cf871271d46b517b52a29376f0fd0abe4aa216eac8df12
|
7
|
+
data.tar.gz: bffa8feaa2d47e409bb4cfa9660ce26451d231ed21129af8bc03694ca41c8deab23322467164d5ded801a059e3d78287145173fc8cc779a04a0a969948d458c7
|
data/README.md
CHANGED
@@ -43,7 +43,7 @@ The templating engine on Nekonote Framework is Liquid.
|
|
43
43
|
|
44
44
|
Please see [Getting Started](https://nekonote-framework.github.io/document/1.0.0-beta/getting-started.html) on the reference manual.
|
45
45
|
|
46
|
-
You need to use `--pre` option when
|
46
|
+
You need to use `--pre` option when installing pre-beta version.
|
47
47
|
|
48
48
|
$ gem install nekonote-framework --pre
|
49
49
|
|
@@ -2,29 +2,20 @@
|
|
2
2
|
#
|
3
3
|
# e.g.
|
4
4
|
# FooHandler:
|
5
|
-
# path: /foo
|
6
|
-
# execute: foo
|
7
|
-
# method:
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# custom: some value
|
5
|
+
# path: /foo # This directive is required. The following directives are optional.
|
6
|
+
# execute: foo # It says FooHandler#foo will be called.
|
7
|
+
# method: POST # It says requests only with POST method are accepted.
|
8
|
+
# content: json # It says Content-Type: application/json will be set to response.
|
9
|
+
# template: foo # template/foo.tpl will be used.
|
10
|
+
# layout: common # template/layout/common.tpl will be used
|
11
|
+
# page_cache_time: 3600 # Setting an integer in seconds to turning on page caching.
|
12
|
+
# include: common # Includes a group of the directives from route_include.yml.
|
13
|
+
# custom: some value # Unknown directives are custom fields and are assigned into your templates.
|
14
14
|
|
15
|
-
# ----------------------
|
16
|
-
# routing options
|
17
|
-
# ----------------------
|
18
|
-
preference:
|
19
|
-
path_as_regexp: false
|
20
|
-
allow_dup_slash: false
|
21
|
-
|
22
|
-
# ----------------------
|
23
|
-
# Routes
|
24
|
-
# ----------------------
|
25
15
|
WelcomeHandler:
|
26
16
|
path: /
|
27
17
|
execute: index
|
28
18
|
template: welcome/index
|
19
|
+
layout: default
|
29
20
|
css: /css/welcome.css
|
30
21
|
page-title: Welcome
|
@@ -1,28 +1,32 @@
|
|
1
|
-
#
|
1
|
+
# Error Routes
|
2
|
+
#
|
3
|
+
# It's possible to comment out the directives below then error routes does not be used.
|
2
4
|
|
3
5
|
# This route is used when any route does not match a URL.
|
4
|
-
# You must set “path_as_regexp” directive to “true” which in route.yml to use this route.
|
5
6
|
missing_route:
|
6
7
|
handler: ErrorHandler
|
7
8
|
execute: missing_route
|
9
|
+
template: error
|
8
10
|
layout: error
|
9
11
|
|
10
|
-
# This route is used when
|
11
|
-
# and a request HTTP method is not declared in that value.
|
12
|
+
# This route is used when a HTTP method in request does not much the value set in "method" directive in route.yml.
|
12
13
|
wrong_http_method:
|
13
14
|
handler: ErrorHandler
|
14
15
|
execute: wrong_http_method
|
16
|
+
template: error
|
15
17
|
layout: error
|
16
18
|
|
17
|
-
# This route is used when a fatal error raised in program.
|
18
|
-
# The exception object
|
19
|
+
# This route is used when a fatal error raised in your program.
|
20
|
+
# The exception object will be set to the property named @error.
|
19
21
|
fatal:
|
20
22
|
handler: ErrorHandler
|
21
23
|
execute: fatal
|
24
|
+
template: error
|
22
25
|
layout: error
|
23
26
|
|
24
|
-
# This route is used when a
|
27
|
+
# This route is used when a request file does not exist under the "public" directory.
|
25
28
|
not_found:
|
26
29
|
handler: ErrorHandler
|
27
30
|
execute: not_found
|
28
|
-
|
31
|
+
template: error
|
32
|
+
layout: error
|
@@ -4,19 +4,18 @@
|
|
4
4
|
# e.g.
|
5
5
|
# common:
|
6
6
|
# method: GET
|
7
|
-
# params: id=int
|
8
7
|
# content: json
|
9
8
|
# template: false
|
10
9
|
# layoute: false
|
11
10
|
#
|
12
|
-
# In order to set the above preferences you must write 'include' directive
|
11
|
+
# In order to set the above preferences you must write 'include' directive
|
13
12
|
#
|
14
13
|
# FooHandler:
|
15
14
|
# path: /foo
|
16
|
-
#
|
15
|
+
# execute: foo
|
17
16
|
# include: common
|
18
17
|
#
|
19
18
|
# BarHandler:
|
20
19
|
# path: /bar
|
21
|
-
#
|
22
|
-
# include: common
|
20
|
+
# execute: bar
|
21
|
+
# include: common
|
@@ -5,3 +5,4 @@ url:
|
|
5
5
|
github: https://github.com/khotta/Nekonote-Framework
|
6
6
|
contribute: https://nekonote-framework.github.io/contribute
|
7
7
|
license: https://github.com/khotta/Nekonote-Framework/blob/master/LICENSE
|
8
|
+
changelog: https://github.com/khotta/Nekonote-Framework/blob/master/CHANGELOG.md
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<h3>Welcome to Nekonote Framework!</h3>
|
3
3
|
<p class="description">{{description}}</p>
|
4
4
|
|
5
|
-
<h4>
|
5
|
+
<h4>Environments</h4>
|
6
6
|
<ul>
|
7
7
|
<li>The version is <em>{{version}}</em></li>
|
8
8
|
<li>Current Environment: <em>{{env}}</em></li>
|
@@ -11,15 +11,16 @@
|
|
11
11
|
|
12
12
|
<h4>Do you need help?</h4>
|
13
13
|
<ul>
|
14
|
-
<li>Reference Manual <a href="{% setting_get url, document %}">{% setting_get url, document %}</a></li>
|
15
|
-
<li>Contribute <a href="{% setting_get url, contribute %}">{% setting_get url, contribute %}</a></li>
|
14
|
+
<li>Reference Manual <a target="_blank" href="{% setting_get url, document %}">{% setting_get url, document %}</a></li>
|
15
|
+
<li>Contribute <a target="_blank" href="{% setting_get url, contribute %}">{% setting_get url, contribute %}</a></li>
|
16
|
+
<li>Changelog <a target="_blank" href="{% setting_get url, changelog %}">{% setting_get url, changelog %}</a></li>
|
16
17
|
</ul>
|
17
18
|
|
18
19
|
<h4>Nekonote Framework is open-source software</h4>
|
19
20
|
<ul>
|
20
|
-
<li>License <a href="{% setting_get url, license %}">{% setting_get url, license %}</a></li>
|
21
|
-
<li>GitHub <a href="{% setting_get url, github %}">{% setting_get url, github %}</a></li>
|
22
|
-
<li>Repository <a href="{% setting_get url, gem %}">{% setting_get url, gem %}</a></li>
|
21
|
+
<li>License <a target="_blank" href="{% setting_get url, license %}">{% setting_get url, license %}</a></li>
|
22
|
+
<li>GitHub <a target="_blank" href="{% setting_get url, github %}">{% setting_get url, github %}</a></li>
|
23
|
+
<li>Repository <a target="_blank" href="{% setting_get url, gem %}">{% setting_get url, gem %}</a></li>
|
23
24
|
</ul>
|
24
25
|
|
25
26
|
<div id="footer-logo"></div>
|
data/lib/nekonote/handler.rb
CHANGED
@@ -4,45 +4,10 @@ module Nekonote
|
|
4
4
|
require Nekonote.get_lib_root_path + 'handler/protected_methods'
|
5
5
|
include ProtectedMethods
|
6
6
|
|
7
|
-
# =============================================
|
8
7
|
# Accessors
|
9
|
-
# =============================================
|
10
8
|
attr_accessor :route_regexp,
|
11
9
|
:url_path_params_mapper
|
12
10
|
|
13
|
-
# =============================================
|
14
|
-
# Static method
|
15
|
-
# =============================================
|
16
|
-
# make error handler and execute it
|
17
|
-
# @param string field
|
18
|
-
# @param hash env
|
19
|
-
# @param nil e
|
20
|
-
# @return array
|
21
|
-
def self.call_error_handler(field, env = {}, e = nil)
|
22
|
-
pref = Preference.instance.get_route_error
|
23
|
-
|
24
|
-
# field is expected String and pref[field] is expected Hash
|
25
|
-
if !field.is_a?(String) || !pref[field].is_a?(Hash)
|
26
|
-
raise HandlerError, HandlerError::MSG_MISSING_FIELD%[field, Preference.instance.path_route_error_yml]
|
27
|
-
end
|
28
|
-
|
29
|
-
# make handler newly
|
30
|
-
handler_name = pref[field][Preference::FIELD_ROUTE_HANDLER]
|
31
|
-
if handler_name.is_a? String
|
32
|
-
begin
|
33
|
-
handler_class = Object.const_get handler_name
|
34
|
-
error_handler = handler_class.new pref[field].clone, field, e
|
35
|
-
rescue
|
36
|
-
raise HandlerError, HandlerError::MSG_MISSING_CONST% handler_name
|
37
|
-
end
|
38
|
-
else
|
39
|
-
raise HandlerError, HandlerError::MSG_MISSING_ERR_HANDLER
|
40
|
-
end
|
41
|
-
|
42
|
-
return error_handler.call env
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
11
|
# It would be called only one time
|
47
12
|
# @param hash info route information
|
48
13
|
# @param bool|nil error_field_name
|
@@ -63,32 +28,17 @@ module Nekonote
|
|
63
28
|
@custom_fields = Preference.get_custom_fields info, error_field_name.is_a?(String)
|
64
29
|
end
|
65
30
|
|
66
|
-
# reload preferences
|
67
|
-
private
|
68
|
-
def pref_reloader
|
69
|
-
path = Nekonote.get_root_path + Preference::FILE_NAME_FOR_RELOAD
|
70
|
-
if File.exist? path
|
71
|
-
# reload logger
|
72
|
-
Nekonote.init_logger
|
73
|
-
|
74
|
-
# reload setting
|
75
|
-
Setting.init
|
76
|
-
|
77
|
-
Util::Filer::safe_delete_empty_file path
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
31
|
# This method would be called from rack and called in every request
|
82
32
|
# @param hash env rack environment
|
83
33
|
public
|
84
34
|
def call(env)
|
85
35
|
# reload preferences if needed
|
86
|
-
|
36
|
+
reload_pref
|
87
37
|
|
88
38
|
# get reponse data from page cache if it's available
|
89
39
|
if @view.can_get_from_page_cache?(env['REQUEST_URI'])
|
90
40
|
response_data = @view.get_response_data_from_page_cache env['REQUEST_URI']
|
91
|
-
if response_data.size == 3
|
41
|
+
if response_data.size == 3 # response code, headers, body
|
92
42
|
# return the cache
|
93
43
|
return response_data
|
94
44
|
else
|
@@ -107,9 +57,9 @@ module Nekonote
|
|
107
57
|
@session = Env.get 'rack.session'
|
108
58
|
|
109
59
|
# set request
|
110
|
-
@request = Request.new env
|
60
|
+
@request = Request.new env
|
111
61
|
|
112
|
-
# set request body
|
62
|
+
# set request body from payload if it exists
|
113
63
|
if env['rack.input'].is_a? StringIO
|
114
64
|
# reverting file pointer I don't know why the pointer moved just one...?
|
115
65
|
env['rack.input'].rewind
|
@@ -150,17 +100,6 @@ module Nekonote
|
|
150
100
|
return View.get_default_error_response
|
151
101
|
end
|
152
102
|
|
153
|
-
# @param StandardError|ScriptError e
|
154
|
-
# @throws StandardError|ScriptError
|
155
|
-
private
|
156
|
-
def process_exception_raised(e)
|
157
|
-
# logging if logger is enabled
|
158
|
-
Error.logging_error e
|
159
|
-
|
160
|
-
# raise the exception for ShowExceptions if it's enabled
|
161
|
-
raise e if Preference.instance.is_enabled_show_exceptions
|
162
|
-
end
|
163
|
-
|
164
103
|
# It would be called by every request
|
165
104
|
# @param hash env
|
166
105
|
# @return array
|
@@ -188,28 +127,34 @@ module Nekonote
|
|
188
127
|
return get_response_data
|
189
128
|
end
|
190
129
|
|
191
|
-
#
|
192
|
-
# @
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
if @url_path_params_mapper.is_a? Hash
|
199
|
-
stack = requested_path.split('/')
|
200
|
-
map = {}
|
201
|
-
@url_path_params_mapper.each_pair do |name, index|
|
202
|
-
map[name] = stack[index]
|
203
|
-
end
|
204
|
-
@request.assign_from_url map
|
205
|
-
end
|
130
|
+
# make error handler and execute it
|
131
|
+
# @param string field
|
132
|
+
# @param hash env
|
133
|
+
# @param nil e
|
134
|
+
# @return array
|
135
|
+
def self.call_error_handler(field, env = {}, e = nil)
|
136
|
+
pref = Preference.instance.get_route_error
|
206
137
|
|
207
|
-
|
138
|
+
# check if there is a route for it?
|
139
|
+
if !pref.is_a?(Hash) || !pref[field].is_a?(Hash)
|
140
|
+
# no route for it
|
141
|
+
raise HandlerError, HandlerError::MSG_NO_ERROR_ROUTE% field
|
142
|
+
end
|
208
143
|
|
144
|
+
# make error handler
|
145
|
+
handler_name = pref[field][Preference::FIELD_ROUTE_HANDLER]
|
146
|
+
if handler_name.is_a? String
|
147
|
+
begin
|
148
|
+
handler_class = Object.const_get handler_name
|
149
|
+
error_handler = handler_class.new pref[field].clone, field, e
|
150
|
+
rescue
|
151
|
+
raise HandlerError, HandlerError::MSG_MISSING_CONST% handler_name
|
152
|
+
end
|
209
153
|
else
|
210
|
-
|
211
|
-
return false
|
154
|
+
raise HandlerError, HandlerError::MSG_MISSING_ERR_HANDLER
|
212
155
|
end
|
156
|
+
|
157
|
+
return error_handler.call env
|
213
158
|
end
|
214
159
|
|
215
160
|
# Get response data and return values as rack needed
|
@@ -232,6 +177,66 @@ module Nekonote
|
|
232
177
|
return @view.get_response_data
|
233
178
|
end
|
234
179
|
|
180
|
+
# reload preferences
|
181
|
+
# only for logger.yml setting/**/*.yml
|
182
|
+
private
|
183
|
+
def reload_pref
|
184
|
+
path = Nekonote.get_root_path + Preference::FILE_NAME_FOR_RELOAD
|
185
|
+
|
186
|
+
if File.exist? path
|
187
|
+
# reload logger
|
188
|
+
Nekonote.init_logger
|
189
|
+
|
190
|
+
# reload setting
|
191
|
+
Setting.init
|
192
|
+
|
193
|
+
Util::Filer::safe_delete_empty_file path
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# @param StandardError|ScriptError e
|
198
|
+
# @throws StandardError|ScriptError
|
199
|
+
private
|
200
|
+
def process_exception_raised(e)
|
201
|
+
# logging if logger is enabled
|
202
|
+
Error.logging_error e
|
203
|
+
|
204
|
+
# raise the exception for ShowExceptions if it's enabled
|
205
|
+
raise e if Preference.instance.is_enabled_show_exceptions
|
206
|
+
end
|
207
|
+
|
208
|
+
# Check does requested path correspond with the given value to #map
|
209
|
+
# @return bool
|
210
|
+
private
|
211
|
+
def matched_route_strictly?(requested_path, expected_path)
|
212
|
+
match_data = @route_regexp.match requested_path
|
213
|
+
if match_data.is_a? MatchData
|
214
|
+
# set URL path parameters to Request object
|
215
|
+
set_url_path_params requested_path
|
216
|
+
return true
|
217
|
+
|
218
|
+
else
|
219
|
+
# doesn't match, the requested path is wrong
|
220
|
+
return false
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# set url path params to@request object
|
225
|
+
# @param string requested_path
|
226
|
+
private
|
227
|
+
def set_url_path_params(requested_path)
|
228
|
+
# if there is URL path parameters
|
229
|
+
if @url_path_params_mapper.is_a?(Hash) && @url_path_params_mapper.size > 0
|
230
|
+
stack = requested_path.split('/')
|
231
|
+
map = {}
|
232
|
+
@url_path_params_mapper.each_pair do |name, index|
|
233
|
+
map[name] = stack[index]
|
234
|
+
end
|
235
|
+
|
236
|
+
@request.assign_from_url map
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
235
240
|
# @param string|symbol|nil task method name defined in 'klass'
|
236
241
|
private
|
237
242
|
def execute_handler_methods(task)
|
@@ -261,14 +266,19 @@ module Nekonote
|
|
261
266
|
# @return false|nil|int
|
262
267
|
private
|
263
268
|
def is_allowed_http_method(method)
|
269
|
+
# invalid input to NG
|
264
270
|
return false if !method.is_a? String
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
271
|
+
|
272
|
+
# expecting http method
|
273
|
+
allow_method = @view.info_allow_method
|
274
|
+
|
275
|
+
# no configuration to OK
|
276
|
+
return true if !allow_method.is_a? String
|
277
|
+
|
278
|
+
allow_method.strip!
|
279
|
+
|
280
|
+
# case-insensitive judge
|
281
|
+
return allow_method.casecmp(method) == 0
|
272
282
|
end
|
273
283
|
end
|
274
284
|
end
|
data/lib/nekonote/preference.rb
CHANGED
@@ -8,14 +8,7 @@ module Nekonote
|
|
8
8
|
# for route.yml
|
9
9
|
FIELD_ROUTE_INCLUDE = 'include'
|
10
10
|
|
11
|
-
# routing options
|
12
|
-
FIELD_ROUTING_OPTIONS = 'preference'
|
13
|
-
FIELD_OPTION_ROUTE_REGEXP = 'path_as_regexp'
|
14
|
-
FIELD_OPTION_ALLOW_DUP_SLASH = 'allow_dup_slash'
|
15
|
-
|
16
11
|
# default values for routing options
|
17
|
-
DEFAULT_OPTION_ROUTE_REGEXP = false
|
18
|
-
DEFAULT_OPTION_ALLOW_DUP_SLASH = false
|
19
12
|
DEFAULT_OPTION_TEMPLATE_FILE_EXT = 'tpl'
|
20
13
|
DEFAULT_OPTION_LAYOUT_FILE_EXT = 'tpl'
|
21
14
|
|
@@ -28,8 +21,7 @@ module Nekonote
|
|
28
21
|
# for route.yml and route_error.yml
|
29
22
|
FIELD_ROUTE_PATH = 'path'
|
30
23
|
FIELD_ROUTE_EXEC_METHOD = 'execute'
|
31
|
-
|
32
|
-
FIELD_ROUTE_PARAMS = 'params'
|
24
|
+
FIELD_ROUTE_ALLOW_METHOD = 'method'
|
33
25
|
FIELD_ROUTE_CONTENT_TYPE = 'content'
|
34
26
|
FIELD_ROUTE_TEMPLATE = 'template'
|
35
27
|
FIELD_ROUTE_LAYOUT = 'layout'
|
@@ -40,8 +32,7 @@ module Nekonote
|
|
40
32
|
FIELDS_IN_ROUTE = [
|
41
33
|
FIELD_ROUTE_PATH,
|
42
34
|
FIELD_ROUTE_EXEC_METHOD,
|
43
|
-
|
44
|
-
FIELD_ROUTE_PARAMS,
|
35
|
+
FIELD_ROUTE_ALLOW_METHOD,
|
45
36
|
FIELD_ROUTE_CONTENT_TYPE,
|
46
37
|
FIELD_ROUTE_TEMPLATE,
|
47
38
|
FIELD_ROUTE_LAYOUT,
|
@@ -129,11 +120,7 @@ module Nekonote
|
|
129
120
|
# @return bool
|
130
121
|
public
|
131
122
|
def has_error_route?(field)
|
132
|
-
# not found route_error.yml just return false
|
133
|
-
if @parsed_route_error_yml == nil
|
134
|
-
return false
|
135
|
-
end
|
136
|
-
|
123
|
+
# not found route_error.yml just return false
|
137
124
|
# check if the field exists
|
138
125
|
if !@parsed_route_error_yml.is_a?(Hash) || !@parsed_route_error_yml[field].is_a?(Hash)
|
139
126
|
return false
|
@@ -142,18 +129,6 @@ module Nekonote
|
|
142
129
|
return @parsed_route_error_yml[field][FIELD_ROUTE_HANDLER].is_a?(String)
|
143
130
|
end
|
144
131
|
|
145
|
-
# @return bool
|
146
|
-
public
|
147
|
-
def is_path_regexp?
|
148
|
-
return @is_path_regexp
|
149
|
-
end
|
150
|
-
|
151
|
-
# @return bool
|
152
|
-
public
|
153
|
-
def is_allow_dup_slash?
|
154
|
-
return @is_allow_dup_slash
|
155
|
-
end
|
156
|
-
|
157
132
|
# @return string
|
158
133
|
public
|
159
134
|
def get_template_file_extension
|
@@ -180,42 +155,8 @@ module Nekonote
|
|
180
155
|
raise PreferenceError, PreferenceError::MSG_EMPTY_YAML% @path_route_yml
|
181
156
|
end
|
182
157
|
|
183
|
-
# set route options
|
184
|
-
init_routing_options
|
185
|
-
end
|
186
|
-
|
187
|
-
# initialize routing options
|
188
|
-
public
|
189
|
-
def init_routing_options
|
190
|
-
@is_path_regexp = nil
|
191
|
-
@is_allow_dup_slash = nil
|
192
|
-
@template_file_extension = nil
|
193
|
-
@layout_file_extension = nil
|
194
|
-
|
195
|
-
# read route.yml
|
196
|
-
pref = YamlAccess::get_parsed @path_route_yml
|
197
|
-
|
198
|
-
# not found but already it's checked though
|
199
|
-
return if !pref.is_a?(Hash)
|
200
|
-
|
201
|
-
routing_options = pref['preference']
|
202
|
-
|
203
|
-
# not found routing options to default
|
204
|
-
return if !routing_options.is_a?(Hash)
|
205
|
-
|
206
|
-
# set value to property
|
207
|
-
# true -> Nekonote::URLMapper, false -> :Rack::URLMap
|
208
|
-
@is_path_regexp = routing_options[FIELD_OPTION_ROUTE_REGEXP] || DEFAULT_OPTION_ROUTE_REGEXP
|
209
|
-
@is_allow_dup_slash = routing_options[FIELD_OPTION_ALLOW_DUP_SLASH] || DEFAULT_OPTION_ALLOW_DUP_SLASH
|
210
158
|
@template_file_extension = DEFAULT_OPTION_TEMPLATE_FILE_EXT
|
211
159
|
@layout_file_extension = DEFAULT_OPTION_LAYOUT_FILE_EXT
|
212
|
-
|
213
|
-
# validation for file extension
|
214
|
-
if !@template_file_extension.is_a?(String) || @template_file_extension == ''
|
215
|
-
raise PreferenceError, Error::MSG_WRONG_TYPE% [FIELD_OPTION_TEMPLATE_EXT, 'String']
|
216
|
-
elsif !@layout_file_extension.is_a?(String) || @layout_file_extension == ''
|
217
|
-
raise PreferenceError, Error::MSG_WRONG_TYPE% [FIELD_OPTION_LAYOUT_EXT, 'String']
|
218
|
-
end
|
219
160
|
end
|
220
161
|
|
221
162
|
# @param array info information about route
|
@@ -20,79 +20,29 @@ module Nekonote
|
|
20
20
|
|
21
21
|
# replace variable with wildcard
|
22
22
|
url_path_params_mapper.each_key do |name|
|
23
|
-
pattern.sub! (':' + name), '
|
23
|
+
pattern.sub! (':' + name), '\w+'
|
24
24
|
end
|
25
|
-
end
|
26
|
-
|
27
|
-
return url_path_params_mapper, pattern
|
28
|
-
end
|
29
|
-
|
30
|
-
# @param string pattern
|
31
|
-
# @returns regexp, hash, string
|
32
|
-
def get_route_regexp(pattern)
|
33
|
-
# if home page
|
34
|
-
pattern = '/' if pattern == ''
|
35
|
-
|
36
|
-
# escape special meaning characters in regexp
|
37
|
-
pattern = Regexp.quote pattern
|
38
|
-
|
39
|
-
# parse path for url path parameters
|
40
|
-
url_path_params_mapper, pattern = parse_url_path_params pattern
|
41
|
-
|
42
|
-
pattern = %(^#{pattern}$)
|
43
25
|
|
44
|
-
|
45
|
-
if Preference.instance.is_allow_dup_slash?
|
46
|
-
pattern.gsub! '/', '/+'
|
26
|
+
# todo think in case of "path: /path/to/:something" -> It can match /path/to/foo/bar with {"something"=>"foo"}
|
47
27
|
end
|
48
28
|
|
49
|
-
|
50
|
-
|
51
|
-
return match, url_path_params_mapper, pattern
|
29
|
+
return url_path_params_mapper, pattern
|
52
30
|
end
|
53
31
|
|
54
|
-
# @param string
|
32
|
+
# @param string path
|
55
33
|
# @returns regexp, hash, string
|
56
|
-
def get_route_regexp_custom(
|
57
|
-
option = nil
|
58
|
-
code = nil
|
59
|
-
|
34
|
+
def get_route_regexp_custom(path)
|
60
35
|
# parse path for url path parameters
|
61
|
-
url_path_params_mapper,
|
62
|
-
|
63
|
-
if pattern == ''
|
64
|
-
# home page
|
65
|
-
pattern = '/$'
|
66
|
-
|
67
|
-
elsif /\/[ixmn]+$/ =~ pattern
|
68
|
-
# there is regexp option
|
69
|
-
matched_str = $&.delete '/'
|
70
|
-
pattern = pattern.sub /\/[ixmn]+$/, ''
|
71
|
-
option = 0
|
72
|
-
matched_str.each_char do |char|
|
73
|
-
case char
|
74
|
-
when 'i'
|
75
|
-
option = option | Regexp::IGNORECASE
|
76
|
-
when 'm'
|
77
|
-
option = option | Regexp::MULTILINE
|
78
|
-
when 'x'
|
79
|
-
option = option | Regexp::EXTENDED
|
80
|
-
when 'n'
|
81
|
-
code = 'n'
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
36
|
+
url_path_params_mapper, path = parse_url_path_params path
|
85
37
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
38
|
+
if path == ''
|
39
|
+
# home page, it doesn't matter '' or '/'
|
40
|
+
pattern = /^\/?$/
|
41
|
+
else
|
42
|
+
pattern = /^#{path}$/
|
91
43
|
end
|
92
44
|
|
93
|
-
|
94
|
-
|
95
|
-
return match, url_path_params_mapper, pattern
|
45
|
+
return pattern, url_path_params_mapper
|
96
46
|
end
|
97
47
|
# =========================================================================
|
98
48
|
# End adding source code
|
@@ -116,11 +66,8 @@ module Nekonote
|
|
116
66
|
# Start adding source code for Nekonote Framework
|
117
67
|
# =========================================================================
|
118
68
|
# get regexp for matching URL
|
119
|
-
|
120
|
-
|
121
|
-
else
|
122
|
-
match, url_path_params_mapper, location = get_route_regexp location
|
123
|
-
end
|
69
|
+
# path will be evaluated as regexp
|
70
|
+
match, url_path_params_mapper = get_route_regexp_custom location
|
124
71
|
|
125
72
|
# set the values to Nekonote::Handler class
|
126
73
|
app.route_regexp = match
|
data/lib/nekonote/rackup.rb
CHANGED
@@ -262,13 +262,8 @@ EOS
|
|
262
262
|
# include directive has been set in the route
|
263
263
|
if pref_common[info[Preference::FIELD_ROUTE_INCLUDE]].is_a? Hash
|
264
264
|
pref_common[info[Preference::FIELD_ROUTE_INCLUDE]].each_pair do |k, v|
|
265
|
-
|
266
|
-
|
267
|
-
else
|
268
|
-
# directive name is duplicate between route.yml and route_include.yml
|
269
|
-
# values in route.yml takes precedence over values in route_include.yml that without method or params
|
270
|
-
info[k] += ',' + v if k == Preference::FIELD_ROUTE_PARAMS || k == Preference::FIELD_ROUTE_ALLOW_METHODS
|
271
|
-
end
|
265
|
+
# duplicated then values in route.yml should take precedence
|
266
|
+
info[k] = v
|
272
267
|
end
|
273
268
|
info.delete Preference::FIELD_ROUTE_INCLUDE
|
274
269
|
else
|
data/lib/nekonote/request.rb
CHANGED
@@ -1,11 +1,5 @@
|
|
1
1
|
module Nekonote
|
2
2
|
class Request
|
3
|
-
STRING = 'string'
|
4
|
-
INTEGER = 'int'
|
5
|
-
ARRAY = 'array'
|
6
|
-
FLOAT = 'float'
|
7
|
-
BOOL = 'bool'
|
8
|
-
|
9
3
|
# accessor
|
10
4
|
attr_reader :path,
|
11
5
|
:uri,
|
@@ -13,43 +7,36 @@ module Nekonote
|
|
13
7
|
:payload
|
14
8
|
|
15
9
|
# @param hash env
|
16
|
-
|
17
|
-
def initialize(env, restricted = nil)
|
10
|
+
def initialize(env)
|
18
11
|
# set properties
|
19
12
|
@path = env['REQUEST_PATH']
|
20
13
|
@uri = env['REQUEST_URI']
|
21
14
|
@method = env['REQUEST_METHOD']
|
22
|
-
@accepted_list = get_accepted_list restricted
|
23
15
|
|
24
16
|
# query string
|
25
|
-
@query_string
|
26
|
-
@query_string_raw = {}
|
17
|
+
@query_string = {}
|
27
18
|
|
28
19
|
# POST data
|
29
|
-
@post_data
|
30
|
-
@post_data_raw = {}
|
20
|
+
@post_data = {}
|
31
21
|
|
32
22
|
# URL path parameters
|
33
|
-
@path_params
|
34
|
-
@path_params_raw = {}
|
23
|
+
@path_params = {} # this will be set from handler
|
35
24
|
|
36
25
|
# request body
|
37
26
|
@payload = nil
|
38
27
|
|
39
28
|
# set query string
|
40
29
|
if env['QUERY_STRING'].is_a? String
|
41
|
-
@
|
42
|
-
@query_string = get_sanitized @query_string_raw
|
30
|
+
@query_string = get_param_maps env['QUERY_STRING']
|
43
31
|
end
|
44
32
|
|
45
33
|
# set POST data
|
46
34
|
if env['rack.input'].is_a? StringIO
|
47
|
-
@
|
48
|
-
@post_data = get_sanitized @post_data_raw
|
35
|
+
@post_data = get_param_maps env['rack.input'].gets
|
49
36
|
end
|
50
37
|
end
|
51
38
|
|
52
|
-
# Returns
|
39
|
+
# Returns query string
|
53
40
|
# @params string|symbol name
|
54
41
|
# @return mixed
|
55
42
|
public
|
@@ -57,15 +44,7 @@ module Nekonote
|
|
57
44
|
return get_value name, @query_string
|
58
45
|
end
|
59
46
|
|
60
|
-
# Returns
|
61
|
-
# @params string|symbol name
|
62
|
-
# @return mixed
|
63
|
-
public
|
64
|
-
def query_string_raw(name = nil)
|
65
|
-
return get_value name, @query_string_raw
|
66
|
-
end
|
67
|
-
|
68
|
-
# Returns sanitized POST data
|
47
|
+
# Returns POST data
|
69
48
|
# @params string|symbol name
|
70
49
|
# @return mixed
|
71
50
|
public
|
@@ -73,15 +52,7 @@ module Nekonote
|
|
73
52
|
return get_value name, @post_data
|
74
53
|
end
|
75
54
|
|
76
|
-
# Returns
|
77
|
-
# @params string|symbol name
|
78
|
-
# @return mixed
|
79
|
-
public
|
80
|
-
def post_data_raw(name = nil)
|
81
|
-
return get_value name, @post_data_raw
|
82
|
-
end
|
83
|
-
|
84
|
-
# Returns sanitized URL parameters
|
55
|
+
# Returns URL parameters
|
85
56
|
# @params string|symbol name
|
86
57
|
# @return mixed
|
87
58
|
public
|
@@ -89,14 +60,6 @@ module Nekonote
|
|
89
60
|
return get_value name, @path_params
|
90
61
|
end
|
91
62
|
|
92
|
-
# Returns raw URL parameters
|
93
|
-
# @params string|symbol name
|
94
|
-
# @return mixed
|
95
|
-
public
|
96
|
-
def path_params_raw(name = nil)
|
97
|
-
return get_value name, @path_params_raw
|
98
|
-
end
|
99
|
-
|
100
63
|
# Returns sanitized parameters
|
101
64
|
# @params string|symbol name
|
102
65
|
# @return mixed
|
@@ -113,22 +76,6 @@ module Nekonote
|
|
113
76
|
return get_value name, maps
|
114
77
|
end
|
115
78
|
|
116
|
-
# Returns raw parameters
|
117
|
-
# @params string|symbol name
|
118
|
-
# @return mixed
|
119
|
-
public
|
120
|
-
def params_raw(name = nil)
|
121
|
-
case @method
|
122
|
-
when 'GET'
|
123
|
-
maps = @query_string_raw
|
124
|
-
when 'POST'
|
125
|
-
maps = @post_data_raw
|
126
|
-
else
|
127
|
-
maps = {}
|
128
|
-
end
|
129
|
-
return get_value name, maps
|
130
|
-
end
|
131
|
-
|
132
79
|
# Returns parsed payload as json format
|
133
80
|
# @return hash|nil|false
|
134
81
|
public
|
@@ -154,8 +101,7 @@ module Nekonote
|
|
154
101
|
return nil if !map.is_a? Hash
|
155
102
|
|
156
103
|
# set url params
|
157
|
-
@
|
158
|
-
@path_params = get_sanitized @path_params_raw
|
104
|
+
@path_params = map
|
159
105
|
end
|
160
106
|
|
161
107
|
# @param mixed payload
|
@@ -193,27 +139,6 @@ module Nekonote
|
|
193
139
|
end
|
194
140
|
end
|
195
141
|
|
196
|
-
# Returns the accepable name list
|
197
|
-
# @param string|nil restricted
|
198
|
-
# @return array
|
199
|
-
private
|
200
|
-
def get_accepted_list(restricted)
|
201
|
-
accepted_list = []
|
202
|
-
if restricted.is_a? String
|
203
|
-
restricted.split(',').each do |data|
|
204
|
-
data.strip!
|
205
|
-
pair = data.split('=')
|
206
|
-
if pair.size != 2
|
207
|
-
raise Error, Error::MSG_INVALID_FIELD%['params', Preference.instance.path_route_yml]
|
208
|
-
end
|
209
|
-
# add field name and hash as Hash into array
|
210
|
-
accepted_list << {pair[0] => pair[1]}
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
return accepted_list
|
215
|
-
end
|
216
|
-
|
217
142
|
# @param string str query string
|
218
143
|
# @return hash
|
219
144
|
private
|
@@ -233,63 +158,5 @@ module Nekonote
|
|
233
158
|
|
234
159
|
return maps
|
235
160
|
end
|
236
|
-
|
237
|
-
# Removing waste parameter and converting to the exected type
|
238
|
-
# @param hash maps
|
239
|
-
# @param bool decode
|
240
|
-
# @return hash
|
241
|
-
private
|
242
|
-
def get_sanitized(maps, decode = false)
|
243
|
-
return maps if @accepted_list.size == 0
|
244
|
-
|
245
|
-
sanitized_maps = {}
|
246
|
-
@accepted_list.each do |field|
|
247
|
-
field.each_pair do |name, type|
|
248
|
-
converted = get_expected type, maps[name]
|
249
|
-
|
250
|
-
# URL decode if necessary
|
251
|
-
if decode || converted.is_a?(String)
|
252
|
-
converted = URI.decode_www_form_component converted
|
253
|
-
end
|
254
|
-
|
255
|
-
sanitized_maps[name] = converted
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
return sanitized_maps
|
260
|
-
end
|
261
|
-
|
262
|
-
# @param string type type expected
|
263
|
-
# @param mixed value real value
|
264
|
-
# @param string converted value by the expected type
|
265
|
-
private
|
266
|
-
def get_expected(type, value)
|
267
|
-
return nil if value == nil
|
268
|
-
|
269
|
-
v = nil
|
270
|
-
begin
|
271
|
-
case type
|
272
|
-
when INTEGER
|
273
|
-
v = value.to_i
|
274
|
-
when STRING
|
275
|
-
v = value.to_s
|
276
|
-
when ARRAY
|
277
|
-
v = value.to_s.split(',')
|
278
|
-
v.map! { |val| val.strip }
|
279
|
-
when FLOAT
|
280
|
-
v = value.to_f
|
281
|
-
when BOOL
|
282
|
-
if value == nil || value == false || value == 'false' || value == 0 || value == '0' || value == 'no' || value == ''
|
283
|
-
v = false
|
284
|
-
else
|
285
|
-
v = true
|
286
|
-
end
|
287
|
-
end
|
288
|
-
rescue
|
289
|
-
# value is nil if failed to convert value to expected type
|
290
|
-
end
|
291
|
-
|
292
|
-
return v
|
293
|
-
end
|
294
161
|
end
|
295
162
|
end
|
data/lib/nekonote/spec.rb
CHANGED
@@ -1,22 +1,17 @@
|
|
1
1
|
module Nekonote
|
2
2
|
LIBS_NAME = %(nekonote-framework).freeze
|
3
|
-
VERSION = %(1.0.0-
|
3
|
+
VERSION = %(1.0.0-beta8).freeze
|
4
4
|
HOMEPAGE = %(https://nekonote-framework.github.io).freeze
|
5
5
|
SUMMARY = %(Simple and Lightweight Ruby Framework for Web Development).freeze
|
6
6
|
DESCRIPTION = %(Nekonote Framework is a small web application framework that helps your web development.).freeze
|
7
7
|
INSTALL_MESSAGE = <<EOS
|
8
8
|
|
9
|
-
.*・゜゚・*:.。..。.:・
|
9
|
+
.*・゜゚・*:.。..。.:・ Thank you for installing Nekonote Framework .*・゜゚・*:.。..。.:*・
|
10
10
|
|
11
11
|
^___^
|
12
|
-
(=^x^=) < meow
|
13
|
-
~ / )
|
14
|
-
|
15
|
-
|
16
|
-
Note:
|
17
|
-
Installing dependent libraries is not completed yet.
|
18
|
-
After generating an application structure by 'nekonote new app some_app_name', you are supposed to get a Gemfile to install the dependencies.
|
19
|
-
Please install the dependent libraries from the Gemfile by Bundler.
|
12
|
+
(=^x^=) < meow meow | |
|
13
|
+
~ / ) | |
|
14
|
+
w \( h h w w w w w =(**=)~~ | | w w .
|
20
15
|
|
21
16
|
EOS
|
22
|
-
end
|
17
|
+
end
|
data/lib/nekonote/view.rb
CHANGED
@@ -13,8 +13,7 @@ module Nekonote
|
|
13
13
|
attr_reader :is_error_route,
|
14
14
|
:info_path,
|
15
15
|
:info_exec_method,
|
16
|
-
:
|
17
|
-
:info_params,
|
16
|
+
:info_allow_method,
|
18
17
|
:info_content_type,
|
19
18
|
:info_template,
|
20
19
|
:info_layout,
|
@@ -259,8 +258,7 @@ module Nekonote
|
|
259
258
|
def register_info_properies(info)
|
260
259
|
@info_path = info[Preference::FIELD_ROUTE_PATH]
|
261
260
|
@info_exec_method = info[Preference::FIELD_ROUTE_EXEC_METHOD]
|
262
|
-
@
|
263
|
-
@info_params = info[Preference::FIELD_ROUTE_PARAMS]
|
261
|
+
@info_allow_method = info[Preference::FIELD_ROUTE_ALLOW_METHOD]
|
264
262
|
@info_content_type = info[Preference::FIELD_ROUTE_CONTENT_TYPE]
|
265
263
|
@info_template = info[Preference::FIELD_ROUTE_TEMPLATE]
|
266
264
|
@info_layout = info[Preference::FIELD_ROUTE_LAYOUT]
|
data/lib/nekonote/yaml_access.rb
CHANGED
@@ -35,7 +35,7 @@ module Nekonote
|
|
35
35
|
route_list = []
|
36
36
|
ast.root.children.each_with_index do |node, index|
|
37
37
|
cnt = index / 2
|
38
|
-
if node.is_a?(Psych::Nodes::Scalar)
|
38
|
+
if node.is_a?(Psych::Nodes::Scalar)
|
39
39
|
route_list[cnt] = {Preference::FIELD_ROUTE_HANDLER => node.value}
|
40
40
|
elsif node.is_a? Psych::Nodes::Mapping
|
41
41
|
if route_list[cnt].is_a? Hash
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nekonote-framework
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.
|
4
|
+
version: 1.0.0.pre.beta8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- khotta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: color_echo
|
@@ -111,17 +111,12 @@ licenses:
|
|
111
111
|
metadata: {}
|
112
112
|
post_install_message: |2+
|
113
113
|
|
114
|
-
.*・゜゚・*:.。..。.:・
|
114
|
+
.*・゜゚・*:.。..。.:・ Thank you for installing Nekonote Framework .*・゜゚・*:.。..。.:*・
|
115
115
|
|
116
116
|
^___^
|
117
|
-
(=^x^=) < meow
|
118
|
-
~ / )
|
119
|
-
|
120
|
-
|
121
|
-
Note:
|
122
|
-
Installing dependent libraries is not completed yet.
|
123
|
-
After generating an application structure by 'nekonote new app some_app_name', you are supposed to get a Gemfile to install the dependencies.
|
124
|
-
Please install the dependent libraries from the Gemfile by Bundler.
|
117
|
+
(=^x^=) < meow meow | |
|
118
|
+
~ / ) | |
|
119
|
+
w ( h h w w w w w =(**=)~~ | | w w .
|
125
120
|
|
126
121
|
rdoc_options: []
|
127
122
|
require_paths:
|