plezi 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/CHANGELOG.md +450 -0
- data/Gemfile +4 -0
- data/KNOWN_ISSUES.md +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +341 -0
- data/Rakefile +2 -0
- data/TODO.md +19 -0
- data/bin/plezi +301 -0
- data/lib/plezi.rb +125 -0
- data/lib/plezi/base/cache.rb +77 -0
- data/lib/plezi/base/connections.rb +33 -0
- data/lib/plezi/base/dsl.rb +177 -0
- data/lib/plezi/base/engine.rb +85 -0
- data/lib/plezi/base/events.rb +84 -0
- data/lib/plezi/base/io_reactor.rb +41 -0
- data/lib/plezi/base/logging.rb +62 -0
- data/lib/plezi/base/rack_app.rb +89 -0
- data/lib/plezi/base/services.rb +57 -0
- data/lib/plezi/base/timers.rb +71 -0
- data/lib/plezi/handlers/controller_magic.rb +383 -0
- data/lib/plezi/handlers/http_echo.rb +27 -0
- data/lib/plezi/handlers/http_host.rb +215 -0
- data/lib/plezi/handlers/http_router.rb +69 -0
- data/lib/plezi/handlers/magic_helpers.rb +43 -0
- data/lib/plezi/handlers/route.rb +272 -0
- data/lib/plezi/handlers/stubs.rb +143 -0
- data/lib/plezi/server/README.md +33 -0
- data/lib/plezi/server/helpers/http.rb +169 -0
- data/lib/plezi/server/helpers/mime_types.rb +999 -0
- data/lib/plezi/server/protocols/http_protocol.rb +318 -0
- data/lib/plezi/server/protocols/http_request.rb +133 -0
- data/lib/plezi/server/protocols/http_response.rb +294 -0
- data/lib/plezi/server/protocols/websocket.rb +208 -0
- data/lib/plezi/server/protocols/ws_response.rb +92 -0
- data/lib/plezi/server/services/basic_service.rb +224 -0
- data/lib/plezi/server/services/no_service.rb +196 -0
- data/lib/plezi/server/services/ssl_service.rb +193 -0
- data/lib/plezi/version.rb +3 -0
- data/plezi.gemspec +26 -0
- data/resources/404.erb +68 -0
- data/resources/404.haml +64 -0
- data/resources/404.html +67 -0
- data/resources/404.slim +63 -0
- data/resources/500.erb +68 -0
- data/resources/500.haml +63 -0
- data/resources/500.html +67 -0
- data/resources/500.slim +63 -0
- data/resources/Gemfile +85 -0
- data/resources/anorexic_gray.png +0 -0
- data/resources/anorexic_websockets.html +47 -0
- data/resources/code.rb +8 -0
- data/resources/config.ru +39 -0
- data/resources/controller.rb +139 -0
- data/resources/db_ac_config.rb +58 -0
- data/resources/db_dm_config.rb +51 -0
- data/resources/db_sequel_config.rb +42 -0
- data/resources/en.yml +204 -0
- data/resources/environment.rb +41 -0
- data/resources/haml_config.rb +6 -0
- data/resources/i18n_config.rb +14 -0
- data/resources/rakefile.rb +22 -0
- data/resources/redis_config.rb +35 -0
- data/resources/routes.rb +26 -0
- data/resources/welcome_page.html +72 -0
- data/websocket chatroom.md +639 -0
- metadata +141 -0
@@ -0,0 +1,139 @@
|
|
1
|
+
#########################################
|
2
|
+
# this is your SampleController
|
3
|
+
#
|
4
|
+
# feed it and give it plenty of children, borothers and sisters.
|
5
|
+
#
|
6
|
+
#########################################
|
7
|
+
#
|
8
|
+
# this is a skelaton for a RESTful and WebSocket controller implementation.
|
9
|
+
#
|
10
|
+
# it can also be used for non RESTful requests by utilizing only the
|
11
|
+
# index method or other, non-RESTful, named methods.
|
12
|
+
#
|
13
|
+
# if a method returns false, an 404 not found is assumed. and routes continue to search.
|
14
|
+
#
|
15
|
+
# otherwise, the method's returned value is added to the response body (if it's a String).
|
16
|
+
#
|
17
|
+
# methods should return true (if the response was set/sent) or the body's string as their last value.
|
18
|
+
#
|
19
|
+
# no inheritance is required (the Plezi framework inherits your code, not the other way around).
|
20
|
+
#
|
21
|
+
# here are some of the available controller properties and methods:
|
22
|
+
#
|
23
|
+
# attr_accessor :params, :request, :response, :cookies
|
24
|
+
#
|
25
|
+
# params:: short-cut for request.params
|
26
|
+
# request:: the request object
|
27
|
+
# response:: the response object.
|
28
|
+
# cookies:: a magic cookie-jar (sets and gets cookies).
|
29
|
+
# flash:: a hash used for one-time cookies (get and set). any added values will be available for the same client for this and the next connection, after which they are removed.
|
30
|
+
#
|
31
|
+
# redirect_to:: easily set up redirection.
|
32
|
+
# send_data:: easily send data, setting the content-type and content-length headers.
|
33
|
+
# render:: easily render Slim, Haml and IRB files into String text.
|
34
|
+
#
|
35
|
+
class SampleController
|
36
|
+
|
37
|
+
# it is possible to includes all the Plezi::FeedHaml helper methods...
|
38
|
+
# ... this breakes the strict MVC architecture by running the HAML view
|
39
|
+
# as part of the controller class. It's good for hacking, but bad practice.
|
40
|
+
# include Plezi::FeedHaml if defined? Plezi::FeedHaml
|
41
|
+
|
42
|
+
# called before any action except WebSockets actions
|
43
|
+
def before
|
44
|
+
# some actions before the request is parsed
|
45
|
+
# you can remove this, ofcourse. the router doesn't require the method to exist.
|
46
|
+
|
47
|
+
## uncomment the following line for a very loose reloading - use for debug mode only.
|
48
|
+
# load Root.join("environment.rb").to_s unless ENV['RACK_ENV'] == 'production'
|
49
|
+
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
# called after any action except WebSockets actions
|
54
|
+
def after
|
55
|
+
# some actions after the request is parsed
|
56
|
+
# you can remove this, ofcourse. the router doesn't require the method to exist.
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
# called when request is GET and there's no "id" in quary
|
61
|
+
def index
|
62
|
+
# while using sym redirection (unlike string redirection),
|
63
|
+
# Plezi will attempt to auto-format a valid URL.
|
64
|
+
redirect_to "assets_welcome.html".to_sym
|
65
|
+
end
|
66
|
+
|
67
|
+
# called when the params[:id] == fail. this a demonstration for custom routing.
|
68
|
+
def fail
|
69
|
+
# throw up this code and feed plezi your own lines :)
|
70
|
+
raise "Plezi raising hell!"
|
71
|
+
end
|
72
|
+
|
73
|
+
# called when request is GET and quary defines "id"
|
74
|
+
def show
|
75
|
+
"I'd love to show you object with id: #{params[:id]}"
|
76
|
+
end
|
77
|
+
|
78
|
+
# called when the request is GET and the params[:id] == "new"
|
79
|
+
def new
|
80
|
+
"let's make something new."
|
81
|
+
end
|
82
|
+
|
83
|
+
# called when request is POST or PUT and there's no "id" in quary
|
84
|
+
def save
|
85
|
+
false
|
86
|
+
end
|
87
|
+
|
88
|
+
# called when request is POST or PUT and quary defines "id"
|
89
|
+
def update
|
90
|
+
false
|
91
|
+
end
|
92
|
+
|
93
|
+
# called when request is DELETE and quary defines "id"
|
94
|
+
def delete
|
95
|
+
false
|
96
|
+
end
|
97
|
+
|
98
|
+
# called before the protocol is swithed from HTTP to WebSockets.
|
99
|
+
#
|
100
|
+
# this allows setting headers, cookies and other data (such as authentication)
|
101
|
+
# prior to opening a WebSocket.
|
102
|
+
#
|
103
|
+
# if the method returns false, the connection will be refused and the remaining routes will be attempted.
|
104
|
+
def pre_connect
|
105
|
+
false
|
106
|
+
end
|
107
|
+
|
108
|
+
# called immediately after a WebSocket connection has been established.
|
109
|
+
# here we simply close the connection.
|
110
|
+
def on_connect
|
111
|
+
response.close
|
112
|
+
false
|
113
|
+
end
|
114
|
+
|
115
|
+
# called when new data is recieved
|
116
|
+
#
|
117
|
+
# data is a string that contains binary or UTF8 (message dependent) data.
|
118
|
+
#
|
119
|
+
# the demo content simply broadcasts the message.
|
120
|
+
def on_message data
|
121
|
+
# broadcast sends an asynchronous message to all sibling instances, but not to self.
|
122
|
+
broadcast :_print_out, data
|
123
|
+
end
|
124
|
+
|
125
|
+
# called when a disconnect packet has been recieved or the connection has been cut
|
126
|
+
# (ISN'T called after a disconnect message has been sent).
|
127
|
+
def on_disconnect
|
128
|
+
end
|
129
|
+
|
130
|
+
# a demo event method that recieves a broadcast from instance siblings.
|
131
|
+
#
|
132
|
+
# methods that are protected and methods that start with an underscore are hidden from the router
|
133
|
+
# BUT, broadcasted methods must be public (or the broadcast will quietly fail)... so we have to use
|
134
|
+
# the _underscore for this method.
|
135
|
+
def _print_out data
|
136
|
+
response << "Someone said #{data}"
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#################
|
2
|
+
## SETTINGS FOR DATABASES
|
3
|
+
#
|
4
|
+
# this file contains common settings and rake tasks for ORM gems.
|
5
|
+
#
|
6
|
+
# please review / edit the settings you need.
|
7
|
+
#
|
8
|
+
############
|
9
|
+
## ActiveRecord without Rails
|
10
|
+
# more info @:
|
11
|
+
# https://www.youtube.com/watch?v=o0SzhgYntK8
|
12
|
+
# demo code here:
|
13
|
+
# https://github.com/stungeye/ActiveRecord-without-Rails
|
14
|
+
if defined? ActiveRecord
|
15
|
+
|
16
|
+
if defined? SQLite3
|
17
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => Root.join('db','db.sqlite3').to_s, encoding: 'unicode'
|
18
|
+
elsif defined? PG
|
19
|
+
ActiveRecord::Base.establish_connection :adapter => 'postgresql', encoding: 'unicode'
|
20
|
+
else
|
21
|
+
Plezi.logger.warning "ActiveRecord database adapter not auto-set. Update the db_ac_config.rb file"
|
22
|
+
end
|
23
|
+
|
24
|
+
# if debugging purposes, uncomment this line to see the ActiveRecord's generated SQL:
|
25
|
+
# ActiveRecord::Base.logger = Plezi.logger
|
26
|
+
|
27
|
+
# Uncomment this line to make the logger output look nicer in Windows.
|
28
|
+
# ActiveSupport::LogSubscriber.colorize_logging = false
|
29
|
+
|
30
|
+
if defined? Rake
|
31
|
+
##########
|
32
|
+
# start rake segment
|
33
|
+
|
34
|
+
namespace :db do
|
35
|
+
|
36
|
+
desc "Migrate the database so that it is fully updated, using db/migrate."
|
37
|
+
task :migrate do
|
38
|
+
ActiveRecord::Base.logger = Plezi.logger
|
39
|
+
ActiveRecord::Migrator.migrate(Root.join('db', 'migrate').to_s, ENV["VERSION"] ? ENV["VERSION"].to_i : nil )
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Seed the database using the db/seeds.rb file"
|
43
|
+
task :seed do
|
44
|
+
if ::File.exists? Root.join('db','seeds.rb').to_s
|
45
|
+
load Root.join('db','seeds.rb').to_s
|
46
|
+
else
|
47
|
+
puts "the seeds file doesn't exists. please create a seeds.db file and place it in the db folder for the app."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
# end rake segment
|
54
|
+
##########
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#################
|
2
|
+
## SETTINGS FOR DATABASES
|
3
|
+
#
|
4
|
+
# this file contains common settings and rake tasks for ORM gems.
|
5
|
+
#
|
6
|
+
# please review / edit the settings you need.
|
7
|
+
#
|
8
|
+
############
|
9
|
+
## DataMapper
|
10
|
+
# more info @:
|
11
|
+
# http://datamapper.org
|
12
|
+
if defined? DataMapper
|
13
|
+
# If you want the logs...
|
14
|
+
DataMapper::Logger.new(Plezi.logger, :debug)
|
15
|
+
|
16
|
+
if defined? SQLite3
|
17
|
+
# An in-memory Sqlite3 connection:
|
18
|
+
DataMapper.setup(:default, 'sqlite::memory:')
|
19
|
+
|
20
|
+
# A Sqlite3 connection to a persistent database
|
21
|
+
DataMapper.setup(:default, "sqlite:///#{Root.join('db', 'db.sqlite3').to_s}")
|
22
|
+
elsif defined? PG
|
23
|
+
# A Postgres connection:
|
24
|
+
if ENV['DYNO']
|
25
|
+
DataMapper.setup(:default, ENV['HEROKU_POSTGRESQL_RED_URL'])
|
26
|
+
else
|
27
|
+
Root.to_s.split(/\/\\/).last
|
28
|
+
DataMapper.setup(:default, "postgres://localhost/#{Root.to_s.split(/[\/\\]/).last}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
if defined? Rake
|
32
|
+
##########
|
33
|
+
# start rake segment
|
34
|
+
|
35
|
+
namespace :db do
|
36
|
+
take :rebuild do
|
37
|
+
DataMapper.finalize.auto_migrate!
|
38
|
+
end
|
39
|
+
task :migrate do
|
40
|
+
DataMapper.finalize.auto_upgrade!
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
# end rake segment
|
46
|
+
##########
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#################
|
2
|
+
## SETTINGS FOR DATABASES
|
3
|
+
#
|
4
|
+
# this file contains common settings and rake tasks for ORM gems.
|
5
|
+
#
|
6
|
+
# please review / edit the settings you need.
|
7
|
+
#
|
8
|
+
############
|
9
|
+
## Sequel
|
10
|
+
# more info @:
|
11
|
+
# http://sequel.jeremyevans.net
|
12
|
+
if defined? Sequel
|
13
|
+
|
14
|
+
if defined? SQLite3
|
15
|
+
# An in-memory Sqlite3 connection:
|
16
|
+
# DB = Sequel.sqlite
|
17
|
+
|
18
|
+
# A Sqlite3 connection to a persistent database
|
19
|
+
DB = Sequel.sqlite(Root.join('db', 'db.sqlite3').to_s)
|
20
|
+
|
21
|
+
elsif defined? PG
|
22
|
+
if ENV['DYNO']
|
23
|
+
# A Postgres connection for Heroku:
|
24
|
+
DB = Sequel.connect(ENV['HEROKU_POSTGRESQL_RED_URL'])
|
25
|
+
else
|
26
|
+
# app name is the same as the root app folder: Root.to_s.split(/\/\\/).last
|
27
|
+
DB = Sequel.connect("postgres://localhost/#{Root.to_s.split(/[\/\\]/).last}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
if defined? Rake
|
31
|
+
##########
|
32
|
+
# start rake segment
|
33
|
+
|
34
|
+
# not yet implemented
|
35
|
+
|
36
|
+
# end rake segment
|
37
|
+
##########
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
|
data/resources/en.yml
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
en:
|
2
|
+
date:
|
3
|
+
abbr_day_names:
|
4
|
+
- Sun
|
5
|
+
- Mon
|
6
|
+
- Tue
|
7
|
+
- Wed
|
8
|
+
- Thu
|
9
|
+
- Fri
|
10
|
+
- Sat
|
11
|
+
abbr_month_names:
|
12
|
+
-
|
13
|
+
- Jan
|
14
|
+
- Feb
|
15
|
+
- Mar
|
16
|
+
- Apr
|
17
|
+
- May
|
18
|
+
- Jun
|
19
|
+
- Jul
|
20
|
+
- Aug
|
21
|
+
- Sep
|
22
|
+
- Oct
|
23
|
+
- Nov
|
24
|
+
- Dec
|
25
|
+
day_names:
|
26
|
+
- Sunday
|
27
|
+
- Monday
|
28
|
+
- Tuesday
|
29
|
+
- Wednesday
|
30
|
+
- Thursday
|
31
|
+
- Friday
|
32
|
+
- Saturday
|
33
|
+
formats:
|
34
|
+
default: ! '%Y-%m-%d'
|
35
|
+
long: ! '%B %d, %Y'
|
36
|
+
short: ! '%b %d'
|
37
|
+
month_names:
|
38
|
+
-
|
39
|
+
- January
|
40
|
+
- February
|
41
|
+
- March
|
42
|
+
- April
|
43
|
+
- May
|
44
|
+
- June
|
45
|
+
- July
|
46
|
+
- August
|
47
|
+
- September
|
48
|
+
- October
|
49
|
+
- November
|
50
|
+
- December
|
51
|
+
order:
|
52
|
+
- :year
|
53
|
+
- :month
|
54
|
+
- :day
|
55
|
+
datetime:
|
56
|
+
distance_in_words:
|
57
|
+
about_x_hours:
|
58
|
+
one: about 1 hour
|
59
|
+
other: about %{count} hours
|
60
|
+
about_x_months:
|
61
|
+
one: about 1 month
|
62
|
+
other: about %{count} months
|
63
|
+
about_x_years:
|
64
|
+
one: about 1 year
|
65
|
+
other: about %{count} years
|
66
|
+
almost_x_years:
|
67
|
+
one: almost 1 year
|
68
|
+
other: almost %{count} years
|
69
|
+
half_a_minute: half a minute
|
70
|
+
less_than_x_minutes:
|
71
|
+
one: less than a minute
|
72
|
+
other: less than %{count} minutes
|
73
|
+
less_than_x_seconds:
|
74
|
+
one: less than 1 second
|
75
|
+
other: less than %{count} seconds
|
76
|
+
over_x_years:
|
77
|
+
one: over 1 year
|
78
|
+
other: over %{count} years
|
79
|
+
x_days:
|
80
|
+
one: 1 day
|
81
|
+
other: ! '%{count} days'
|
82
|
+
x_minutes:
|
83
|
+
one: 1 minute
|
84
|
+
other: ! '%{count} minutes'
|
85
|
+
x_months:
|
86
|
+
one: 1 month
|
87
|
+
other: ! '%{count} months'
|
88
|
+
x_seconds:
|
89
|
+
one: 1 second
|
90
|
+
other: ! '%{count} seconds'
|
91
|
+
prompts:
|
92
|
+
day: Day
|
93
|
+
hour: Hour
|
94
|
+
minute: Minute
|
95
|
+
month: Month
|
96
|
+
second: Seconds
|
97
|
+
year: Year
|
98
|
+
errors:
|
99
|
+
format: ! '%{attribute} %{message}'
|
100
|
+
messages:
|
101
|
+
accepted: must be accepted
|
102
|
+
blank: can't be blank
|
103
|
+
present: must be blank
|
104
|
+
confirmation: ! "doesn't match %{attribute}"
|
105
|
+
empty: can't be empty
|
106
|
+
equal_to: must be equal to %{count}
|
107
|
+
even: must be even
|
108
|
+
exclusion: is reserved
|
109
|
+
greater_than: must be greater than %{count}
|
110
|
+
greater_than_or_equal_to: must be greater than or equal to %{count}
|
111
|
+
inclusion: is not included in the list
|
112
|
+
invalid: is invalid
|
113
|
+
less_than: must be less than %{count}
|
114
|
+
less_than_or_equal_to: must be less than or equal to %{count}
|
115
|
+
not_a_number: is not a number
|
116
|
+
not_an_integer: must be an integer
|
117
|
+
odd: must be odd
|
118
|
+
record_invalid: ! 'Validation failed: %{errors}'
|
119
|
+
restrict_dependent_destroy:
|
120
|
+
one: "Cannot delete record because a dependent %{record} exists"
|
121
|
+
many: "Cannot delete record because dependent %{record} exist"
|
122
|
+
taken: has already been taken
|
123
|
+
too_long:
|
124
|
+
one: is too long (maximum is 1 character)
|
125
|
+
other: is too long (maximum is %{count} characters)
|
126
|
+
too_short:
|
127
|
+
one: is too short (minimum is 1 character)
|
128
|
+
other: is too short (minimum is %{count} characters)
|
129
|
+
wrong_length:
|
130
|
+
one: is the wrong length (should be 1 character)
|
131
|
+
other: is the wrong length (should be %{count} characters)
|
132
|
+
other_than: "must be other than %{count}"
|
133
|
+
template:
|
134
|
+
body: ! 'There were problems with the following fields:'
|
135
|
+
header:
|
136
|
+
one: 1 error prohibited this %{model} from being saved
|
137
|
+
other: ! '%{count} errors prohibited this %{model} from being saved'
|
138
|
+
helpers:
|
139
|
+
select:
|
140
|
+
prompt: Please select
|
141
|
+
submit:
|
142
|
+
create: Create %{model}
|
143
|
+
submit: Save %{model}
|
144
|
+
update: Update %{model}
|
145
|
+
number:
|
146
|
+
currency:
|
147
|
+
format:
|
148
|
+
delimiter: ! ','
|
149
|
+
format: ! '%u%n'
|
150
|
+
precision: 2
|
151
|
+
separator: .
|
152
|
+
significant: false
|
153
|
+
strip_insignificant_zeros: false
|
154
|
+
unit: $
|
155
|
+
format:
|
156
|
+
delimiter: ! ','
|
157
|
+
precision: 3
|
158
|
+
separator: .
|
159
|
+
significant: false
|
160
|
+
strip_insignificant_zeros: false
|
161
|
+
human:
|
162
|
+
decimal_units:
|
163
|
+
format: ! '%n %u'
|
164
|
+
units:
|
165
|
+
billion: Billion
|
166
|
+
million: Million
|
167
|
+
quadrillion: Quadrillion
|
168
|
+
thousand: Thousand
|
169
|
+
trillion: Trillion
|
170
|
+
unit: ''
|
171
|
+
format:
|
172
|
+
delimiter: ''
|
173
|
+
precision: 3
|
174
|
+
significant: true
|
175
|
+
strip_insignificant_zeros: true
|
176
|
+
storage_units:
|
177
|
+
format: ! '%n %u'
|
178
|
+
units:
|
179
|
+
byte:
|
180
|
+
one: Byte
|
181
|
+
other: Bytes
|
182
|
+
gb: GB
|
183
|
+
kb: KB
|
184
|
+
mb: MB
|
185
|
+
tb: TB
|
186
|
+
percentage:
|
187
|
+
format:
|
188
|
+
delimiter: ''
|
189
|
+
format: "%n%"
|
190
|
+
precision:
|
191
|
+
format:
|
192
|
+
delimiter: ''
|
193
|
+
support:
|
194
|
+
array:
|
195
|
+
last_word_connector: ! ', and '
|
196
|
+
two_words_connector: ! ' and '
|
197
|
+
words_connector: ! ', '
|
198
|
+
time:
|
199
|
+
am: am
|
200
|
+
formats:
|
201
|
+
default: ! '%a, %d %b %Y %H:%M:%S %z'
|
202
|
+
long: ! '%B %d, %Y %H:%M'
|
203
|
+
short: ! '%d %b %H:%M'
|
204
|
+
pm: pm
|