gors 0.0.1 → 0.0.2
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.
- data/bin/gors +39 -0
- data/lib/gors.rb +128 -17
- metadata +4 -2
data/bin/gors
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optitron'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'gors'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
class GorsCLI < Optitron::CLI
|
8
|
+
desc "Create Gors project"
|
9
|
+
def new projectname
|
10
|
+
puts "Creating project directory and structure"
|
11
|
+
Dir.mkdir("#{projectname}")
|
12
|
+
Dir.mkdir("#{projectname}/controllers")
|
13
|
+
Dir.mkdir("#{projectname}/models")
|
14
|
+
Dir.mkdir("#{projectname}/views")
|
15
|
+
FileUtils.touch("#{projectname}/views/layout.html.erb")
|
16
|
+
File.write("#{projectname}/main.rb","# Example of basic configuration\ngors = Gors::Server.new\ngors.routes do\n\nend\n\ngors.autoimport\ngors.start")
|
17
|
+
File.write("#{projectname}/controllers/default_controller.rb","class DefaultController < Gors::Controller
|
18
|
+
\n def index\n \"<h1>Welcome to GORS</h1><i>Great Opensource Ruby Server</i><p>Gors is loading routes from routes.json but you should write your own main.rb<br/>This is just to gettings started</p>\"\n end\nend");
|
19
|
+
File.write("#{projectname}/routes.json","{\n \"get\": [{\n \"/\": \"DefaultController#index\"\n}]\n}")
|
20
|
+
puts "Done"
|
21
|
+
puts "Test GORS by running \"gors s\""
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "Start gors server with default configuration"
|
25
|
+
def s
|
26
|
+
gors = Gors::Server.new
|
27
|
+
|
28
|
+
routes = JSON.parse(File.read("routes.json"))
|
29
|
+
gors.routes do
|
30
|
+
routes["get"].each do |route|
|
31
|
+
get route
|
32
|
+
end
|
33
|
+
end
|
34
|
+
gors.autoimport
|
35
|
+
gors.start
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
GorsCLI.dispatch
|
data/lib/gors.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rack'
|
|
2
2
|
require 'erb'
|
3
3
|
require 'tilt'
|
4
4
|
require 'json'
|
5
|
+
require 'filemagic'
|
5
6
|
|
6
7
|
module Gors
|
7
8
|
class Server
|
@@ -10,29 +11,55 @@ module Gors
|
|
10
11
|
@logger = Logger.new(@settings)
|
11
12
|
@routesklass = Routes.new(@logger)
|
12
13
|
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
|
17
|
+
end
|
18
|
+
|
13
19
|
def call env
|
14
|
-
@
|
15
|
-
|
20
|
+
if(@settings.errorhandler != nil)
|
21
|
+
@errorhandler = Object.const_get(@settings.errorhandler).new
|
22
|
+
else
|
23
|
+
@errorhandler = Gors::DefaultErrorHandler.new
|
24
|
+
end
|
25
|
+
|
26
|
+
routesinfo = @routesklass.routes(env["REQUEST_PATH"])
|
27
|
+
controller = routesinfo[0]
|
28
|
+
@logger.log controller.inspect
|
29
|
+
matcheddata = routesinfo[1]
|
30
|
+
|
16
31
|
if(controller == nil)
|
32
|
+
if(File.exist?("public"+env["REQUEST_PATH"]))
|
33
|
+
fm = FileMagic.new(FileMagic::MAGIC_MIME)
|
34
|
+
mime = fm.file("public/"+env["REQUEST_PATH"])
|
35
|
+
return ["200",{"Content-type" => mime},[File.read("public"+env["REQUEST_PATH"])]]
|
36
|
+
end
|
17
37
|
if(@settings.server != "thin")
|
18
38
|
response = ["<h1>404 Not Found</h1>"]
|
19
39
|
else
|
20
40
|
response = "<h1>404 Not Found</h1>"
|
21
41
|
end
|
22
|
-
return
|
42
|
+
return @errorhandler.call "404"
|
23
43
|
end
|
24
44
|
|
45
|
+
#
|
25
46
|
if(controller.include? "Gors::")
|
26
47
|
ctrl = controller.split("#")
|
27
48
|
params = ctrl[1].split(":")
|
28
49
|
|
29
|
-
|
50
|
+
req = Rack::Request.new(env)
|
51
|
+
|
52
|
+
data = Model.new(req).call(params[1])
|
30
53
|
return ["200",{"Content-type" => "application/json"},[data]]
|
31
54
|
end
|
32
55
|
|
33
56
|
# Call the Controller
|
34
57
|
request = Request.new
|
35
58
|
request.request.params = Rack::Utils.parse_query(env["QUERY_STRING"])
|
59
|
+
if(matcheddata != nil)
|
60
|
+
request.request.params.merge! (matcheddata)
|
61
|
+
end
|
62
|
+
request.request.params.default = ""
|
36
63
|
|
37
64
|
infoctrl = controller.split("#")
|
38
65
|
ctrl = Object.const_get(infoctrl[0]).new(request)
|
@@ -45,6 +72,12 @@ module Gors
|
|
45
72
|
end
|
46
73
|
|
47
74
|
def start
|
75
|
+
if(@settings.errorhandler != nil)
|
76
|
+
@errorhandler = Object.const_get(@settings.errorhandler).new
|
77
|
+
else
|
78
|
+
@errorhandler = Gors::DefaultErrorHandler.new
|
79
|
+
end
|
80
|
+
|
48
81
|
if(@settings.daemon)
|
49
82
|
puts "Sending Gors to background"
|
50
83
|
system("kill `cat running.pid`")
|
@@ -75,6 +108,8 @@ module Gors
|
|
75
108
|
|
76
109
|
end
|
77
110
|
class Routes
|
111
|
+
NAME_PATTERN = /:(\S+)/
|
112
|
+
|
78
113
|
attr_accessor :routes
|
79
114
|
attr_accessor :models
|
80
115
|
attr_accessor :posts
|
@@ -87,10 +122,14 @@ module Gors
|
|
87
122
|
end
|
88
123
|
|
89
124
|
def get hash
|
90
|
-
@routes[hash.keys.first.to_s] = hash[hash.keys.first.to_s]
|
125
|
+
@routes[pattern_for(hash.keys.first.to_s)] = hash[hash.keys.first.to_s]
|
91
126
|
@logger.log "Adding route GET "+hash.keys.first.to_s
|
92
127
|
end
|
93
128
|
|
129
|
+
def json
|
130
|
+
# TODO zorg evoor dat routes ook van routes.json gehaald kunnen worden (structuur zie generator in de CLI)
|
131
|
+
end
|
132
|
+
|
94
133
|
def post hash
|
95
134
|
@routespost[hash.keys.first.to_s] = hash[hash.keys.first.to_s]
|
96
135
|
@logger.log "Adding route POST "+hash.keys.first.to_s
|
@@ -105,6 +144,39 @@ module Gors
|
|
105
144
|
puts "Adding model with path "+hash.keys.first.to_s
|
106
145
|
end
|
107
146
|
|
147
|
+
def routes(path)
|
148
|
+
hash = {}
|
149
|
+
controller = nil
|
150
|
+
@routes.each do |route,controller|
|
151
|
+
if(matched = route.match path)
|
152
|
+
matched.names.each do |name|
|
153
|
+
hash[name] = matched[name]
|
154
|
+
end
|
155
|
+
|
156
|
+
return [controller,hash]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
# Logic from github.com/alisnic/nyny
|
161
|
+
def pattern_for signature
|
162
|
+
if(signature.class == Regexp)
|
163
|
+
return signature
|
164
|
+
end
|
165
|
+
build_regex(signature.start_with?('/') ? signature : "/#{signature}")
|
166
|
+
end
|
167
|
+
|
168
|
+
def build_regex signature
|
169
|
+
return %r(^#{signature}$) unless signature.include?(':')
|
170
|
+
|
171
|
+
groups = signature.split('/').map do |part|
|
172
|
+
next part if part.empty?
|
173
|
+
next part unless part.start_with? ':'
|
174
|
+
name = NAME_PATTERN.match(part)[1]
|
175
|
+
%Q{(?<#{name}>\\S+)}
|
176
|
+
end.select {|s| !s.empty? }.join('\/')
|
177
|
+
|
178
|
+
%r(^\/#{groups}$)
|
179
|
+
end
|
108
180
|
end
|
109
181
|
class Controller
|
110
182
|
attr_accessor :info
|
@@ -118,9 +190,13 @@ module Gors
|
|
118
190
|
|
119
191
|
def erb template
|
120
192
|
renderer = Tilt::ERBTemplate.new("views/layout.erb")
|
121
|
-
output = renderer.render(self){ Tilt::ERBTemplate.new("views/"+template+".erb").render(self) }
|
193
|
+
output = renderer.render(self){ Tilt::ERBTemplate.new("views/"+template.to_s+".erb").render(self) }
|
122
194
|
return output
|
123
195
|
end
|
196
|
+
|
197
|
+
def params
|
198
|
+
@info.request.params
|
199
|
+
end
|
124
200
|
end
|
125
201
|
|
126
202
|
class Request
|
@@ -138,15 +214,31 @@ module Gors
|
|
138
214
|
end
|
139
215
|
|
140
216
|
class Model
|
217
|
+
def initialize req
|
218
|
+
@req = req
|
219
|
+
end
|
220
|
+
|
141
221
|
def call modelname
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
222
|
+
case @req.request_method
|
223
|
+
when "GET"
|
224
|
+
if(Object.const_get(modelname.capitalize).respond_to? "append")
|
225
|
+
model = Object.const_get(modelname.capitalize).all.send(Object.const_get(modelname.capitalize).append)
|
226
|
+
else
|
227
|
+
model = Object.const_get(modelname.capitalize).all
|
228
|
+
end
|
229
|
+
model.to_json
|
230
|
+
when "POST"
|
231
|
+
if(Object.const_get(modelname.capitalize).respond_to? "append")
|
232
|
+
model = Object.const_get(modelname.capitalize).create(JSON.parse(@req.body.string))
|
233
|
+
else
|
234
|
+
model = Object.const_get(modelname.capitalize).create(JSON.parse(@req.body.string))
|
235
|
+
end
|
236
|
+
model.to_json
|
237
|
+
else
|
238
|
+
|
239
|
+
end
|
149
240
|
end
|
241
|
+
|
150
242
|
end
|
151
243
|
|
152
244
|
class Settings
|
@@ -154,12 +246,14 @@ module Gors
|
|
154
246
|
attr_accessor :server
|
155
247
|
attr_accessor :verbose
|
156
248
|
attr_accessor :daemon
|
249
|
+
attr_accessor :errorhandler
|
157
250
|
|
158
251
|
def initialize
|
159
252
|
@port = 8080
|
160
253
|
@server = "thin"
|
161
254
|
@verbose = true
|
162
255
|
@daemon = false
|
256
|
+
@errorhandler = nil
|
163
257
|
end
|
164
258
|
end
|
165
259
|
class Logger
|
@@ -178,12 +272,29 @@ module Gors
|
|
178
272
|
end
|
179
273
|
|
180
274
|
end
|
181
|
-
|
182
|
-
class
|
183
|
-
def
|
184
|
-
|
275
|
+
|
276
|
+
class ErrorHelper
|
277
|
+
def call(errortype)
|
278
|
+
if(self.respond_to? "error_"+errortype)
|
279
|
+
[errortype, {},[self.send("error_"+errortype)]]
|
280
|
+
else
|
281
|
+
Gors::DefaultErrorHandler.new.send("error_"+errortype)
|
282
|
+
end
|
185
283
|
end
|
186
284
|
end
|
285
|
+
|
286
|
+
class DefaultErrorHandler < Gors::ErrorHelper
|
287
|
+
def error_404
|
288
|
+
"<h1>404 Not Found</h1>"
|
289
|
+
end
|
290
|
+
def error_500
|
291
|
+
"<h1>500 Internal server error</h1>"
|
292
|
+
end
|
293
|
+
def error_403
|
294
|
+
"<h1>403 Forbidden</h1>"
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
187
298
|
end
|
188
299
|
|
189
300
|
at_exit do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -62,11 +62,13 @@ dependencies:
|
|
62
62
|
description: A web framework built on top of Rack, it has the simplicity of sinatra
|
63
63
|
and the structure of rails
|
64
64
|
email: bram.vandenbogaerde@gmail.com
|
65
|
-
executables:
|
65
|
+
executables:
|
66
|
+
- gors
|
66
67
|
extensions: []
|
67
68
|
extra_rdoc_files: []
|
68
69
|
files:
|
69
70
|
- lib/gors.rb
|
71
|
+
- bin/gors
|
70
72
|
homepage: http://rubygems.org/gems/gors
|
71
73
|
licenses:
|
72
74
|
- MIT
|