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/haml_config.rb
DELETED
data/resources/i18n_config.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
if defined? I18n
|
4
|
-
# set up i18n locales paths
|
5
|
-
I18n.load_path = Dir[Root.join('locales', '*.{rb,yml}').to_s]
|
6
|
-
|
7
|
-
# This will prevent certain errors from showing up.
|
8
|
-
I18n.enforce_available_locales = false
|
9
|
-
|
10
|
-
# set default locale, if not english
|
11
|
-
# I18n.default_locale = :ru
|
12
|
-
|
13
|
-
end
|
14
|
-
|
data/resources/initialize.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
# this file sets up the basic framework.
|
4
|
-
|
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
|
-
|
10
|
-
# make sure all file access and file loading is relative to the application's root folder
|
11
|
-
Dir.chdir Root.to_s
|
12
|
-
|
13
|
-
# ensure development mode? (comment before production, environment dependent)
|
14
|
-
ENV['ENV'] ||= ENV["RACK_ENV"] ||= "development"
|
15
|
-
|
16
|
-
# save the process id (pid) to file - notice Heroku doesn't allow to write files.
|
17
|
-
(IO.write File.expand_path(File.join 'tmp','pid'), Process.pid unless ENV["DYNO"]) rescue true
|
18
|
-
|
19
|
-
# using bundler to load gems (including the plezi gem)
|
20
|
-
require 'bundler'
|
21
|
-
Bundler.require(:default, ENV['ENV'].to_s.to_sym)
|
22
|
-
|
23
|
-
# require tilt/sass in a thread safe way (before multi-threading cycle begins)
|
24
|
-
require 'tilt/sass' if defined?(::Slim) && defined?(::Sass)
|
25
|
-
|
26
|
-
# # set up Plezi's logs to a log file?
|
27
|
-
# Iodine.logger = Logger.new(File.expand_path(File.join 'logs','server.log')) unless ENV["DYNO"]
|
28
|
-
|
29
|
-
# set the session token name?
|
30
|
-
Iodine::Http.session_token = 'appname_uui'
|
31
|
-
|
32
|
-
## Allow forking? ONLY if your code is fully scalable across processes.
|
33
|
-
# Iodine.processes = 4
|
34
|
-
|
35
|
-
# load all config files
|
36
|
-
Dir[File.join "{initialize}", "**" , "*.rb"].each {|file| load File.expand_path(file)}
|
37
|
-
|
38
|
-
# load all library files
|
39
|
-
Dir[File.join "{lib}", "**" , "*.rb"].each {|file| load File.expand_path(file)}
|
40
|
-
|
41
|
-
# load all application files
|
42
|
-
Dir[File.join "{app}", "**" , "*.rb"].each {|file| load File.expand_path(file)}
|
43
|
-
|
44
|
-
# change some of the default settings here.
|
45
|
-
host host: :default,
|
46
|
-
public: Root.join('public').to_s,
|
47
|
-
assets: Root.join('assets').to_s,
|
48
|
-
assets_public: '/assets',
|
49
|
-
templates: Root.join('app','views').to_s
|
data/resources/mini_exec.rb
DELETED
data/resources/oauth_config.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
###############
|
2
|
-
# # OAuth2 Config File
|
3
|
-
# # ==================
|
4
|
-
# #
|
5
|
-
# # Here you can sets the OAuth2 variables and require the OAuth2 Plezi controller.
|
6
|
-
# # (if the variables aren't set BEFORE the inclution, automatic setup will NOT take place)
|
7
|
-
# #
|
8
|
-
# # First set the variables:
|
9
|
-
# #
|
10
|
-
# ENV["FB_APP_ID"] ||= "app id"
|
11
|
-
# ENV["FB_APP_SECRET"] ||= "secret"
|
12
|
-
# ENV['GOOGLE_APP_ID'] = "app id"
|
13
|
-
# ENV['GOOGLE_APP_SECRET'] = "secret"
|
14
|
-
# #
|
15
|
-
# # Then, require the actual OAuth2 controller class (Plezi::OAuth2Ctrl).
|
16
|
-
# #
|
17
|
-
# require 'plezi/oauth'
|
18
|
-
# #
|
19
|
-
# # Last, but not least, remember to add the authentication route in the 'routes.rb' (remember path priority placement):
|
20
|
-
# create_auth_shared_route do |service_name, auth_token, remote_user_id, remote_user_email, remote_response|
|
21
|
-
# # ...callback for authentication.
|
22
|
-
# # This callback should return the app user object or false
|
23
|
-
# # This callback has access to the magic controller methods (request, cookies, etc')
|
24
|
-
# end
|
data/resources/plezi_client.js
DELETED
@@ -1,198 +0,0 @@
|
|
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 + window.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) {this.autoreconnect = true;}
|
52
|
-
}
|
53
|
-
// The Websocket onopen callback
|
54
|
-
PleziClient.prototype.___on_open = function(e) {
|
55
|
-
this.owner.connected = true;
|
56
|
-
if (this.owner.onopen) { this.owner.onopen(e) }
|
57
|
-
}
|
58
|
-
// The Websocket onclose callback
|
59
|
-
PleziClient.prototype.___on_close = function(e) {
|
60
|
-
this.owner.connected = false;
|
61
|
-
if (this.owner.onclose) { this.owner.onclose(e) }
|
62
|
-
if(this.owner.autoreconnect) {
|
63
|
-
setTimeout( function(obj) {
|
64
|
-
obj.reconnect();
|
65
|
-
}, this.owner.reconnect_interval, this.owner);
|
66
|
-
}
|
67
|
-
}
|
68
|
-
// The Websocket onerror callback
|
69
|
-
PleziClient.prototype.___on_error = function(e) {
|
70
|
-
if (this.owner.onerror) {this.owner.onerror(e)}
|
71
|
-
}
|
72
|
-
// The Websocket onmessage callback
|
73
|
-
PleziClient.prototype.___on_message = function(e) {
|
74
|
-
try {
|
75
|
-
var msg = JSON.parse(e.data);
|
76
|
-
this.owner.___dispatch(msg);
|
77
|
-
} catch(err) {
|
78
|
-
console.error("PleziClient experienced an error parsing the following data (not JSON):",
|
79
|
-
err, e.data)
|
80
|
-
}
|
81
|
-
}
|
82
|
-
PleziClient.prototype.___dispatch = function(msg) {
|
83
|
-
try {
|
84
|
-
if (this.log_events) {console.log(msg)}
|
85
|
-
if ( msg.event == '_ack_') { clearTimeout(msg._EID_) }
|
86
|
-
if ( (msg.event) && (this[msg.event])) {
|
87
|
-
this[msg.event](msg);
|
88
|
-
} else if ( (msg.event) && (this['on' + msg.event])) {
|
89
|
-
console.warn('PleziClient: use a callback called "' + msg.event +
|
90
|
-
'" instead of of "on' + msg.event + '"');
|
91
|
-
this['on' + msg.event](msg);
|
92
|
-
} else
|
93
|
-
{
|
94
|
-
if (this['unknown'] && (msg.event != '_ack_') ) {this['unknown'](msg)};
|
95
|
-
}
|
96
|
-
} catch(err) {
|
97
|
-
console.error("PleziClient experienced an error while responding to the following onmessage event",
|
98
|
-
err, e)
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
// Sets a timeout for the websocket message
|
103
|
-
PleziClient.prototype.___set_failed_timeout = function(event, callback, timeout) {
|
104
|
-
if(event._EID_) {return event;};
|
105
|
-
if(!timeout) { timeout = this.emit_timeout; };
|
106
|
-
if(!callback) { callback = this.___on_timeout; };
|
107
|
-
if(!timeout) { return event; };
|
108
|
-
event._EID_ = setTimeout(callback, timeout, event, this);
|
109
|
-
return event;
|
110
|
-
}
|
111
|
-
// Removes the _client_ property from the event and calls
|
112
|
-
// the ontimeout callback within the correct scope
|
113
|
-
PleziClient.prototype.___on_timeout = function(event, client) {
|
114
|
-
if (client.ajaj.auto) {
|
115
|
-
if (client.log_events) {console.log("falling back on AJAJ for the event:", event)}
|
116
|
-
client.ajaj.emit(event, client.ontimeout);
|
117
|
-
} else {
|
118
|
-
client.ontimeout(event);
|
119
|
-
}
|
120
|
-
}
|
121
|
-
// The timeout callback
|
122
|
-
PleziClient.prototype.ontimeout = function(event) {
|
123
|
-
console.warn("Timeout reached - it's assumed the connection was lost " +
|
124
|
-
"and the following event was ignored by the server:", event);
|
125
|
-
console.log(this);
|
126
|
-
}
|
127
|
-
|
128
|
-
PleziClient.prototype.reconnect = function() {
|
129
|
-
this.connected = NaN;
|
130
|
-
this.ws = new WebSocket(this.url);
|
131
|
-
// lets us access the client from the callbacks
|
132
|
-
this.ws.owner = this
|
133
|
-
// The Websocket onopen callback
|
134
|
-
this.ws.onopen = this.___on_open
|
135
|
-
// The Websocket onclose callback
|
136
|
-
this.ws.onclose = this.___on_close
|
137
|
-
// The Websocket onerror callback
|
138
|
-
this.ws.onerror = this.___on_error
|
139
|
-
// The Websocket onmessage callback
|
140
|
-
this.ws.onmessage = this.___on_message
|
141
|
-
}
|
142
|
-
|
143
|
-
PleziClient.prototype.close = function() {
|
144
|
-
this.autoreconnect = false;
|
145
|
-
this.ws.close();
|
146
|
-
}
|
147
|
-
|
148
|
-
PleziClient.origin = (window.location.protocol.match(/https/) ? 'wws' : 'ws') + '://' + window.location.hostname + (window.location.port == '' ? '' : (':' + window.location.port) );
|
149
|
-
|
150
|
-
PleziClient.prototype.sendraw = function(data) {
|
151
|
-
if (this.ws.readyState != 1) { return false; }
|
152
|
-
this.ws.send(data);
|
153
|
-
if (this.ws.readyState != 1) { return false; }
|
154
|
-
return true
|
155
|
-
}
|
156
|
-
|
157
|
-
PleziClient.prototype.emit = function(event, callback, timeout) {
|
158
|
-
this.___set_failed_timeout(event, callback, timeout)
|
159
|
-
return this.sendraw( JSON.stringify(event) );
|
160
|
-
}
|
161
|
-
|
162
|
-
PleziClient.prototype.readyState = function() { return this.ws.readyState; }
|
163
|
-
|
164
|
-
PleziClient.prototype.___ajaj__emit = function(event, callback) {
|
165
|
-
var combined = {}
|
166
|
-
for (var k in this.add) {combined[k] = this.add[k];};
|
167
|
-
for (var k in event) {combined[k] = event[k];};
|
168
|
-
if(!combined.id) {combined.id = event.event;};
|
169
|
-
var req = new XMLHttpRequest();
|
170
|
-
req.client = this.client;
|
171
|
-
req.json = combined;
|
172
|
-
req.callback = callback
|
173
|
-
// if(!req.callback) req.callback = this.failed
|
174
|
-
req.onreadystatechange = function() {
|
175
|
-
if (this.readyState != 4) { return }
|
176
|
-
if (this.status == 200) {
|
177
|
-
try {
|
178
|
-
var res = JSON.parse(this.responseText);
|
179
|
-
this.client.___dispatch(res);
|
180
|
-
} catch(err) {
|
181
|
-
console.error("PleziClient experienced an error parsing the following data (not JSON):",
|
182
|
-
err, this.responseText)
|
183
|
-
}
|
184
|
-
|
185
|
-
} else {
|
186
|
-
if(this.callback) {
|
187
|
-
this.callback(this.json);
|
188
|
-
}
|
189
|
-
}
|
190
|
-
}
|
191
|
-
req.open("POST", this.url ,true);
|
192
|
-
req.setRequestHeader("Content-type", "application/json");
|
193
|
-
try {
|
194
|
-
req.send(JSON.stringify(combined));
|
195
|
-
} catch(err) {
|
196
|
-
callback(event)
|
197
|
-
}
|
198
|
-
}
|
@@ -1,47 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<head>
|
3
|
-
<meta charset='UTF-8'>
|
4
|
-
<style>
|
5
|
-
html, body {width: 100%; height:100%;}
|
6
|
-
body {font-size: 1.5em; background-color: #eee;}
|
7
|
-
p {padding: 0.2em; margin: 0;}
|
8
|
-
.received { color: #00f;}
|
9
|
-
.sent { color: #f0f;}
|
10
|
-
.connection { color: #0f0;}
|
11
|
-
.error { color: #f00;}
|
12
|
-
input, #output {font-size: 1em; width: 60%; margin: 0.5em 19%; padding: 0.5em 1%;}
|
13
|
-
#output {height: 60%; overflow: auto; background-color: #fff;}
|
14
|
-
</style>
|
15
|
-
<script>
|
16
|
-
var websocket = NaN;
|
17
|
-
function connect() { websocket = new WebSocket( (window.location.protocol.match(/https/) ? 'wws' : 'ws') + '://' + window.location.hostname + (window.location.port == '' ? '' : (':' + window.location.port) ) + "/" ); }
|
18
|
-
function init()
|
19
|
-
{
|
20
|
-
connect()
|
21
|
-
websocket.onopen = function(evt) { WriteMessage("Connected.", "connection") };
|
22
|
-
websocket.onclose = function(evt) { WriteMessage("Disconnected.", "connection");connect(); };
|
23
|
-
websocket.onmessage = function(evt) {
|
24
|
-
WriteMessage(evt.data);
|
25
|
-
};
|
26
|
-
websocket.onerror = function(evt) { WriteMessage(evt.data, 'error'); };
|
27
|
-
}
|
28
|
-
function WriteMessage( message, message_type )
|
29
|
-
{
|
30
|
-
if (!message_type) message_type = 'received'
|
31
|
-
var msg = document.createElement("p");
|
32
|
-
msg.className = message_type;
|
33
|
-
msg.innerHTML = message;
|
34
|
-
document.getElementById("output").appendChild(msg);
|
35
|
-
}
|
36
|
-
function Send(message)
|
37
|
-
{
|
38
|
-
WriteMessage(message, 'sent');
|
39
|
-
websocket.send(message);
|
40
|
-
}
|
41
|
-
window.addEventListener("load", init, false);
|
42
|
-
</script>
|
43
|
-
</head>
|
44
|
-
<body>
|
45
|
-
<div id='output'>test</div>
|
46
|
-
<input type='text' placeholder='your message goes here.' value='' />
|
47
|
-
</body>
|
data/resources/redis_config.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
if defined? Redis
|
4
|
-
|
5
|
-
# ## Plezi Redis Automation
|
6
|
-
# ## ====
|
7
|
-
# ##
|
8
|
-
# ## Sets up Plezi to use Radis broadcast.
|
9
|
-
# ##
|
10
|
-
# ## If Plezi Redis Automation is enabled:
|
11
|
-
# ## Plezi creates is own listening thread that listens for messages and broadcasts using Redis.
|
12
|
-
# ##
|
13
|
-
# ## Only one thread will be created and initiated during startup (dynamically created controller routes might be ignored).
|
14
|
-
# ##
|
15
|
-
# `redis_channel_name` should be set when using the Placebo API.
|
16
|
-
# (otherwise, it's only optional, as the automatic settings are good enough)
|
17
|
-
Plezi::Settings.redis_channel_name = 'appsecret'
|
18
|
-
ENV['PL_REDIS_URL'] ||= ENV['REDIS_URL'] ||
|
19
|
-
ENV['REDISCLOUD_URL'] ||
|
20
|
-
ENV['REDISTOGO_URL'] ||
|
21
|
-
nil # use: "redis://:password@my.host:6389/0"
|
22
|
-
|
23
|
-
|
24
|
-
# ## OR, write your own custom Redis implementation here
|
25
|
-
# ## ====
|
26
|
-
# ##
|
27
|
-
# ## create a listening thread - rewrite the following code for your own Redis tailored solution.
|
28
|
-
# ##
|
29
|
-
# ## the following is only sample code for you to change:
|
30
|
-
# RADIS_CHANNEL = 'appsecret'
|
31
|
-
# RADIS_URI = ENV['REDIS_URL'] || ENV['REDISCLOUD_URL'] || "redis://:password@my.host:6389/0"
|
32
|
-
# RADIS_CONNECTION = Redis.new(url: RADIS_URI)
|
33
|
-
# RADIS_THREAD = Thread.new do
|
34
|
-
# Redis.new(RADIS_URI).subscribe(RADIS_CHANNEL) do |on|
|
35
|
-
# on.message do |channel, msg|
|
36
|
-
# msg = JSON.parse(msg)
|
37
|
-
# # do stuff, i.e.:
|
38
|
-
# # Plezi.run(msg) { |m| Plezi.info m.to_s }
|
39
|
-
# end
|
40
|
-
# end
|
41
|
-
# end
|
42
|
-
end
|
data/resources/slim_config.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
if defined?(Slim)
|
4
|
-
require 'rouge/plugins/redcarpet' if defined?(Redcarpet) && defined?(Rouge)
|
5
|
-
if defined?(Redcarpet::Render::HTML) && defined?(Rouge::Plugins::Redcarpet)
|
6
|
-
Slim::Embedded.options[:markdown] = {
|
7
|
-
fenced_code_blocks: true,
|
8
|
-
renderer: (Class.new(Redcarpet::Render::HTML) {include Rouge::Plugins::Redcarpet} ).new
|
9
|
-
}
|
10
|
-
end
|
11
|
-
end
|
data/resources/welcome_page.html
DELETED
@@ -1,272 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<head>
|
3
|
-
<title>appname - Feed Me!</title>
|
4
|
-
<meta content="width=device-width, initial-scale=1, maximum-scale=2.0, user-scalable=yes, minimal-ui=yes" name="viewport">
|
5
|
-
<link href='https://fonts.googleapis.com/css?family=Shadows+Into+Light|Architects+Daughter' rel='stylesheet' type='text/css'>
|
6
|
-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
7
|
-
<style type="text/css">
|
8
|
-
/*
|
9
|
-
med-blue: #44518E
|
10
|
-
dark-gray: #424A70
|
11
|
-
blue: #1B2864
|
12
|
-
light-blue: #818ECE
|
13
|
-
light-gray: #99A3CE
|
14
|
-
*/
|
15
|
-
body, html
|
16
|
-
{
|
17
|
-
background-color: #99A3CE;
|
18
|
-
padding: 0; margin: 0;
|
19
|
-
width: 100%;
|
20
|
-
font-size: 1em;
|
21
|
-
}
|
22
|
-
|
23
|
-
h1
|
24
|
-
{
|
25
|
-
font-family: 'Shadows Into Light', cursive;
|
26
|
-
background-color: #1B2864;
|
27
|
-
color: #99A3CE;
|
28
|
-
text-align: center;
|
29
|
-
border-bottom: 4px solid #424A70;
|
30
|
-
margin: 0 0 1em 0;
|
31
|
-
padding: 0.4em 0;
|
32
|
-
width: 100%;
|
33
|
-
}
|
34
|
-
h2
|
35
|
-
{
|
36
|
-
background-color: #44518E;
|
37
|
-
color: #C6CCE7;
|
38
|
-
text-align: left;
|
39
|
-
margin: 0 0 1em 0;
|
40
|
-
padding: 0.5em 5%;
|
41
|
-
border-radius: 20px 20px 0 0;
|
42
|
-
font-family: 'Architects Daughter', cursive;
|
43
|
-
border-bottom: 3px solid #424A70;
|
44
|
-
font-size: 1.2em;
|
45
|
-
}
|
46
|
-
h3
|
47
|
-
{
|
48
|
-
font-family: 'Architects Daughter', cursive;
|
49
|
-
background-color: #44518E;
|
50
|
-
color: #C6CCE7;
|
51
|
-
text-align: left;
|
52
|
-
margin: 0 0 1em 0;
|
53
|
-
padding: 0.5em 5%;
|
54
|
-
border-radius: 1em 1em 0 0;
|
55
|
-
border-bottom: 2px solid #424A70;
|
56
|
-
font-size: 1.1em;
|
57
|
-
}
|
58
|
-
h2:before {
|
59
|
-
content: "|||";
|
60
|
-
color: #99A3CE;
|
61
|
-
padding-right: 0.3em;
|
62
|
-
margin-left: -0.5em;
|
63
|
-
}
|
64
|
-
h3:before {
|
65
|
-
content: "|||||";
|
66
|
-
color: #99A3CE;
|
67
|
-
padding-right: 0.3em;
|
68
|
-
margin-left: -1em;
|
69
|
-
}
|
70
|
-
h1 a, h2 a, h3 a
|
71
|
-
{
|
72
|
-
color: #EBCD86;
|
73
|
-
}
|
74
|
-
h1 a:hover, h2 a:hover, h3 a:hover
|
75
|
-
{
|
76
|
-
color: #EBD7A6;
|
77
|
-
}
|
78
|
-
p
|
79
|
-
{
|
80
|
-
font-size: 1em;
|
81
|
-
padding: 0 1em;
|
82
|
-
margin: 0.5em 0;
|
83
|
-
}
|
84
|
-
a
|
85
|
-
{
|
86
|
-
color: #D0AC54;
|
87
|
-
text-decoration: none;
|
88
|
-
}
|
89
|
-
a:hover
|
90
|
-
{
|
91
|
-
color: #927121;
|
92
|
-
text-decoration: underline;
|
93
|
-
}
|
94
|
-
#wrapper
|
95
|
-
{
|
96
|
-
background-color: #fff;
|
97
|
-
margin: 1em 5%;
|
98
|
-
padding: 0 0 2%;
|
99
|
-
border-radius: 20px;
|
100
|
-
min-height: 50%;
|
101
|
-
color: #007;
|
102
|
-
}
|
103
|
-
|
104
|
-
#wrapper p{ padding: 0 2%;}
|
105
|
-
.bold { font-weight: bold; }
|
106
|
-
#wrapper ol li{ padding: 0 2%;}
|
107
|
-
pre
|
108
|
-
{
|
109
|
-
border-radius: 20px;
|
110
|
-
padding: 0.5em 0;
|
111
|
-
background-color: #444;
|
112
|
-
color: #ddd;
|
113
|
-
}
|
114
|
-
input[type=text]
|
115
|
-
{
|
116
|
-
width: 60%;
|
117
|
-
font-size: 1.1em;
|
118
|
-
display: inline-block;
|
119
|
-
background-color: #fff;
|
120
|
-
color: #424A70;
|
121
|
-
border-radius: 0.5em;
|
122
|
-
border: 1px solid #424A70;
|
123
|
-
outline: none;
|
124
|
-
box-sizing: border-box;
|
125
|
-
padding: 0 1em;
|
126
|
-
}
|
127
|
-
input[type=submit]
|
128
|
-
{
|
129
|
-
font-size: 1.1em;
|
130
|
-
color: #424A70;
|
131
|
-
border-radius: 0.5em;
|
132
|
-
box-sizing: border-box;
|
133
|
-
border: 1px solid #424A70;
|
134
|
-
background-color: #fff;
|
135
|
-
padding: 0 0.4em;
|
136
|
-
}
|
137
|
-
input[type=submit]:hover
|
138
|
-
{
|
139
|
-
background-color: #818ECE; color:#fff;
|
140
|
-
}
|
141
|
-
input[type=submit]:active
|
142
|
-
{
|
143
|
-
background-color: #1B2864; color:#fff;
|
144
|
-
}
|
145
|
-
|
146
|
-
#monitor
|
147
|
-
{
|
148
|
-
margin: 0 5%; padding: 0.5em 3em;
|
149
|
-
box-sizing: border-box;
|
150
|
-
width: 90%;
|
151
|
-
font-size: 1.1em;
|
152
|
-
display: inline-block;
|
153
|
-
background-color: #C6CCE7;
|
154
|
-
color: #424A70;
|
155
|
-
border-radius: 0.5em;
|
156
|
-
border: 1px solid #424A70;
|
157
|
-
}
|
158
|
-
#monitor p
|
159
|
-
{
|
160
|
-
text-align: center;
|
161
|
-
}
|
162
|
-
.system_message { color: #1B2864; font-style: italic;}
|
163
|
-
@media screen and (max-width: 680px)
|
164
|
-
{
|
165
|
-
input[type=submit], input[type=text] {
|
166
|
-
font-size: 1em;
|
167
|
-
}
|
168
|
-
input[type=text] { width: 100%;}
|
169
|
-
#monitor
|
170
|
-
{
|
171
|
-
margin: 0 3%; padding: 0.5em 1em;
|
172
|
-
}
|
173
|
-
ul {padding: 0 1em;}
|
174
|
-
}
|
175
|
-
|
176
|
-
</style>
|
177
|
-
<script type="text/javascript">
|
178
|
-
// Your websocket URI should be an absolute path. The following sets the base URI.
|
179
|
-
// remember to update to the specific controller's path to your websocket URI.
|
180
|
-
var ws_controller_path = '/' // window.location.pathname; // change to '/controller/path'
|
181
|
-
var ws_uri = (window.location.protocol.match(/https/) ? 'wss' : 'ws') + '://' + window.document.location.host + ws_controller_path
|
182
|
-
// websocket variable.
|
183
|
-
var websocket = NaN
|
184
|
-
// count failed attempts
|
185
|
-
var websocket_fail_count = 0
|
186
|
-
|
187
|
-
function init_websocket()
|
188
|
-
{
|
189
|
-
if(websocket && websocket.readyState == 1) return true; // console.log('no need to renew socket connection');
|
190
|
-
websocket = new WebSocket(ws_uri);
|
191
|
-
websocket.onopen = function(e) {
|
192
|
-
//restart fail count
|
193
|
-
websocket_fail = 0
|
194
|
-
// what do you want to do now?
|
195
|
-
var msg = document.createElement("li");
|
196
|
-
msg.className = 'system_message'
|
197
|
-
msg.innerHTML = "Connected.";
|
198
|
-
document.getElementById("output").appendChild(msg);
|
199
|
-
};
|
200
|
-
|
201
|
-
websocket.onclose = function(e) {
|
202
|
-
// what do you want to do now?
|
203
|
-
if(websocket_fail == 0) {
|
204
|
-
var msg = document.createElement("li");
|
205
|
-
msg.className = 'system_message'
|
206
|
-
msg.innerHTML = "Disconnected.";
|
207
|
-
document.getElementById("output").appendChild(msg);
|
208
|
-
};
|
209
|
-
// you probably want to reopen the websocket if it closes (unless the issue repeats).
|
210
|
-
if(websocket_fail <= 5) {
|
211
|
-
websocket_fail += 1;
|
212
|
-
setTimeout( init_websocket, 250);
|
213
|
-
};
|
214
|
-
};
|
215
|
-
websocket.onerror = function(e) {
|
216
|
-
// what do you want to do now?
|
217
|
-
};
|
218
|
-
websocket.onmessage = function(e) {
|
219
|
-
// what do you want to do now?
|
220
|
-
console.log(e.data);
|
221
|
-
var msg = document.createElement("li");
|
222
|
-
msg.innerHTML = e.data;
|
223
|
-
document.getElementById("output").appendChild(msg);
|
224
|
-
// to use JSON, use:
|
225
|
-
// msg = JSON.parse(e.data); // remember to use JSON also in your Plezi controller.
|
226
|
-
};
|
227
|
-
}
|
228
|
-
window.addEventListener("load", init_websocket, false);
|
229
|
-
function send_text()
|
230
|
-
{
|
231
|
-
var msg = document.getElementById("input").value;
|
232
|
-
document.getElementById("input").value = '';
|
233
|
-
websocket.send(msg);
|
234
|
-
return false;
|
235
|
-
}
|
236
|
-
</script>
|
237
|
-
</head>
|
238
|
-
<body>
|
239
|
-
<h1>Welcome to <a href="http://www.plezi.io/">Plezi</a></h1>
|
240
|
-
<div id="wrapper">
|
241
|
-
<h2>Congratulations, <a href='/'>appname</a> is running - What's next?</h2>
|
242
|
-
<p><span class="bold">Congratulations</span>, you're now running appname and it has so much potential!</p>
|
243
|
-
<p>appname started out <a href="http://www.plezi.io/">Plezi</a> and it's your quest to feed it your code and make sure appname grows strong and happy.</p>
|
244
|
-
<p>You're the master of this quest, and your next steps might include:</p>
|
245
|
-
<ol><li><p class="bold">Deciding which gems to use:</p>
|
246
|
-
<ul>
|
247
|
-
<li>edit Gemfile in the appname folder.</li>
|
248
|
-
</ul>
|
249
|
-
</li>
|
250
|
-
<li>
|
251
|
-
<p class="bold">Reviewing the sample code and feeding <a href="http://www.plezi.io/">Plezi</a> your code:</p>
|
252
|
-
<ul>
|
253
|
-
<li>Review the 'sample_controller.rb' file in the appname/app/controllers folder.</li>
|
254
|
-
<li>Delete the 'sample_controller.rb' file and this file (appname/assets/welcome.html).</li>
|
255
|
-
<li>Write your own controller and code.</li>
|
256
|
-
<li>Edit the 'routes.rb' file to set up your routes.</li>
|
257
|
-
</ul>
|
258
|
-
</li>
|
259
|
-
<li>
|
260
|
-
<p><span class="bold">Having fun</span> and submitting any issues you discover to the <a href="https://github.com/boazsegev/plezi">Plezi Github Project.</a></p>
|
261
|
-
</li>
|
262
|
-
</ol>
|
263
|
-
<p class="bold">Good Luck!</p>
|
264
|
-
<h3> Did you try our websocket broadcast? </h3>
|
265
|
-
<p>Your appname app can send <span class="bold">WebSocket</span> broadcasts (and unicasts). Why not try them out? You can even try them across multiple windows.</p>
|
266
|
-
<form onsubmit='send_text(); return false;' id='monitor'>
|
267
|
-
<p><input type='text' id='input' placeholder='Your message' /> <input type='submit' value='Broadcast'/> </p>
|
268
|
-
<ul id='output'>
|
269
|
-
</ul>
|
270
|
-
</form>
|
271
|
-
</div>
|
272
|
-
</body>
|