plezi 0.12.22 → 0.14.0

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 (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/LICENSE.txt +17 -18
  4. data/README.md +54 -698
  5. data/Rakefile +7 -4
  6. data/bin/config.ru +22 -0
  7. data/{test → bin}/console +4 -6
  8. data/bin/hello_world +52 -0
  9. data/bin/setup +8 -0
  10. data/exe/plezi +145 -0
  11. data/lib/plezi.rb +24 -137
  12. data/lib/plezi/activation.rb +28 -0
  13. data/lib/plezi/api.rb +62 -0
  14. data/lib/plezi/controller/controller.rb +259 -0
  15. data/lib/plezi/controller/controller_class.rb +176 -0
  16. data/lib/plezi/controller/cookies.rb +40 -0
  17. data/lib/plezi/helpers.rb +60 -0
  18. data/lib/plezi/rake.rb +2 -24
  19. data/lib/plezi/render/erb.rb +34 -0
  20. data/lib/plezi/render/has_cache.rb +36 -0
  21. data/lib/plezi/render/markdown.rb +63 -0
  22. data/lib/plezi/render/render.rb +49 -0
  23. data/lib/plezi/render/sass.rb +55 -0
  24. data/lib/plezi/render/slim.rb +33 -0
  25. data/lib/plezi/router/adclient.rb +23 -0
  26. data/lib/plezi/router/assets.rb +67 -0
  27. data/lib/plezi/router/errors.rb +29 -0
  28. data/lib/plezi/router/route.rb +112 -0
  29. data/lib/plezi/router/router.rb +120 -0
  30. data/lib/plezi/version.rb +1 -1
  31. data/lib/plezi/websockets/message_dispatch.rb +91 -0
  32. data/lib/plezi/websockets/redis.rb +55 -0
  33. data/plezi.gemspec +25 -16
  34. data/resources/404.erb +5 -4
  35. data/resources/500.erb +5 -4
  36. data/resources/{500.html → 503.html} +8 -9
  37. data/resources/client.js +253 -0
  38. data/resources/config.ru +5 -36
  39. data/resources/ctrlr.rb +34 -0
  40. data/resources/gemfile +4 -0
  41. data/resources/mini_app.rb +28 -82
  42. data/resources/mini_exec +7 -0
  43. data/resources/mini_welcome_page.html +0 -0
  44. data/resources/procfile +3 -0
  45. data/resources/rakefile +4 -8
  46. data/resources/routes.rb +9 -26
  47. data/resources/{websockets.js → simple-client.js} +3 -3
  48. metadata +60 -85
  49. data/bin/plezi +0 -104
  50. data/docs/async_helpers.md +0 -245
  51. data/docs/controllers.md +0 -27
  52. data/docs/logging.md +0 -49
  53. data/docs/routes.md +0 -209
  54. data/docs/websockets.md +0 -213
  55. data/lib/plezi/builders/ac_model.rb +0 -59
  56. data/lib/plezi/builders/app_builder.rb +0 -137
  57. data/lib/plezi/builders/builder.rb +0 -43
  58. data/lib/plezi/builders/form_builder.rb +0 -27
  59. data/lib/plezi/common/api.rb +0 -92
  60. data/lib/plezi/common/cache.rb +0 -122
  61. data/lib/plezi/common/defer.rb +0 -21
  62. data/lib/plezi/common/dsl.rb +0 -94
  63. data/lib/plezi/common/redis.rb +0 -65
  64. data/lib/plezi/common/renderer.rb +0 -141
  65. data/lib/plezi/common/settings.rb +0 -52
  66. data/lib/plezi/handlers/controller_core.rb +0 -106
  67. data/lib/plezi/handlers/controller_magic.rb +0 -284
  68. data/lib/plezi/handlers/http_router.rb +0 -205
  69. data/lib/plezi/handlers/placebo.rb +0 -112
  70. data/lib/plezi/handlers/route.rb +0 -216
  71. data/lib/plezi/handlers/session.rb +0 -109
  72. data/lib/plezi/handlers/stubs.rb +0 -156
  73. data/lib/plezi/handlers/ws_identity.rb +0 -253
  74. data/lib/plezi/handlers/ws_object.rb +0 -308
  75. data/lib/plezi/helpers/http_sender.rb +0 -84
  76. data/lib/plezi/helpers/magic_helpers.rb +0 -104
  77. data/lib/plezi/helpers/mime_types.rb +0 -1995
  78. data/lib/plezi/oauth.rb +0 -5
  79. data/lib/plezi/oauth/auth_controller.rb +0 -229
  80. data/logo/dark.png +0 -0
  81. data/logo/light.png +0 -0
  82. data/logo/sign.png +0 -0
  83. data/resources/404.haml +0 -121
  84. data/resources/404.html +0 -124
  85. data/resources/404.slim +0 -120
  86. data/resources/500.haml +0 -120
  87. data/resources/500.slim +0 -120
  88. data/resources/Gemfile +0 -86
  89. data/resources/code.rb +0 -8
  90. data/resources/controller.rb +0 -142
  91. data/resources/database.yml +0 -33
  92. data/resources/db_ac_config.rb +0 -59
  93. data/resources/db_dm_config.rb +0 -51
  94. data/resources/db_sequel_config.rb +0 -33
  95. data/resources/en.yml +0 -204
  96. data/resources/haml_config.rb +0 -6
  97. data/resources/i18n_config.rb +0 -14
  98. data/resources/initialize.rb +0 -49
  99. data/resources/mini_exec.rb +0 -7
  100. data/resources/oauth_config.rb +0 -24
  101. data/resources/plezi_client.js +0 -198
  102. data/resources/plezi_websockets.html +0 -47
  103. data/resources/redis_config.rb +0 -42
  104. data/resources/slim_config.rb +0 -11
  105. data/resources/welcome_page.html +0 -272
  106. data/test/dispatch +0 -58
  107. data/test/hello_world +0 -13
  108. data/test/plezi_tests.rb +0 -581
data/lib/plezi/api.rb ADDED
@@ -0,0 +1,62 @@
1
+ require 'plezi/activation'
2
+ require 'plezi/helpers'
3
+ require 'plezi/router/router'
4
+
5
+ module Plezi
6
+ class << self
7
+ # Get / set the template folder for the {Controller#render} function.
8
+ attr_accessor :templates
9
+ # Get / set the assets folder for the `:assets` route (the root for `Plezi.route '/assets/path'`, :assets).
10
+ attr_accessor :assets
11
+ # Get / set the application name, which is used to create and identify the application's global pub/sub channel when using Redis.
12
+ attr_accessor :app_name
13
+ end
14
+ @app_name = "#{File.basename($PROGRAM_NAME, '.*')}_app"
15
+ @templates = File.expand_path(File.join(File.dirname($PROGRAM_NAME), 'views'.freeze))
16
+ @assets = File.expand_path(File.join(File.dirname($PROGRAM_NAME), 'assets'.freeze))
17
+ @plezi_autostart = nil
18
+
19
+ module_function
20
+
21
+ # Disables the autostart feature
22
+ def no_autostart
23
+ @plezi_autostart = false
24
+ end
25
+
26
+ # @private
27
+ # Allows Plezi to be used as middleware.
28
+ def new(app, *_args)
29
+ Plezi::Base::Router.new(app)
30
+ end
31
+
32
+ # Returns the Plezi Rack application
33
+ def app
34
+ no_autostart
35
+ puts "Running Plezi version: #{::Plezi::VERSION}"
36
+ Plezi::Base::Router.method :call
37
+ end
38
+
39
+ # Will add a route to the Plezi application.
40
+ #
41
+ # The order of route creation is the order of precedence.
42
+ #
43
+ # path:: the HTTP path for the route. Inline parameters and optional parameters are supported. i.e.
44
+ #
45
+ # Plezi.route '/fixed/path', controller
46
+ # Plezi.route '/fixed/path/:required_param/(:optional_param)', controller
47
+ # Plezi.route '/(:format)', /^(html|json|xml)$/ # a rewrite route, usally on top.
48
+ # Plezi.route '*', controller # catch all
49
+ #
50
+ #
51
+ # controller:: A Controller class or one of the included controllers: `false` for rewrite routes; `:client` for the Javascript Auto Dispatch client; `:assets` for a missing asset baker controller (bakes any unbaked assets into the public folder file).
52
+ def route(path, controller)
53
+ plezi_initialize
54
+ Plezi::Base::Router.route path, controller
55
+ end
56
+
57
+ # Will make a weak attempt to retrive a string representing a valid URL for the requested Controller's function.
58
+ # False positives (invalid URL strings) are possible (i.e., when requesting a URL of a method that doesn't exist).
59
+ def url_for(controller, method_sym, params = {})
60
+ Plezi::Base::Router.url_for controller, method_sym, params
61
+ end
62
+ end
@@ -0,0 +1,259 @@
1
+ require 'plezi/render/render'
2
+ require 'plezi/controller/cookies'
3
+ require 'plezi/controller/controller_class'
4
+ require 'plezi/websockets/message_dispatch'
5
+
6
+ module Plezi
7
+ # This module contains the functionality provided to any Controller class.
8
+ #
9
+ # This module will be included within every Class that is asigned to a route, providing the functionality without forcing an inheritance model.
10
+ module Controller
11
+ def self.included(base)
12
+ base.extend ::Plezi::Controller::ClassMethods
13
+ end
14
+
15
+ # A Rack::Request object for the current request.
16
+ attr_reader :request
17
+ # A Rack::Response object used for the current request.
18
+ attr_reader :response
19
+ # A union between the `request.params` and the route's inline parameters. This is different then `request.params`
20
+ attr_reader :params
21
+ # A cookie jar for both accessing and setting cookies. Unifies `request.set_cookie`, `request.delete_cookie` and `request.cookies` with a single Hash like inteface.
22
+ #
23
+ # Read a cookie:
24
+ #
25
+ # cookies["name"]
26
+ #
27
+ # Set a cookie:
28
+ #
29
+ # cookies["name"] = "value"
30
+ # cookies["name"] = {value: "value", secure: true}
31
+ #
32
+ # Delete a cookie:
33
+ #
34
+ # cookies["name"] = nil
35
+ #
36
+ attr_reader :cookies
37
+
38
+ # @private
39
+ # This function is used internally by Plezi, do not call.
40
+ def _pl_respond(request, response, params)
41
+ @request = request
42
+ @response = response
43
+ @params = params
44
+ @cookies = Cookies.new(request, response)
45
+ m = requested_method
46
+ # puts "m == #{m.nil? ? 'nil' : m.to_s}"
47
+ return _pl_ad_httpreview(__send__(m)) if m
48
+ false
49
+ end
50
+
51
+ # Returns the method that was called by the HTTP request.
52
+ #
53
+ # It's possible to override this method to change the default Controller behavior.
54
+ #
55
+ # For Websocket connections this method is most likely to return :preform_upgrade
56
+ def requested_method
57
+ params['_method'.freeze] = (params['_method'.freeze] || request.request_method.downcase).to_sym
58
+ self.class._pl_params2method(params, request.env)
59
+ end
60
+
61
+ # Renders the requested template (should be a string, subfolders are fine).
62
+ #
63
+ # Template name shouldn't include the template's extension or format - this allows for dynamic format template resolution, so that `json` and `html` requests can share the same code. i.e.
64
+ #
65
+ # Plezi.templates = "views/"
66
+ # render "users/index"
67
+ #
68
+ # Using layouts (nested templates) is easy by using a block (a little different then other frameworks):
69
+ #
70
+ # render("users/layout") { render "users/index" }
71
+ #
72
+ def render(template, &block)
73
+ frmt = params['format'.freeze] || 'html'.freeze
74
+ mime = nil
75
+ ret = ::Plezi::Renderer.render "#{File.join(::Plezi.templates, template.to_s)}.#{frmt}", binding, &block
76
+ response[Rack::CONTENT_TYPE] = mime if ret && !response.content_type && (mime = Rack::Mime.mime_type(".#{frmt}".freeze, nil))
77
+ ret
78
+ end
79
+
80
+ # Sends a block of data, setting a file name, mime type and content disposition headers when possible. This should also be a good choice when sending large amounts of data.
81
+ #
82
+ # By default, `send_data` sends the data as an attachment, unless `inline: true` was set.
83
+ #
84
+ # If a mime type is provided, it will be used to set the Content-Type header. i.e. `mime: "text/plain"`
85
+ #
86
+ # If a file name was provided, Rack will be used to find the correct mime type (unless provided). i.e. `filename: "sample.pdf"` will set the mime type to `application/pdf`
87
+ #
88
+ # Available options: `:inline` (`true` / `false`), `:filename`, `:mime`.
89
+ def send_data(data, options = {})
90
+ response.write data if data
91
+ # set headers
92
+ content_disposition = options[:inline] ? 'inline'.dup : 'attachment'.dup
93
+ content_disposition << "; filename=#{::File.basename(options[:filename])}" if options[:filename]
94
+
95
+ response['content-type'.freeze] = (options[:mime] ||= options[:filename] && Rack::Mime.mime_type(::File.extname(options[:filename])))
96
+ response['content-disposition'.freeze] = content_disposition
97
+ true
98
+ end
99
+
100
+ # Same as {#send_data}, but accepts a file name (to be opened and sent) rather then a String.
101
+ #
102
+ # See {#send_data} for available options.
103
+ def send_file(filename, options = {})
104
+ response['X-Sendfile'.freeze] = filename
105
+ options[:filename] ||= File.basename(filename)
106
+ filename = File.open(filename, 'rb'.freeze) # unless Iodine::Rack.public
107
+ send_data filename, options
108
+ end
109
+
110
+ # A shortcut for Rack's `response.redirect`.
111
+ def redirect_to(target, status = 302)
112
+ response.redirect target, status
113
+ true
114
+ end
115
+
116
+ # Returns a relative URL for the controller, placing the requested parameters in the URL (inline, where possible and as query data when not possible).
117
+ def url_for(func, params = {})
118
+ ::Plezi::Base::Router.url_for self.class, func, params
119
+ end
120
+
121
+ # A connection's Plezi ID uniquely identifies the connection across application instances, allowing it to receive and send messages using {#unicast}.
122
+ def id
123
+ @_pl_id ||= (uuid && "#{::Plezi::Base::MessageDispatch.pid}-#{uuid.to_s(16)}")
124
+ end
125
+
126
+ # @private
127
+ # This is the process specific Websocket's UUID. This function is here to protect you from yourself. Don't call it.
128
+ def uuid
129
+ defined?(super) && super
130
+ end
131
+
132
+ # Override this method to read / write cookies, perform authentication or perform validation before establishing a Websocket connecion.
133
+ #
134
+ # Return `false` or `nil` to refuse the websocket connection.
135
+ def pre_connect
136
+ true
137
+ end
138
+
139
+ # Experimental: takes a module to be used for Websocket callbacks events.
140
+ #
141
+ # This function can only be called **after** a websocket connection was established (i.e., within the `on_open` callback).
142
+ #
143
+ # This allows a module "library" to be used similar to the way "rooms" are used in node.js, so that a number of different Controllers can listen to shared events.
144
+ #
145
+ # By dynamically extending a Controller instance using a module, Websocket broadcasts will be allowed to invoke the module's functions.
146
+ #
147
+ # Notice: It is impossible to `unextend` an extended module at this time.
148
+ def extend(mod)
149
+ raise TypeError, '`mod` should be a module' unless mod.class == Module
150
+ raise "#{self} already extended by #{mod.name}" if is_a?(mod)
151
+ mod.extend ::Plezi::Controller::ClassMethods
152
+ super(mod)
153
+ _pl_ws_map.update mod._pl_ws_map
154
+ _pl_ad_map.update mod._pl_ad_map
155
+ end
156
+
157
+ # Invokes a method on the `target` websocket connection. When using Iodine, the method is invoked asynchronously.
158
+ #
159
+ # def perform_poke(target)
160
+ # unicast target, :poke, self.id
161
+ # end
162
+ # def poke(from)
163
+ # unicast from, :poke_back, self.id
164
+ # end
165
+ # def poke_back(from)
166
+ # puts "#{from} is available"
167
+ # end
168
+ #
169
+ # Methods invoked using {unicast}, {broadcast} or {multicast} will quitely fail if the connection was lost, the requested method is undefined or the 'target' was invalid.
170
+ def unicast(target, event_method, *args)
171
+ ::Plezi::Base::MessageDispatch.unicast(id ? self : self.class, target, event_method, args)
172
+ end
173
+
174
+ # Invokes a method on every websocket connection that belongs to this Controller / Type. When using Iodine, the method is invoked asynchronously.
175
+ #
176
+ # self.broadcast :my_method, "argument 1", "argument 2", 3
177
+ #
178
+ # Methods invoked using {unicast}, {broadcast} or {multicast} will quitely fail if the connection was lost, the requested method is undefined or the 'target' was invalid.
179
+ def broadcast(event_method, *args)
180
+ ::Plezi::Base::MessageDispatch.broadcast(id ? self : self.class, event_method, args)
181
+ end
182
+
183
+ # Invokes a method on every websocket connection in the application.
184
+ #
185
+ # self.multicast :my_method, "argument 1", "argument 2", 3
186
+ #
187
+ # Methods invoked using {unicast}, {broadcast} or {multicast} will quitely fail if the connection was lost, the requested method is undefined or the 'target' was invalid.
188
+ def multicast(event_method, *args)
189
+ ::Plezi::Base::MessageDispatch.multicast(id ? self : self.class, event_method, args)
190
+ end
191
+
192
+ # @private
193
+ # This function is used internally by Plezi, do not call.
194
+ def _pl_ws_map
195
+ @_pl_ws_map ||= self.class._pl_ws_map.dup
196
+ end
197
+
198
+ # @private
199
+ # This function is used internally by Plezi, do not call.
200
+ def _pl_ad_map
201
+ @_pl_ad_map ||= self.class._pl_ad_map.dup
202
+ end
203
+
204
+ # @private
205
+ # This function is used internally by Plezi, for Auto-Dispatch support do not call.
206
+ def on_message(data)
207
+ json = nil
208
+ begin
209
+ json = JSON.parse(data, symbolize_names: true)
210
+ rescue
211
+ puts 'AutoDispatch Warnnig: Received non-JSON message. Closing Connection.'
212
+ close
213
+ return
214
+ end
215
+ envt = _pl_ad_map[json[:event]] || _pl_ad_map[:unknown]
216
+ if json[:event].nil? || envt.nil?
217
+ puts _pl_ad_map
218
+ puts "AutoDispatch Warnnig: JSON missing/invalid `event` name '#{json[:event]}' for class #{self.class.name}. Closing Connection."
219
+ close
220
+ end
221
+ write("{\"event\":\"_ack_\",\"_EID_\":#{json[:_EID_].to_json}}") if json[:_EID_]
222
+ _pl_ad_review __send__(envt, json)
223
+ end
224
+
225
+ # @private
226
+ # This function is used internally by Plezi, do not call.
227
+ def _pl_ad_review(data)
228
+ case data
229
+ when Hash
230
+ write data.to_json
231
+ when String
232
+ write data
233
+ # when Array
234
+ # write ret
235
+ end if self.class._pl_is_ad?
236
+ data
237
+ end
238
+
239
+ # @private
240
+ # This function is used internally by Plezi, do not call.
241
+ def _pl_ad_httpreview(data)
242
+ data = data.to_json if self.class._pl_is_ad? && data.is_a?(Hash)
243
+ data
244
+ end
245
+
246
+ private
247
+
248
+ # @private
249
+ # This function is used internally by Plezi, do not call.
250
+ def preform_upgrade
251
+ return false unless pre_connect
252
+ request.env['upgrade.websocket'.freeze] = self
253
+ @params = @params.dup # disable memory saving (used a single object per thread)
254
+ @_pl_ws_map = self.class._pl_ws_map.dup
255
+ @_pl_ad_map = self.class._pl_ad_map.dup
256
+ true
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,176 @@
1
+ require 'json'
2
+ module Plezi
3
+ module Controller
4
+ module ClassMethods
5
+ # A Ruby callback used to initialize class data for new Controllers.
6
+ def self.extended(base)
7
+ base._pl_init_class_data
8
+ end
9
+
10
+ # Returns a relative URL for the controller, placing the requested parameters in the URL (inline, where possible and as query data when not possible).
11
+ def url_for(func, params = {})
12
+ ::Plezi::Base::Router.url_for self, func, params
13
+ end
14
+
15
+ # Invokes a method on the `target` websocket connection. When using Iodine, the method is invoked asynchronously.
16
+ #
17
+ # self.unicast target, :my_method, "argument 1"
18
+ #
19
+ # Methods invoked using {unicast}, {broadcast} or {multicast} will quitely fail if the connection was lost, the requested method is undefined or the 'target' was invalid.
20
+ def unicast(target, event_method, *args)
21
+ ::Plezi::Base::MessageDispatch.unicast(self, target, event_method, args)
22
+ end
23
+
24
+ # Invokes a method on every websocket connection that belongs to this Controller / Type. When using Iodine, the method is invoked asynchronously.
25
+ #
26
+ # self.broadcast :my_method, "argument 1", "argument 2", 3
27
+ #
28
+ # Methods invoked using {unicast}, {broadcast} or {multicast} will quitely fail if the connection was lost, the requested method is undefined or the 'target' was invalid.
29
+ def broadcast(event_method, *args)
30
+ ::Plezi::Base::MessageDispatch.broadcast(self, event_method, args)
31
+ end
32
+
33
+ # Invokes a method on every websocket connection in the application.
34
+ #
35
+ # self.multicast :my_method, "argument 1", "argument 2", 3
36
+ #
37
+ # Methods invoked using {unicast}, {broadcast} or {multicast} will quitely fail if the connection was lost, the requested method is undefined or the 'target' was invalid.
38
+ def multicast(event_method, *args)
39
+ ::Plezi::Base::MessageDispatch.multicast(self, event_method, args)
40
+ end
41
+
42
+ # @private
43
+ # This is used internally by Plezi, do not use.
44
+ RESERVED_METHODS = [:delete, :create, :update, :new, :show, :pre_connect, :on_open, :on_close, :on_shutdown, :on_message].freeze
45
+ # @private
46
+ # This function is used internally by Plezi, do not call.
47
+ def _pl_get_map
48
+ return @_pl_get_map if @_pl_get_map
49
+
50
+ @_pl_get_map = {}
51
+ mths = public_instance_methods false
52
+ mths.delete_if { |m| m.to_s[0] == '_' || !(-1..0).cover?(instance_method(m).arity) }
53
+ @_pl_get_map[nil] = :index if mths.include?(:index)
54
+ RESERVED_METHODS.each { |m| mths.delete m }
55
+ mths.each { |m| @_pl_get_map[m.to_s.freeze] = m }
56
+
57
+ @_pl_get_map
58
+ end
59
+
60
+ # @private
61
+ # This function is used internally by Plezi, do not call.
62
+ def _pl_has_delete
63
+ @_pl_has_delete
64
+ end
65
+
66
+ # @private
67
+ # This function is used internally by Plezi, do not call.
68
+ def _pl_has_update
69
+ @_pl_has_update
70
+ end
71
+
72
+ # @private
73
+ # This function is used internally by Plezi, do not call.
74
+ def _pl_has_create
75
+ @_pl_has_create
76
+ end
77
+
78
+ # @private
79
+ # This function is used internally by Plezi, do not call.
80
+ def _pl_has_new
81
+ @_pl_has_new
82
+ end
83
+
84
+ # @private
85
+ # This function is used internally by Plezi, do not call.
86
+ def _pl_has_show
87
+ @_pl_has_show
88
+ end
89
+
90
+ # @private
91
+ # This function is used internally by Plezi, do not call.
92
+ def _pl_is_websocket?
93
+ @_pl_is_websocket
94
+ end
95
+
96
+ # @private
97
+ # This function is used internally by Plezi, do not call.
98
+ def _pl_is_ad?
99
+ @auto_dispatch
100
+ end
101
+
102
+ # @private
103
+ # This function is used internally by Plezi, do not call.
104
+ def _pl_ws_map
105
+ return @_pl_ws_map if @_pl_ws_map
106
+
107
+ @_pl_ws_map = {}
108
+ mths = instance_methods false
109
+ mths.delete :index
110
+ RESERVED_METHODS.each { |m| mths.delete m }
111
+ mths.each { |m| @_pl_ws_map[m.to_s.freeze] = m; @_pl_ws_map[m] = m }
112
+
113
+ @_pl_ws_map
114
+ end
115
+
116
+ # @private
117
+ # This function is used internally by Plezi, do not call.
118
+ def _pl_ad_map
119
+ return @_pl_ad_map if @_pl_ad_map
120
+
121
+ @_pl_ad_map = {}
122
+ mths = public_instance_methods false
123
+ mths.delete_if { |m| m.to_s[0] == '_' || ![-2, -1, 1].freeze.include?(instance_method(m).arity) }
124
+ mths.delete :index
125
+ RESERVED_METHODS.each { |m| mths.delete m }
126
+ mths.each { |m| @_pl_ad_map[m.to_s.freeze] = m; @_pl_ad_map[m] = m }
127
+
128
+ @_pl_ad_map
129
+ end
130
+
131
+ # @private
132
+ # This function is used internally by Plezi, do not call.
133
+ def _pl_params2method(params, env)
134
+ par_id = params['id'.freeze]
135
+ meth_id = _pl_get_map[par_id]
136
+ return meth_id if par_id && meth_id
137
+ # puts "matching against #{params}"
138
+ case params['_method'.freeze]
139
+ when :get # since this is common, it's pushed upwards.
140
+ if env['HTTP_UPGRADE'.freeze] && _pl_is_websocket? && env['HTTP_UPGRADE'.freeze].downcase.start_with?('websocket'.freeze)
141
+ @_pl_init_global_data ||= ::Plezi.plezi_initialize # wake up pub/sub drivers in case of `fork`
142
+ return :preform_upgrade
143
+ end
144
+ return :new if _pl_has_new && par_id == 'new'.freeze
145
+ return meth_id || (_pl_has_show && :show) || nil
146
+ when :put, :patch
147
+ return :create if _pl_has_create && (par_id.nil? || par_id == 'new'.freeze)
148
+ return :update if _pl_has_update
149
+ when :post
150
+ return :create if _pl_has_create
151
+ when :delete
152
+ return :delete if _pl_has_delete
153
+ end
154
+ meth_id || (_pl_has_show && :show) || nil
155
+ end
156
+
157
+ # @private
158
+ # This function is used internally by Plezi, do not call.
159
+ def _pl_init_class_data
160
+ @auto_dispatch ||= nil
161
+ @_pl_get_map = nil
162
+ @_pl_ad_map = nil
163
+ @_pl_ws_map = nil
164
+ @_pl_has_show = public_instance_methods(false).include?(:show)
165
+ @_pl_has_new = public_instance_methods(false).include?(:new)
166
+ @_pl_has_create = public_instance_methods(false).include?(:create)
167
+ @_pl_has_update = public_instance_methods(false).include?(:update)
168
+ @_pl_has_delete = public_instance_methods(false).include?(:delete)
169
+ @_pl_is_websocket = (instance_variable_defined?(:@auto_dispatch) && instance_variable_get(:@auto_dispatch)) || instance_methods(false).include?(:on_message)
170
+ _pl_get_map
171
+ _pl_ad_map
172
+ _pl_ws_map
173
+ end
174
+ end
175
+ end
176
+ end