Capcode 0.9.9 → 1.0.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.
- data/README.rdoc +3 -0
- data/examples/rest.log +15 -0
- data/examples/static.rb +12 -0
- data/examples/static/static-index.html +1 -0
- data/lib/capcode.rb +14 -344
- data/lib/capcode/filters.rb +1 -0
- data/lib/capcode/helpers.rb +246 -0
- data/lib/capcode/http_error.rb +49 -0
- data/lib/capcode/static_files.rb +68 -0
- data/lib/capcode/version.rb +1 -1
- metadata +46 -61
- data/doc/rdoc/classes/Capcode.html +0 -1076
- data/doc/rdoc/classes/Capcode/Base.html +0 -136
- data/doc/rdoc/classes/Capcode/Configuration.html +0 -290
- data/doc/rdoc/classes/Capcode/HTTPError.html +0 -148
- data/doc/rdoc/classes/Capcode/Helpers.html +0 -674
- data/doc/rdoc/classes/Capcode/Helpers/Authorization.html +0 -219
- data/doc/rdoc/classes/Capcode/Resource.html +0 -111
- data/doc/rdoc/classes/Capcode/StaticFiles.html +0 -199
- data/doc/rdoc/classes/Capcode/Views.html +0 -112
- data/doc/rdoc/created.rid +0 -1
- data/doc/rdoc/files/AUTHORS.html +0 -107
- data/doc/rdoc/files/COPYING.html +0 -531
- data/doc/rdoc/files/README_rdoc.html +0 -887
- data/doc/rdoc/files/lib/capcode/base/db_rb.html +0 -101
- data/doc/rdoc/files/lib/capcode/configuration_rb.html +0 -101
- data/doc/rdoc/files/lib/capcode/filters_rb.html +0 -101
- data/doc/rdoc/files/lib/capcode/helpers/auth_rb.html +0 -101
- data/doc/rdoc/files/lib/capcode/render/text_rb.html +0 -101
- data/doc/rdoc/files/lib/capcode_rb.html +0 -144
- data/doc/rdoc/fr_class_index.html +0 -35
- data/doc/rdoc/fr_file_index.html +0 -35
- data/doc/rdoc/fr_method_index.html +0 -56
- data/doc/rdoc/index.html +0 -24
- data/doc/rdoc/rdoc-style.css +0 -208
- data/lib/capcode.rbSAVE +0 -881
data/README.rdoc
CHANGED
@@ -12,6 +12,9 @@ Capcode is a web microframework
|
|
12
12
|
|
13
13
|
== FEATURES/PROBLEMS:
|
14
14
|
|
15
|
+
=== 1.0.0
|
16
|
+
* json helper removed
|
17
|
+
|
15
18
|
=== 0.9.9
|
16
19
|
* Better static files support {See example static.rb}[http://github.com/glejeune/Capcode/tree/master/examples/static.rb]
|
17
20
|
* Rewrite routes loader
|
data/examples/rest.log
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Logfile created on Mon Jan 17 12:47:10 +0100 2011 by logger.rb/22285
|
2
|
+
127.0.0.1 - - [17/Jan/2011 12:47:14] "GET / HTTP/1.1" 200 586 0.1240
|
3
|
+
127.0.0.1 - - [17/Jan/2011 12:47:14] "GET /favicon.ico HTTP/1.1" 404 23 0.0015
|
4
|
+
GET...
|
5
|
+
127.0.0.1 - - [17/Jan/2011 12:47:16] "GET /action?data=A HTTP/1.1" 200 619 0.0092
|
6
|
+
127.0.0.1 - - [17/Jan/2011 12:47:16] "GET /favicon.ico HTTP/1.1" 404 23 0.0015
|
7
|
+
POST...
|
8
|
+
127.0.0.1 - - [17/Jan/2011 12:47:19] "POST /action HTTP/1.1" 200 620 0.0094
|
9
|
+
127.0.0.1 - - [17/Jan/2011 12:47:19] "GET /favicon.ico HTTP/1.1" 404 23 0.0015
|
10
|
+
DELETE...
|
11
|
+
127.0.0.1 - - [17/Jan/2011 12:47:22] "POST /action HTTP/1.1" 200 622 0.0102
|
12
|
+
127.0.0.1 - - [17/Jan/2011 12:47:22] "GET /favicon.ico HTTP/1.1" 404 23 0.0014
|
13
|
+
PUT...
|
14
|
+
127.0.0.1 - - [17/Jan/2011 12:47:25] "POST /action HTTP/1.1" 200 619 0.0104
|
15
|
+
127.0.0.1 - - [17/Jan/2011 12:47:25] "GET /favicon.ico HTTP/1.1" 404 23 0.0015
|
data/examples/static.rb
CHANGED
@@ -5,8 +5,20 @@ require 'rubygems'
|
|
5
5
|
module Capcode
|
6
6
|
set :static, "static"
|
7
7
|
|
8
|
+
before_filter :only_static, :only => [:StaticFiles]
|
9
|
+
def only_static
|
10
|
+
puts "-> Filter for static files!"
|
11
|
+
|
12
|
+
p session
|
13
|
+
|
14
|
+
puts "<- Filter for static files!"
|
15
|
+
|
16
|
+
return nil
|
17
|
+
end
|
18
|
+
|
8
19
|
class Index < Route '/'
|
9
20
|
def get
|
21
|
+
session['date'] = Time.now
|
10
22
|
render :markaby => :index
|
11
23
|
end
|
12
24
|
end
|
data/lib/capcode.rb
CHANGED
@@ -9,8 +9,11 @@ require 'optparse'
|
|
9
9
|
require 'irb'
|
10
10
|
require 'capcode/version'
|
11
11
|
require 'capcode/core_ext'
|
12
|
+
require 'capcode/helpers'
|
12
13
|
require 'capcode/helpers/auth'
|
13
14
|
require 'capcode/render/text'
|
15
|
+
require 'capcode/http_error'
|
16
|
+
require 'capcode/static_files'
|
14
17
|
require 'capcode/configuration'
|
15
18
|
require 'capcode/filters'
|
16
19
|
require 'capcode/ext/rack/urlmap'
|
@@ -32,347 +35,12 @@ module Capcode
|
|
32
35
|
module Views; end
|
33
36
|
|
34
37
|
# Helpers contains methods available in your controllers
|
35
|
-
module Helpers
|
36
|
-
def self.args
|
37
|
-
@args ||= nil
|
38
|
-
end
|
39
|
-
def self.args=(x)
|
40
|
-
@args = x
|
41
|
-
end
|
42
|
-
|
43
|
-
# Render a view
|
44
|
-
#
|
45
|
-
# render's parameter can be a Hash or a string. Passing a string is equivalent to do
|
46
|
-
# render( :text => string )
|
47
|
-
#
|
48
|
-
# If you want to use a specific renderer, use one of this options :
|
49
|
-
#
|
50
|
-
# * :markaby => :my_func : :my_func must be defined in Capcode::Views
|
51
|
-
# * :erb => :my_erb_file : this suppose that's my_erb_file.rhtml exist in erb_path
|
52
|
-
# * :haml => :my_haml_file : this suppose that's my_haml_file.haml exist in haml_path
|
53
|
-
# * :sass => :my_sass_file : this suppose that's my_sass_file.sass exist in sass_path
|
54
|
-
# * :text => "my text"
|
55
|
-
# * :json => MyObject : this suppose that's MyObject respond to .to_json
|
56
|
-
# * :static => "my_file.xxx" : this suppose that's my_file.xxx exist in the static directory
|
57
|
-
# * :xml => :my_func : :my_func must be defined in Capcode::Views
|
58
|
-
# * :webdav => /path/to/root
|
59
|
-
#
|
60
|
-
# Or you can use a "HTTP code" renderer :
|
61
|
-
#
|
62
|
-
# render 200 => "Ok", :server => "Capcode #{Capcode::CAPCOD_VERION}", ...
|
63
|
-
#
|
64
|
-
# If you want to use a specific layout, you can specify it with option
|
65
|
-
# :layout
|
66
|
-
#
|
67
|
-
# If you want to change the Content-Type, you can specify it with option
|
68
|
-
# :content_type
|
69
|
-
# Note that this will not work with the JSON renderer
|
70
|
-
#
|
71
|
-
# If you use the WebDav renderer, you can use the option
|
72
|
-
# :resource_class (see http://github.com/georgi/rack_dav for more informations)
|
73
|
-
def render( hash )
|
74
|
-
if hash.class == Hash
|
75
|
-
render_type = nil
|
76
|
-
possible_code_renderer = nil
|
77
|
-
|
78
|
-
hash.keys.each do |key|
|
79
|
-
begin
|
80
|
-
gem "capcode-render-#{key.to_s}"
|
81
|
-
require "capcode/render/#{key.to_s}"
|
82
|
-
rescue Gem::LoadError
|
83
|
-
nil
|
84
|
-
rescue LoadError
|
85
|
-
raise Capcode::RenderError, "Hum... The #{key} renderer is malformated! Please try to install a new version or use an other renderer!", caller
|
86
|
-
end
|
87
|
-
|
88
|
-
if self.respond_to?("render_#{key.to_s}")
|
89
|
-
unless render_type.nil?
|
90
|
-
raise Capcode::RenderError, "Can't use multiple renderer (`#{render_type}' and `#{key}') !", caller
|
91
|
-
end
|
92
|
-
render_type = key
|
93
|
-
end
|
94
|
-
|
95
|
-
if key.class == Fixnum
|
96
|
-
possible_code_renderer = key
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
if render_type.nil? and possible_code_renderer.nil?
|
101
|
-
raise Capcode::RenderError, "Renderer type not specified!", caller
|
102
|
-
end
|
103
|
-
|
104
|
-
unless self.respond_to?("render_#{render_type.to_s}")
|
105
|
-
if possible_code_renderer.nil?
|
106
|
-
raise Capcode::RenderError, "#{render_type} renderer not present ! please require 'capcode/render/#{render_type}'", caller
|
107
|
-
else
|
108
|
-
code = possible_code_renderer
|
109
|
-
body = hash.delete(possible_code_renderer)
|
110
|
-
header = {}
|
111
|
-
hash.each do |k, v|
|
112
|
-
k = k.to_s.split(/_/).map{|e| e.capitalize}.join("-")
|
113
|
-
header[k] = v
|
114
|
-
end
|
115
|
-
|
116
|
-
[code, header, body]
|
117
|
-
end
|
118
|
-
else
|
119
|
-
render_name = hash.delete(render_type)
|
120
|
-
content_type = hash.delete(:content_type)
|
121
|
-
unless content_type.nil?
|
122
|
-
@response['Content-Type'] = content_type
|
123
|
-
end
|
124
|
-
|
125
|
-
begin
|
126
|
-
self.send( "render_#{render_type.to_s}", render_name, hash )
|
127
|
-
rescue => e
|
128
|
-
raise Capcode::RenderError, "Error rendering `#{render_type.to_s}' : #{e.message}"#, caller
|
129
|
-
end
|
130
|
-
end
|
131
|
-
else
|
132
|
-
render( :text => hash )
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
# Help you to return a JSON response
|
137
|
-
#
|
138
|
-
# module Capcode
|
139
|
-
# class JsonResponse < Route '/json/([^\/]*)/(.*)'
|
140
|
-
# def get( arg1, arg2 )
|
141
|
-
# json( { :1 => arg1, :2 => arg2 })
|
142
|
-
# end
|
143
|
-
# end
|
144
|
-
# end
|
145
|
-
#
|
146
|
-
# <b>DEPRECATED</b>, please use <tt>render( :json => o )</tt>
|
147
|
-
def json( d ) ## DELETE THIS IN 1.0.0
|
148
|
-
warn( "json is deprecated and will be removed in version 1.0, please use `render( :json => ... )'" )
|
149
|
-
render :json => d
|
150
|
-
end
|
151
|
-
|
152
|
-
# Send a redirect response
|
153
|
-
#
|
154
|
-
# module Capcode
|
155
|
-
# class Hello < Route '/hello/(.*)'
|
156
|
-
# def get( you )
|
157
|
-
# if you.nil?
|
158
|
-
# redirect( WhoAreYou )
|
159
|
-
# else
|
160
|
-
# ...
|
161
|
-
# end
|
162
|
-
# end
|
163
|
-
# end
|
164
|
-
# end
|
165
|
-
#
|
166
|
-
# The first parameter can be a controller class name
|
167
|
-
#
|
168
|
-
# redirect( MyController )
|
169
|
-
#
|
170
|
-
# it can be a string path
|
171
|
-
#
|
172
|
-
# redirect( "/path/to/my/resource" )
|
173
|
-
#
|
174
|
-
# it can be an http status code (by default <tt>redirect</tt> use the http status code 302)
|
175
|
-
#
|
176
|
-
# redirect( 304, MyController )
|
177
|
-
#
|
178
|
-
# For more informations about HTTP status, see http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection
|
179
|
-
def redirect( klass, *a )
|
180
|
-
httpCode = 302
|
181
|
-
|
182
|
-
if( klass.class == Fixnum )
|
183
|
-
httpCode = klass
|
184
|
-
klass = a.shift
|
185
|
-
end
|
186
|
-
|
187
|
-
[httpCode, {'Location' => URL(klass, *a)}, '']
|
188
|
-
end
|
189
|
-
|
190
|
-
# Builds an URL route to a controller or a path
|
191
|
-
#
|
192
|
-
# if you declare the controller Hello :
|
193
|
-
#
|
194
|
-
# module Capcode
|
195
|
-
# class Hello < Route '/hello/(.*)'
|
196
|
-
# ...
|
197
|
-
# end
|
198
|
-
# end
|
199
|
-
#
|
200
|
-
# then
|
201
|
-
#
|
202
|
-
# URL( Capcode::Hello, "you" ) # => /hello/you
|
203
|
-
def URL( klass, *a )
|
204
|
-
path = nil
|
205
|
-
result = {}
|
206
|
-
|
207
|
-
a = a.delete_if{ |x| x.nil? }
|
208
|
-
|
209
|
-
if klass.class == Class
|
210
|
-
klass.__urls__[0].each do |cpath, data|
|
211
|
-
args = a.clone
|
212
|
-
|
213
|
-
n = Regexp.new( data[:regexp] ).number_of_captures
|
214
|
-
equart = (a.size - n).abs
|
215
|
-
|
216
|
-
rtable = data[:regexp].dup.gsub( /\\\(/, "" ).gsub( /\\\)/, "" ).split( /\([^\)]*\)/ )
|
217
|
-
rtable.each do |r|
|
218
|
-
if r == ""
|
219
|
-
cpath = cpath + "/#{args.shift}"
|
220
|
-
else
|
221
|
-
cpath = cpath + "/#{r}"
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
cpath = (cpath + "/" + args.join( "/" )) if args.size > 0
|
226
|
-
cpath = cpath.gsub( /(\/){2,}/, "/" )
|
227
|
-
result[equart] = cpath
|
228
|
-
end
|
229
|
-
|
230
|
-
path = result[result.keys.min]
|
231
|
-
else
|
232
|
-
path = klass
|
233
|
-
end
|
234
|
-
|
235
|
-
(ENV['RACK_BASE_URI']||'')+path
|
236
|
-
end
|
237
|
-
|
238
|
-
# Calling content_for stores a block of markup in an identifier.
|
239
|
-
#
|
240
|
-
# module Capcode
|
241
|
-
# class ContentFor < Route '/'
|
242
|
-
# def get
|
243
|
-
# render( :markaby => :page, :layout => :layout )
|
244
|
-
# end
|
245
|
-
# end
|
246
|
-
# end
|
247
|
-
#
|
248
|
-
# module Capcode::Views
|
249
|
-
# def layout
|
250
|
-
# html do
|
251
|
-
# head do
|
252
|
-
# yield :header
|
253
|
-
# end
|
254
|
-
# body do
|
255
|
-
# yield :content
|
256
|
-
# end
|
257
|
-
# end
|
258
|
-
# end
|
259
|
-
#
|
260
|
-
# def page
|
261
|
-
# content_for :header do
|
262
|
-
# title "This is the title!"
|
263
|
-
# end
|
264
|
-
#
|
265
|
-
# content_for :content do
|
266
|
-
# p "this is the content!"
|
267
|
-
# end
|
268
|
-
# end
|
269
|
-
# end
|
270
|
-
def content_for( x )
|
271
|
-
if Capcode::Helpers.args.map{|_| _.to_s }.include?(x.to_s)
|
272
|
-
yield
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
# Return information about the static directory
|
277
|
-
#
|
278
|
-
# * <tt>static[:uri]</tt> give the static URI
|
279
|
-
# * <tt>static[:path]</tt> give the path to the static directory on the server
|
280
|
-
def static
|
281
|
-
{
|
282
|
-
:uri => Capcode.static,
|
283
|
-
:path => File.expand_path( File.join(Capcode::Configuration.get(:root), Capcode::Configuration.get(:static) ) )
|
284
|
-
}
|
285
|
-
end
|
286
|
-
|
287
|
-
# Use the Rack logger
|
288
|
-
#
|
289
|
-
# log.write( "This is a log !" )
|
290
|
-
def log
|
291
|
-
Capcode.logger || env['rack.errors']
|
292
|
-
end
|
293
|
-
|
38
|
+
module Helpers
|
294
39
|
include Authorization
|
295
40
|
end
|
296
41
|
|
297
42
|
include Rack
|
298
|
-
|
299
|
-
# HTTPError help you to create your own 404, 500 and/or 501 response
|
300
|
-
#
|
301
|
-
# To create a custom 404 reponse, create a fonction HTTPError.r404 in
|
302
|
-
# your application :
|
303
|
-
#
|
304
|
-
# module Capcode
|
305
|
-
# class HTTPError
|
306
|
-
# def r404(f)
|
307
|
-
# "#{f} not found :("
|
308
|
-
# end
|
309
|
-
# end
|
310
|
-
# end
|
311
|
-
#
|
312
|
-
# the rXXX method can also receive a second optional parameter corresponding
|
313
|
-
# of the header's Hash :
|
314
|
-
#
|
315
|
-
# module Capcode
|
316
|
-
# class HTTPError
|
317
|
-
# def r404(f, h)
|
318
|
-
# h['Content-Type'] = 'text/plain'
|
319
|
-
# "You are here ---> X (#{f} point)"
|
320
|
-
# end
|
321
|
-
# end
|
322
|
-
# end
|
323
|
-
#
|
324
|
-
# Do the same (r500, r501, r403) to customize 500, 501, 403 errors
|
325
|
-
class HTTPError
|
326
|
-
def initialize(app) #:nodoc:
|
327
|
-
@app = app
|
328
|
-
end
|
329
|
-
|
330
|
-
def call(env) #:nodoc:
|
331
|
-
status, headers, body = @app.call(env)
|
332
|
-
if self.methods.include? "r#{status}"
|
333
|
-
headers.delete('Content-Type') if headers.keys.include?('Content-Type')
|
334
|
-
body = begin
|
335
|
-
self.send( "r#{status}", env['REQUEST_PATH'], headers )
|
336
|
-
rescue
|
337
|
-
self.send( "r#{status}", env['REQUEST_PATH'] )
|
338
|
-
end
|
339
|
-
headers['Content-Length'] = body.length.to_s
|
340
|
-
headers['Content-Type'] = "text/html" unless headers.keys.include?('Content-Type')
|
341
|
-
end
|
342
43
|
|
343
|
-
[status, headers, body]
|
344
|
-
end
|
345
|
-
end
|
346
|
-
|
347
|
-
# Static file loader
|
348
|
-
#
|
349
|
-
# Use :
|
350
|
-
# set :static, "path/to/static"
|
351
|
-
class StaticFiles
|
352
|
-
def initialize(app)
|
353
|
-
@app = app
|
354
|
-
end
|
355
|
-
|
356
|
-
def call(env)
|
357
|
-
static = File.expand_path( File.join(Capcode::Configuration.get(:root), Capcode::Configuration.get(:static) ) )
|
358
|
-
file = File.join(static, env['REQUEST_PATH'].split("/") )
|
359
|
-
file = File.join(file, "index.html" ) if File.directory?(file)
|
360
|
-
if File.exist?(file)
|
361
|
-
body = [::File.read(file)]
|
362
|
-
header = {
|
363
|
-
"Last-Modified" => ::File.mtime(file).httpdate,
|
364
|
-
"Content-Type" => ::Rack::Mime.mime_type(::File.extname(file), 'text/plain'),
|
365
|
-
"Content-Length" => body.first.size.to_s
|
366
|
-
}
|
367
|
-
return [200, header, body]
|
368
|
-
else
|
369
|
-
return @app.call(env)
|
370
|
-
end
|
371
|
-
|
372
|
-
return @app.call(env)
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
44
|
class << self
|
377
45
|
attr :__auth__, true #:nodoc:
|
378
46
|
|
@@ -458,7 +126,7 @@ module Capcode
|
|
458
126
|
|
459
127
|
# Session hash
|
460
128
|
def session
|
461
|
-
|
129
|
+
env['rack.session']
|
462
130
|
end
|
463
131
|
|
464
132
|
# Return the Rack::Request object
|
@@ -693,16 +361,18 @@ module Capcode
|
|
693
361
|
# app = Rack::URLMap.new(Capcode.routes)
|
694
362
|
app = Capcode::Ext::Rack::URLMap.new(Capcode.routes)
|
695
363
|
puts "** Initialize static directory (#{Capcode.static}) in #{File.expand_path(Capcode::Configuration.get(:root))}" if Capcode::Configuration.get(:verbose)
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
364
|
+
|
365
|
+
#app = Rack::Static.new(
|
366
|
+
# app,
|
367
|
+
# #:urls => [@@__STATIC_DIR],
|
368
|
+
# :urls => [Capcode.static],
|
369
|
+
# :root => File.expand_path(Capcode::Configuration.get(:root))
|
370
|
+
#) unless Capcode::Configuration.get(:static).nil?
|
371
|
+
|
702
372
|
puts "** Initialize session" if Capcode::Configuration.get(:verbose)
|
703
|
-
app = Rack::Session::Cookie.new( app, Capcode::Configuration.get(:session) )
|
704
373
|
app = Capcode::StaticFiles.new(app)
|
705
374
|
app = Capcode::HTTPError.new(app)
|
375
|
+
app = Rack::Session::Cookie.new( app, Capcode::Configuration.get(:session) )
|
706
376
|
app = Rack::ContentLength.new(app)
|
707
377
|
app = Rack::Lint.new(app)
|
708
378
|
app = Rack::ShowExceptions.new(app)
|