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/resources/404.erb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
<%
|
2
2
|
# # consider replacing the Html with the following Ruby code:
|
3
|
-
#
|
3
|
+
# cookies[:notice] = "Sorry, we couldn't find #{request.original_path} - error code 404"
|
4
|
+
# response.redirect_to "/"
|
4
5
|
# # OR
|
5
|
-
# render
|
6
|
+
# render("layout") { render("template") }
|
6
7
|
%><!DOCTYPE html>
|
7
8
|
<head>
|
8
9
|
<style>
|
@@ -46,7 +47,7 @@
|
|
46
47
|
}
|
47
48
|
h3
|
48
49
|
{
|
49
|
-
font-family: 'Architects Daughter', cursive;
|
50
|
+
font-family: 'Architects Daughter', cursive;
|
50
51
|
background-color: #44518E;
|
51
52
|
color: #C6CCE7;
|
52
53
|
text-align: left;
|
@@ -80,7 +81,7 @@
|
|
80
81
|
{
|
81
82
|
font-size: 1em;
|
82
83
|
padding: 0 1em;
|
83
|
-
margin: 0.5em 0;
|
84
|
+
margin: 0.5em 0;
|
84
85
|
}
|
85
86
|
a
|
86
87
|
{
|
data/resources/500.erb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
<%
|
2
2
|
# # consider replacing the Html with the following Ruby code:
|
3
|
-
#
|
3
|
+
# cookies[:notice] = "Internal error for #{request.original_path} - error code 500"
|
4
|
+
# response.redirect_to "/"
|
4
5
|
# # OR
|
5
|
-
# render
|
6
|
+
# render("layout") { render("template") }
|
6
7
|
%><!DOCTYPE html>
|
7
8
|
<head>
|
8
9
|
<style>
|
@@ -46,7 +47,7 @@
|
|
46
47
|
}
|
47
48
|
h3
|
48
49
|
{
|
49
|
-
font-family: 'Architects Daughter', cursive;
|
50
|
+
font-family: 'Architects Daughter', cursive;
|
50
51
|
background-color: #44518E;
|
51
52
|
color: #C6CCE7;
|
52
53
|
text-align: left;
|
@@ -80,7 +81,7 @@
|
|
80
81
|
{
|
81
82
|
font-size: 1em;
|
82
83
|
padding: 0 1em;
|
83
|
-
margin: 0.5em 0;
|
84
|
+
margin: 0.5em 0;
|
84
85
|
}
|
85
86
|
a
|
86
87
|
{
|
@@ -1,7 +1,6 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<head>
|
3
3
|
<style>
|
4
|
-
body, html
|
5
4
|
/*
|
6
5
|
med-blue: #44518E
|
7
6
|
dark-gray: #424A70
|
@@ -42,7 +41,7 @@
|
|
42
41
|
}
|
43
42
|
h3
|
44
43
|
{
|
45
|
-
font-family: 'Architects Daughter', cursive;
|
44
|
+
font-family: 'Architects Daughter', cursive;
|
46
45
|
background-color: #44518E;
|
47
46
|
color: #C6CCE7;
|
48
47
|
text-align: left;
|
@@ -76,7 +75,7 @@
|
|
76
75
|
{
|
77
76
|
font-size: 1em;
|
78
77
|
padding: 0 1em;
|
79
|
-
margin: 0.5em 0;
|
78
|
+
margin: 0.5em 0;
|
80
79
|
}
|
81
80
|
a
|
82
81
|
{
|
@@ -114,12 +113,12 @@
|
|
114
113
|
</style>
|
115
114
|
</head>
|
116
115
|
<body>
|
117
|
-
<h1>
|
116
|
+
<h1>Our servers are busy, working at full capacity...</h1>
|
118
117
|
<div id='wrapper'>
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
<p>
|
123
|
-
<p
|
118
|
+
<h2 id='missing'>
|
119
|
+
Please try again in a few minutes.
|
120
|
+
</h2>
|
121
|
+
<p>It seems our servers are all quite busy. This unexpected high load will probably be over soon...</p>
|
122
|
+
<p>... Please try again in a few minutes. If this issue persists, please let us know.</p>
|
124
123
|
</div>
|
125
124
|
</body>
|
data/resources/client.js
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
// This is a commonly used structure for WebSocket messanging.
|
2
|
+
// The documentation is available on the www.plezi.io website:
|
3
|
+
// http://www.plezi.io/docs/websockets#websocket-json-auto-dispatch
|
4
|
+
//
|
5
|
+
// Basics:
|
6
|
+
// To open a websocket connection to the current location:
|
7
|
+
//
|
8
|
+
// var client = new PleziClient()
|
9
|
+
//
|
10
|
+
// To open a connection to a different path for the original server (SSL will be preserved when in use), use:
|
11
|
+
//
|
12
|
+
// var client = new PleziClient(PleziClient.origin + "/path")
|
13
|
+
//
|
14
|
+
// To automatically renew the connection when disconnections are reported by the browser, use:
|
15
|
+
//
|
16
|
+
// client.autoreconnect = true
|
17
|
+
// client.reconnect_interval = 250 // sets how long to wait before reconnection attempts. default is 250 ms.
|
18
|
+
//
|
19
|
+
// To set up event handling, directly set an `<event name>` callback. i.e., for an event called `chat`:
|
20
|
+
//
|
21
|
+
// client.chat = function(event) { "..." }
|
22
|
+
//
|
23
|
+
// To sent / emit event in JSON format, use the `emit` method:
|
24
|
+
//
|
25
|
+
// client.emit({event: "chat", data: "the message"})
|
26
|
+
//
|
27
|
+
function PleziClient(url, autoreconnect) {
|
28
|
+
// Set URL
|
29
|
+
if (url) {
|
30
|
+
this.url = url;
|
31
|
+
} else {
|
32
|
+
this.url = PleziClient.origin + self.location.pathname;
|
33
|
+
}
|
34
|
+
// Connect Websocket
|
35
|
+
this.reconnect();
|
36
|
+
// Setup AJAJ
|
37
|
+
this.ajaj = {};
|
38
|
+
this.ajaj.client = this;
|
39
|
+
this.ajaj.url = this.url.replace(/^ws:\/\//i, "http://").replace(/^wss:\/\//i, "https://");
|
40
|
+
this.ajaj.add = {};
|
41
|
+
this.ajaj.emit = this.___ajaj__emit;
|
42
|
+
this.ajaj.auto = false;
|
43
|
+
// auto-reconnection
|
44
|
+
this.autoreconnect = false;
|
45
|
+
this.reconnect_interval = 200;
|
46
|
+
// dump data to console?
|
47
|
+
this.log_events = false;
|
48
|
+
// the timeout for a message ack receipt
|
49
|
+
this.emit_timeout = false;
|
50
|
+
// Set the autoreconnect property
|
51
|
+
if (autoreconnect) {
|
52
|
+
this.autoreconnect = true;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
// The Websocket onopen callback
|
56
|
+
PleziClient.prototype.___on_open = function(e) {
|
57
|
+
this.owner.connected = true;
|
58
|
+
if (this.owner.onopen) {
|
59
|
+
this.owner.onopen(e);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
// The Websocket onclose callback
|
63
|
+
PleziClient.prototype.___on_close = function(e) {
|
64
|
+
this.owner.connected = false;
|
65
|
+
if (this.owner.onclose) {
|
66
|
+
this.owner.onclose(e);
|
67
|
+
}
|
68
|
+
if (this.owner.autoreconnect) {
|
69
|
+
setTimeout(function(obj) {
|
70
|
+
obj.reconnect();
|
71
|
+
}, this.owner.reconnect_interval, this.owner);
|
72
|
+
}
|
73
|
+
}
|
74
|
+
// The Websocket onerror callback
|
75
|
+
PleziClient.prototype.___on_error = function(e) {
|
76
|
+
if (this.owner.onerror) {
|
77
|
+
this.owner.onerror(e);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
// The Websocket onmessage callback
|
81
|
+
PleziClient.prototype.___on_message = function(e) {
|
82
|
+
try {
|
83
|
+
var msg = JSON.parse(e.data);
|
84
|
+
this.owner.___dispatch(msg);
|
85
|
+
} catch (err) {
|
86
|
+
console.error("PleziClient experienced an error parsing the following data (not JSON):",
|
87
|
+
err, e);
|
88
|
+
}
|
89
|
+
}
|
90
|
+
PleziClient.prototype.___dispatch = function(msg) {
|
91
|
+
try {
|
92
|
+
if (this.log_events) {
|
93
|
+
console.log(msg);
|
94
|
+
}
|
95
|
+
if (msg.event == '_ack_') {
|
96
|
+
clearTimeout(msg._EID_);
|
97
|
+
if (this[msg._EID_] && this[msg._EID_].callback) {
|
98
|
+
this[msg._EID_].callback(this[msg._EID_].event, this);
|
99
|
+
}
|
100
|
+
delete this[msg._EID_];
|
101
|
+
}
|
102
|
+
if ((msg.event) && (this[msg.event])) {
|
103
|
+
this[msg.event](msg);
|
104
|
+
} else if ((msg.event) && (this['on' + msg.event])) {
|
105
|
+
console.warn('PleziClient: use a callback called "' + msg.event +
|
106
|
+
'" instead of of "on' + msg.event + '"');
|
107
|
+
this['on' + msg.event](msg);
|
108
|
+
} else {
|
109
|
+
if (this['unknown'] && (msg.event != '_ack_')) {
|
110
|
+
this['unknown'](msg);
|
111
|
+
};
|
112
|
+
}
|
113
|
+
} catch (err) {
|
114
|
+
console.error("PleziClient experienced an error while responding to the following onmessage event",
|
115
|
+
err, msg);
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
// Clears meta timeout data
|
120
|
+
PleziClient.prototype.___perform_timeout_callback = function(event, pl_client, callback) {
|
121
|
+
delete pl_client[event._EID_];
|
122
|
+
callback(event, pl_client);
|
123
|
+
}
|
124
|
+
|
125
|
+
// Sets a timeout for the websocket message
|
126
|
+
PleziClient.prototype.___set_failed_timeout = function(event, callback, timeout) {
|
127
|
+
if (event._EID_) {
|
128
|
+
return event;
|
129
|
+
};
|
130
|
+
if (!timeout) {
|
131
|
+
timeout = this.emit_timeout;
|
132
|
+
};
|
133
|
+
if (!callback) {
|
134
|
+
callback = this.___on_timeout;
|
135
|
+
};
|
136
|
+
if (!timeout) {
|
137
|
+
return event;
|
138
|
+
};
|
139
|
+
event._EID_ = setTimeout(this.___perform_timeout_callback, timeout, event, this, callback);
|
140
|
+
return event;
|
141
|
+
}
|
142
|
+
// Removes the _client_ property from the event and calls
|
143
|
+
// the ontimeout callback within the correct scope
|
144
|
+
PleziClient.prototype.___on_timeout = function(event, client) {
|
145
|
+
if (client.ajaj.auto) {
|
146
|
+
if (client.log_events) {
|
147
|
+
console.log("falling back on AJAJ for the event:", event);
|
148
|
+
}
|
149
|
+
client.ajaj.emit(event, client.ontimeout);
|
150
|
+
} else {
|
151
|
+
client.ontimeout(event);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
// The timeout callback
|
155
|
+
PleziClient.prototype.ontimeout = function(event) {
|
156
|
+
console.warn("Timeout reached - it's assumed the connection was lost " +
|
157
|
+
"and the following event was ignored by the server:", event);
|
158
|
+
console.log(this);
|
159
|
+
}
|
160
|
+
|
161
|
+
PleziClient.prototype.reconnect = function() {
|
162
|
+
this.connected = NaN;
|
163
|
+
this.ws = new WebSocket(this.url);
|
164
|
+
// lets us access the client from the callbacks
|
165
|
+
this.ws.owner = this;
|
166
|
+
// The Websocket onopen callback
|
167
|
+
this.ws.onopen = this.___on_open;
|
168
|
+
// The Websocket onclose callback
|
169
|
+
this.ws.onclose = this.___on_close;
|
170
|
+
// The Websocket onerror callback
|
171
|
+
this.ws.onerror = this.___on_error;
|
172
|
+
// The Websocket onmessage callback
|
173
|
+
this.ws.onmessage = this.___on_message;
|
174
|
+
}
|
175
|
+
|
176
|
+
PleziClient.prototype.close = function() {
|
177
|
+
this.autoreconnect = false;
|
178
|
+
this.ws.close();
|
179
|
+
}
|
180
|
+
|
181
|
+
PleziClient.origin = (self.location.protocol.match(/https/) ? 'wws' : 'ws') + '://' + self.location.hostname + (self.location.port == '' ? '' : (':' + self.location.port));
|
182
|
+
|
183
|
+
PleziClient.prototype.sendraw = function(data) {
|
184
|
+
if (this.ws.readyState != 1) {
|
185
|
+
return false;
|
186
|
+
}
|
187
|
+
this.ws.send(data);
|
188
|
+
if (this.ws.readyState != 1) {
|
189
|
+
return false;
|
190
|
+
}
|
191
|
+
return true;
|
192
|
+
}
|
193
|
+
|
194
|
+
PleziClient.prototype.emit = function(event, callback, timeout_callback, timeout) {
|
195
|
+
if (!timeout && callback && !this.emit_timeout)
|
196
|
+
timeout = 10;
|
197
|
+
this.___set_failed_timeout(event, timeout_callback, timeout)
|
198
|
+
if (callback) {
|
199
|
+
this[event._EID_] = {
|
200
|
+
callback: callback,
|
201
|
+
event: event
|
202
|
+
};
|
203
|
+
}
|
204
|
+
return this.sendraw(JSON.stringify(event));
|
205
|
+
}
|
206
|
+
|
207
|
+
PleziClient.prototype.readyState = function() {
|
208
|
+
return this.ws.readyState;
|
209
|
+
}
|
210
|
+
|
211
|
+
PleziClient.prototype.___ajaj__emit = function(event, callback) {
|
212
|
+
var combined = {}
|
213
|
+
for (var k in this.add) {
|
214
|
+
combined[k] = this.add[k];
|
215
|
+
};
|
216
|
+
for (var k in event) {
|
217
|
+
combined[k] = event[k];
|
218
|
+
};
|
219
|
+
if (!combined.id) {
|
220
|
+
combined.id = event.event;
|
221
|
+
};
|
222
|
+
var req = new XMLHttpRequest();
|
223
|
+
req.client = this.client;
|
224
|
+
req.json = combined;
|
225
|
+
req.callback = callback;
|
226
|
+
// if(!req.callback) req.callback = this.failed
|
227
|
+
req.onreadystatechange = function() {
|
228
|
+
if (this.readyState != 4) {
|
229
|
+
return;
|
230
|
+
}
|
231
|
+
if (this.status == 200) {
|
232
|
+
try {
|
233
|
+
var res = JSON.parse(this.responseText);
|
234
|
+
this.client.___dispatch(res);
|
235
|
+
} catch (err) {
|
236
|
+
console.error("PleziClient experienced an error parsing the following data (not JSON):",
|
237
|
+
err, this.responseText);
|
238
|
+
}
|
239
|
+
|
240
|
+
} else {
|
241
|
+
if (this.callback) {
|
242
|
+
this.callback(this.json);
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
req.open("POST", this.url, true);
|
247
|
+
req.setRequestHeader("Content-type", "application/json");
|
248
|
+
try {
|
249
|
+
req.send(JSON.stringify(combined));
|
250
|
+
} catch (err) {
|
251
|
+
callback(event);
|
252
|
+
}
|
253
|
+
}
|
data/resources/config.ru
CHANGED
@@ -1,39 +1,8 @@
|
|
1
|
-
|
2
|
-
# RackServer rack interface
|
3
|
-
#
|
4
|
-
# using Rack with Plezi poses some limitations...:
|
5
|
-
#
|
6
|
-
# 1. there is NO WebSockets support for Rack apps.
|
7
|
-
#
|
8
|
-
# 2. this might break any streaming / asynchronous methods calls, such as Iodine's Http streaming.
|
9
|
-
#
|
10
|
-
# 3. Plezi parameters and file uploads are different then Rack - HTML Form code might be incompatible!
|
11
|
-
# This MIGHT BREAKE YOUR CODE! (changing this requires Plezi to re-parse the HTML, and costs in performance).
|
12
|
-
#
|
13
|
-
# also, all Plezi server specific configuration will be ignored.
|
14
|
-
#
|
15
|
-
# on the other hand, there is an upside:
|
16
|
-
#
|
17
|
-
# 1. you can choose a well tested server written in C that might (or might not) bring a performance boost.
|
18
|
-
#
|
19
|
-
# 2. you have better control over Middleware then you could have with Plezi.
|
20
|
-
# ("wait", you might say, "there is no Middleware in Plezi!"... "Ahhh", I will answer, "so much to discover...")
|
21
|
-
#
|
22
|
-
#
|
23
|
-
##############
|
24
|
-
#
|
25
|
-
# For now, Rack mode is NOT supported unless using the Iodine Http server,
|
26
|
-
# even than you're 404 not found pages will break unless using a catch-all route.
|
1
|
+
# Default Rack interface
|
27
2
|
|
28
|
-
# load
|
29
|
-
load ::File.expand_path(File.join(
|
3
|
+
# load the application
|
4
|
+
load ::File.expand_path(File.join('..', 'appname.rb'), __FILE__)
|
30
5
|
|
31
|
-
|
32
|
-
load ::File.expand_path(File.join("..", "routes.rb"), __FILE__)
|
6
|
+
Iodine::Rack.public ||= './public'
|
33
7
|
|
34
|
-
|
35
|
-
if Rack::Handler.default == Iodine::Http::Rack
|
36
|
-
run(Proc.new { [404, {}, ["not found"]] })
|
37
|
-
else
|
38
|
-
raise "Unsupported Server - Plezi only runs using Iodine."
|
39
|
-
end
|
8
|
+
run Plezi.app
|
data/resources/ctrlr.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# Replace this sample with real code.
|
2
|
+
class RootController
|
3
|
+
# HTTP
|
4
|
+
def index
|
5
|
+
# any String returned will be appended to the response. We return a String.
|
6
|
+
render 'welcome'
|
7
|
+
end
|
8
|
+
|
9
|
+
# Websockets
|
10
|
+
def on_message(data)
|
11
|
+
data = ERB::Util.html_escape data
|
12
|
+
print data
|
13
|
+
broadcast :print, data
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_open
|
17
|
+
print 'Welcome to appname!'
|
18
|
+
@handle = params['id'.freeze] || 'Somebody'
|
19
|
+
broadcast :print, "#{ERB::Util.html_escape @handle} joind us :-)"
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_close
|
23
|
+
broadcast :print, "#{@handle} left us :-("
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
# write is inherites when a Websocket connection is opened.
|
29
|
+
#
|
30
|
+
# Inherited functions aren't exposed (for our security), so we need to wrap it.
|
31
|
+
def print(data)
|
32
|
+
write data
|
33
|
+
end
|
34
|
+
end
|
data/resources/gemfile
ADDED
data/resources/mini_app.rb
CHANGED
@@ -1,87 +1,33 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
## Set environment, working directory, load gems and create logs
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
## Log to a file?
|
20
|
-
# Iodine.logger = Logger.new Root.join('server.log').to_s
|
4
|
+
ENV['ENV'] ||= ENV['RACK_ENV'] # production ENV will render SASS as compressed.
|
5
|
+
## Using pathname extentions for setting public folder
|
6
|
+
require 'pathname'
|
7
|
+
## Set up root object, it might be used by the environment and\or the plezi extension gems.
|
8
|
+
Root ||= Pathname.new(File.dirname(__FILE__)).expand_path
|
9
|
+
## If this app is independant, use bundler to load gems (including the plezi gem).
|
10
|
+
## otherwise, use the original app's Gemfile and Plezi will automatically switch to Rack mode.
|
11
|
+
require 'bundler'
|
12
|
+
Bundler.require(:default, ENV['ENV'].to_s.to_sym)
|
13
|
+
|
14
|
+
# Load all the code from a subfolder called 'app'
|
15
|
+
Dir[File.join '{app}', '**', '*.rb'].each { |file| load File.expand_path(file) }
|
16
|
+
|
17
|
+
## Logging
|
18
|
+
Iodine::Rack.log = 1 if Iodine::Rack.log.nil?
|
21
19
|
|
22
20
|
# # Optional Scaling (across processes or machines):
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
#
|
35
|
-
|
36
|
-
# HTTP
|
37
|
-
def index
|
38
|
-
# return response << "Hello World!" # for a hello world app
|
39
|
-
render :welcome
|
40
|
-
end
|
41
|
-
# Websockets
|
42
|
-
def on_message data
|
43
|
-
data = ERB::Util.html_escape data
|
44
|
-
print data
|
45
|
-
broadcast :print, data
|
46
|
-
end
|
47
|
-
def on_open
|
48
|
-
print 'Welcome!'
|
49
|
-
@handle = params[:id] || 'Somebody'
|
50
|
-
broadcast :print, "#{@handle} joind us :-)"
|
51
|
-
end
|
52
|
-
def on_close
|
53
|
-
broadcast :print, "#{@handle} left us :-("
|
54
|
-
end
|
55
|
-
|
56
|
-
protected
|
57
|
-
|
58
|
-
def print data
|
59
|
-
response << data
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
# change some of the default settings here.
|
65
|
-
host templates: Root.join('templates').to_s,
|
66
|
-
# public: Root.join('public').to_s,
|
67
|
-
assets: Root.join('assets').to_s
|
68
|
-
|
69
|
-
# # I18n re-write, i.e.: `/en/home` will be rewriten as `/home`, while setting params[:locale] to "en"
|
70
|
-
# route "/:locale{#{I18n.available_locales.join "|"}}/*" , false if defined? I18n
|
71
|
-
|
72
|
-
# # Response format re-write, i.e.: `/xml/home` will use .xml templates automatically
|
73
|
-
# # with :locale a request might look like `/en/json/...`
|
74
|
-
# route "/:format{html|json|xml}/*" , false
|
75
|
-
|
76
|
-
# # OAuth2 - Facebook / Google authentication
|
77
|
-
# ENV["FB_APP_ID"] ||= "app id"; ENV["FB_APP_SECRET"] ||= "secret"; ENV['GOOGLE_APP_ID'] = "app id"; ENV['GOOGLE_APP_SECRET'] = "secret"
|
78
|
-
# require 'plezi/oauth' # do this AFTER setting ENV variables.
|
79
|
-
# create_auth_shared_route do |service_name, auth_token, remote_user_id, remote_user_email, remote_response|
|
80
|
-
# # ...callback for authentication.
|
81
|
-
# # This callback should return the app user object or false
|
82
|
-
# # This callback has access to the controller's methods (request, cookies, response, etc')
|
83
|
-
# end
|
84
|
-
|
85
|
-
# Add your routes and controllers by order of priority.
|
86
|
-
route '/(:id)', MyController
|
87
|
-
|
21
|
+
ENV['PL_REDIS_URL'] ||= ENV['REDIS_URL'] ||
|
22
|
+
ENV['REDISCLOUD_URL'] ||
|
23
|
+
ENV['REDISTOGO_URL'] ||
|
24
|
+
nil # "redis://:password@my.host:6389/0"
|
25
|
+
# # redis channel name should be changed IF using the same Plezi code within
|
26
|
+
# # more then one application (i.e., using both Rails and Plezi together).
|
27
|
+
# Plezi.app_name = 'appsecret'
|
28
|
+
|
29
|
+
# Map the views folder to the template root (for the {#render} function).
|
30
|
+
Plezi.templates = Root.join('views').to_s
|
31
|
+
|
32
|
+
# load routes.
|
33
|
+
load Root.join('routes.rb').to_s
|