lux-fw 0.1.17 → 0.1.35

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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.version +1 -1
  3. data/bin/cli/am +38 -29
  4. data/bin/cli/assets +8 -4
  5. data/bin/cli/exceptions +6 -6
  6. data/bin/cli/generate +0 -0
  7. data/bin/cli/get +0 -0
  8. data/bin/cli/nginx +11 -5
  9. data/bin/cli/routes +0 -0
  10. data/bin/cli/systemd +36 -0
  11. data/bin/forever +0 -0
  12. data/bin/job_que +0 -0
  13. data/bin/lux +1 -0
  14. data/lib/common/base32.rb +0 -0
  15. data/lib/common/class_attributes.rb +13 -4
  16. data/lib/common/crypt.rb +6 -10
  17. data/lib/common/dynamic_class.rb +23 -0
  18. data/lib/common/generic_model.rb +0 -0
  19. data/lib/common/hash_with_indifferent_access.rb +352 -0
  20. data/lib/common/method_attr.rb +69 -0
  21. data/lib/lux/api/api.rb +26 -27
  22. data/lib/lux/api/lib/application_api.rb +26 -7
  23. data/lib/lux/api/lib/doc_builder.rb +18 -17
  24. data/lib/lux/api/lib/dsl.rb +23 -41
  25. data/lib/lux/api/lib/error.rb +3 -0
  26. data/lib/lux/api/lib/model_api.rb +22 -20
  27. data/lib/lux/api/lib/rescue.rb +5 -15
  28. data/lib/lux/api/lib/response.rb +46 -0
  29. data/lib/lux/cache/cache.rb +13 -6
  30. data/lib/lux/cell/cell.rb +3 -14
  31. data/lib/lux/config/config.rb +4 -3
  32. data/lib/lux/controller/controller.rb +3 -3
  33. data/lib/lux/controller/lib/nav.rb +6 -2
  34. data/lib/lux/error/error.rb +15 -14
  35. data/lib/lux/helper/helper.rb +5 -5
  36. data/lib/lux/helper/lib/html_tag.rb +67 -0
  37. data/lib/lux/html/lib/input_types.rb +26 -16
  38. data/lib/lux/lib/lux.rb +51 -0
  39. data/lib/lux/lux.rb +5 -52
  40. data/lib/lux/page/lib/response.rb +178 -0
  41. data/lib/lux/page/page.rb +72 -51
  42. data/lib/lux/rescue_from/rescue_from.rb +8 -6
  43. data/lib/lux/template/template.rb +1 -0
  44. data/lib/lux-fw.rb +2 -0
  45. data/lib/overload/array.rb +4 -0
  46. data/lib/overload/date.rb +2 -0
  47. data/lib/overload/hash.rb +19 -10
  48. data/lib/overload/it.rb +29 -0
  49. data/lib/overload/object.rb +3 -19
  50. data/lib/overload/r.rb +53 -0
  51. data/lib/overload/string.rb +5 -6
  52. data/lib/overload/string_inflections.rb +4 -3
  53. data/lib/plugins/assets/assets_plug.rb +9 -4
  54. data/lib/plugins/assets/helper_module_adapter.rb +4 -2
  55. data/lib/plugins/db_helpers/link_plugin.rb +2 -2
  56. data/lib/plugins/db_logger/init.rb +1 -1
  57. data/lib/vendor/mini_assets/lib/asset/css.rb +19 -0
  58. data/lib/vendor/mini_assets/lib/asset/js.rb +17 -0
  59. data/lib/vendor/mini_assets/lib/asset.rb +71 -0
  60. data/lib/vendor/mini_assets/lib/base/javascript.rb +13 -0
  61. data/lib/vendor/mini_assets/lib/base/stylesheet.rb +5 -0
  62. data/lib/vendor/mini_assets/lib/base.rb +69 -0
  63. data/lib/vendor/mini_assets/lib/manifest.rb +18 -0
  64. data/lib/vendor/mini_assets/lib/opts.rb +16 -0
  65. data/lib/vendor/mini_assets/mini_assets.rb +74 -0
  66. metadata +23 -10
  67. data/lib/common/class_method_params.rb +0 -94
  68. data/lib/overload/hash_wia.rb +0 -282
  69. data/lib/overload/inflections.rb +0 -199
  70. data/lib/vendor/mini_assets/mini_asset/base.rb +0 -167
  71. data/lib/vendor/mini_assets/mini_asset/css.rb +0 -38
  72. data/lib/vendor/mini_assets/mini_asset/js.rb +0 -38
  73. 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)*1000).to_i.to_s
107
- num = num.sub(/(\d)(\d{3})$/,'\1s \2')
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(request)
42
- @render_start = Time.now
40
+ def initialize request
43
41
  @files_in_use = []
44
- @request = 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
- @session['_junk'] = Crypt.uid
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(@session[:lux_flash])
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
- Lux.page.request.env['HTTP_CACHE_CONTROL'] == 'no-cache' ? true : false
145
+ @request.env['HTTP_CACHE_CONTROL'] == 'no-cache' ? true : false
134
146
  rescue
135
147
  false
136
148
  end
137
149
 
138
- def redirect(where=nil, opts={})
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 : "#{Lux.page.host}#{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(where)
149
- redirect(where, status:301)
166
+ def permanent_redirect where
167
+ redirect where, status:301
150
168
  end
151
169
 
152
- def content_type(type=nil)
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=(type)
166
- content_type(type)
185
+ def content_type= type
186
+ content_type type
167
187
  end
168
188
 
169
- def etag(*args)
170
- @headers['etag'] ||= %[W/"#{Lux.cache.generate_key(args)}"]
189
+ def etag *args
190
+ @headers['etag'] ||= 'W/"%s"' % Lux.cache.generate_key(args)
171
191
 
172
- if Lux.page.request.env['HTTP_IF_NONE_MATCH'] == @headers['etag']
173
- if Lux.config(:perform_caching)
174
- Lux.page.status(304)
175
- Lux.page.body 'not-modified'
176
- return true
177
- else
178
- print ' 304>' if Lux.page.status != 304 && Lux.verbose?
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
- def once(id, data=nil)
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
- data || yield
207
+ yield if block_given?
208
+ data || true
189
209
  end
190
210
 
191
- def process_body
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
- # show out of process errors if enables and if is html page
216
- # becasue for eaxmple we dont want to show error page instead of image
217
- # we want user to see it
218
- if Lux.config(:show_server_errors) && @content_type == 'text/html' && File.exist?(Lux::Error::OUT_OF_PROCESS_ERROR_PATH)
219
- data = File.read(Lux::Error::OUT_OF_PROCESS_ERROR_PATH)
220
- File.unlink(Lux::Error::OUT_OF_PROCESS_ERROR_PATH)
221
- @body = Lux::Error::render data
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
- process_body
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(klass)
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(name, &block)
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
- def call
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
- elsif @rescues['default'] # catch them all
51
- @rescues['default'].call(e.message)
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
- @rescues['allways'].call(e.message) if @rescues['allways']
58
+ context.instance_exec e.message, &@rescues['allways'] if @rescues['allways']
57
59
 
58
60
  Lux.page.status e.class
59
61
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require 'thread'
2
3
 
3
4
  class Lux::Template
4
5
  @@template_cache = {}
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'
@@ -49,4 +49,8 @@ class Array
49
49
  end
50
50
  end
51
51
 
52
+ def all
53
+ self
54
+ end
55
+
52
56
  end
data/lib/overload/date.rb CHANGED
@@ -27,6 +27,8 @@ class Time
27
27
  end
28
28
 
29
29
  def ago(start_time, end_time=nil)
30
+ start_time = Time.new(start_time.year, start_time.month, start_time.day) if start_time.class == Date
31
+
30
32
  end_time ||= Time.now
31
33
  time_diff = end_time.to_i - start_time.to_i
32
34
 
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
- opts = ''
14
- self.each do |k,v|
15
- opts += ' '+k.to_s.gsub(/_/,'-')+'="'+v.to_s.gsub(/"/,'&quot;')+'"' 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
 
@@ -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
@@ -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(_or)
3
+ def or _or
20
4
  self.blank? || self == 0 ? _or : self
21
5
  end
22
6
 
23
- def try(*args)
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(desc=nil, exp_object=nil)
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