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.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/.version +1 -1
  3. data/bin/README.md +26 -13
  4. data/bin/cli/benchmark.rb +18 -0
  5. data/bin/cli/cerb.rb +90 -0
  6. data/bin/cli/config.rb +4 -11
  7. data/bin/cli/console.rb +72 -30
  8. data/bin/cli/eval.rb +5 -27
  9. data/bin/cli/generate.rb +9 -11
  10. data/bin/cli/get.rb +14 -6
  11. data/bin/cli/memory.rb +12 -0
  12. data/bin/cli/new.rb +2 -0
  13. data/bin/cli/secrets.rb +3 -31
  14. data/bin/cli/server.rb +28 -9
  15. data/bin/cli/stats.rb +26 -20
  16. data/bin/cli/template.rb +10 -0
  17. data/bin/generate_doc +168 -0
  18. data/bin/lux +73 -10
  19. data/lib/README.md +18 -8
  20. data/lib/common/crypt.rb +60 -9
  21. data/lib/common/string_base.rb +54 -15
  22. data/lib/common/struct_opts.rb +30 -0
  23. data/lib/common/time_difference.rb +75 -0
  24. data/lib/loader.rb +41 -0
  25. data/lib/lux/application/README.md +67 -105
  26. data/lib/lux/application/application.rb +87 -329
  27. data/lib/lux/application/lib/magic_routes.rb +22 -0
  28. data/lib/lux/application/lib/nav.rb +218 -99
  29. data/lib/lux/application/lib/render.rb +47 -67
  30. data/lib/lux/application/lib/routes.rb +242 -0
  31. data/lib/lux/application/lib/shared.rb +47 -0
  32. data/lib/lux/application/lux_adapter.rb +6 -0
  33. data/lib/lux/application/lux_config.rb +26 -0
  34. data/lib/lux/cache/Find Results +24 -0
  35. data/lib/lux/cache/README.md +28 -35
  36. data/lib/lux/cache/cache.rb +78 -26
  37. data/lib/lux/cache/lib/memcached_server.rb +36 -0
  38. data/lib/lux/cache/lib/memory_server.rb +44 -0
  39. data/lib/lux/cache/lib/null_server.rb +33 -0
  40. data/lib/lux/cache/lib/sqlite_server.rb +62 -0
  41. data/lib/lux/cache/lux_adapter.rb +19 -0
  42. data/lib/lux/config/config.rb +93 -144
  43. data/lib/lux/config/lux_adapter.rb +27 -0
  44. data/lib/lux/controller/README.md +67 -12
  45. data/lib/lux/controller/controller.rb +237 -187
  46. data/lib/lux/current/README.md +29 -10
  47. data/lib/lux/current/current.rb +166 -77
  48. data/lib/lux/current/lib/current.rb +6 -0
  49. data/lib/lux/current/lib/encrypt_params.rb +38 -36
  50. data/lib/lux/current/lib/session.rb +86 -65
  51. data/lib/lux/current/lux_adapter.rb +5 -0
  52. data/lib/lux/environment/README.md +24 -0
  53. data/lib/lux/environment/environment.rb +91 -0
  54. data/lib/lux/environment/lux_adapter.rb +13 -0
  55. data/lib/lux/error/README.md +18 -19
  56. data/lib/lux/error/error.rb +207 -152
  57. data/lib/lux/error/lux_adapter.rb +9 -0
  58. data/lib/lux/logger/README.md +45 -0
  59. data/lib/lux/logger/lux_adapter.rb +27 -0
  60. data/lib/lux/lux.rb +72 -129
  61. data/lib/lux/mailer/README.md +12 -5
  62. data/lib/lux/mailer/lux_config.rb +4 -0
  63. data/lib/lux/mailer/mailer.rb +81 -59
  64. data/lib/lux/plugin/README.md +19 -0
  65. data/lib/lux/plugin/lux_adapter.rb +8 -0
  66. data/lib/lux/plugin/plugin.rb +65 -0
  67. data/lib/lux/render/README.md +100 -0
  68. data/lib/lux/render/render.rb +12 -0
  69. data/lib/lux/response/README.md +57 -1
  70. data/lib/lux/response/lib/file.rb +87 -65
  71. data/lib/lux/response/lib/flash.rb +49 -34
  72. data/lib/lux/response/lib/header.rb +34 -33
  73. data/lib/lux/response/response.rb +252 -164
  74. data/lib/lux/template/helper.rb +130 -0
  75. data/lib/lux/template/inline_render_proxy.rb +31 -0
  76. data/lib/lux/template/lux_adapter.rb +5 -0
  77. data/lib/lux/template/template.rb +127 -0
  78. data/lib/lux-fw.rb +15 -33
  79. data/lib/overload/array.rb +33 -7
  80. data/lib/overload/blank.rb +8 -3
  81. data/lib/overload/boolean.rb +46 -0
  82. data/lib/overload/class.rb +28 -0
  83. data/lib/overload/dir.rb +117 -7
  84. data/lib/overload/file.rb +40 -5
  85. data/lib/overload/float.rb +38 -3
  86. data/lib/overload/hash.rb +81 -91
  87. data/lib/overload/integer.rb +15 -0
  88. data/lib/overload/json.rb +26 -0
  89. data/lib/overload/nil.rb +4 -8
  90. data/lib/overload/object.rb +91 -24
  91. data/lib/overload/pathname.rb +11 -0
  92. data/lib/overload/raise_variants.rb +26 -36
  93. data/lib/overload/string.rb +100 -27
  94. data/lib/overload/thread_simple.rb +100 -0
  95. data/lib/overload/time.rb +60 -38
  96. data/tasks/loader.rb +20 -7
  97. metadata +170 -169
  98. data/bin/.DS_Store +0 -0
  99. data/bin/build_gem +0 -77
  100. data/bin/cli/dbconsole.rb +0 -8
  101. data/bin/cli/routes.rb +0 -90
  102. data/lib/.DS_Store +0 -0
  103. data/lib/common/.DS_Store +0 -0
  104. data/lib/common/class_attributes.rb +0 -51
  105. data/lib/common/class_callbacks.rb +0 -47
  106. data/lib/common/free_struct.rb +0 -42
  107. data/lib/common/hash_with_indifferent_access.rb +0 -74
  108. data/lib/common/html_tag_builder.rb +0 -91
  109. data/lib/common/method_attr.rb +0 -69
  110. data/lib/common/url.rb +0 -191
  111. data/lib/lux/.DS_Store +0 -0
  112. data/lib/lux/README.md +0 -10
  113. data/lib/lux/cache/.DS_Store +0 -0
  114. data/lib/lux/cache/lib/memory.rb +0 -36
  115. data/lib/lux/cache/lib/null.rb +0 -21
  116. data/lib/lux/config/README.md +0 -63
  117. data/lib/lux/config/lib/plugin.rb +0 -65
  118. data/lib/lux/config/lib/secrets.rb +0 -48
  119. data/lib/lux/current/.DS_Store +0 -0
  120. data/lib/lux/delayed_job/.DS_Store +0 -0
  121. data/lib/lux/delayed_job/README.md +0 -3
  122. data/lib/lux/delayed_job/delayed_job.rb +0 -51
  123. data/lib/lux/delayed_job/lib/memory.rb +0 -16
  124. data/lib/lux/delayed_job/lib/nsq.rb +0 -3
  125. data/lib/lux/delayed_job/lib/postgre.rb +0 -6
  126. data/lib/lux/delayed_job/lib/redis.rb +0 -19
  127. data/lib/lux/event_bus/README.md +0 -36
  128. data/lib/lux/event_bus/event_bus.rb +0 -27
  129. data/lib/lux/view/README.md +0 -85
  130. data/lib/lux/view/cell.rb +0 -102
  131. data/lib/lux/view/helper.rb +0 -120
  132. data/lib/lux/view/lib/cell_helpers.rb +0 -29
  133. data/lib/lux/view/view.rb +0 -95
  134. data/lib/overload/it.rb +0 -29
  135. data/plugins/api/README.md +0 -49
  136. data/plugins/api/api.rb +0 -153
  137. data/plugins/api/lib/attr.rb +0 -31
  138. data/plugins/api/lib/dsl.rb +0 -52
  139. data/plugins/api/lib/error.rb +0 -3
  140. data/plugins/api/lib/model_api.rb +0 -203
  141. data/plugins/api/lib/response.rb +0 -85
  142. data/plugins/db/.DS_Store +0 -0
  143. data/plugins/db/README.md +0 -29
  144. data/plugins/db/auto_migrate/auto_migrate.rb +0 -268
  145. data/plugins/db/auto_migrate/db.rake +0 -15
  146. data/plugins/db/helpers/array_search.rb +0 -27
  147. data/plugins/db/helpers/before_save_filters.rb +0 -32
  148. data/plugins/db/helpers/composite_primary_keys.rb +0 -36
  149. data/plugins/db/helpers/core.rb +0 -94
  150. data/plugins/db/helpers/dataset_methods.rb +0 -138
  151. data/plugins/db/helpers/enums_plugin.rb +0 -52
  152. data/plugins/db/helpers/find_precache.rb +0 -31
  153. data/plugins/db/helpers/link_objects.rb +0 -84
  154. data/plugins/db/helpers/schema_checks.rb +0 -83
  155. data/plugins/db/helpers/typero_adapter.rb +0 -71
  156. data/plugins/db/logger/config.rb +0 -22
  157. data/plugins/db/logger/lux_response_adapter.rb +0 -10
  158. data/plugins/db/paginate/helper.rb +0 -32
  159. data/plugins/db/paginate/sequel_adapter.rb +0 -23
  160. data/plugins/exceptions/exceptions.rake +0 -43
  161. data/plugins/exceptions/simple_exception.rb +0 -64
  162. data/plugins/favicon/favicon.rb +0 -10
  163. data/plugins/html/README.md +0 -3
  164. data/plugins/html/html_form.rb +0 -118
  165. data/plugins/html/html_input.rb +0 -98
  166. data/plugins/html/html_menu.rb +0 -79
  167. data/plugins/html/input_types.rb +0 -346
  168. data/plugins/js_widgets/README.md +0 -5
  169. data/plugins/js_widgets/js/html_tag.coffee +0 -42
  170. data/plugins/js_widgets/js/widgets.coffee +0 -161
  171. data/plugins/js_widgets/js_widgets.rb +0 -15
  172. data/plugins/oauth/lib/facebook.rb +0 -35
  173. data/plugins/oauth/lib/github.rb +0 -38
  174. data/plugins/oauth/lib/google.rb +0 -41
  175. data/plugins/oauth/lib/linkedin.rb +0 -41
  176. data/plugins/oauth/lib/stackexchange.rb +0 -41
  177. data/plugins/oauth/lib/twitter.rb +0 -38
  178. data/plugins/oauth/oauth.rb +0 -42
  179. data/plugins/policy/policy.rb +0 -53
  180. data/tasks/nginx.rake +0 -23
  181. /data/lib/lux/{view/lib → mailer}/helper_modules.rb +0 -0
@@ -1,29 +0,0 @@
1
- # make cell available in helpers
2
-
3
- require_relative 'helper_modules'
4
-
5
- class ViewCell < Lux::View::Cell
6
- end
7
-
8
- HtmlHelper.class_eval do
9
- def cell name=nil, vars={}
10
- if name
11
- ViewCell.get(name, self, vars)
12
- else
13
- return @cell_base ||= ViewCell::Loader.new(self)
14
- end
15
- end
16
- end
17
-
18
- # make cell available in controllers
19
- Lux::Controller.class_eval do
20
- def cell name=nil
21
- name = if name
22
- name.to_s.classify
23
- else
24
- self.class.to_s.split('::').last.sub('Controller')
25
- end
26
-
27
- name.constantize.new(self, vars)
28
- end
29
- end
data/lib/lux/view/view.rb DELETED
@@ -1,95 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'thread'
3
-
4
- class Lux::View
5
- @@template_cache = {}
6
-
7
- class << self
8
- def render_with_layout layout, template, helper={}
9
- part_data = new(template, helper).render_part
10
- new(layout, helper).render_part { part_data }
11
- end
12
-
13
- def render_part template, helper={}
14
- new(template, helper).render_part
15
- end
16
- end
17
-
18
- def initialize template, context={}
19
- template = template.sub(/^[^\w]+/, '')
20
- @original_template = template
21
-
22
- @helper = if context.class == Hash
23
- # create helper class if only hash given
24
- Lux::View::Helper.new(context)
25
- else
26
- context
27
- end
28
-
29
- mutex = Mutex.new
30
-
31
- # if auto_code_reload is on then clear only once per request
32
- if Lux.config(:auto_code_reload) && !Thread.current[:lux][:template_cache]
33
- Thread.current[:lux][:template_cache] = true
34
- mutex.synchronize { @@template_cache = {} }
35
- end
36
-
37
- if ref = @@template_cache[template]
38
- @tilt, @template = *ref
39
- return
40
- end
41
-
42
- for dir in ['./app/views']
43
- for ext in Tilt.default_mapping.template_map.keys
44
- next if @template
45
- test = "#{dir}/#{template}.#{ext}"
46
- @template = test if File.exists?(test)
47
- end
48
- end
49
-
50
- unless @template
51
- err = caller.reject{ |l| l =~ %r{(/lux/|/gems/)} }.map{ |l| el=l.to_s.split(Lux.root.to_s); el[1] || l }.join("\n")
52
- msg = %[Lux::View "#{template}.{erb,haml}" not found]
53
- msg += %[\n\n#{err}] if Lux.config(:dump_errors)
54
-
55
- Lux.error msg
56
- end
57
-
58
- begin
59
- mutex.synchronize do
60
- # @tilt = Tilt.new(@template, ugly:true, escape_html: false)
61
- @tilt = Tilt.new(@template, escape_html: false)
62
- @@template_cache[template] = [@tilt, @template]
63
- end
64
- rescue
65
- Lux.error("#{$!.message}\n\nTemplate: #{@template}")
66
- end
67
- end
68
-
69
- def render_part
70
- # global thread safe reference pointer to last temaplte rendered
71
- # we nned this for inline template render
72
-
73
- Thread.current[:lux][:last_template_path] = @template.sub('/app/views','').sub(/\/[^\/]+$/,'').sub(/^\./,'')
74
- Lux.current.files_in_use @template
75
-
76
- data = nil
77
-
78
- speed = Lux.speed do
79
- begin
80
- data = @tilt.render(@helper) do
81
- yield if block_given?
82
- end
83
- rescue => e
84
- data = Lux::Error.inline %[Lux::View #{@template} render error], e
85
- end
86
- end
87
-
88
- Lux.log " app/views/#{@template.split('app/views/').last}, #{speed}"
89
-
90
- data
91
- end
92
-
93
- end
94
-
95
-
data/lib/overload/it.rb DELETED
@@ -1,29 +0,0 @@
1
- # class Array
2
- # def it
3
- # @_it
4
- # end
5
-
6
- # # list.xeach { it.foo }
7
- # def xeach &block
8
- # each do |_|
9
- # @_it = _
10
- # instance_eval &block
11
- # end
12
- # end
13
-
14
- # # list.xmap { it * 2 }
15
- # def xmap &block
16
- # map do |_|
17
- # @_it = _
18
- # instance_eval &block
19
- # end
20
- # end
21
-
22
- # # list.xselect { it.class != Module }
23
- # def xselect &block
24
- # select do |_|
25
- # @_it = _
26
- # instance_eval &block
27
- # end
28
- # end
29
- # end
@@ -1,49 +0,0 @@
1
- ## Lux::Api
2
-
3
- Default class for writing APIs
4
-
5
- ### General rules
6
-
7
- * defines Lux::Api, ApplicationApi and ModelApi
8
- * ApplicationApi - defines decorator and default rescue for output messages
9
- * ModelApi - defines create, read, update and delete methods
10
- * checks every action via Policy.can?(current_user, action, model)
11
- ``` Policy.can?(Lux.current.var.user, :update?, @note) ```
12
- checks if current user can update defined model
13
- * you shuld modify and inherit from ApplicationApi or ModelApi
14
-
15
- * you can use before and after filters
16
- * attributes that are requested and checked via "param :name" are available as @_name
17
-
18
-
19
- ### Example
20
-
21
- ```
22
- class BlogApi < ModelApi
23
-
24
- name 'List all blogs'
25
- desc 'will list all blogs'
26
- def index
27
- Blog.order(:id).select(:id, :name).page
28
- end
29
-
30
- name 'Show single blog by id'
31
- param :id, Integer
32
- def show
33
- Blog.find(@_id)
34
- end
35
-
36
- end
37
- ```
38
-
39
- ### Rescues
40
-
41
- Define API rescue handler
42
-
43
- ```
44
- ApplicationApi.on_error do |e|
45
- key = SimpleException.log(e)
46
- response.meta :error_key, key
47
- response.meta :error_class, e.class
48
- end
49
- ```
data/plugins/api/api.rb DELETED
@@ -1,153 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # 2xx - Success 4xx / 5xx - Error 3xx - Redirection
4
- # 200 OK 400 Bad Request 301 Moved
5
- # 201 Created 401 Unauthorized 302 Found
6
- # 203 Partial Information 402 Payment Required 304 Not Modified
7
- # 204 No response 403 Forbidden
8
- # 404 Not Found
9
- # 500 Internal Server Error
10
- # 503 Service Unavailable
11
-
12
- class Lux::Api
13
- attr_accessor :message, :response
14
-
15
- class_callback :before
16
- class_callback :after
17
-
18
- class << self
19
- # public mount method for router
20
- def call path, opts={}
21
- if path.is_a?(Symbol)
22
- # TestApi.call(:foo, email: '...')
23
- new.call path, opts
24
- else
25
- # Lux::Api.call([:user, :profile], email: '...' )
26
- return error 'Unsupported API call' if !path[1] || path[3]
27
-
28
- if path[2]
29
- opts[:_id] = path[1]
30
- path[1] = path[2]
31
- end
32
-
33
- run path[0], path[1], opts
34
- end
35
- end
36
-
37
- # public method for running actions on global class
38
- # use as Lux::Api.run 'users', 'show', { email:'rejotl@gmail.com' }
39
- # safe create api class and fix params
40
- def run klass, action, params={}
41
- params.delete_if{ |el| [:captures, :splat].index(el.to_sym) }
42
-
43
- action = action.to_s.sub(/[^\w_]/,'')
44
-
45
- class_name = klass.to_s.classify
46
-
47
- if params[class_name.underscore]
48
- begin
49
- params.merge! params.delete(class_name.underscore)
50
- rescue
51
- return error "#{$!.message}. Domain value is probably not hash, invalid parameter #{class_name.underscore}"
52
- end
53
- end
54
-
55
- for k,v in params
56
- params[k] = params[k].gsub('<','&lt;').gsub('>','&gt;').gsub(/\A^\s+|\s+\z/,'') if v.kind_of?(String)
57
- end
58
-
59
- begin
60
- klass = (klass.singularize.camelize+'Api').constantize
61
- rescue
62
- return error "API #{klass} not found"
63
- end
64
-
65
- klass.new.call(action.to_sym, params)
66
- end
67
-
68
- def error message
69
- Lux::Api::Response.error message
70
- end
71
- end
72
-
73
- ###
74
-
75
- def call action, params={}
76
- begin
77
- rescued_call action, params
78
- rescue Lux::Api::Error => e
79
- response.error e.message if e.message.to_s != 'false'
80
- rescue => e
81
- on_error(e)
82
- end
83
-
84
- puts response.render.pretty_generate if Lux.config(:log_to_stdout)
85
-
86
- response.render
87
- end
88
-
89
- # internal method for running actions
90
- # UserApi.new.call(:login, { email:'', pass:'' })
91
- def rescued_call action, params={}
92
- @response = Lux::Api::Response.new
93
- @params = params
94
- @action = action
95
- @class_name = self.class.to_s.sub(/Api$/,'')
96
-
97
- error("Protected action call") if [:call, :rescued_call, :params, :error].index action
98
- error("Action #{action} not found in #{self.class.to_s}") unless respond_to? action
99
-
100
- # load default object
101
- if @params[:_id]
102
- eval "@object = @#{@class_name.underscore} = #{@class_name}[@params[:_id].to_i]"
103
- @params.delete(:_id)
104
- end
105
-
106
- @method_attr = self.class.method_attr[action] || {}
107
-
108
- return if response.errors?
109
-
110
- # execte api call and verify params if possible
111
- Object.class_callback :before, self
112
- response.data = send(action) unless response.errors?
113
- Object.class_callback :after, self unless response.errors?
114
- end
115
-
116
- def params
117
- @params
118
- end
119
-
120
- def error what=nil
121
- raise Lux::Api::Error.new(what || 'false')
122
- end
123
-
124
- def message what
125
- response.message = what
126
- end
127
-
128
- def current
129
- Lux.current
130
- end
131
-
132
- # default after block, can be overloaded
133
- def after
134
- return unless Lux.current
135
-
136
- response.meta :ip, Lux.current.request.ip
137
- response.meta :user, Lux.current.var.user ? Lux.current.var.user.email : nil
138
- response.meta :http_status, Lux.current.response.status(200)
139
- end
140
-
141
- def on_error error
142
- response.meta :error_key, Lux.error.log(error)
143
- response.meta :error_class, error.class.to_s
144
- response.error error.message
145
- end
146
-
147
- end
148
-
149
- ApplicationApi ||= Class.new Lux::Api
150
-
151
-
152
-
153
-
@@ -1,31 +0,0 @@
1
- # - in ApplicationApi, class level
2
- # api_attr :secure_token do |name|
3
- # error 'User session required' unless User.current
4
- # error 'Secure token not found' unless params[:secure_token]
5
- # error 'Invalid secure token' if User.current.secure_token(name) != params.delete(:secure_token)
6
- # end
7
-
8
- # - in object api, instance level
9
- # secure_token :delete
10
- # def delete_me
11
- # 'ok'
12
- # end
13
-
14
- class ApplicationApi
15
- API_ATTR ||= {}
16
-
17
- def self.api_attr name, &block
18
- method_attr name
19
-
20
- API_ATTR[name] = block
21
- end
22
-
23
- ## api_attr check
24
- before do
25
- for method_attr_name, block in API_ATTR
26
- for data in @method_attr[method_attr_name].or([])
27
- instance_exec data, &block
28
- end
29
- end
30
- end
31
- end
@@ -1,52 +0,0 @@
1
- class ApplicationApi
2
- # name 'Show user data'
3
- # param :email, type: :email, req: false
4
- # param :pass
5
- # def show
6
- # @user = User.where(email:@_email).first
7
- # @user.slice(:id, :name, :avatar, :email)
8
- # end
9
-
10
- # helper for standard definition of parametars
11
- # param :o_id
12
- # param :o_id, Integer
13
- # param :o_id, Integer, req: false
14
- # param :o_id, req: false
15
- method_attr :param do |field, type=String, opts={}|
16
- opts = type.is_a?(Hash) ? type : opts.merge(type: type)
17
- opts[:name] = field
18
- opts[:req] = true if opts[:req].nil?
19
- opts[:type] ||= String
20
- opts
21
- end
22
-
23
- # helper for standard definition of name
24
- method_attr :name
25
-
26
- # helper for standard definition of description
27
- method_attr :data
28
-
29
- ###
30
-
31
- before do
32
- if @method_attr[:param]
33
- local = @method_attr[:param].inject({}) { |h, el| o=el.dup; h[o.delete(:name)] = o; h }
34
- rules = Typero.new local
35
- errors = rules.validate(@params)
36
-
37
- if errors.keys.length > 0
38
- raise ArgumentError.new(errors.values.to_sentence) unless Lux.current
39
-
40
- Lux.current.response.status 400
41
- error errors.values.to_sentence
42
- end
43
-
44
- # define local prefixed @_ variables
45
- for key in local.keys.map(&:to_s)
46
- value = params[key]
47
- eval "@_#{key.downcase.gsub(/[^\w]/,'_')} = value" if key.length < 15 && value.present? && key =~ /^[\w]+$/
48
- end
49
- end
50
- end
51
-
52
- end
@@ -1,3 +0,0 @@
1
- class Lux::Api::Error < StandardError
2
-
3
- end
@@ -1,203 +0,0 @@
1
- class Sequel::Model
2
- module InstanceMethods
3
- def same_as_last_field_value data
4
- data = data.join('-') if data.is_array?
5
- data = '' if data.is_hash?
6
- data
7
- end
8
-
9
- def same_as_last?
10
- @last = self.class.xorder('id desc').first
11
- return unless @last
12
-
13
- return if respond_to?(:name) && name != @last[:name]
14
-
15
- new_o = self.to_h
16
- new_o.delete :created_at
17
- new_o.delete :updated_at
18
- new_o.delete :id
19
-
20
- old_o = new_o.keys.inject({}) do |t, key|
21
- t[key] = @last.send(key)
22
-
23
- new_o[key] = same_as_last_field_value new_o[key]
24
- t[key] = same_as_last_field_value t[key]
25
-
26
- t
27
- end
28
-
29
- if new_o.to_s.length == old_o.to_s.length
30
- raise "#{self.class} is the copy of the last one created."
31
- end
32
- end
33
- end
34
- end
35
-
36
- ###
37
-
38
- class ModelApi < ApplicationApi
39
- class << self
40
- def toggle_ids name
41
- self.class_eval %[
42
- param :#{name}_id, Integer
43
- def toggle_#{name}
44
- message toggle!(@object, :#{name}_ids, @_#{name}_id) ? 'added' : 'removed'
45
- end
46
- ]
47
- end
48
- end
49
-
50
- # toggles value in postgre array field
51
- def toggle! object, field, value
52
- object[field] ||= []
53
-
54
- if object[field].include?(value)
55
- object[field] -= [value]
56
- object.save
57
- false
58
- else
59
- object[field] += [value]
60
- object.save
61
- true
62
- end
63
- end
64
-
65
- ###
66
-
67
- def index
68
- raise 'No index method defiend'
69
- end
70
-
71
- def show
72
- error "Object not found" unless @object
73
-
74
- can? :read, @object
75
-
76
- attributes
77
- end
78
-
79
- def create
80
- @object = @class_name.constantize.new
81
-
82
- for k, v in @params
83
- v = nil if v.blank?
84
- @object.send("#{k}=", v) if @object.respond_to?(k.to_sym)
85
- end
86
-
87
- @object.same_as_last? rescue error($!.message)
88
-
89
- can? :create, @object
90
- @object.save if @object.valid?
91
- return if report_errros_if_any @object
92
-
93
- if @object.id
94
- message '%s created' % @class_name.capitalize
95
- else
96
- error 'object not created, error unknown'
97
- end
98
-
99
- add_response_object_path
100
-
101
- attributes
102
- end
103
-
104
- def update
105
- error "Object not found" unless @object
106
-
107
- for k,v in @params
108
- m = "#{k}=".to_sym
109
- v = nil if v.blank?
110
- @object.send(m, v) if @object.respond_to?(m)
111
- end
112
-
113
- can? :update, @object
114
-
115
- @object.updated_at = Time.now.utc if @object.respond_to?(:updated_at)
116
- @object.save if @object.valid?
117
-
118
- report_errros_if_any @object
119
-
120
- response.message '%s updated' % @class_name
121
-
122
- add_response_object_path
123
-
124
- attributes
125
- end
126
-
127
- # if you put active boolean field to objects, then they will be unactivated on destroy
128
- def destroy force: false
129
- error "Object not found" unless @object
130
- can? :delete, @object
131
-
132
- if !force && @object.respond_to?(:is_active)
133
- @object.update is_active: false
134
-
135
- message 'Object deleted (exists in trashcan)'
136
- elsif !force && @object.respond_to?(:active)
137
- @object.update active: false
138
-
139
- message 'Object deleted (exists in trashcan)'
140
- else
141
- @object.destroy
142
- message '%s deleted' % @object.class.name
143
- end
144
-
145
- report_errros_if_any @object
146
-
147
- attributes
148
- end
149
-
150
- def undelete
151
- error "Object not found" unless @object
152
- can? :create, @object
153
-
154
- if @object.respond_to?(:is_active)
155
- @object.update :is_active=>true
156
- elsif @object.respond_to?(:active)
157
- @object.update :active=>true
158
- else
159
- error "No is_active, can't undelete"
160
- end
161
-
162
- response.message = 'Object raised from the dead.'
163
- end
164
-
165
- private
166
-
167
- def report_errros_if_any obj
168
- return if obj.errors.count == 0
169
-
170
- for k, v in obj.errors
171
- desc = v.join(', ')
172
-
173
- response.error k, desc
174
- end
175
-
176
- error
177
- end
178
-
179
- def can? action, object=nil
180
- object ||= @object
181
- object.can?(action) do |err|
182
- msg = 'No %s permission for %s' % [action.to_s.sub('?',''), Lux.current.var.user ? Lux.current.var.user.email : :guests]
183
- msg += ' on %s' % object.class.name if object
184
- error msg
185
- end
186
- end
187
-
188
- def add_response_object_path
189
- begin
190
- if @object.respond_to?(:path)
191
- response.meta :path, @object.path
192
- response.meta :string_id, @object.id.string_id
193
- end
194
- rescue
195
- nil
196
- end
197
- end
198
-
199
- def attributes
200
- @object.attributes.pluck(:id, :name, :email)
201
- end
202
-
203
- end