lux-fw 0.5.36 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.version +1 -1
- data/bin/README.md +26 -13
- data/bin/cli/benchmark.rb +18 -0
- data/bin/cli/cerb.rb +90 -0
- data/bin/cli/config.rb +4 -11
- data/bin/cli/console.rb +72 -30
- data/bin/cli/eval.rb +5 -27
- data/bin/cli/generate.rb +9 -11
- data/bin/cli/get.rb +14 -6
- data/bin/cli/memory.rb +12 -0
- data/bin/cli/new.rb +2 -0
- data/bin/cli/secrets.rb +3 -31
- data/bin/cli/server.rb +28 -9
- data/bin/cli/stats.rb +26 -20
- data/bin/cli/template.rb +10 -0
- data/bin/generate_doc +168 -0
- data/bin/lux +73 -10
- data/lib/README.md +18 -8
- data/lib/common/crypt.rb +60 -9
- data/lib/common/string_base.rb +54 -15
- data/lib/common/struct_opts.rb +30 -0
- data/lib/common/time_difference.rb +75 -0
- data/lib/loader.rb +41 -0
- data/lib/lux/application/README.md +67 -105
- data/lib/lux/application/application.rb +87 -329
- data/lib/lux/application/lib/magic_routes.rb +22 -0
- data/lib/lux/application/lib/nav.rb +218 -99
- data/lib/lux/application/lib/render.rb +47 -67
- data/lib/lux/application/lib/routes.rb +242 -0
- data/lib/lux/application/lib/shared.rb +47 -0
- data/lib/lux/application/lux_adapter.rb +6 -0
- data/lib/lux/application/lux_config.rb +26 -0
- data/lib/lux/cache/Find Results +24 -0
- data/lib/lux/cache/README.md +28 -35
- data/lib/lux/cache/cache.rb +78 -26
- data/lib/lux/cache/lib/memcached_server.rb +36 -0
- data/lib/lux/cache/lib/memory_server.rb +44 -0
- data/lib/lux/cache/lib/null_server.rb +33 -0
- data/lib/lux/cache/lib/sqlite_server.rb +62 -0
- data/lib/lux/cache/lux_adapter.rb +19 -0
- data/lib/lux/config/config.rb +93 -144
- data/lib/lux/config/lux_adapter.rb +27 -0
- data/lib/lux/controller/README.md +67 -12
- data/lib/lux/controller/controller.rb +237 -187
- data/lib/lux/current/README.md +29 -10
- data/lib/lux/current/current.rb +166 -77
- data/lib/lux/current/lib/current.rb +6 -0
- data/lib/lux/current/lib/encrypt_params.rb +38 -36
- data/lib/lux/current/lib/session.rb +86 -65
- data/lib/lux/current/lux_adapter.rb +5 -0
- data/lib/lux/environment/README.md +24 -0
- data/lib/lux/environment/environment.rb +91 -0
- data/lib/lux/environment/lux_adapter.rb +13 -0
- data/lib/lux/error/README.md +18 -19
- data/lib/lux/error/error.rb +207 -152
- data/lib/lux/error/lux_adapter.rb +9 -0
- data/lib/lux/logger/README.md +45 -0
- data/lib/lux/logger/lux_adapter.rb +27 -0
- data/lib/lux/lux.rb +72 -129
- data/lib/lux/mailer/README.md +12 -5
- data/lib/lux/mailer/lux_config.rb +4 -0
- data/lib/lux/mailer/mailer.rb +81 -59
- data/lib/lux/plugin/README.md +19 -0
- data/lib/lux/plugin/lux_adapter.rb +8 -0
- data/lib/lux/plugin/plugin.rb +65 -0
- data/lib/lux/render/README.md +100 -0
- data/lib/lux/render/render.rb +12 -0
- data/lib/lux/response/README.md +57 -1
- data/lib/lux/response/lib/file.rb +87 -65
- data/lib/lux/response/lib/flash.rb +49 -34
- data/lib/lux/response/lib/header.rb +34 -33
- data/lib/lux/response/response.rb +252 -164
- data/lib/lux/template/helper.rb +130 -0
- data/lib/lux/template/inline_render_proxy.rb +31 -0
- data/lib/lux/template/lux_adapter.rb +5 -0
- data/lib/lux/template/template.rb +127 -0
- data/lib/lux-fw.rb +15 -33
- data/lib/overload/array.rb +33 -7
- data/lib/overload/blank.rb +8 -3
- data/lib/overload/boolean.rb +46 -0
- data/lib/overload/class.rb +28 -0
- data/lib/overload/dir.rb +117 -7
- data/lib/overload/file.rb +40 -5
- data/lib/overload/float.rb +38 -3
- data/lib/overload/hash.rb +81 -91
- data/lib/overload/integer.rb +15 -0
- data/lib/overload/json.rb +26 -0
- data/lib/overload/nil.rb +4 -8
- data/lib/overload/object.rb +91 -24
- data/lib/overload/pathname.rb +11 -0
- data/lib/overload/raise_variants.rb +26 -36
- data/lib/overload/string.rb +100 -27
- data/lib/overload/thread_simple.rb +100 -0
- data/lib/overload/time.rb +60 -38
- data/tasks/loader.rb +20 -7
- metadata +170 -169
- data/bin/.DS_Store +0 -0
- data/bin/build_gem +0 -77
- data/bin/cli/dbconsole.rb +0 -8
- data/bin/cli/routes.rb +0 -90
- data/lib/.DS_Store +0 -0
- data/lib/common/.DS_Store +0 -0
- data/lib/common/class_attributes.rb +0 -51
- data/lib/common/class_callbacks.rb +0 -47
- data/lib/common/free_struct.rb +0 -42
- data/lib/common/hash_with_indifferent_access.rb +0 -74
- data/lib/common/html_tag_builder.rb +0 -91
- data/lib/common/method_attr.rb +0 -69
- data/lib/common/url.rb +0 -191
- data/lib/lux/.DS_Store +0 -0
- data/lib/lux/README.md +0 -10
- data/lib/lux/cache/.DS_Store +0 -0
- data/lib/lux/cache/lib/memory.rb +0 -36
- data/lib/lux/cache/lib/null.rb +0 -21
- data/lib/lux/config/README.md +0 -63
- data/lib/lux/config/lib/plugin.rb +0 -65
- data/lib/lux/config/lib/secrets.rb +0 -48
- data/lib/lux/current/.DS_Store +0 -0
- data/lib/lux/delayed_job/.DS_Store +0 -0
- data/lib/lux/delayed_job/README.md +0 -3
- data/lib/lux/delayed_job/delayed_job.rb +0 -51
- data/lib/lux/delayed_job/lib/memory.rb +0 -16
- data/lib/lux/delayed_job/lib/nsq.rb +0 -3
- data/lib/lux/delayed_job/lib/postgre.rb +0 -6
- data/lib/lux/delayed_job/lib/redis.rb +0 -19
- data/lib/lux/event_bus/README.md +0 -36
- data/lib/lux/event_bus/event_bus.rb +0 -27
- data/lib/lux/view/README.md +0 -85
- data/lib/lux/view/cell.rb +0 -102
- data/lib/lux/view/helper.rb +0 -120
- data/lib/lux/view/lib/cell_helpers.rb +0 -29
- data/lib/lux/view/view.rb +0 -95
- data/lib/overload/it.rb +0 -29
- data/plugins/api/README.md +0 -49
- data/plugins/api/api.rb +0 -153
- data/plugins/api/lib/attr.rb +0 -31
- data/plugins/api/lib/dsl.rb +0 -52
- data/plugins/api/lib/error.rb +0 -3
- data/plugins/api/lib/model_api.rb +0 -203
- data/plugins/api/lib/response.rb +0 -85
- data/plugins/db/.DS_Store +0 -0
- data/plugins/db/README.md +0 -29
- data/plugins/db/auto_migrate/auto_migrate.rb +0 -268
- data/plugins/db/auto_migrate/db.rake +0 -15
- data/plugins/db/helpers/array_search.rb +0 -27
- data/plugins/db/helpers/before_save_filters.rb +0 -32
- data/plugins/db/helpers/composite_primary_keys.rb +0 -36
- data/plugins/db/helpers/core.rb +0 -94
- data/plugins/db/helpers/dataset_methods.rb +0 -138
- data/plugins/db/helpers/enums_plugin.rb +0 -52
- data/plugins/db/helpers/find_precache.rb +0 -31
- data/plugins/db/helpers/link_objects.rb +0 -84
- data/plugins/db/helpers/schema_checks.rb +0 -83
- data/plugins/db/helpers/typero_adapter.rb +0 -71
- data/plugins/db/logger/config.rb +0 -22
- data/plugins/db/logger/lux_response_adapter.rb +0 -10
- data/plugins/db/paginate/helper.rb +0 -32
- data/plugins/db/paginate/sequel_adapter.rb +0 -23
- data/plugins/exceptions/exceptions.rake +0 -43
- data/plugins/exceptions/simple_exception.rb +0 -64
- data/plugins/favicon/favicon.rb +0 -10
- data/plugins/html/README.md +0 -3
- data/plugins/html/html_form.rb +0 -118
- data/plugins/html/html_input.rb +0 -98
- data/plugins/html/html_menu.rb +0 -79
- data/plugins/html/input_types.rb +0 -346
- data/plugins/js_widgets/README.md +0 -5
- data/plugins/js_widgets/js/html_tag.coffee +0 -42
- data/plugins/js_widgets/js/widgets.coffee +0 -161
- data/plugins/js_widgets/js_widgets.rb +0 -15
- data/plugins/oauth/lib/facebook.rb +0 -35
- data/plugins/oauth/lib/github.rb +0 -38
- data/plugins/oauth/lib/google.rb +0 -41
- data/plugins/oauth/lib/linkedin.rb +0 -41
- data/plugins/oauth/lib/stackexchange.rb +0 -41
- data/plugins/oauth/lib/twitter.rb +0 -38
- data/plugins/oauth/oauth.rb +0 -42
- data/plugins/policy/policy.rb +0 -53
- data/tasks/nginx.rake +0 -23
- /data/lib/lux/{view/lib → mailer}/helper_modules.rb +0 -0
@@ -1,104 +1,223 @@
|
|
1
1
|
# experiment for different nav in rooter
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
3
|
+
module Lux
|
4
|
+
class Application
|
5
|
+
class Nav
|
6
|
+
attr_accessor :format
|
7
|
+
attr_reader :original, :domain, :subdomain, :querystring, :ids
|
8
|
+
|
9
|
+
# acepts path as a string
|
10
|
+
def initialize request
|
11
|
+
@path = request.path.split('/').slice(1, 100) || []
|
12
|
+
@original = @path.dup
|
13
|
+
@request = request
|
14
|
+
@querystring = {}.to_hwia
|
15
|
+
@ids = []
|
16
|
+
@shifted = []
|
17
|
+
|
18
|
+
set_variables
|
19
|
+
set_domain request
|
20
|
+
set_format
|
21
|
+
end
|
22
|
+
|
23
|
+
def root
|
24
|
+
@path.first
|
25
|
+
end
|
26
|
+
|
27
|
+
def root= value
|
28
|
+
@path[0] = value
|
29
|
+
end
|
30
|
+
|
31
|
+
def shift
|
32
|
+
@path.shift.tap do |value|
|
33
|
+
@shifted.push value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# used to make admin.lvm.me/users to lvh.me/admin/users
|
38
|
+
def unshift name = nil
|
39
|
+
if name
|
40
|
+
@path.unshift name
|
41
|
+
@path = @path.flatten
|
42
|
+
name
|
43
|
+
else
|
44
|
+
@path.unshift @shifted.pop
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# pop element of the path
|
49
|
+
def pop replace_with = nil
|
50
|
+
if block_given?
|
51
|
+
if result = yield(@path.last)
|
52
|
+
@path.pop
|
53
|
+
@path.unshift replace_with if replace_with
|
54
|
+
result
|
55
|
+
end
|
56
|
+
else
|
57
|
+
@path.shift
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def last
|
62
|
+
# if block_given?
|
63
|
+
# # replace root in place if yields not nil
|
64
|
+
# return unless @path.last.present?
|
65
|
+
# result = yield(@path.last) || return
|
66
|
+
# @path.pop
|
67
|
+
# result
|
68
|
+
# else
|
69
|
+
@path.last
|
70
|
+
# end
|
71
|
+
end
|
72
|
+
|
73
|
+
# get Url object initialized with request.url - relative
|
74
|
+
# current.nav.url(:foo, 1).to_s # /path?foo=1
|
75
|
+
def url *args
|
76
|
+
if args.first
|
77
|
+
Url.current.qs(*args)
|
78
|
+
else
|
79
|
+
Url.current
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def path *args
|
84
|
+
if args.first
|
85
|
+
# contruct path
|
86
|
+
# /upload_dialog/is_image:true/model:posts/id:2/field:image_url
|
87
|
+
# = nav.path :model, :id, :field -> /upload_dialog/model:posts/id:2/field:image_url
|
88
|
+
parts = @original.select {|el| !el.include?(':') }
|
89
|
+
parts += args.map do |el|
|
90
|
+
if value = Lux.current.params[el]
|
91
|
+
[el, value].join(':')
|
92
|
+
end
|
93
|
+
end.compact
|
94
|
+
'/' + parts.join('/')
|
95
|
+
elsif block_given?
|
96
|
+
@path = @path.map { _1.gsub('-', '_') }
|
97
|
+
else
|
98
|
+
@path
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def path= list
|
103
|
+
@path = list
|
104
|
+
end
|
105
|
+
|
106
|
+
# removes leading www.
|
107
|
+
# https://www.foo.bar/path -> https://foo.bar/path
|
108
|
+
def remove_www
|
109
|
+
url = Lux.current.request.url
|
110
|
+
|
111
|
+
if url.include?('://www.')
|
112
|
+
Lux.current.response.redirect_to url.sub('://www.', '://')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# nav.rename_domain 'localhost', 'lvh.me'
|
117
|
+
# http://localhost:3000/foo?bar=123 -> http://lvh.me:3000/foo?bar=123
|
118
|
+
def rename_domain from_domain, to_domain
|
119
|
+
if from_domain == @domain
|
120
|
+
url = Url.new Lux.current.request.url
|
121
|
+
Lux.current.response.redirect_to url.domain(to_domain).to_s
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# http://tiger.lvh.me:3000/foo?bar=1 -> http://tiger.lvh.me:3000
|
126
|
+
def base
|
127
|
+
@base ||= Lux.current.request.url.split('/').first(3).join('/')
|
128
|
+
end
|
129
|
+
|
130
|
+
def to_s
|
131
|
+
@path.join('/').sub(/\/$/, '')
|
132
|
+
end
|
133
|
+
|
134
|
+
# accept only two strings locale
|
135
|
+
# nav.locale { _1.length == 2 ? _1 : nil }
|
136
|
+
def locale
|
137
|
+
if @locale
|
138
|
+
return @locale.to_s == '' ? nil : @locale
|
139
|
+
end
|
140
|
+
|
141
|
+
if @path[0].to_s.downcase =~ /^[a-z]{2}(-[a-z]{2})?$/
|
142
|
+
if @locale = yield(@path[0])
|
143
|
+
@path.shift
|
144
|
+
else
|
145
|
+
@locale = ''
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
@locale
|
150
|
+
end
|
151
|
+
|
152
|
+
def locale= name
|
153
|
+
@locale = name.present? ? name.to_s : nil
|
154
|
+
end
|
155
|
+
|
156
|
+
def id
|
157
|
+
@ids.last
|
158
|
+
end
|
159
|
+
|
160
|
+
# replace nav path with id, when mached (works with resourceful routes map 'controler')
|
161
|
+
# nav.path_id { _1.split('-').last.string_id rescue nil }
|
162
|
+
# /foo/test-cbjy/bar -> ['foo', :id, 'bar]
|
163
|
+
def path_id
|
164
|
+
@path = @path.map do |el|
|
165
|
+
if result = yield(el)
|
166
|
+
@ids.push result
|
167
|
+
:id
|
168
|
+
else
|
169
|
+
el
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
@ids.last
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
def set_variables
|
179
|
+
# convert /foo/bar:baz to /foo?bar=baz
|
180
|
+
while @path.last&.include?(':')
|
181
|
+
key, val = @path.pop.split(':', 2)
|
182
|
+
@querystring[key] = val
|
183
|
+
Lux.current.params[key.to_sym] ||= val
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def set_domain request
|
188
|
+
begin
|
189
|
+
# NoMethodError
|
190
|
+
# Message undefined method `start_with?' for nil:NilClass
|
191
|
+
# gems/rack-2.2.4/lib/rack/request.rb:567:in `wrap_ipv6'
|
192
|
+
parts = request.host.to_s.split('.')
|
193
|
+
rescue NoMethodError
|
194
|
+
raise Lux::Error.bad_request('Host name error')
|
195
|
+
end
|
196
|
+
|
197
|
+
if parts.last.is_numeric?
|
198
|
+
@domain = request.host
|
199
|
+
else
|
200
|
+
count = 2
|
201
|
+
count = 1 if parts.last == 'localhost'
|
202
|
+
count = 3 if parts.last(2).join('.') == 5 # foo.co.uk
|
203
|
+
|
204
|
+
@domain = parts.pop(count).join('.')
|
205
|
+
@domain += ".#{parts.pop}" if @domain.length < 6
|
206
|
+
@subdomain = parts.join('.')
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def set_format
|
211
|
+
return unless @path.last
|
212
|
+
parts = @path.last.split('.')
|
213
|
+
|
214
|
+
if parts[1]
|
215
|
+
@format = parts.pop.to_s.downcase.to_sym
|
216
|
+
@path.last = parts.join('.')
|
217
|
+
end
|
218
|
+
|
219
|
+
@path.shift if @path[0] == ''
|
220
|
+
end
|
61
221
|
end
|
62
222
|
end
|
63
|
-
|
64
|
-
def root= value
|
65
|
-
@path[0] = value
|
66
|
-
end
|
67
|
-
|
68
|
-
def first
|
69
|
-
if block_given?
|
70
|
-
# shift first in place if yields not nil
|
71
|
-
return unless @path[1].present?
|
72
|
-
result = yield(@path[1]) || return
|
73
|
-
@path.slice!(1,1)
|
74
|
-
result
|
75
|
-
else
|
76
|
-
@path[1]
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def last
|
81
|
-
if block_given?
|
82
|
-
# replace root in place if yields not nil
|
83
|
-
return unless @path.last.present?
|
84
|
-
result = yield(@path.last) || return
|
85
|
-
@path.pop
|
86
|
-
result
|
87
|
-
else
|
88
|
-
@path.last
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def second
|
93
|
-
@path[2]
|
94
|
-
end
|
95
|
-
|
96
|
-
def active
|
97
|
-
@active
|
98
|
-
end
|
99
|
-
|
100
|
-
def to_s
|
101
|
-
@path.join('/').sub(/\/$/, '')
|
102
|
-
end
|
103
|
-
|
104
223
|
end
|
@@ -1,69 +1,49 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
env[k.to_s.upcase] = v
|
1
|
+
# renders pages without server
|
2
|
+
|
3
|
+
module Lux
|
4
|
+
class Application
|
5
|
+
module Render
|
6
|
+
extend self
|
7
|
+
|
8
|
+
# Alternative was to call render action
|
9
|
+
# `Lux.app.new(path, full_opts).render.headers`
|
10
|
+
# `Lux.render.post(path, params, rest_of_opts).headers`
|
11
|
+
# `Lux.render.get('/search', params: { q: 'london' }, session: {user_id: 1} }).body`
|
12
|
+
%i(get post delete patch put).each do |req_method|
|
13
|
+
define_method req_method do |path, opts={}|
|
14
|
+
Lux.app.new(path, opts.merge(method: req_method)).render
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Render controller action without routes, pass a block to yield before action call.
|
19
|
+
# `Lux.render.controller('main/cities#foo').body`
|
20
|
+
# `Lux.render.controller('main/cities#foo') { @city = City.last_updated }.body`
|
21
|
+
def controller klass, &block
|
22
|
+
klass, action = klass.split('#')
|
23
|
+
|
24
|
+
klass = (klass+'Controller').classify.constantize if klass.is_a?(String)
|
25
|
+
c = klass.new
|
26
|
+
c.instance_exec &block if block
|
27
|
+
c.send action
|
28
|
+
|
29
|
+
Lux.current.response
|
30
|
+
end
|
31
|
+
|
32
|
+
# Lux.render.controller('main/cities#bar') { @city = City.last_updated }.body
|
33
|
+
def template *args
|
34
|
+
Lux::Template.render *args
|
35
|
+
end
|
36
|
+
|
37
|
+
# Lux.render.cell(:user, self, { product: @bar }).foo
|
38
|
+
# Lux.render.cell(:user, self).foo
|
39
|
+
# Lux.render.cell(:user, { product: @bar }).foo
|
40
|
+
# Lux.render.cell(:user).foo @arg
|
41
|
+
def cell name, *args
|
42
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
43
|
+
context = args.shift
|
44
|
+
Lux::ViewCell.get(name, context, opts)
|
45
|
+
end
|
47
46
|
end
|
48
|
-
|
49
|
-
current = Lux::Current.new(env)
|
50
|
-
current.session.merge!(in_opts[:session]) if in_opts[:session]
|
51
|
-
|
52
|
-
app = new current
|
53
|
-
|
54
|
-
return app.instance_exec &block if block_given?
|
55
|
-
|
56
|
-
response = app.render
|
57
|
-
|
58
|
-
body = response[2].join('')
|
59
|
-
body = JSON.parse body if response[1]['content-type'].index('/json')
|
60
|
-
|
61
|
-
{
|
62
|
-
time: response[1]['x-lux-speed'],
|
63
|
-
status: response[0],
|
64
|
-
headers: response[1],
|
65
|
-
session: current.session.hash,
|
66
|
-
body: body
|
67
|
-
}.h
|
68
47
|
end
|
69
|
-
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,242 @@
|
|
1
|
+
module Lux
|
2
|
+
class Application
|
3
|
+
module Routes
|
4
|
+
# generate get, get?, post, post? ...
|
5
|
+
# get {}
|
6
|
+
# get foo: 'main/bar', only: [:show], except: [:index]
|
7
|
+
%w{get head post delete put patch}.each do |m|
|
8
|
+
define_method('%s?' % m) do |*args, &block|
|
9
|
+
cm = current.request.request_method
|
10
|
+
cm = 'GET' if cm == 'HEAD'
|
11
|
+
return unless cm == m.upcase
|
12
|
+
|
13
|
+
if block
|
14
|
+
# get? { ... }
|
15
|
+
block.call
|
16
|
+
elsif args.first
|
17
|
+
# post api: 'api#call'
|
18
|
+
map *args
|
19
|
+
else
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Matches if there is not root in nav
|
26
|
+
# Example calls MainController.action(:index) if in root
|
27
|
+
# ```
|
28
|
+
# root 'main#index'
|
29
|
+
# ```
|
30
|
+
def root target
|
31
|
+
call target unless nav.root
|
32
|
+
end
|
33
|
+
|
34
|
+
# standard route match
|
35
|
+
# match '/:city/people', Main::PeopleController
|
36
|
+
def match base, target
|
37
|
+
base = base.split('/').slice(1, 100)
|
38
|
+
|
39
|
+
base.each_with_index do |el, i|
|
40
|
+
if el[0,1] == ':'
|
41
|
+
params[el.sub(':','').to_sym] = nav.path[i]
|
42
|
+
else
|
43
|
+
return unless el == nav.path[i]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
call target
|
48
|
+
end
|
49
|
+
|
50
|
+
# Matches given subdomain name
|
51
|
+
def subdomain name
|
52
|
+
return unless nav.subdomain == name.to_s
|
53
|
+
yield
|
54
|
+
Lux.error.not_found 'Subdomain "%s" matched but nothing called' % name
|
55
|
+
end
|
56
|
+
|
57
|
+
# Main routing object, maps path part to target
|
58
|
+
# if path part is positively matched with `test?` method, target is called with `call` method
|
59
|
+
# ```
|
60
|
+
# map api: ApiController
|
61
|
+
# map api: 'api'
|
62
|
+
# map [:api, ApiController]
|
63
|
+
# map 'main/root' do
|
64
|
+
# map [:login, :signup] => 'main/root'
|
65
|
+
# map :city do
|
66
|
+
# map 'city' do
|
67
|
+
# map :about
|
68
|
+
# end
|
69
|
+
# ```
|
70
|
+
def map route_object = nil, target = nil &block
|
71
|
+
return @magic unless route_object
|
72
|
+
return if response.body?
|
73
|
+
|
74
|
+
route_object = [route_object, target] if target
|
75
|
+
|
76
|
+
if block_given?
|
77
|
+
# map 'admin' do ...
|
78
|
+
if test?(route_object)
|
79
|
+
yield nav.root
|
80
|
+
nav.unshift
|
81
|
+
end
|
82
|
+
|
83
|
+
return
|
84
|
+
end
|
85
|
+
|
86
|
+
klass = nil
|
87
|
+
route = nil
|
88
|
+
action = nil
|
89
|
+
opts = {}
|
90
|
+
|
91
|
+
case route_object
|
92
|
+
when String
|
93
|
+
# map 'root#call'
|
94
|
+
nav.shift
|
95
|
+
catch(:done) { call route_object }
|
96
|
+
when Hash
|
97
|
+
route = route_object.keys.first
|
98
|
+
klass = route_object.values.first
|
99
|
+
|
100
|
+
if route_object.keys.length > 1
|
101
|
+
opts = route_object.dup
|
102
|
+
opts.delete route
|
103
|
+
end
|
104
|
+
|
105
|
+
if route.class == Array
|
106
|
+
# map [:foo, :bar] => 'root'
|
107
|
+
for route_action in route
|
108
|
+
if test?(route_action)
|
109
|
+
call klass, route_action
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
return
|
114
|
+
elsif route.is_a?(String) && route[0,1] == '/'
|
115
|
+
# map '/skils/:skill' => 'main/skills#show'
|
116
|
+
return match route, klass
|
117
|
+
end
|
118
|
+
when Array
|
119
|
+
# map [:foo, 'main/root']
|
120
|
+
route, klass, opts = *route_object
|
121
|
+
else
|
122
|
+
Lux.error 'Unsupported route type "%s"' % route_object.class
|
123
|
+
end
|
124
|
+
|
125
|
+
test?(route) ? call(klass, nil, opts) : nil
|
126
|
+
end
|
127
|
+
|
128
|
+
# Calls target action in a controller, if no action is given, defaults to :call
|
129
|
+
# ```
|
130
|
+
# call :api_router
|
131
|
+
# call { 'string' }
|
132
|
+
# call proc { [400, {}, 'error: ...'] }
|
133
|
+
# call [200, {}, ['ok']]
|
134
|
+
# call Main::UsersController
|
135
|
+
# call Main::UsersController, :index
|
136
|
+
# call [Main::UsersController, :index]
|
137
|
+
# call 'main/orgs' -> index, show
|
138
|
+
# call 'main/orgs#show' -> show
|
139
|
+
# call 'main/orgs?list' -> list_index, list_show # provies namespace in controller
|
140
|
+
# ```
|
141
|
+
def call object=nil, action=nil, opts=nil, &block
|
142
|
+
# log original app caller
|
143
|
+
root = Lux.root.join('app/').to_s
|
144
|
+
sources = caller.select { |it| it.include?(root) }.map { |it| 'app/' + it.sub(root, '').split(':in').first }
|
145
|
+
action = action.gsub('-', '_').to_sym if action && action.is_a?(String)
|
146
|
+
namespace = nil
|
147
|
+
object ||= block if block_given?
|
148
|
+
|
149
|
+
Lux.log { ' Routed from: %s' % sources.join(' ') } if sources.first
|
150
|
+
|
151
|
+
case object
|
152
|
+
when Symbol
|
153
|
+
return send(object)
|
154
|
+
when Hash
|
155
|
+
object = [object.keys.first, object.values.first]
|
156
|
+
when String
|
157
|
+
if object.include?('#')
|
158
|
+
object, action = object.split('#')
|
159
|
+
else
|
160
|
+
action = if nav.root == :id
|
161
|
+
nav.path[1] || :show
|
162
|
+
else
|
163
|
+
nav.path[0] || :index
|
164
|
+
end
|
165
|
+
end
|
166
|
+
when Array
|
167
|
+
if object[0].class == Integer && object[1].class == Hash
|
168
|
+
# [200, {}, 'ok']
|
169
|
+
for key, value in object[1]
|
170
|
+
response.header key, value
|
171
|
+
end
|
172
|
+
|
173
|
+
response.status object[0]
|
174
|
+
response.body object[2].is_a?(Array) ? object[2].first : object[2]
|
175
|
+
else
|
176
|
+
object, action = object
|
177
|
+
end
|
178
|
+
when Proc
|
179
|
+
case data = object.call
|
180
|
+
when Array
|
181
|
+
response.status = data.first
|
182
|
+
response.body data[2].is_a?(Array) ? data[2][0] : data[2]
|
183
|
+
else
|
184
|
+
response.body data
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
if object.is_a?(String)
|
189
|
+
object = ('%s_controller' % object).classify.constantize
|
190
|
+
end
|
191
|
+
|
192
|
+
if [Module, Class].include?(object.class) && object.respond_to?(:call)
|
193
|
+
response.rack object
|
194
|
+
end
|
195
|
+
|
196
|
+
if object.respond_to?(:source_location)
|
197
|
+
current.files_in_use object.source_location
|
198
|
+
end
|
199
|
+
|
200
|
+
opts ||= {}
|
201
|
+
action ||= nav.path.last || :index
|
202
|
+
|
203
|
+
if opts[:only] && !opts[:only].include?(action.to_sym)
|
204
|
+
Lux.error.not_found Lux.env.show_errors? ? "Action :#{action} not allowed on #{object}, allowed are: #{opts[:only]}" : nil
|
205
|
+
end
|
206
|
+
|
207
|
+
if opts[:except] && opts[:except].include?(action.to_sym)
|
208
|
+
Lux.error.not_found Lux.env.show_errors? ? "Action :#{action} not allowed on #{object}, forbidden are: #{opts[:except]}" : nil
|
209
|
+
end
|
210
|
+
|
211
|
+
if object.respond_to?(:action)
|
212
|
+
object.action action.to_sym
|
213
|
+
end
|
214
|
+
|
215
|
+
throw :done if response.body?
|
216
|
+
end
|
217
|
+
|
218
|
+
# Tests current root against the string to get a mach.
|
219
|
+
# Used by map function
|
220
|
+
def test? route
|
221
|
+
root = nav.root.to_s
|
222
|
+
|
223
|
+
ok = case route
|
224
|
+
when String
|
225
|
+
root == route.sub(/^\//,'')
|
226
|
+
when Symbol
|
227
|
+
route.to_s == root
|
228
|
+
when Regexp
|
229
|
+
!!(route =~ root)
|
230
|
+
when Array
|
231
|
+
!!route.map(&:to_s).include?(root)
|
232
|
+
else
|
233
|
+
false
|
234
|
+
end
|
235
|
+
|
236
|
+
nav.shift if ok
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
|