gors 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/gors +39 -0
  2. data/lib/gors.rb +128 -17
  3. 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
- @logger.log env["REQUEST_METHOD"]+" "+env["REQUEST_PATH"]
15
- controller = @routesklass.routes[env["PATH_INFO"]]
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 ["404",{},response]
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
- data = Model.new.call(params[1])
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
- if(Object.const_get(modelname.capitalize).respond_to? "append")
143
- puts "Running appending function"
144
- model = Object.const_get(modelname.capitalize).all.send(Object.const_get(modelname.capitalize).append)
145
- else
146
- model = Object.const_get(modelname.capitalize).all
147
- end
148
- model.to_json
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 DataManager
183
- def self.model modelname
184
- Object.const_get(modelname)
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.1
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