lux-fw 0.1.17 → 0.1.35
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/cli/am +38 -29
- data/bin/cli/assets +8 -4
- data/bin/cli/exceptions +6 -6
- data/bin/cli/generate +0 -0
- data/bin/cli/get +0 -0
- data/bin/cli/nginx +11 -5
- data/bin/cli/routes +0 -0
- data/bin/cli/systemd +36 -0
- data/bin/forever +0 -0
- data/bin/job_que +0 -0
- data/bin/lux +1 -0
- data/lib/common/base32.rb +0 -0
- data/lib/common/class_attributes.rb +13 -4
- data/lib/common/crypt.rb +6 -10
- data/lib/common/dynamic_class.rb +23 -0
- data/lib/common/generic_model.rb +0 -0
- data/lib/common/hash_with_indifferent_access.rb +352 -0
- data/lib/common/method_attr.rb +69 -0
- data/lib/lux/api/api.rb +26 -27
- data/lib/lux/api/lib/application_api.rb +26 -7
- data/lib/lux/api/lib/doc_builder.rb +18 -17
- data/lib/lux/api/lib/dsl.rb +23 -41
- data/lib/lux/api/lib/error.rb +3 -0
- data/lib/lux/api/lib/model_api.rb +22 -20
- data/lib/lux/api/lib/rescue.rb +5 -15
- data/lib/lux/api/lib/response.rb +46 -0
- data/lib/lux/cache/cache.rb +13 -6
- data/lib/lux/cell/cell.rb +3 -14
- data/lib/lux/config/config.rb +4 -3
- data/lib/lux/controller/controller.rb +3 -3
- data/lib/lux/controller/lib/nav.rb +6 -2
- data/lib/lux/error/error.rb +15 -14
- data/lib/lux/helper/helper.rb +5 -5
- data/lib/lux/helper/lib/html_tag.rb +67 -0
- data/lib/lux/html/lib/input_types.rb +26 -16
- data/lib/lux/lib/lux.rb +51 -0
- data/lib/lux/lux.rb +5 -52
- data/lib/lux/page/lib/response.rb +178 -0
- data/lib/lux/page/page.rb +72 -51
- data/lib/lux/rescue_from/rescue_from.rb +8 -6
- data/lib/lux/template/template.rb +1 -0
- data/lib/lux-fw.rb +2 -0
- data/lib/overload/array.rb +4 -0
- data/lib/overload/date.rb +2 -0
- data/lib/overload/hash.rb +19 -10
- data/lib/overload/it.rb +29 -0
- data/lib/overload/object.rb +3 -19
- data/lib/overload/r.rb +53 -0
- data/lib/overload/string.rb +5 -6
- data/lib/overload/string_inflections.rb +4 -3
- data/lib/plugins/assets/assets_plug.rb +9 -4
- data/lib/plugins/assets/helper_module_adapter.rb +4 -2
- data/lib/plugins/db_helpers/link_plugin.rb +2 -2
- data/lib/plugins/db_logger/init.rb +1 -1
- data/lib/vendor/mini_assets/lib/asset/css.rb +19 -0
- data/lib/vendor/mini_assets/lib/asset/js.rb +17 -0
- data/lib/vendor/mini_assets/lib/asset.rb +71 -0
- data/lib/vendor/mini_assets/lib/base/javascript.rb +13 -0
- data/lib/vendor/mini_assets/lib/base/stylesheet.rb +5 -0
- data/lib/vendor/mini_assets/lib/base.rb +69 -0
- data/lib/vendor/mini_assets/lib/manifest.rb +18 -0
- data/lib/vendor/mini_assets/lib/opts.rb +16 -0
- data/lib/vendor/mini_assets/mini_assets.rb +74 -0
- metadata +23 -10
- data/lib/common/class_method_params.rb +0 -94
- data/lib/overload/hash_wia.rb +0 -282
- data/lib/overload/inflections.rb +0 -199
- data/lib/vendor/mini_assets/mini_asset/base.rb +0 -167
- data/lib/vendor/mini_assets/mini_asset/css.rb +0 -38
- data/lib/vendor/mini_assets/mini_asset/js.rb +0 -38
- data/lib/vendor/mini_assets/mini_asset.rb +0 -31
data/lib/lux/lux.rb
CHANGED
@@ -41,7 +41,7 @@ module Lux
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def page
|
44
|
-
Thread.current[:lux][:page]
|
44
|
+
Thread.current[:lux][:page] ||= Lux::Page.prepare('/mock')
|
45
45
|
end
|
46
46
|
|
47
47
|
def page=(what)
|
@@ -61,6 +61,7 @@ module Lux
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def error data
|
64
|
+
page.status 500
|
64
65
|
Lux::Error.show(data)
|
65
66
|
end
|
66
67
|
|
@@ -101,64 +102,16 @@ module Lux
|
|
101
102
|
end
|
102
103
|
|
103
104
|
def speed loops=1
|
104
|
-
render_start = Time.now
|
105
|
+
render_start = Time.now.to_f
|
105
106
|
loops.times { yield }
|
106
|
-
num = ((Time.now-render_start)*
|
107
|
-
num = num
|
108
|
-
num = "#{num}ms"
|
107
|
+
num = ((Time.now.to_f - render_start)*1_000_000).to_i.to_s
|
108
|
+
num = "#{num} ms"
|
109
109
|
loops == 1 ? num : "Done #{loops.to_s.sub(/(\d)(\d{3})$/,'\1s \2')} loops in #{num}"
|
110
110
|
end
|
111
111
|
|
112
112
|
def consumed_memory
|
113
113
|
`ps -o rss -p #{$$}`.chomp.split("\n").last.to_i / 1000
|
114
114
|
end
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
# handy :)
|
119
|
-
# renders full pages and exposes page object (req, res) in yiled
|
120
|
-
# for easy and powerful testing
|
121
|
-
# Hash :qs, Hash :post, String :method, Hash :cookies, Hash :session
|
122
|
-
# https://github.com/rack/rack/blob/master/test/spec_request.rb
|
123
|
-
def Lux(path, in_opts={}, &block)
|
124
|
-
allowed_opts = [:qs, :post, :method, :session, :cookies]
|
125
|
-
in_opts.keys.each { |k| die "#{k} is not allowed as opts param. allowed are #{allowed_opts}" unless allowed_opts.index(k) }
|
126
|
-
|
127
|
-
opts = {}
|
128
|
-
|
129
|
-
if in_opts[:post]
|
130
|
-
opts[:query_string] = in_opts[:post]
|
131
|
-
opts[:request_method] = :post
|
132
|
-
else
|
133
|
-
opts[:query_string] = in_opts[:qs] || {}
|
134
|
-
opts[:request_method] ||= in_opts[:method] || :get
|
135
|
-
end
|
136
|
-
opts[:request_method] = opts[:request_method].to_s.upcase
|
137
|
-
opts[:query_string] = opts[:query_string].to_query if opts[:query_string].class.to_s == 'Hash'
|
138
|
-
|
139
|
-
if path[0,4] == 'http'
|
140
|
-
parsed = URI.parse(path)
|
141
|
-
opts[:server_name] = parsed.host
|
142
|
-
opts[:server_port] = parsed.port
|
143
|
-
path = '/'+path.split('/', 4).last
|
144
|
-
end
|
145
|
-
|
146
|
-
env = Rack::MockRequest.env_for(path)
|
147
|
-
env[:input] = opts[:post] if opts[:post]
|
148
|
-
for k,v in opts
|
149
|
-
env[k.to_s.upcase] = v
|
150
|
-
end
|
151
|
-
|
152
|
-
page = Lux::Page.prepare(env)
|
153
|
-
page.session = in_opts[:session] if in_opts[:session]
|
154
|
-
|
155
|
-
return page.instance_exec &block if block_given?
|
156
|
-
|
157
|
-
response = page.render
|
158
|
-
body = response[2].join('')
|
159
|
-
body = JSON.parse body if response[1]['content-type'].index('/json')
|
160
|
-
|
161
|
-
{ status: response[0], headers: response[1], body: body }.h
|
162
115
|
end
|
163
116
|
|
164
117
|
require_relative 'config/config'
|
@@ -0,0 +1,178 @@
|
|
1
|
+
# class Lux::Page::Response
|
2
|
+
# attr_accessor :body, :headers, :cookies, :content_type, :status
|
3
|
+
|
4
|
+
# def initialize request
|
5
|
+
# @render_start = Time.now
|
6
|
+
# @headers = {}
|
7
|
+
# @cookies = {}
|
8
|
+
# @request = request
|
9
|
+
|
10
|
+
# for cookie in request.env['HTTP_COOKIE'].to_s.split(/;\s*/).map{ |el| el.split('=',2) }
|
11
|
+
# @cookies[cookie[0]] = cookie[1]
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
|
15
|
+
# def header name, value=:_
|
16
|
+
# name = name.downcase
|
17
|
+
# @headers[name] = value if value != :_
|
18
|
+
# @headers[name]
|
19
|
+
# end
|
20
|
+
|
21
|
+
# def cache_control value=nil
|
22
|
+
# raise ArgumentError.new('Vrong value') unless [:private, :public].include?(value)
|
23
|
+
|
24
|
+
# # if "no-store" is present then HTTP_IF_NONE_MATCH is not sent from browser
|
25
|
+
# @headers['cache-control'] = 'must-revalidate, %s, max-age=0' % value
|
26
|
+
# end
|
27
|
+
|
28
|
+
# def etag *args
|
29
|
+
# @headers['etag'] ||= 'W/"%s"' % Lux.cache.generate_key(args)
|
30
|
+
|
31
|
+
# if @request.env['HTTP_IF_NONE_MATCH'] == @headers['etag']
|
32
|
+
# @status = 304
|
33
|
+
# @body = 'not-modified'
|
34
|
+
# true
|
35
|
+
# else
|
36
|
+
# false
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
|
40
|
+
# def status num=nil
|
41
|
+
# Lux.log caller if num == 500
|
42
|
+
# return @status if @status
|
43
|
+
# if num
|
44
|
+
# if num.is_numeric?
|
45
|
+
# @status ||= num.to_i
|
46
|
+
# else
|
47
|
+
# @status = case num.to_s
|
48
|
+
# when 'StandardError'; 400
|
49
|
+
# when 'BadRequestError'; 400
|
50
|
+
# when 'UnauthorizedError'; 401
|
51
|
+
# when 'ForbidenError'; 403
|
52
|
+
# when 'NotFoundError'; 404
|
53
|
+
# when 'RateLimitError'; 503
|
54
|
+
# else; 500
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
|
59
|
+
# @status
|
60
|
+
# end
|
61
|
+
|
62
|
+
# def body what=nil
|
63
|
+
# @body ||= what
|
64
|
+
|
65
|
+
# if @body && block_given?
|
66
|
+
# @body = yield @body
|
67
|
+
# Lux.error 'Lux.page.body is not a string (bad page.body filter)' unless @body.is_a?(String)
|
68
|
+
# end
|
69
|
+
|
70
|
+
# @body
|
71
|
+
# end
|
72
|
+
|
73
|
+
# def body= what
|
74
|
+
# body(what)
|
75
|
+
# end
|
76
|
+
|
77
|
+
# def body! what
|
78
|
+
# @body = what
|
79
|
+
# end
|
80
|
+
|
81
|
+
# def content_type type=nil
|
82
|
+
# return @content_type unless type
|
83
|
+
|
84
|
+
# # can be set only once
|
85
|
+
# return @content_type if @content_type
|
86
|
+
|
87
|
+
# type = 'application/json' if type == :json
|
88
|
+
# type = 'text/plain' if type == :text
|
89
|
+
# type = 'text/html' if type == :html
|
90
|
+
|
91
|
+
# raise 'Invalid page content-type %s' % type if type === Symbol
|
92
|
+
|
93
|
+
# @content_type = type
|
94
|
+
# end
|
95
|
+
|
96
|
+
# def content_type= type
|
97
|
+
# content_type type
|
98
|
+
# end
|
99
|
+
|
100
|
+
# def redirect where=nil, opts={}
|
101
|
+
# return @headers['location'] unless where
|
102
|
+
|
103
|
+
# @status = opts.delete(:status) || 302
|
104
|
+
# opts.map { |k,v| flash.send(k, v) }
|
105
|
+
|
106
|
+
# @headers['location'] = where.index('//') ? where : "#{host}#{where}"
|
107
|
+
# @body = %[redirecting to #{@headers['location']}\n\n#{opts.values.join("\n")}]
|
108
|
+
# end
|
109
|
+
|
110
|
+
# def permanent_redirect where
|
111
|
+
# redirect where, status:301
|
112
|
+
# end
|
113
|
+
|
114
|
+
# def write_response_body
|
115
|
+
# # if @body is not set, this is error now
|
116
|
+
# unless @body
|
117
|
+
# @status = 500
|
118
|
+
# @body = 'Page BODY not defined. Maybe you did not call cell action but method instad.'
|
119
|
+
# end
|
120
|
+
|
121
|
+
# # respond as JSON if we recive hash
|
122
|
+
# if @body.kind_of?(Hash)
|
123
|
+
# @body = Lux.dev? ? JSON.pretty_generate(@body) : JSON.generate(@body)
|
124
|
+
|
125
|
+
# if Lux.page.request.params[:callback]
|
126
|
+
# @body = "#{@request.params[:callback]}(#{ret})"
|
127
|
+
# @content_type ||= 'text/javascript'
|
128
|
+
# else
|
129
|
+
# @content_type ||= 'application/json'
|
130
|
+
# end
|
131
|
+
|
132
|
+
# @body += "\n"
|
133
|
+
# else
|
134
|
+
# # if somebody sets @content_type, respect that
|
135
|
+
# @body = @body.to_s unless @body.kind_of?(String)
|
136
|
+
# @content_type ||= 'text/plain' if @body[0,1] != '<'
|
137
|
+
# @content_type ||= 'text/html'
|
138
|
+
# end
|
139
|
+
# end
|
140
|
+
|
141
|
+
# def write_response_header
|
142
|
+
# domain =
|
143
|
+
# if request.host =~ %r{^[\d\.]+$} # if request is IP
|
144
|
+
# request.host
|
145
|
+
# else
|
146
|
+
# base_domain.index('.') ? ".#{base_domain}" : base_domain
|
147
|
+
# end
|
148
|
+
|
149
|
+
# @session[:lux_flash] = flash.to_h
|
150
|
+
|
151
|
+
# # skip adding of cookies and time to strong etag parameters
|
152
|
+
# if !@headers['etag'] || @headers['etag'].index('/')
|
153
|
+
# @headers['set-cookie'] = "__luxs=#{Crypt.encrypt(@session.to_json)}; Expires=#{(Time.now+1.month).utc}; Path=/; Domain=#{domain};"
|
154
|
+
# @headers['x-lux-speed'] = "#{((Time.now-@render_start)*1000).round(1)}ms"
|
155
|
+
# end
|
156
|
+
|
157
|
+
# @headers['content-type'] ||= "#{@content_type}; charset=utf-8"
|
158
|
+
|
159
|
+
# Lux.page.etag(@body) if Lux.page.request.request_method == 'GET'
|
160
|
+
# end
|
161
|
+
|
162
|
+
# def write_response
|
163
|
+
# write_response_body
|
164
|
+
# write_response_header
|
165
|
+
|
166
|
+
# @status ||= 200
|
167
|
+
# Lux.log " #{@status}, #{@headers['x-lux-speed']}"
|
168
|
+
|
169
|
+
# if ENV['LUX_PRINT_ROUTES']
|
170
|
+
# print '* Finished route print '
|
171
|
+
# puts @status == 404 ? 'without a match'.red : 'with a match'.green
|
172
|
+
# exit
|
173
|
+
# end
|
174
|
+
|
175
|
+
# [@status, @headers, [@body]]
|
176
|
+
# end
|
177
|
+
|
178
|
+
# end
|
data/lib/lux/page/page.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# we need this for command line
|
4
|
-
Thread.current[:lux] ||= {}
|
5
|
-
Thread.current[:lux][:cache] ||= {}
|
4
|
+
Thread.current[:lux] ||= { cache: {} }
|
6
5
|
|
7
6
|
class Lux::Page
|
8
7
|
attr_accessor :headers, :cookies, :session, :files_in_use
|
@@ -38,13 +37,14 @@ class Lux::Page
|
|
38
37
|
|
39
38
|
###
|
40
39
|
|
41
|
-
def initialize
|
42
|
-
@render_start = Time.now
|
40
|
+
def initialize request
|
43
41
|
@files_in_use = []
|
44
|
-
@request
|
45
|
-
@headers
|
46
|
-
@cookies
|
47
|
-
@session
|
42
|
+
@request = request
|
43
|
+
@headers = {}
|
44
|
+
@cookies = {}
|
45
|
+
@session = {}
|
46
|
+
|
47
|
+
@render_start = Time.now
|
48
48
|
|
49
49
|
for cookie in request.env['HTTP_COOKIE'].to_s.split(/;\s*/).map{ |el| el.split('=',2) }
|
50
50
|
@cookies[cookie[0]] = cookie[1]
|
@@ -57,8 +57,16 @@ class Lux::Page
|
|
57
57
|
puts "ERROR: There is no session set!".red
|
58
58
|
end
|
59
59
|
|
60
|
+
# hard sec, bind session to user agent and IP
|
61
|
+
check = get_client_unique_hash
|
62
|
+
@session = {} if @session['_c'] && @session['_c'] != check
|
63
|
+
@session['_c'] = check
|
64
|
+
|
60
65
|
@session = HashWithIndifferentAccess.new(@session)
|
61
|
-
|
66
|
+
|
67
|
+
if request.post? && Lux.config(:log_to_stdout)
|
68
|
+
ap request.params
|
69
|
+
end
|
62
70
|
|
63
71
|
@params = request.params.h_wia
|
64
72
|
Lux::Page::EncryptParams.decrypt @params
|
@@ -66,6 +74,10 @@ class Lux::Page
|
|
66
74
|
@nav = Lux::Controller::Nav.new request
|
67
75
|
end
|
68
76
|
|
77
|
+
def get_client_unique_hash
|
78
|
+
Crypt.md5(@request.ip.to_s+@request.env['HTTP_USER_AGENT'].to_s)
|
79
|
+
end
|
80
|
+
|
69
81
|
def status num=nil
|
70
82
|
Lux.log caller if num == 500
|
71
83
|
return @status if @status
|
@@ -108,7 +120,7 @@ class Lux::Page
|
|
108
120
|
end
|
109
121
|
|
110
122
|
def flash message=nil
|
111
|
-
@flash ||= Flash.new
|
123
|
+
@flash ||= Flash.new @session[:lux_flash]
|
112
124
|
|
113
125
|
message ? @flash.error(message) : @flash
|
114
126
|
end
|
@@ -125,31 +137,37 @@ class Lux::Page
|
|
125
137
|
end
|
126
138
|
|
127
139
|
def host
|
128
|
-
"#{request.env['rack.url_scheme']}://#{request.host}:#{request.port}".sub(':80','') rescue 'http://locahost:3000'
|
140
|
+
"#{request.env['rack.url_scheme']}://#{request.host}:#{request.port}".sub(':80','')# rescue 'http://locahost:3000'
|
129
141
|
end
|
130
142
|
|
131
143
|
def no_cache? force=nil
|
132
144
|
return false if !force && Lux.prod?
|
133
|
-
|
145
|
+
@request.env['HTTP_CACHE_CONTROL'] == 'no-cache' ? true : false
|
134
146
|
rescue
|
135
147
|
false
|
136
148
|
end
|
137
149
|
|
138
|
-
def
|
150
|
+
def header name, value=:_
|
151
|
+
name = name.downcase
|
152
|
+
@headers[name] = value if value != :_
|
153
|
+
@headers[name]
|
154
|
+
end
|
155
|
+
|
156
|
+
def redirect where=nil, opts={}
|
139
157
|
return @headers['location'] unless where
|
140
158
|
|
141
159
|
@status = opts.delete(:status) || 302
|
142
160
|
opts.map { |k,v| flash.send(k, v) }
|
143
161
|
|
144
|
-
@headers['location'] = where.index('//') ? where : "#{
|
162
|
+
@headers['location'] = where.index('//') ? where : "#{host}#{where}"
|
145
163
|
@body = %[redirecting to #{@headers['location']}\n\n#{opts.values.join("\n")}]
|
146
164
|
end
|
147
165
|
|
148
|
-
def permanent_redirect
|
149
|
-
redirect
|
166
|
+
def permanent_redirect where
|
167
|
+
redirect where, status:301
|
150
168
|
end
|
151
169
|
|
152
|
-
def content_type
|
170
|
+
def content_type type=nil
|
153
171
|
return @content_type unless type
|
154
172
|
|
155
173
|
# can be set only once
|
@@ -159,36 +177,38 @@ class Lux::Page
|
|
159
177
|
type = 'text/plain' if type == :text
|
160
178
|
type = 'text/html' if type == :html
|
161
179
|
|
180
|
+
raise 'Invalid page content-type %s' % type if type === Symbol
|
181
|
+
|
162
182
|
@content_type = type
|
163
183
|
end
|
164
184
|
|
165
|
-
def content_type=
|
166
|
-
content_type
|
185
|
+
def content_type= type
|
186
|
+
content_type type
|
167
187
|
end
|
168
188
|
|
169
|
-
def etag
|
170
|
-
@headers['etag'] ||=
|
189
|
+
def etag *args
|
190
|
+
@headers['etag'] ||= 'W/"%s"' % Lux.cache.generate_key(args)
|
171
191
|
|
172
|
-
if
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
end
|
192
|
+
if @request.env['HTTP_IF_NONE_MATCH'] == @headers['etag']
|
193
|
+
@status = 304
|
194
|
+
body! 'not-modified'
|
195
|
+
# print ' %s>' % Lux.page.status if Lux.config(:log_to_stdout)
|
196
|
+
true
|
197
|
+
else
|
198
|
+
false
|
180
199
|
end
|
181
|
-
false
|
182
200
|
end
|
183
201
|
|
184
|
-
|
202
|
+
# execute action once per page
|
203
|
+
def once id, data=nil
|
185
204
|
@once_hash ||= {}
|
186
|
-
return if @once_hash[id]
|
205
|
+
return false if @once_hash[id]
|
187
206
|
@once_hash[id] = true
|
188
|
-
|
207
|
+
yield if block_given?
|
208
|
+
data || true
|
189
209
|
end
|
190
210
|
|
191
|
-
def
|
211
|
+
def write_response_body
|
192
212
|
# if @body is not set, this is error now
|
193
213
|
unless @body
|
194
214
|
@status = 500
|
@@ -198,12 +218,14 @@ class Lux::Page
|
|
198
218
|
# respond as JSON if we recive hash
|
199
219
|
if @body.kind_of?(Hash)
|
200
220
|
@body = Lux.dev? ? JSON.pretty_generate(@body) : JSON.generate(@body)
|
221
|
+
|
201
222
|
if Lux.page.request.params[:callback]
|
202
223
|
@body = "#{@request.params[:callback]}(#{ret})"
|
203
224
|
@content_type ||= 'text/javascript'
|
204
225
|
else
|
205
226
|
@content_type ||= 'application/json'
|
206
227
|
end
|
228
|
+
|
207
229
|
@body += "\n"
|
208
230
|
else
|
209
231
|
# if somebody sets @content_type, respect that
|
@@ -211,22 +233,15 @@ class Lux::Page
|
|
211
233
|
@content_type ||= 'text/plain' if @body[0,1] != '<'
|
212
234
|
@content_type ||= 'text/html'
|
213
235
|
end
|
236
|
+
end
|
214
237
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
end
|
223
|
-
|
224
|
-
if request.host =~ %r{^[\d\.]+$} # if request is IP
|
225
|
-
domain = request.host
|
226
|
-
else
|
227
|
-
domain = base_domain
|
228
|
-
domain = domain.index('.') ? ".#{domain}" : domain
|
229
|
-
end
|
238
|
+
def write_response_header
|
239
|
+
domain =
|
240
|
+
if request.host =~ %r{^[\d\.]+$} # if request is IP
|
241
|
+
request.host
|
242
|
+
else
|
243
|
+
base_domain.index('.') ? ".#{base_domain}" : base_domain
|
244
|
+
end
|
230
245
|
|
231
246
|
@session[:lux_flash] = flash.to_h
|
232
247
|
|
@@ -239,9 +254,15 @@ class Lux::Page
|
|
239
254
|
@headers['content-type'] ||= "#{@content_type}; charset=utf-8"
|
240
255
|
|
241
256
|
# if "no-store" is present then HTTP_IF_NONE_MATCH is not sent from browser
|
242
|
-
@headers['cache-control'] ||= 'must-revalidate, %s, max-age=0' % Lux.page.var.user ? :private : :public
|
257
|
+
@headers['cache-control'] ||= 'must-revalidate, %s, max-age=0' % (Lux.page.var.user ? :private : :public)
|
243
258
|
|
244
259
|
Lux.page.etag(@body) if Lux.page.request.request_method == 'GET'
|
260
|
+
end
|
261
|
+
|
262
|
+
def write_response
|
263
|
+
write_response_body
|
264
|
+
write_response_header
|
265
|
+
|
245
266
|
@status ||= 200
|
246
267
|
Lux.log " #{@status}, #{@headers['x-lux-speed']}"
|
247
268
|
|
@@ -263,7 +284,7 @@ class Lux::Page
|
|
263
284
|
Lux::Controller.new.rescued_main
|
264
285
|
BeforeAndAfter.execute(self, :after)
|
265
286
|
|
266
|
-
|
287
|
+
write_response
|
267
288
|
end
|
268
289
|
|
269
290
|
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
class Lux::RescueFrom
|
15
15
|
|
16
16
|
class << self
|
17
|
-
def define
|
17
|
+
def define klass
|
18
18
|
ClassAttributes.define klass, :rescue_from_hash
|
19
19
|
|
20
20
|
klass.class_eval %[
|
@@ -32,12 +32,13 @@ class Lux::RescueFrom
|
|
32
32
|
@rescues = {}
|
33
33
|
end
|
34
34
|
|
35
|
-
def add
|
35
|
+
def add name, &block
|
36
36
|
die ":#{name} is not allowed rescue name, only allowed are :default and :allways" if name.is_symbol? && ![:default, :allways].index(name)
|
37
37
|
@rescues[name.to_s] = block
|
38
38
|
end
|
39
39
|
|
40
|
-
|
40
|
+
# we pass context so we can execute errors it object context
|
41
|
+
def call context
|
41
42
|
begin
|
42
43
|
yield
|
43
44
|
rescue Exception => e
|
@@ -47,13 +48,14 @@ class Lux::RescueFrom
|
|
47
48
|
|
48
49
|
if proc = @rescues[e.class.to_s]
|
49
50
|
proc.call(e.message)
|
50
|
-
|
51
|
-
|
51
|
+
context.instance_exec e.message, &proc
|
52
|
+
elsif proc = @rescues['default'] # catch them all
|
53
|
+
context.instance_exec e.message, &proc
|
52
54
|
else
|
53
55
|
raise e
|
54
56
|
end
|
55
57
|
|
56
|
-
|
58
|
+
context.instance_exec e.message, &@rescues['allways'] if @rescues['allways']
|
57
59
|
|
58
60
|
Lux.page.status e.class
|
59
61
|
end
|
data/lib/lux-fw.rb
CHANGED
@@ -26,7 +26,9 @@ Encoding.default_internal = Encoding.default_external = 'utf-8'
|
|
26
26
|
|
27
27
|
Sequel.extension :inflector, :string_date_time
|
28
28
|
Sequel::Model.plugin :after_initialize, :def_dataset_method
|
29
|
+
|
29
30
|
Sequel.database_timezone = :utc
|
31
|
+
Sequel.default_timezone = +2
|
30
32
|
|
31
33
|
# load basic lux libs
|
32
34
|
require_relative './lux/lux'
|
data/lib/overload/array.rb
CHANGED
data/lib/overload/date.rb
CHANGED
data/lib/overload/hash.rb
CHANGED
@@ -10,16 +10,7 @@ class Hash
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def tag node=nil, text=nil
|
13
|
-
|
14
|
-
self.each do |k,v|
|
15
|
-
opts += ' '+k.to_s.gsub(/_/,'-')+'="'+v.to_s.gsub(/"/,'"')+'"' if v.present?
|
16
|
-
end
|
17
|
-
|
18
|
-
return opts unless node
|
19
|
-
|
20
|
-
text = yield opts if block_given?
|
21
|
-
text ||= '' unless ['input', 'img', 'meta', 'link', 'hr', 'br'].include?(node.to_s)
|
22
|
-
text ? %{<#{node}#{opts}>#{text}</#{node}>} : %{<#{node}#{opts} />}
|
13
|
+
Lux::Helper::HtmlTag.build self, node, text
|
23
14
|
end
|
24
15
|
|
25
16
|
def to_struct name=nil
|
@@ -82,5 +73,23 @@ class Hash
|
|
82
73
|
replace(hash)
|
83
74
|
omit
|
84
75
|
end
|
76
|
+
|
77
|
+
# full dinmaic option, slow
|
78
|
+
# def to_opts! *keys
|
79
|
+
# self.keys.each { |key| raise 'Hash key :%s is not allowed!' % key unless keys.include?(key) }
|
80
|
+
|
81
|
+
# template = Class.new
|
82
|
+
# keys.each { |key| template.send(:attr_accessor, key) }
|
83
|
+
|
84
|
+
# klass = template.new
|
85
|
+
# keys.map { |key| klass.send '%s=' % key, self[key] }
|
86
|
+
# klass
|
87
|
+
# end
|
88
|
+
def to_opts! *keys
|
89
|
+
self.keys.each { |key| raise 'Hash key :%s is not allowed!' % key unless keys.include?(key) }
|
90
|
+
|
91
|
+
DynamicClass.new keys
|
92
|
+
.inject({}) { |_, key| _[key] = self[key]; _ }
|
93
|
+
end
|
85
94
|
end
|
86
95
|
|
data/lib/overload/it.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# class Array
|
2
|
+
# # list.xeach { it.foo }
|
3
|
+
# def xeach &block
|
4
|
+
# define_singleton_method(:it) { @_it } unless respond_to?(:it)
|
5
|
+
# each do |_|
|
6
|
+
# @_it = _
|
7
|
+
# instance_eval &block
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
|
11
|
+
# # list.xmap { it * 2 }
|
12
|
+
# def xmap &block
|
13
|
+
# define_singleton_method(:it) { @_it } unless respond_to?(:it)
|
14
|
+
# map do |_|
|
15
|
+
# @_it = _
|
16
|
+
# instance_eval &block
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
|
20
|
+
# # list.xselect { it.class != Module }
|
21
|
+
# def xselect &block
|
22
|
+
# define_singleton_method(:it) { @_it } unless respond_to?(:it)
|
23
|
+
# select do |_|
|
24
|
+
# @_it = _
|
25
|
+
# instance_eval &block
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
|
29
|
+
# end
|
data/lib/overload/object.rb
CHANGED
@@ -1,31 +1,15 @@
|
|
1
|
-
class LocalRaiseError < StandardError
|
2
|
-
end
|
3
|
-
|
4
1
|
class Object
|
5
|
-
def r(what=nil)
|
6
|
-
opath = what.class.ancestors
|
7
|
-
out = opath.join("\n> ")
|
8
|
-
|
9
|
-
data = what.is_a?(Hash) ? JSON.pretty_generate(what) : what.ai(plain:true)
|
10
|
-
out = [data, out, ''].join("\n\n-\n\n")
|
11
|
-
|
12
|
-
raise LocalRaiseError.new out
|
13
|
-
end
|
14
|
-
|
15
|
-
def instance_variables_hash
|
16
|
-
Hash[instance_variables.map { |name| [name, instance_variable_get(name)] } ]
|
17
|
-
end
|
18
2
|
|
19
|
-
def or
|
3
|
+
def or _or
|
20
4
|
self.blank? || self == 0 ? _or : self
|
21
5
|
end
|
22
6
|
|
23
|
-
def try
|
7
|
+
def try *args
|
24
8
|
return nil if self.class == NilClass
|
25
9
|
self.send(*args)
|
26
10
|
end
|
27
11
|
|
28
|
-
def die
|
12
|
+
def die desc=nil, exp_object=nil
|
29
13
|
desc ||= 'died without desc'
|
30
14
|
desc = '%s: %s' % [exp_object.class, desc] if exp_object
|
31
15
|
raise desc
|