plezi 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/bin/plezi +1 -1
- data/lib/plezi.rb +1 -1
- data/lib/plezi/base/cache.rb +7 -0
- data/lib/plezi/base/services.rb +1 -1
- data/lib/plezi/handlers/controller_magic.rb +63 -22
- data/lib/plezi/handlers/http_host.rb +1 -1
- data/lib/plezi/handlers/route.rb +116 -25
- data/lib/plezi/server/helpers/http.rb +3 -0
- data/lib/plezi/server/protocols/http_response.rb +1 -1
- data/lib/plezi/version.rb +1 -1
- data/plezi.gemspec +4 -3
- data/resources/Gemfile +11 -8
- data/resources/rakefile +12 -0
- data/resources/routes.rb +1 -1
- metadata +9 -12
- data/resources/rakefile.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2c1ce05a4f21add0356e4feb915c3f559ac29b7
|
4
|
+
data.tar.gz: 949097175113449016158060ae646d3b94124469
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60e319eb716785ff1363ded7fa6aa8a2d8e81da7239598c3ce17bab2bcb996ecda364b15ccac56b0bf1f66c260b1018a4cf04cd1249647220dd113b17868247d
|
7
|
+
data.tar.gz: 694bc16bb7c79cc83a90e77a6ef0880769e1a22d70d48656367592731a6aaa0f0ad4a5d1048691fba23c5ed66283403c18ade96639bfe96ce9fe11d2651cace8
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,24 @@
|
|
2
2
|
|
3
3
|
***
|
4
4
|
|
5
|
+
Change log v.0.7.3
|
6
|
+
|
7
|
+
**major fix**: Fixed a conflict in the controller namespaces and caching system, which caused routing and Redis connection errors. The errors were resolved by moving the caching to the Framework's global caching system.
|
8
|
+
|
9
|
+
**fix + feature**: It is now possible to dynamically add or remove routes from existing controllers. As you know, Plezi controllers behave like "smart folders" and their public methods are automatically published as routes. But - That routing tables is cached. Now the cache is automatically reset whenever a method is added or removed from the controller, or, you can reset the controller's routing cache by calling the controller class method #reset_routing_cache. This allows you to dynamically add or remove routes from existing controllers.
|
10
|
+
|
11
|
+
**fix**: fixed as issue with utf-8 data in the cookie and flash data, where utf-8 data wasn't encoded properly as an ASCII string before being sent in the HTTP headers.
|
12
|
+
|
13
|
+
**fix**: fixed an error with catch-all and re-write routes that caused some routes to fail or that rewrote routes that should not have been re-written. This bug was introduces when re-write routes conflicted with similar actual routes (such as '/en' conflicting with '/entance', the 'en' would be removed although that was not the intention).
|
14
|
+
|
15
|
+
**fix**: fixed the raketasks... which do nothing just yet.
|
16
|
+
|
17
|
+
**fix**: fixed the 404 error for the slim template. It now has access to the request object, so that it is possible to dynamically show the requested path or other parameters and cookies.
|
18
|
+
|
19
|
+
**fix**: fixed the timing of the first service start up logging to log only once services actually start.
|
20
|
+
|
21
|
+
***
|
22
|
+
|
5
23
|
Change log v.0.7.2
|
6
24
|
|
7
25
|
**fix**: fixed the template's Proc file for Heroku integration. There was a issue due to the main app file name convention change (the app file no longer has the .rb extention, and now the Proc file correctly reflects that change).
|
data/bin/plezi
CHANGED
@@ -54,7 +54,7 @@ class AppTemplate
|
|
54
54
|
# app core files.
|
55
55
|
app_tree["environment.rb"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"environment.rb"), __FILE__)
|
56
56
|
app_tree["routes.rb"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"routes.rb"), __FILE__)
|
57
|
-
app_tree["rakefile
|
57
|
+
app_tree["rakefile"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"rakefile"), __FILE__)
|
58
58
|
app_tree["Procfile"] ||= ""
|
59
59
|
app_tree["Procfile"] << "\nweb: bundle exec ./#{ARGV[1]} -p $PORT\n"
|
60
60
|
app_tree["Gemfile"] ||= IO.read ::File.expand_path(File.join("..", "..", "resources" ,"Gemfile"), __FILE__)
|
data/lib/plezi.rb
CHANGED
data/lib/plezi/base/cache.rb
CHANGED
@@ -49,16 +49,23 @@ module Plezi
|
|
49
49
|
end
|
50
50
|
data
|
51
51
|
end
|
52
|
+
|
52
53
|
# places data into the cache, under an identifier ( file name ).
|
53
54
|
def cache_data filename, data, mtime = Time.now
|
54
55
|
LOCK.synchronize { CACHE_STORE[filename] = CacheObject.new( data, mtime ) }
|
55
56
|
data
|
56
57
|
end
|
58
|
+
|
57
59
|
# Get data from the cache. will throw an exception if there is no data in the cache.
|
58
60
|
def get_cached filename
|
59
61
|
CACHE_STORE[filename].data # if CACHE_STORE[filename]
|
60
62
|
end
|
61
63
|
|
64
|
+
# Remove data from the cache, if it exists.
|
65
|
+
def clear_cached filename
|
66
|
+
LOCK.synchronize { CACHE_STORE.delete filename } # if CACHE_STORE[filename]
|
67
|
+
end
|
68
|
+
|
62
69
|
# returns true if the filename is cached.
|
63
70
|
def cached? filename
|
64
71
|
!CACHE_STORE[filename].nil?
|
data/lib/plezi/base/services.rb
CHANGED
@@ -44,7 +44,7 @@ module Plezi
|
|
44
44
|
service = nil
|
45
45
|
service = parameters[:service_type].create_service(port, parameters) unless ( defined?(BUILDING_PLEZI_TEMPLATE) || defined?(PLEZI_ON_RACK) )
|
46
46
|
S_LOCKER.synchronize {SERVICES[service] = parameters}
|
47
|
-
info "Started listening on port #{port}."
|
47
|
+
Plezi.callback Plezi, :info, "Started listening on port #{port}."
|
48
48
|
true
|
49
49
|
end
|
50
50
|
|
@@ -193,7 +193,7 @@ module Plezi
|
|
193
193
|
# set DELETE method if simulated
|
194
194
|
request.request_method = 'DELETE' if params[:_method].to_s.downcase == 'delete'
|
195
195
|
# respond to special :id routing
|
196
|
-
return params[:id].to_sym if params[:id] && available_public_methods.include?(params[:id].to_sym)
|
196
|
+
return params[:id].to_sym if params[:id] && self.class.available_public_methods.include?(params[:id].to_sym)
|
197
197
|
#review general cases
|
198
198
|
case request.request_method
|
199
199
|
when 'GET', 'HEAD'
|
@@ -207,18 +207,6 @@ module Plezi
|
|
207
207
|
false
|
208
208
|
end
|
209
209
|
|
210
|
-
# lists the available methods that will be exposed to HTTP requests
|
211
|
-
def available_public_methods
|
212
|
-
# set class global to improve performance while checking for supported methods
|
213
|
-
@@___available_public_methods___ ||= available_routing_methods - [:before, :after, :save, :show, :update, :delete, :initialize, :on_message, :pre_connect, :on_connect, :on_disconnect]
|
214
|
-
end
|
215
|
-
|
216
|
-
# lists the available methods that will be exposed to the HTTP router
|
217
|
-
def available_routing_methods
|
218
|
-
# set class global to improve performance while checking for supported methods
|
219
|
-
@@___available_routing_methods___ ||= (((self.class.public_instance_methods - Object.public_instance_methods) - Plezi::ControllerMagic::InstanceMethods.instance_methods).delete_if {|m| m.to_s[0] == '_'})
|
220
|
-
end
|
221
|
-
|
222
210
|
## WebSockets Magic
|
223
211
|
|
224
212
|
# WebSockets.
|
@@ -261,7 +249,6 @@ module Plezi
|
|
261
249
|
# the method will be called asynchrnously for each sibling instance of this Controller class.
|
262
250
|
def collect method_name, *args, &block
|
263
251
|
return Plezi.callback(self, :collect, *args, &block) if block
|
264
|
-
|
265
252
|
r = []
|
266
253
|
ObjectSpace.each_object(self.class) { |controller| r << controller.method(method_name).call(*args) if controller.accepts_broadcast? && (controller.object_id != self.object_id) }
|
267
254
|
return r
|
@@ -280,21 +267,75 @@ module Plezi
|
|
280
267
|
module ClassMethods
|
281
268
|
public
|
282
269
|
|
270
|
+
# lists the available methods that will be exposed to HTTP requests
|
271
|
+
def available_public_methods
|
272
|
+
# set class global to improve performance while checking for supported methods
|
273
|
+
Plezi.cached?(self.superclass.name + "_p&rt") ? Plezi.get_cached(self.superclass.name + "_p&rt") : Plezi.cache_data(self.superclass.name + "_p&rt", available_routing_methods - [:before, :after, :save, :show, :update, :delete, :initialize, :on_message, :pre_connect, :on_connect, :on_disconnect])
|
274
|
+
end
|
275
|
+
|
276
|
+
# lists the available methods that will be exposed to the HTTP router
|
277
|
+
def available_routing_methods
|
278
|
+
# set class global to improve performance while checking for supported methods
|
279
|
+
Plezi.cached?(self.superclass.name + "_r&rt") ? Plezi.get_cached(self.superclass.name + "_r&rt") : Plezi.cache_data(self.superclass.name + "_r&rt", (((public_instance_methods - Object.public_instance_methods) - Plezi::ControllerMagic::InstanceMethods.instance_methods).delete_if {|m| m.to_s[0] == '_'}) )
|
280
|
+
end
|
281
|
+
|
282
|
+
# resets this controller's router, to allow for dynamic changes
|
283
|
+
def reset_routing_cache
|
284
|
+
Plezi.clear_cached(self.superclass.name + "_p&rt")
|
285
|
+
Plezi.clear_cached(self.superclass.name + "_r&rt")
|
286
|
+
available_routing_methods
|
287
|
+
available_public_methods
|
288
|
+
end
|
289
|
+
|
290
|
+
# a callback that resets the class router whenever a method (a potential route) is added
|
291
|
+
def method_added(id)
|
292
|
+
reset_routing_cache
|
293
|
+
end
|
294
|
+
# a callback that resets the class router whenever a method (a potential route) is removed
|
295
|
+
def method_removed(id)
|
296
|
+
reset_routing_cache
|
297
|
+
end
|
298
|
+
# a callback that resets the class router whenever a method (a potential route) is undefined (using #undef_method).
|
299
|
+
def method_undefined(id)
|
300
|
+
reset_routing_cache
|
301
|
+
end
|
302
|
+
|
283
303
|
# reviews the Redis connection, sets it up if it's missing and returns the Redis connection.
|
284
304
|
#
|
285
305
|
# todo: review thread status? (incase an exception killed it)
|
286
306
|
def redis_connection
|
307
|
+
# return false unless defined?(Redis) && ENV['PL_REDIS_URL']
|
308
|
+
# return @@redis if defined?(@@redis_sub_thread) && @@redis
|
309
|
+
# @@redis_uri ||= URI.parse(ENV['PL_REDIS_URL'])
|
310
|
+
# @@redis ||= Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password)
|
311
|
+
# @@redis_sub_thread = Thread.new do
|
312
|
+
# begin
|
313
|
+
# Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password).subscribe(redis_channel_name) do |on|
|
314
|
+
# on.message do |channel, msg|
|
315
|
+
# args = JSON.parse(msg)
|
316
|
+
# params = args.shift
|
317
|
+
# __inner_process_broadcast params['_pl_ignore_object'], params['_pl_method_broadcasted'].to_sym, args
|
318
|
+
# end
|
319
|
+
# end
|
320
|
+
# rescue Exception => e
|
321
|
+
# Plezi.error e
|
322
|
+
# retry
|
323
|
+
# end
|
324
|
+
# end
|
325
|
+
# raise "Redis connction failed for: #{ENV['PL_REDIS_URL']}" unless @@redis
|
326
|
+
# @@redis
|
287
327
|
return false unless defined?(Redis) && ENV['PL_REDIS_URL']
|
288
|
-
return
|
328
|
+
return Plezi.get_cached(self.superclass.name + "_b") if Plezi.cached?(self.superclass.name + "_b")
|
289
329
|
@@redis_uri ||= URI.parse(ENV['PL_REDIS_URL'])
|
290
|
-
|
291
|
-
|
330
|
+
Plezi.cache_data self.superclass.name + "_b", Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password)
|
331
|
+
raise "Redis connction failed for: #{ENV['PL_REDIS_URL']}" unless Plezi.cached?(self.superclass.name + "_b")
|
332
|
+
t = Thread.new do
|
292
333
|
begin
|
293
334
|
Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password).subscribe(redis_channel_name) do |on|
|
294
335
|
on.message do |channel, msg|
|
295
336
|
args = JSON.parse(msg)
|
296
337
|
params = args.shift
|
297
|
-
__inner_process_broadcast params['
|
338
|
+
__inner_process_broadcast params['_pl_ignore_object'], params['_pl_method_broadcasted'].to_sym, args
|
298
339
|
end
|
299
340
|
end
|
300
341
|
rescue Exception => e
|
@@ -302,13 +343,13 @@ module Plezi
|
|
302
343
|
retry
|
303
344
|
end
|
304
345
|
end
|
305
|
-
|
306
|
-
|
346
|
+
Plezi.cache_data self.superclass.name + "_t", t
|
347
|
+
Plezi.get_cached(self.superclass.name + "_b")
|
307
348
|
end
|
308
349
|
|
309
350
|
# returns a Redis channel name for this controller.
|
310
351
|
def redis_channel_name
|
311
|
-
self.name.to_s
|
352
|
+
self.superclass.name.to_s
|
312
353
|
end
|
313
354
|
|
314
355
|
# broadcasts messages (methods) for this process
|
@@ -321,7 +362,7 @@ module Plezi
|
|
321
362
|
return false unless redis_connection
|
322
363
|
raise "Radis broadcasts cannot accept blocks (no inter-process callbacks of memory sharing)!" if block
|
323
364
|
# raise "Radis broadcasts accept only one paramater, which is an optional Hash (no inter-process memory sharing)" if args.length > 1 || (args[0] && !args[0].is_a?(Hash))
|
324
|
-
args.unshift ({
|
365
|
+
args.unshift ({_pl_method_broadcasted: method_name, _pl_ignore_object: ignore})
|
325
366
|
redis_connection.publish(redis_channel_name, args.to_json )
|
326
367
|
true
|
327
368
|
end
|
@@ -98,7 +98,7 @@ module Plezi
|
|
98
98
|
if params[:root]
|
99
99
|
if defined?(::Slim) && Plezi.file_exists?(File.join(params[:root], "#{code}.slim"))
|
100
100
|
Plezi.cache_data File.join(params[:root], "#{code}.slim"), Slim::Template.new( File.join( params[:root], "#{code}.slim" ) ) unless Plezi.cached? File.join(params[:root], "#{code}.slim")
|
101
|
-
return send_raw_data request, Plezi.get_cached( File.join(params[:root], "#{code}.slim") ).render( self ), 'text/html', code, headers
|
101
|
+
return send_raw_data request, Plezi.get_cached( File.join(params[:root], "#{code}.slim") ).render( self, request: request ), 'text/html', code, headers
|
102
102
|
elsif defined?(::Haml) && Plezi.file_exists?(File.join(params[:root], "#{code}.haml"))
|
103
103
|
Plezi.cache_data File.join(params[:root], "#{code}.haml"), Haml::Engine.new( IO.read( File.join( params[:root], "#{code}.haml" ) ) ) unless Plezi.cached? File.join(params[:root], "#{code}.haml")
|
104
104
|
return send_raw_data request, Plezi.get_cached( File.join(params[:root], "#{code}.haml") ).render( self ), 'text/html', code, headers
|
data/lib/plezi/handlers/route.rb
CHANGED
@@ -17,20 +17,23 @@ module Plezi
|
|
17
17
|
fill_parameters = match request.path
|
18
18
|
return false unless fill_parameters
|
19
19
|
fill_parameters.each {|k,v| HTTP.add_param_to_hash k, v, request.params }
|
20
|
+
ret = false
|
20
21
|
response = HTTPResponse.new request
|
21
22
|
if controller
|
22
23
|
ret = controller.new(request, response, params)._route_path_to_methods_and_set_the_response_
|
23
|
-
response.try_finish if ret
|
24
|
-
return ret
|
25
24
|
elsif proc
|
26
25
|
ret = proc.call(request, response)
|
27
26
|
# response << ret if ret.is_a?(String)
|
28
|
-
response.try_finish if ret
|
29
|
-
return ret
|
30
27
|
elsif controller == false
|
31
|
-
request.path = path.match(request.path).to_a.last
|
28
|
+
request.path = path.match(request.path).to_a.last.to_s
|
29
|
+
return false
|
32
30
|
end
|
33
|
-
|
31
|
+
unless ret
|
32
|
+
request.params.delete :id if fill_parameters['id']
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
response.try_finish
|
36
|
+
return ret
|
34
37
|
end
|
35
38
|
|
36
39
|
# handles Rack requests (dresses up as Rack).
|
@@ -111,10 +114,10 @@ module Plezi
|
|
111
114
|
# prep path string and split it where the '/' charected is unescaped.
|
112
115
|
path = path.gsub(/(^\/)|(\/$)/, '').gsub(/([^\\])\//, '\1 - /').split ' - /'
|
113
116
|
@path_sections = path.length
|
114
|
-
path.each do |section|
|
117
|
+
path.each.with_index do |section, section_index|
|
115
118
|
if section == '*'
|
116
119
|
# create catch all
|
117
|
-
@path << "(.*)"
|
120
|
+
section_index == 0 ? (@path << "(.*)") : (@path << "(\\/.*)?")
|
118
121
|
# finish
|
119
122
|
@path = /#{@path}$/
|
120
123
|
return
|
@@ -168,7 +171,7 @@ module Plezi
|
|
168
171
|
# this performs the match and assigns the parameters, if required.
|
169
172
|
def match path
|
170
173
|
hash = {}
|
171
|
-
m = nil
|
174
|
+
# m = nil
|
172
175
|
# unless @fill_parameters.values.include?("format")
|
173
176
|
# if (m = path.match /([^\.]*)\.([^\.\/]+)$/)
|
174
177
|
# HTTP.add_param_to_hash 'format', m[2], hash
|
@@ -201,6 +204,10 @@ module Plezi
|
|
201
204
|
controller.instance_eval { include Plezi::ControllerMagic }
|
202
205
|
ret = Class.new(controller) do
|
203
206
|
|
207
|
+
def name
|
208
|
+
new_class_name
|
209
|
+
end
|
210
|
+
|
204
211
|
def initialize request, response, host_params
|
205
212
|
@request, @params, @flash, @host_params = request, request.params, response.flash, host_params
|
206
213
|
@response = response
|
@@ -215,22 +222,6 @@ module Plezi
|
|
215
222
|
super()
|
216
223
|
end
|
217
224
|
|
218
|
-
def _route_path_to_methods_and_set_the_response_
|
219
|
-
#run :before filter
|
220
|
-
return false if available_routing_methods.include?(:before) && before == false
|
221
|
-
#check request is valid and call requested method
|
222
|
-
ret = requested_method
|
223
|
-
return false unless available_routing_methods.include?(ret)
|
224
|
-
return false unless (ret = self.method(ret).call)
|
225
|
-
#run :after filter
|
226
|
-
return false if available_routing_methods.include?(:after) && after == false
|
227
|
-
# review returned type for adding String to response
|
228
|
-
if ret.is_a?(String)
|
229
|
-
response << ret
|
230
|
-
response['content-length'] = ret.bytesize if response.body.empty? && !response.headers_sent?
|
231
|
-
end
|
232
|
-
return true
|
233
|
-
end
|
234
225
|
# WebSockets.
|
235
226
|
#
|
236
227
|
# this method handles the protocol and handler transition between the HTTP connection
|
@@ -262,8 +253,108 @@ module Plezi
|
|
262
253
|
@_accepts_broadcast = false
|
263
254
|
super if defined? super
|
264
255
|
end
|
256
|
+
|
257
|
+
# Inner Routing
|
258
|
+
#
|
259
|
+
#
|
260
|
+
def _route_path_to_methods_and_set_the_response_
|
261
|
+
#run :before filter
|
262
|
+
return false if self.class.available_routing_methods.include?(:before) && self.before == false
|
263
|
+
#check request is valid and call requested method
|
264
|
+
ret = requested_method
|
265
|
+
return false unless self.class.available_routing_methods.include?(ret)
|
266
|
+
return false unless (ret = self.method(ret).call)
|
267
|
+
#run :after filter
|
268
|
+
return false if self.class.available_routing_methods.include?(:after) && self.after == false
|
269
|
+
# review returned type for adding String to response
|
270
|
+
if ret.is_a?(String)
|
271
|
+
response << ret
|
272
|
+
response['content-length'] = ret.bytesize if response.body.empty? && !response.headers_sent?
|
273
|
+
end
|
274
|
+
return true
|
275
|
+
end
|
276
|
+
# a callback that resets the class router whenever a method (a potential route) is added
|
277
|
+
def self.method_added(id)
|
278
|
+
reset_routing_cache
|
279
|
+
end
|
280
|
+
# a callback that resets the class router whenever a method (a potential route) is removed
|
281
|
+
def self.method_removed(id)
|
282
|
+
reset_routing_cache
|
283
|
+
end
|
284
|
+
# a callback that resets the class router whenever a method (a potential route) is undefined (using #undef_method).
|
285
|
+
def self.method_undefined(id)
|
286
|
+
reset_routing_cache
|
287
|
+
end
|
288
|
+
|
289
|
+
# # lists the available methods that will be exposed to HTTP requests
|
290
|
+
# def self.available_public_methods
|
291
|
+
# # set class global to improve performance while checking for supported methods
|
292
|
+
# @@___available_public_methods___ ||= available_routing_methods - [:before, :after, :save, :show, :update, :delete, :initialize, :on_message, :pre_connect, :on_connect, :on_disconnect]
|
293
|
+
# end
|
294
|
+
|
295
|
+
# # lists the available methods that will be exposed to the HTTP router
|
296
|
+
# def self.available_routing_methods
|
297
|
+
# # set class global to improve performance while checking for supported methods
|
298
|
+
# @@___available_routing_methods___ ||= (((public_instance_methods - Object.public_instance_methods) - Plezi::ControllerMagic::InstanceMethods.instance_methods).delete_if {|m| m.to_s[0] == '_'})
|
299
|
+
# end
|
300
|
+
|
301
|
+
# # resets this controller's router, to allow for dynamic changes
|
302
|
+
# def self.reset_routing_cache
|
303
|
+
# @@___available_routing_methods___ = @@___available_public_methods___ = nil
|
304
|
+
# available_routing_methods
|
305
|
+
# available_public_methods
|
306
|
+
# end
|
307
|
+
|
308
|
+
|
309
|
+
# # reviews the Redis connection, sets it up if it's missing and returns the Redis connection.
|
310
|
+
# #
|
311
|
+
# # todo: review thread status? (incase an exception killed it)
|
312
|
+
# def self.redis_connection
|
313
|
+
# return false unless defined?(Redis) && ENV['PL_REDIS_URL']
|
314
|
+
# return @@redis if defined?(@@redis_sub_thread) && @@redis
|
315
|
+
# @@redis_uri ||= URI.parse(ENV['PL_REDIS_URL'])
|
316
|
+
# @@redis ||= Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password)
|
317
|
+
# @@redis_sub_thread = Thread.new do
|
318
|
+
# begin
|
319
|
+
# Redis.new(host: @@redis_uri.host, port: @@redis_uri.port, password: @@redis_uri.password).subscribe(redis_channel_name) do |on|
|
320
|
+
# on.message do |channel, msg|
|
321
|
+
# args = JSON.parse(msg)
|
322
|
+
# params = args.shift
|
323
|
+
# __inner_process_broadcast params['_pl_ignore_object'], params['_pl_method_broadcasted'].to_sym, args
|
324
|
+
# end
|
325
|
+
# end
|
326
|
+
# rescue Exception => e
|
327
|
+
# Plezi.error e
|
328
|
+
# retry
|
329
|
+
# end
|
330
|
+
# end
|
331
|
+
# raise "Redis connction failed for: #{ENV['PL_REDIS_URL']}" unless @@redis
|
332
|
+
# @@redis
|
333
|
+
# end
|
334
|
+
|
335
|
+
# # returns a Redis channel name for this controller.
|
336
|
+
# def self.redis_channel_name
|
337
|
+
# self.name.to_s
|
338
|
+
# end
|
339
|
+
|
340
|
+
# # broadcasts messages (methods) for this process
|
341
|
+
# def self.__inner_process_broadcast ignore, method_name, args, &block
|
342
|
+
# ObjectSpace.each_object(self) { |controller| Plezi.callback controller, method_name, *args, &block if controller.accepts_broadcast? && (!ignore || controller.uuid != ignore) }
|
343
|
+
# end
|
344
|
+
|
345
|
+
# # broadcasts messages (methods) between all processes (using Redis).
|
346
|
+
# def self.__inner_redis_broadcast ignore, method_name, args, &block
|
347
|
+
# return false unless redis_connection
|
348
|
+
# raise "Radis broadcasts cannot accept blocks (no inter-process callbacks of memory sharing)!" if block
|
349
|
+
# # raise "Radis broadcasts accept only one paramater, which is an optional Hash (no inter-process memory sharing)" if args.length > 1 || (args[0] && !args[0].is_a?(Hash))
|
350
|
+
# args.unshift ({_pl_method_broadcasted: method_name, _pl_ignore_object: ignore})
|
351
|
+
# redis_connection.publish(redis_channel_name, args.to_json )
|
352
|
+
# true
|
353
|
+
# end
|
354
|
+
|
265
355
|
end
|
266
356
|
Object.const_set(new_class_name, ret)
|
357
|
+
Module.const_get(new_class_name).reset_routing_cache
|
267
358
|
ret
|
268
359
|
end
|
269
360
|
|
@@ -126,6 +126,7 @@ module Plezi
|
|
126
126
|
elsif object.is_a?(String)
|
127
127
|
case decode_method
|
128
128
|
when :uri, :url, :form
|
129
|
+
object.force_encoding "binary"
|
129
130
|
object.gsub!(/[^a-zA-Z0-9\*\.\_\-]/) {|m| m.ord <= 16 ? "%0#{m.ord.to_s(16)}" : "%#{m.ord.to_s(16)}"}
|
130
131
|
when :html
|
131
132
|
object.gsub!('&', "&")
|
@@ -134,8 +135,10 @@ module Plezi
|
|
134
135
|
object.gsub!("<", "<")
|
135
136
|
object.gsub!(/[^\sa-zA-Z\d\&\;]/) {|m| "&#%04d;" % m.unpack('U')[0] }
|
136
137
|
# object.gsub!(/[^\s]/) {|m| "&#%04d;" % m.unpack('U')[0] }
|
138
|
+
object.force_encoding "binary"
|
137
139
|
when :utf8
|
138
140
|
object.gsub!(/[^\sa-zA-Z\d]/) {|m| "&#%04d;" % m.unpack('U')[0] }
|
141
|
+
object.force_encoding "binary"
|
139
142
|
else
|
140
143
|
|
141
144
|
end
|
@@ -40,7 +40,7 @@ module Plezi
|
|
40
40
|
@cookies = {}
|
41
41
|
# propegate flash object
|
42
42
|
@flash = Hash.new do |hs,k|
|
43
|
-
hs["plezi_flash_#{k.to_s}"] if hs.has_key? "plezi_flash_#{k.to_s}"
|
43
|
+
hs["plezi_flash_#{k.to_s}".to_sym] if hs.has_key? "plezi_flash_#{k.to_s}".to_sym
|
44
44
|
end
|
45
45
|
request.cookies.each do |k,v|
|
46
46
|
@flash[k] = v if k.to_s.start_with? "plezi_flash_"
|
data/lib/plezi/version.rb
CHANGED
data/plezi.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Plezi::VERSION
|
9
9
|
spec.authors = ["Boaz Segev"]
|
10
10
|
spec.email = ['boaz@2be.co.il']
|
11
|
-
spec.summary = %q{The Ruby
|
12
|
-
spec.description = %q{Plezi is a Rack free Ruby
|
11
|
+
spec.summary = %q{The Ruby Framework for real time web-apps, with Websockets, REST and HTTP streaming support.}
|
12
|
+
spec.description = %q{Plezi is a Rack free Ruby Framework for real time web-apps, with native Websocket, HTTP streaming, and REST routing support.}
|
13
13
|
spec.homepage = "http://boazsegev.github.io/plezi/"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.7"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
23
|
|
24
|
-
spec.post_install_message = "This update might break existing code - please review ChangeLog.md before upgrading any apps
|
24
|
+
# spec.post_install_message = "This update might break existing code - please review ChangeLog.md before upgrading any apps."
|
25
|
+
spec.post_install_message = "Thank you for installing Plezi, the Ruby Framework for real time web-apps."
|
25
26
|
|
26
27
|
end
|
data/resources/Gemfile
CHANGED
@@ -9,23 +9,25 @@ gem 'plezi'
|
|
9
9
|
####################
|
10
10
|
# development gems
|
11
11
|
|
12
|
-
|
12
|
+
## use pry gem for basic debug ( put `binding.pry` at breake point )?
|
13
13
|
# gem 'pry'
|
14
14
|
|
15
|
+
## use rake tasks with bundle exec?
|
16
|
+
# gem 'rake'
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
## active support can run without rails and extends the Ruby language.
|
19
|
+
## it might be heavy, be warned.
|
20
|
+
## see: http://guides.rubyonrails.org/active_support_core_extensions.html
|
19
21
|
#
|
20
22
|
# gem 'activesupport', :require => ['active_support', 'active_support/core_ext']
|
21
|
-
|
23
|
+
## or:
|
22
24
|
# gem 'activesupport', :require => ['active_support', active_support/all']
|
23
25
|
|
24
26
|
|
25
27
|
####################
|
26
28
|
# gems for easy markup
|
27
29
|
|
28
|
-
## Slim is very recommended for HTML markup, it's both easy and fast.
|
30
|
+
## Slim is very recommended for HTML markup, it's both easy and fast. We LOVE it.
|
29
31
|
# gem 'slim'
|
30
32
|
|
31
33
|
## Sass makes CSS easy
|
@@ -50,9 +52,10 @@ gem 'plezi'
|
|
50
52
|
# WebSocket Scaling
|
51
53
|
|
52
54
|
## redis servers are used to allow websocket scaling.
|
53
|
-
## the
|
55
|
+
## the Controller#collect method will work only for the current process.
|
56
|
+
## the Controller#broadcast can be configured to automatically use Redis, but some inter-process limitation apply.
|
54
57
|
## using Redis, we can publish messages and subscribe to 'chunnels' across processes
|
55
|
-
|
58
|
+
## (limited support for :broadcast and NO support for :collect while Redis is running).
|
56
59
|
|
57
60
|
# gem 'redis'
|
58
61
|
|
data/resources/rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# load all framework and gems
|
2
|
+
load ::File.expand_path(File.join("..", "environment.rb"), __FILE__)
|
3
|
+
|
4
|
+
# Make sure the server doesn't start
|
5
|
+
NO_PLEZI_AUTO_START = true
|
6
|
+
|
7
|
+
# create a default task
|
8
|
+
desc "The default task does nothing... it's waiting for you to tell it what to do."
|
9
|
+
task :default do
|
10
|
+
puts "I don't know what to do."
|
11
|
+
puts `rake -T`
|
12
|
+
end
|
data/resources/routes.rb
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
|
12
12
|
# This is an optional re-write route for I18n.
|
13
13
|
# i.e.: `/en/home` will be rewriten as `/home`, while setting params[:locale] to "en"
|
14
|
-
route "
|
14
|
+
route "/:locale{#{I18n.available_locales.join "|"}}/*" , false if defined? I18n
|
15
15
|
|
16
16
|
###
|
17
17
|
# add your routes here:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plezi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,9 +38,8 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
-
description: Plezi is a Rack free Ruby
|
42
|
-
streaming, and REST routing support.
|
43
|
-
framework with an integrated server, ready for seamless WebSockets and RESTful applications.
|
41
|
+
description: Plezi is a Rack free Ruby Framework for real time web-apps, with native
|
42
|
+
Websocket, HTTP streaming, and REST routing support.
|
44
43
|
email:
|
45
44
|
- boaz@2be.co.il
|
46
45
|
executables:
|
@@ -108,7 +107,7 @@ files:
|
|
108
107
|
- resources/i18n_config.rb
|
109
108
|
- resources/plezi_gray.png
|
110
109
|
- resources/plezi_websockets.html
|
111
|
-
- resources/rakefile
|
110
|
+
- resources/rakefile
|
112
111
|
- resources/redis_config.rb
|
113
112
|
- resources/routes.rb
|
114
113
|
- resources/welcome_page.html
|
@@ -117,11 +116,8 @@ homepage: http://boazsegev.github.io/plezi/
|
|
117
116
|
licenses:
|
118
117
|
- MIT
|
119
118
|
metadata: {}
|
120
|
-
post_install_message:
|
121
|
-
|
122
|
-
`params[:list]['0'.to_sym][:key]` to `params[:list][0][:key]` (Fixnum rather then
|
123
|
-
String).\n\r- Pleasemake sure to update `params[:check] == 'true'` to `params[:check]
|
124
|
-
== true` (not aString)."
|
119
|
+
post_install_message: Thank you for installing Plezi, the Ruby Framework for real
|
120
|
+
time web-apps.
|
125
121
|
rdoc_options: []
|
126
122
|
require_paths:
|
127
123
|
- lib
|
@@ -140,5 +136,6 @@ rubyforge_project:
|
|
140
136
|
rubygems_version: 2.4.5
|
141
137
|
signing_key:
|
142
138
|
specification_version: 4
|
143
|
-
summary: The Ruby
|
139
|
+
summary: The Ruby Framework for real time web-apps, with Websockets, REST and HTTP
|
140
|
+
streaming support.
|
144
141
|
test_files: []
|
data/resources/rakefile.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
BUILDING_PLEZI_TEMPLATE = true
|
3
|
-
NO_PLEZI_AUTO_START = true
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
require 'rake'
|
7
|
-
|
8
|
-
app_name = ::File.expand_path(::Dir["."][0]).split(/[\\\/]/).last
|
9
|
-
require ::File.expand_path(::Dir["."][0], ( app_name + ".rb") )
|
10
|
-
|
11
|
-
namespace :app do
|
12
|
-
|
13
|
-
desc "adds and framework files that might be missing (use after adding plezi gems).\nnotice: this will not update rakefile.rb or Gemfile(!)."
|
14
|
-
task :rebuild do
|
15
|
-
Dir.chdir '..'
|
16
|
-
puts `plezi force #{app_name}`
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
task :default do
|
21
|
-
puts `rake -T`
|
22
|
-
end
|