plezi 0.7.3 → 0.7.4
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 +11 -1
- data/README.md +33 -46
- data/lib/plezi.rb +2 -0
- data/lib/plezi/base/cache.rb +5 -0
- data/lib/plezi/base/dsl.rb +22 -0
- data/lib/plezi/base/engine.rb +1 -0
- data/lib/plezi/handlers/controller_magic.rb +10 -6
- data/lib/plezi/handlers/route.rb +2 -1
- data/lib/plezi/server/protocols/http_protocol.rb +6 -0
- data/lib/plezi/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7b74f28a320e2558c0478929989d9904ed191aa
|
4
|
+
data.tar.gz: 3231b1fca07d1ac55bfd14f1eff40be0cb0a7154
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd7d3987c60cad451d7860296ece6fc2e19b24922c318a344fde248832d7bd7b91f956db0c6f600ccca185d7bb43401973036a79b4a8f8c405b08ce9a2a524f7
|
7
|
+
data.tar.gz: 5ca2c5850793f1c23ddec678499989e2166062c9b4c67ae1deb2232eaa9db0069235bfaaad7482aff4728dc2ffaba59012f4ab8e0c22d278f5d7bdb44e807c1a
|
data/CHANGELOG.md
CHANGED
@@ -2,11 +2,21 @@
|
|
2
2
|
|
3
3
|
***
|
4
4
|
|
5
|
+
Change log v.0.7.4
|
6
|
+
|
7
|
+
**change/fix**: it seems that behavior is more predictable when routes macgic parameters are non-persistent between routes. The old behavior (persistent parameters) is now limited to re-write routes.
|
8
|
+
|
9
|
+
**fix**: an error was introduced when using paramd\[:id] with a Fixnum. This was caused by the router attempting to search for a method by that name before using the parameter as an :id. This is now fixed by temporarily converting the Fixnum to a string before the required converstion to a symbol.
|
10
|
+
|
11
|
+
**experimental feature**: added the method `def_special_method`, which can be used in controller classes to create specially named paths, defying Ruby naming restrictions, such as: "play-now", "text.me" etc'. This is an EXPERIMENTAL feature which might be limited in future releases (specifically limited to names without dots '.', in case of future formatting support).
|
12
|
+
|
13
|
+
***
|
14
|
+
|
5
15
|
Change log v.0.7.3
|
6
16
|
|
7
17
|
**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
18
|
|
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
|
19
|
+
**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 table 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
20
|
|
11
21
|
**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
22
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Plezi, The Rack Free Ruby
|
1
|
+
# Plezi, The Rack Free Ruby framework for realtime web-apps
|
2
2
|
[](http://badge.fury.io/rb/plezi)
|
3
3
|
[](http://inch-ci.org/github/boazsegev/plezi)
|
4
4
|
|
@@ -94,7 +94,7 @@ Remember to connect to the service from at least two browser windows - to truly
|
|
94
94
|
|
95
95
|
# do you need automated redis support?
|
96
96
|
# require 'redis'
|
97
|
-
# ENV['PL_REDIS_URL'] = "
|
97
|
+
# ENV['PL_REDIS_URL'] = "redis://user:password@localhost:6379"
|
98
98
|
|
99
99
|
class BroadcastCtrl
|
100
100
|
def index
|
@@ -109,7 +109,10 @@ Remember to connect to the service from at least two browser windows - to truly
|
|
109
109
|
def _send_message data
|
110
110
|
response << data
|
111
111
|
end
|
112
|
-
def
|
112
|
+
def hello
|
113
|
+
'Hello!'
|
114
|
+
end
|
115
|
+
def_special_method "humans.txt" do
|
113
116
|
'I made this :)'
|
114
117
|
end
|
115
118
|
end
|
@@ -119,7 +122,7 @@ Remember to connect to the service from at least two browser windows - to truly
|
|
119
122
|
route '/', BroadcastCtrl
|
120
123
|
```
|
121
124
|
|
122
|
-
method names starting with an underscore ('_') will NOT be made public by the router: so while '/
|
125
|
+
method names starting with an underscore ('_') will NOT be made public by the router: so while both '/hello' and '/humans.txt' are public ( [try it](http://localhost:3000/humans.txt) ), '/_send_message' will return a 404 not found error ( [try it](http://localhost:3000/_send_message) ).
|
123
126
|
|
124
127
|
## Native HTTP streaming with Asynchronous events
|
125
128
|
|
@@ -175,7 +178,7 @@ Plezi can be used to create virtual hosts for the same service:
|
|
175
178
|
listen
|
176
179
|
host 'localhost', alias: 'localhost2'
|
177
180
|
|
178
|
-
shared_route '/
|
181
|
+
shared_route '/humans.txt' do |req, res|
|
179
182
|
res << "we are people - shared by all routes."
|
180
183
|
end
|
181
184
|
|
@@ -195,8 +198,8 @@ Now visit:
|
|
195
198
|
|
196
199
|
* [http://127.0.0.1:3000/]( http://127.0.0.1:3000/ )
|
197
200
|
* [http://localhost:3000/]( http://localhost:3000/ )
|
198
|
-
* [http://127.0.0.1:3000/
|
199
|
-
* [http://localhost:3000/
|
201
|
+
* [http://127.0.0.1:3000/humans.txt]( http://127.0.0.1:3000/humans.txt )
|
202
|
+
* [http://localhost:3000/humans.txt]( http://localhost:3000/humans.txt )
|
200
203
|
|
201
204
|
## Plezi Logging
|
202
205
|
|
@@ -242,32 +245,19 @@ Asynchronous callbacks (works only while services are active and running):
|
|
242
245
|
# an asynchronous method call with an optional callback block
|
243
246
|
PL.callback(Kernel, :puts, "Plezi will start eating our code once we exit terminal.") {puts 'first output finished'}
|
244
247
|
|
245
|
-
##
|
248
|
+
## Re-write Routes
|
246
249
|
|
247
|
-
|
250
|
+
Plezi supports special routes used to re-write the request and extract parameters for all future routes.
|
248
251
|
|
249
|
-
|
252
|
+
This allows you to create path prefixes which will be removed once their information is extracted.
|
250
253
|
|
251
|
-
|
252
|
-
# and then it will fail, so that routing continues.
|
253
|
-
#
|
254
|
-
# this is here just for the demo.
|
255
|
-
#
|
256
|
-
class ReWriteController
|
257
|
-
# using the before filter and regular expressions to make some changes.
|
258
|
-
def before
|
259
|
-
# extract the fr and en locales.
|
260
|
-
result = request.path.match /^\/(en|fr)($|\/.*)/
|
261
|
-
|
262
|
-
if result
|
263
|
-
params[:locale] = result[1]
|
264
|
-
request.path = result[2]
|
265
|
-
end
|
254
|
+
This is great for setting global information such as internationalization (I18n) locales.
|
266
255
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
256
|
+
By using a route with the a 'false' controller, the parameters extracted are automatically retained.
|
257
|
+
|
258
|
+
*(Older versions of Plezi allowed this behavior for all routes, but it was deprecated starting version 0.7.4).
|
259
|
+
|
260
|
+
require 'plezi'
|
271
261
|
|
272
262
|
class Controller
|
273
263
|
def index
|
@@ -286,31 +276,23 @@ Here's some food for thought - code similar to something actually used at some p
|
|
286
276
|
end
|
287
277
|
def delete
|
288
278
|
return "Mon Dieu! Mon français est mauvais!" if params[:locale] == 'fr'
|
289
|
-
"did you try
|
279
|
+
"did you try #{request.base_url + request.original_path}?_method=delete or does your server support a native DELETE method?"
|
290
280
|
end
|
291
281
|
end
|
292
282
|
|
293
283
|
listen
|
294
284
|
|
295
|
-
#
|
296
|
-
#
|
297
|
-
|
298
|
-
#
|
299
|
-
# ...in this specific case, it is possible to dispense with the ReWriteController class
|
300
|
-
# and write:
|
301
|
-
#
|
302
|
-
# route '/(:locale){fr|en}/*', false
|
303
|
-
#
|
304
|
-
# the false controller acts as a simple path re-write that
|
305
|
-
# deletes everything before the '*' sign (the catch-all).
|
306
|
-
#
|
307
|
-
route '*' , ReWriteController
|
285
|
+
# this is our re-write route.
|
286
|
+
# it will extract the locale and re-write the request.
|
287
|
+
route '/:locale{fr|en}/*', false
|
308
288
|
|
309
289
|
# this route takes a regular expression that is a simple math calculation
|
310
290
|
# (calculator)
|
291
|
+
#
|
292
|
+
# it is an example for a Proc controller, which can replace the Class controller.
|
311
293
|
route /^\/[\d\+\-\*\/\(\)\.]+$/ do |request, response|
|
312
294
|
message = (request.params[:locale] == 'fr') ? "La solution est" : "My Answer is"
|
313
|
-
response << "#{message}: #{eval(request.path[1..-1])}"
|
295
|
+
response << "#{message}: #{eval( request.path[1..-1] )}"
|
314
296
|
end
|
315
297
|
|
316
298
|
route "/users" , Controller
|
@@ -322,10 +304,15 @@ try:
|
|
322
304
|
* [http://localhost:3000/](http://localhost:3000/)
|
323
305
|
* [http://localhost:3000/fr](http://localhost:3000/fr)
|
324
306
|
* [http://localhost:3000/users/hello](http://localhost:3000/users/hello)
|
325
|
-
* [http://localhost:3000/(5+5*20-15)/9](http://localhost:3000/(5+5*20-15)/9)
|
326
|
-
* [http://localhost:3000/
|
307
|
+
* [http://localhost:3000/users/(5+5*20-15)/9.0](http://localhost:3000/users/(5+5*20-15)/9.0)
|
308
|
+
* [http://localhost:3000/(5+5*20-15)/9.0](http://localhost:3000/(5+5*20-15)/9)
|
309
|
+
* [http://localhost:3000/fr/(5+5*20-15)/9.0](http://localhost:3000/fr/(5+5*20-15)/9)
|
327
310
|
* [http://localhost:3000/users/hello?_method=delete](http://localhost:3000/users/hello?_method=delete)
|
328
311
|
|
312
|
+
As you can see in the example above, Plezi supports Proc routes as well as Class controller routes.
|
313
|
+
|
314
|
+
Please notice that there are some differences between the two. Proc routes less friedly, but plenty powerful and are great for custom 404 error handling.
|
315
|
+
|
329
316
|
## Plezi Settings
|
330
317
|
|
331
318
|
Plezi is ment to be very flexible. please take a look at the Plezi Module for settings you might want to play with (max_threads, idle_sleep, create_logger) or any monkey patching you might enjoy.
|
data/lib/plezi.rb
CHANGED
@@ -120,6 +120,8 @@ end
|
|
120
120
|
#
|
121
121
|
# thanks to Russ Olsen for his ideas for a DSL and his blog post at:
|
122
122
|
# http://www.jroller.com/rolsen/entry/building_a_dsl_in_ruby1
|
123
|
+
#
|
124
|
+
# ...he doesn't know it, but he inspired a revolution.
|
123
125
|
##############################################################################
|
124
126
|
module Plezi
|
125
127
|
end
|
data/lib/plezi/base/cache.rb
CHANGED
@@ -66,6 +66,11 @@ module Plezi
|
|
66
66
|
LOCK.synchronize { CACHE_STORE.delete filename } # if CACHE_STORE[filename]
|
67
67
|
end
|
68
68
|
|
69
|
+
# clears all cached data.
|
70
|
+
def clear_cache! filename
|
71
|
+
LOCK.synchronize { CACHE_STORE.clear } # if CACHE_STORE[filename]
|
72
|
+
end
|
73
|
+
|
69
74
|
# returns true if the filename is cached.
|
70
75
|
def cached? filename
|
71
76
|
!CACHE_STORE[filename].nil?
|
data/lib/plezi/base/dsl.rb
CHANGED
@@ -153,6 +153,19 @@ def shared_route(path, controller = nil, &block)
|
|
153
153
|
Plezi::DSL.shared_route(path, controller, &block)
|
154
154
|
end
|
155
155
|
|
156
|
+
# defines a method with a special name, such as "humens.txt".
|
157
|
+
#
|
158
|
+
# this could be used in controller classes, to define special routes which might defy
|
159
|
+
# normal Ruby naming conventions, such as "/welcome-home", "/play!", etc'
|
160
|
+
#
|
161
|
+
# could also be used to define methods with special formatting, such as "humans.txt",
|
162
|
+
# until a more refined way to deal with formatting will be implemented.
|
163
|
+
def def_special_method name, obj=self, &block
|
164
|
+
obj.instance_eval { define_method name.to_s.to_sym, &block }
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
|
156
169
|
# finishes setup of the servers and starts them up. This will hange the proceess.
|
157
170
|
#
|
158
171
|
# this method is called automatically by the Plezi framework.
|
@@ -170,8 +183,17 @@ def start_services
|
|
170
183
|
Plezi.start_services
|
171
184
|
end
|
172
185
|
|
186
|
+
# restarts the Plezi app with the same arguments as when it was started.
|
187
|
+
#
|
188
|
+
# EXPERIMENTAL
|
189
|
+
def restart_plezi_app
|
190
|
+
exec "/usr/bin/env ruby #{$PL_SCRIPT} #{$PL_ARGV.join ' '}"
|
191
|
+
end
|
192
|
+
|
173
193
|
# sets to start the services once dsl script is finished loading.
|
174
194
|
at_exit { start_services } unless ( defined?(NO_PLEZI_AUTO_START) || defined?(BUILDING_PLEZI_TEMPLATE) || defined?(PLEZI_ON_RACK) )
|
175
195
|
|
176
196
|
# sets a name for the process (on some systems).
|
197
|
+
$PL_SCRIPT = $0
|
198
|
+
$PL_ARGV = $*.dup
|
177
199
|
$0="Plezi (Ruby)"
|
data/lib/plezi/base/engine.rb
CHANGED
@@ -37,6 +37,7 @@ module Plezi
|
|
37
37
|
run_every(5 , Plezi.method(:clear_connections)) #{info "Cleared inactive Connections"}
|
38
38
|
run_every 3600 , GC.method(:start)
|
39
39
|
# run_every( 1 , Proc.new() { Plezi.info "#{IO_CONNECTION_DIC.length} active connections ( #{ IO_CONNECTION_DIC.select{|k,v| v.protocol.is_a?(WSProtocol)} .length } websockets)." })
|
40
|
+
# run_every 10 , -> {Plezi.info "Cache report: #{CACHE_STORE.length} objects cached." }
|
40
41
|
(max_threads).times { Thread.new { thread_cycle until exit_flag } }
|
41
42
|
|
42
43
|
# Thread.new { check_connections until SERVICES.empty? }
|
@@ -131,11 +131,11 @@ module Plezi
|
|
131
131
|
true
|
132
132
|
end
|
133
133
|
|
134
|
-
# renders a template file (.erb/.haml) or an html file (.html) to text
|
135
|
-
# for example, to render the file `body.html.
|
134
|
+
# renders a template file (.slim/.erb/.haml) or an html file (.html) to text
|
135
|
+
# for example, to render the file `body.html.slim` with the layout `main_layout.html.haml`:
|
136
136
|
# render :body, layout: :main_layout
|
137
137
|
#
|
138
|
-
# or, for example, to render the file `json.js.
|
138
|
+
# or, for example, to render the file `json.js.slim`
|
139
139
|
# render :json, type: 'js'
|
140
140
|
#
|
141
141
|
# or, for example, to render the file `template.haml`
|
@@ -148,7 +148,7 @@ module Plezi
|
|
148
148
|
# options aceept the following keys:
|
149
149
|
# type:: the types for the `:layout' and 'template'. can be any extention, such as `"json"`. defaults to `"html"`.
|
150
150
|
# layout:: a layout template that has at least one `yield` statement where the template will be rendered.
|
151
|
-
# locale:: the I18n locale for the render. (defaults to params[:locale]) - only if the I18n gem namespace is defined (`require 'i18n'`).
|
151
|
+
# locale:: the I18n locale for the render. (defaults to params\[:locale]) - only if the I18n gem namespace is defined (`require 'i18n'`).
|
152
152
|
#
|
153
153
|
# if template is a string, it will assume the string is an
|
154
154
|
# absolute path to a template file. it will NOT search for the template but might raise exceptions.
|
@@ -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] && self.class.available_public_methods.include?(params[:id].to_sym)
|
196
|
+
return params[:id].to_s.to_sym if params[:id] && self.class.available_public_methods.include?(params[:id].to_s.to_sym)
|
197
197
|
#review general cases
|
198
198
|
case request.request_method
|
199
199
|
when 'GET', 'HEAD'
|
@@ -302,7 +302,11 @@ module Plezi
|
|
302
302
|
|
303
303
|
# reviews the Redis connection, sets it up if it's missing and returns the Redis connection.
|
304
304
|
#
|
305
|
-
#
|
305
|
+
# a Redis connection will be automatically created if the `ENV['PL_REDIS_URL']` is set.
|
306
|
+
# for example:
|
307
|
+
# ENV['PL_REDIS_URL'] = ENV['REDISCLOUD_URL']`
|
308
|
+
# or
|
309
|
+
# ENV['PL_REDIS_URL'] = "redis://username:password@my.host:6379"
|
306
310
|
def redis_connection
|
307
311
|
# return false unless defined?(Redis) && ENV['PL_REDIS_URL']
|
308
312
|
# return @@redis if defined?(@@redis_sub_thread) && @@redis
|
data/lib/plezi/handlers/route.rb
CHANGED
@@ -16,6 +16,7 @@ module Plezi
|
|
16
16
|
def on_request request
|
17
17
|
fill_parameters = match request.path
|
18
18
|
return false unless fill_parameters
|
19
|
+
old_params = request.params.dup
|
19
20
|
fill_parameters.each {|k,v| HTTP.add_param_to_hash k, v, request.params }
|
20
21
|
ret = false
|
21
22
|
response = HTTPResponse.new request
|
@@ -29,7 +30,7 @@ module Plezi
|
|
29
30
|
return false
|
30
31
|
end
|
31
32
|
unless ret
|
32
|
-
request.params.
|
33
|
+
request.params.replace old_params unless fill_parameters.empty?
|
33
34
|
return false
|
34
35
|
end
|
35
36
|
response.try_finish
|
@@ -180,6 +180,12 @@ module Plezi
|
|
180
180
|
@parser_data[:path] = @parser_data[:original_path].chomp('/')
|
181
181
|
@parser_data[:original_path].freeze
|
182
182
|
|
183
|
+
# the following can be used to extract the request's 'format':
|
184
|
+
# /(^.*)(\.[^\.\/]*)$/.match @parser_data[:path]
|
185
|
+
# ...? should this be done? Could be limited to certain formats:
|
186
|
+
# /(^.*)(\.(txt|html|json|js|xml|xhtml|csv))$/.match @parser_data[:path]
|
187
|
+
# ... even worst?
|
188
|
+
|
183
189
|
HTTP.make_utf8! @parser_data[:host_name] if @parser_data[:host_name]
|
184
190
|
HTTP.make_utf8! @parser_data[:query]
|
185
191
|
|
data/lib/plezi/version.rb
CHANGED
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.4
|
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-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|