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.
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