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.
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