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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/LICENSE.txt +17 -18
- data/README.md +54 -698
- data/Rakefile +7 -4
- data/bin/config.ru +22 -0
- data/{test → bin}/console +4 -6
- data/bin/hello_world +52 -0
- data/bin/setup +8 -0
- data/exe/plezi +145 -0
- data/lib/plezi.rb +24 -137
- data/lib/plezi/activation.rb +28 -0
- data/lib/plezi/api.rb +62 -0
- data/lib/plezi/controller/controller.rb +259 -0
- data/lib/plezi/controller/controller_class.rb +176 -0
- data/lib/plezi/controller/cookies.rb +40 -0
- data/lib/plezi/helpers.rb +60 -0
- data/lib/plezi/rake.rb +2 -24
- data/lib/plezi/render/erb.rb +34 -0
- data/lib/plezi/render/has_cache.rb +36 -0
- data/lib/plezi/render/markdown.rb +63 -0
- data/lib/plezi/render/render.rb +49 -0
- data/lib/plezi/render/sass.rb +55 -0
- data/lib/plezi/render/slim.rb +33 -0
- data/lib/plezi/router/adclient.rb +23 -0
- data/lib/plezi/router/assets.rb +67 -0
- data/lib/plezi/router/errors.rb +29 -0
- data/lib/plezi/router/route.rb +112 -0
- data/lib/plezi/router/router.rb +120 -0
- data/lib/plezi/version.rb +1 -1
- data/lib/plezi/websockets/message_dispatch.rb +91 -0
- data/lib/plezi/websockets/redis.rb +55 -0
- data/plezi.gemspec +25 -16
- data/resources/404.erb +5 -4
- data/resources/500.erb +5 -4
- data/resources/{500.html → 503.html} +8 -9
- data/resources/client.js +253 -0
- data/resources/config.ru +5 -36
- data/resources/ctrlr.rb +34 -0
- data/resources/gemfile +4 -0
- data/resources/mini_app.rb +28 -82
- data/resources/mini_exec +7 -0
- data/resources/mini_welcome_page.html +0 -0
- data/resources/procfile +3 -0
- data/resources/rakefile +4 -8
- data/resources/routes.rb +9 -26
- data/resources/{websockets.js → simple-client.js} +3 -3
- metadata +60 -85
- data/bin/plezi +0 -104
- data/docs/async_helpers.md +0 -245
- data/docs/controllers.md +0 -27
- data/docs/logging.md +0 -49
- data/docs/routes.md +0 -209
- data/docs/websockets.md +0 -213
- data/lib/plezi/builders/ac_model.rb +0 -59
- data/lib/plezi/builders/app_builder.rb +0 -137
- data/lib/plezi/builders/builder.rb +0 -43
- data/lib/plezi/builders/form_builder.rb +0 -27
- data/lib/plezi/common/api.rb +0 -92
- data/lib/plezi/common/cache.rb +0 -122
- data/lib/plezi/common/defer.rb +0 -21
- data/lib/plezi/common/dsl.rb +0 -94
- data/lib/plezi/common/redis.rb +0 -65
- data/lib/plezi/common/renderer.rb +0 -141
- data/lib/plezi/common/settings.rb +0 -52
- data/lib/plezi/handlers/controller_core.rb +0 -106
- data/lib/plezi/handlers/controller_magic.rb +0 -284
- data/lib/plezi/handlers/http_router.rb +0 -205
- data/lib/plezi/handlers/placebo.rb +0 -112
- data/lib/plezi/handlers/route.rb +0 -216
- data/lib/plezi/handlers/session.rb +0 -109
- data/lib/plezi/handlers/stubs.rb +0 -156
- data/lib/plezi/handlers/ws_identity.rb +0 -253
- data/lib/plezi/handlers/ws_object.rb +0 -308
- data/lib/plezi/helpers/http_sender.rb +0 -84
- data/lib/plezi/helpers/magic_helpers.rb +0 -104
- data/lib/plezi/helpers/mime_types.rb +0 -1995
- data/lib/plezi/oauth.rb +0 -5
- data/lib/plezi/oauth/auth_controller.rb +0 -229
- data/logo/dark.png +0 -0
- data/logo/light.png +0 -0
- data/logo/sign.png +0 -0
- data/resources/404.haml +0 -121
- data/resources/404.html +0 -124
- data/resources/404.slim +0 -120
- data/resources/500.haml +0 -120
- data/resources/500.slim +0 -120
- data/resources/Gemfile +0 -86
- data/resources/code.rb +0 -8
- data/resources/controller.rb +0 -142
- data/resources/database.yml +0 -33
- data/resources/db_ac_config.rb +0 -59
- data/resources/db_dm_config.rb +0 -51
- data/resources/db_sequel_config.rb +0 -33
- data/resources/en.yml +0 -204
- data/resources/haml_config.rb +0 -6
- data/resources/i18n_config.rb +0 -14
- data/resources/initialize.rb +0 -49
- data/resources/mini_exec.rb +0 -7
- data/resources/oauth_config.rb +0 -24
- data/resources/plezi_client.js +0 -198
- data/resources/plezi_websockets.html +0 -47
- data/resources/redis_config.rb +0 -42
- data/resources/slim_config.rb +0 -11
- data/resources/welcome_page.html +0 -272
- data/test/dispatch +0 -58
- data/test/hello_world +0 -13
- 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
|