Capcode 0.9.3 → 0.9.4

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.
@@ -12,7 +12,7 @@ module Capcode
12
12
  def post
13
13
  FileUtils.cp(
14
14
  params["upfile"][:tempfile].path,
15
- File.join( static[:path], params["upfile"][:filename] )
15
+ ::File.join( static[:path], params["upfile"][:filename] )
16
16
  )
17
17
  render :static => params["upfile"][:filename]
18
18
  end
@@ -6,7 +6,7 @@ require 'logger'
6
6
  Logger.class_eval { alias :write :<< } unless Logger.instance_methods.include? "write"
7
7
  require 'optparse'
8
8
  require 'irb'
9
- require 'mime/types'
9
+ require 'active_support'
10
10
  require 'capcode/version'
11
11
  require 'capcode/core_ext'
12
12
  require 'capcode/helpers/auth'
@@ -14,17 +14,9 @@ require 'capcode/render/text'
14
14
  require 'capcode/configuration'
15
15
  require 'capcode/filters'
16
16
 
17
+ require 'capcode/ext/rack/urlmap'
18
+
17
19
  module Capcode
18
- #@@__ROUTES = {}
19
- #@@__STATIC_DIR = nil
20
- #@@__APP = nil
21
-
22
- # @@__FILTERS = []
23
- # def self.before_filter( opts, &b )
24
- # opts[:action] = b
25
- # @@__FILTERS << opts
26
- # end
27
-
28
20
  class ParameterError < ArgumentError #:nodoc: all
29
21
  end
30
22
 
@@ -42,7 +34,6 @@ module Capcode
42
34
 
43
35
  # Helpers contains methods available in your controllers
44
36
  module Helpers
45
- #@@__ARGS__ = nil
46
37
  def self.args
47
38
  @args ||= nil
48
39
  end
@@ -85,33 +76,32 @@ module Capcode
85
76
  render_type = nil
86
77
  possible_code_renderer = nil
87
78
 
88
- if render_type.nil?
89
- hash.keys.each do |key|
90
- begin
91
- gem "capcode-render-#{key.to_s}"
92
- require "capcode/render/#{key.to_s}"
93
- rescue Gem::LoadError
94
- nil
95
- rescue LoadError
96
- raise Capcode::RenderError, "Hum... The #{key} renderer is malformated! Please try to install a new version or use an other renderer!", caller
97
- end
98
-
99
- if self.respond_to?("render_#{key.to_s}")
100
- unless render_type.nil?
101
- raise Capcode::RenderError, "Can't use multiple renderer (`#{render_type}' and `#{key}') !", caller
102
- end
103
- render_type = key
104
- end
105
-
106
- if key.class == Fixnum
107
- possible_code_renderer = key
79
+ hash.keys.each do |key|
80
+ begin
81
+ gem "capcode-render-#{key.to_s}"
82
+ require "capcode/render/#{key.to_s}"
83
+ rescue Gem::LoadError
84
+ nil
85
+ rescue LoadError
86
+ raise Capcode::RenderError, "Hum... The #{key} renderer is malformated! Please try to install a new version or use an other renderer!", caller
87
+ end
88
+
89
+ if self.respond_to?("render_#{key.to_s}")
90
+ unless render_type.nil?
91
+ raise Capcode::RenderError, "Can't use multiple renderer (`#{render_type}' and `#{key}') !", caller
108
92
  end
93
+ render_type = key
109
94
  end
110
95
 
111
- if render_type.nil? and possible_code_renderer.nil?
112
- raise Capcode::RenderError, "Renderer type not specified!", caller
96
+ if key.class == Fixnum
97
+ possible_code_renderer = key
113
98
  end
114
99
  end
100
+
101
+ if render_type.nil? and possible_code_renderer.nil?
102
+ raise Capcode::RenderError, "Renderer type not specified!", caller
103
+ end
104
+
115
105
  unless self.respond_to?("render_#{render_type.to_s}")
116
106
  if possible_code_renderer.nil?
117
107
  raise Capcode::RenderError, "#{render_type} renderer not present ! please require 'capcode/render/#{render_type}'", caller
@@ -123,7 +113,8 @@ module Capcode
123
113
  k = k.to_s.split(/_/).map{|e| e.capitalize}.join("-")
124
114
  header[k] = v
125
115
  end
126
- [code, hash, body]
116
+
117
+ [code, header, body]
127
118
  end
128
119
  else
129
120
  render_name = hash.delete(render_type)
@@ -212,17 +203,39 @@ module Capcode
212
203
  # URL( Capcode::Hello, "you" ) # => /hello/you
213
204
  def URL( klass, *a )
214
205
  path = nil
206
+ result = {}
207
+
215
208
  a = a.delete_if{ |x| x.nil? }
216
209
 
217
210
  if klass.class == Class
218
- Capcode.routes.each do |p, k|
219
- path = p if k.class == klass
211
+ last_size = 0
212
+
213
+ klass.__urls__[0].each do |cpath, regexp|
214
+ data = a.clone
215
+
216
+ n = Regexp.new( regexp ).number_of_captures
217
+ equart = (a.size - n).abs
218
+
219
+ rtable = regexp.dup.gsub( /\\\(/, "" ).gsub( /\\\)/, "" ).split( /\([^\)]*\)/ )
220
+
221
+ rtable.each do |r|
222
+ if r == ""
223
+ cpath = cpath + "/#{data.shift}"
224
+ else
225
+ cpath = cpath + "/#{r}"
226
+ end
227
+ end
228
+
229
+ cpath = (cpath + "/" + data.join( "/" )).gsub( /\/\//, "/" ).gsub( /\/$/, "" )
230
+ result[equart] = cpath
220
231
  end
232
+
233
+ path = result[result.keys.min]
221
234
  else
222
235
  path = klass
223
236
  end
224
237
 
225
- (ENV['RACK_BASE_URI']||'')+path+((a.size>0)?("/"+a.join("/")):(""))
238
+ (ENV['RACK_BASE_URI']||'')+path
226
239
  end
227
240
 
228
241
  # Calling content_for stores a block of markup in an identifier.
@@ -258,7 +271,6 @@ module Capcode
258
271
  # end
259
272
  # end
260
273
  def content_for( x )
261
- #if @@__ARGS__.map{|_| _.to_s }.include?(x.to_s)
262
274
  if Capcode::Helpers.args.map{|_| _.to_s }.include?(x.to_s)
263
275
  yield
264
276
  end
@@ -293,6 +305,18 @@ module Capcode
293
305
  # end
294
306
  # end
295
307
  #
308
+ # the rXXX method can also receive a second optional parameter corresponding
309
+ # of the header's Hash :
310
+ #
311
+ # module Capcode
312
+ # class HTTPError
313
+ # def r404(f, h)
314
+ # h['Content-Type'] = 'text/plain'
315
+ # "You are here ---> X (#{f} point)"
316
+ # end
317
+ # end
318
+ # end
319
+ #
296
320
  # Do the same (r500, r501, r403) to customize 500, 501, 403 errors
297
321
  class HTTPError
298
322
  def initialize(app) #:nodoc:
@@ -301,16 +325,23 @@ module Capcode
301
325
 
302
326
  def call(env) #:nodoc:
303
327
  status, headers, body = @app.call(env)
304
-
305
328
  if self.methods.include? "r#{status}"
306
- body = self.send( "r#{status}", env['REQUEST_PATH'] )
329
+ headers.delete('Content-Type') if headers.keys.include?('Content-Type')
330
+ body = begin
331
+ self.send( "r#{status}", env['REQUEST_PATH'], headers )
332
+ rescue
333
+ self.send( "r#{status}", env['REQUEST_PATH'] )
334
+ end
307
335
  headers['Content-Length'] = body.length.to_s
336
+ headers['Content-Type'] = "text/html" unless headers.keys.include?('Content-Type')
308
337
  end
309
338
 
310
339
  [status, headers, body]
311
340
  end
312
341
  end
313
342
 
343
+ require 'capcode/response'
344
+
314
345
  class << self
315
346
  attr :__auth__, true #:nodoc:
316
347
 
@@ -332,8 +363,10 @@ module Capcode
332
363
  #
333
364
  # If the regexp in the route does not match, all arguments will be <tt>nil</tt>
334
365
  def Route *routes_paths
366
+ create_path = routes_paths[0].nil?
335
367
  Class.new {
336
368
  meta_def(:__urls__) {
369
+ routes_paths = ['/'+self.to_s.gsub( /^Capcode::/, "" ).underscore] if create_path == true
337
370
  # < Route '/hello/world/([^\/]*)/id(\d*)', '/hello/(.*)', :agent => /Songbird (\d\.\d)[\d\/]*?/
338
371
  # # => [ {'/hello/world' => '([^\/]*)/id(\d*)', '/hello' => '(.*)'},
339
372
  # 2,
@@ -391,21 +424,6 @@ module Capcode
391
424
  @response = Rack::Response.new
392
425
  @request = Rack::Request.new(@env)
393
426
 
394
- # __k = self.class.to_s.split( /::/ )[-1].downcase.to_sym
395
- # @@__FILTERS.each do |f|
396
- # proc = f.delete(:action)
397
- # __run = true
398
- # if f[:only]
399
- # __run = f[:only].include?(__k)
400
- # end
401
- # if f[:except]
402
- # __run = !f[:except].include?(__k)
403
- # end
404
- #
405
- # # proc.call(self) if __run
406
- # puts "call #{proc} for #{__k}"
407
- # end
408
-
409
427
  # Check authz
410
428
  authz_options = nil
411
429
  if Capcode.__auth__ and Capcode.__auth__.size > 0
@@ -441,14 +459,17 @@ module Capcode
441
459
  xPath = p.gsub( /^\//, "" ).split( "/" )
442
460
  if (xPath - aPath).size == 0
443
461
  diffArgs = aPath - xPath
444
- diffNArgs = diffArgs.size
462
+ diffNArgs = diffArgs.size - 1
445
463
  if finalNArgs.nil? or finalNArgs > diffNArgs
446
464
  finalPath = p
447
465
  finalNArgs = diffNArgs
448
466
  finalArgs = diffArgs
449
467
  end
450
468
  end
451
-
469
+ end
470
+
471
+ if finalNArgs > self.class.__urls__[1]
472
+ return [404, {'Content-Type' => 'text/plain'}, "Not Found: #{@request.path}"]
452
473
  end
453
474
 
454
475
  nargs = self.class.__urls__[1]
@@ -481,32 +502,33 @@ module Capcode
481
502
  filter_output
482
503
  end
483
504
  }
505
+
484
506
  if r.respond_to?(:to_ary)
485
507
  @response.status = r.shift #r[0]
486
508
  #r[1].each do |k,v|
487
509
  r.shift.each do |k,v|
488
510
  @response[k] = v
489
511
  end
490
- @response.body = r.shift #r[2]
512
+ @response.write r.shift #r[2]
491
513
  else
492
514
  @response.write r
493
515
  end
494
-
516
+
495
517
  @response.finish
496
518
  end
497
519
 
498
520
  include Capcode::Helpers
499
- include Capcode::Views
521
+ include Capcode::Views
500
522
  }
501
523
  end
502
-
524
+ Capcode::Route = Capcode::Route(nil)
525
+
503
526
  # This method help you to map and URL to a Rack or What you want Helper
504
527
  #
505
528
  # Capcode.map( "/file" ) do
506
529
  # Rack::File.new( "." )
507
530
  # end
508
531
  def map( route, &b )
509
- #@@__ROUTES[route] = yield
510
532
  Capcode.routes[route] = yield
511
533
  end
512
534
 
@@ -570,15 +592,28 @@ module Capcode
570
592
  def application( args = {} )
571
593
  Capcode::Configuration.configuration(args)
572
594
 
573
- Capcode.constants.each do |k|
595
+ Capcode.constants.clone.delete_if {|k|
596
+ not( Capcode.const_get(k).to_s =~ /Capcode/ ) or [
597
+ "Filter",
598
+ "Helpers",
599
+ "RouteError",
600
+ "Views",
601
+ "ParameterError",
602
+ "HTTPError",
603
+ "Configuration",
604
+ "MissingLibrary",
605
+ "Route",
606
+ "RenderError"
607
+ ].include?(k)
608
+ }.each do |k|
574
609
  begin
575
610
  if eval "Capcode::#{k}.public_methods(true).include?( '__urls__' )"
576
- hash_of_routes, max_captures_for_routes, klass = eval "Capcode::#{k}.__urls__"
611
+ hash_of_routes, max_captures_for_routes, klass = eval "Capcode::#{k}.__urls__"
577
612
  hash_of_routes.keys.each do |current_route_path|
578
613
  #raise Capcode::RouteError, "Route `#{current_route_path}' already define !", caller if @@__ROUTES.keys.include?(current_route_path)
579
614
  raise Capcode::RouteError, "Route `#{current_route_path}' already define !", caller if Capcode.routes.keys.include?(current_route_path)
580
- #@@__ROUTES[current_route_path] = klass.new
581
- Capcode.routes[current_route_path] = klass.new
615
+ # Capcode.routes[current_route_path] = klass.new
616
+ Capcode.routes[current_route_path] = klass
582
617
  end
583
618
  end
584
619
  rescue => e
@@ -587,13 +622,12 @@ module Capcode
587
622
  end
588
623
 
589
624
  # Set Static directory
590
- #@@__STATIC_DIR = (conf[:static][0].chr == "/")?conf[:static]:"/"+conf[:static] unless conf[:static].nil?
591
625
  Capcode.static = (Capcode::Configuration.get(:static)[0].chr == "/")?Capcode::Configuration.get(:static):"/"+Capcode::Configuration.get(:static) unless Capcode::Configuration.get(:static).nil?
592
626
 
593
627
  # Initialize Rack App
594
628
  puts "** Map routes." if Capcode::Configuration.get(:verbose)
595
- #app = Rack::URLMap.new(@@__ROUTES)
596
- app = Rack::URLMap.new(Capcode.routes)
629
+ # app = Rack::URLMap.new(Capcode.routes)
630
+ app = Capcode::Ext::Rack::URLMap.new(Capcode.routes)
597
631
  puts "** Initialize static directory (#{Capcode.static}) in #{File.expand_path(Capcode::Configuration.get(:root))}" if Capcode::Configuration.get(:verbose)
598
632
  app = Rack::Static.new(
599
633
  app,
@@ -608,7 +642,6 @@ module Capcode
608
642
  app = Rack::Lint.new(app)
609
643
  app = Rack::ShowExceptions.new(app)
610
644
  #app = Rack::Reloader.new(app) ## -- NE RELOAD QUE capcode.rb -- So !!!
611
- # app = Rack::CommonLogger.new( app, Logger.new(conf[:log]) )
612
645
 
613
646
  middlewares.each do |mw|
614
647
  middleware, args, block = mw
@@ -626,6 +659,7 @@ module Capcode
626
659
  end
627
660
 
628
661
  if block_given?
662
+ puts "** Execute block" if Capcode::Configuration.get(:verbose)
629
663
  yield( self )
630
664
  end
631
665
 
@@ -763,16 +797,13 @@ module Capcode
763
797
  end
764
798
 
765
799
  def routes #:nodoc:
766
- #@@__ROUTES
767
800
  @routes ||= {}
768
801
  end
769
802
 
770
803
  def static #:nodoc:
771
- #@@__STATIC_DIR
772
804
  @static_dir ||= nil
773
805
  end
774
806
  def static=(x) #:nodoc:
775
- #@@__STATIC_DIR
776
807
  @static_dir = x
777
808
  end
778
809
 
@@ -0,0 +1,59 @@
1
+ module Capcode
2
+ module Ext
3
+ module Rack
4
+ # Rack::URLMap takes a hash mapping urls or paths to apps, and
5
+ # dispatches accordingly. Support for HTTP/1.1 host names exists if
6
+ # the URLs start with <tt>http://</tt> or <tt>https://</tt>.
7
+ #
8
+ # URLMap modifies the SCRIPT_NAME and PATH_INFO such that the part
9
+ # relevant for dispatch is in the SCRIPT_NAME, and the rest in the
10
+ # PATH_INFO. This should be taken care of when you need to
11
+ # reconstruct the URL in order to create links.
12
+ #
13
+ # URLMap dispatches in such a way that the longest paths are tried
14
+ # first, since they are most specific.
15
+
16
+ class URLMap
17
+ def initialize(map = {})
18
+ remap(map)
19
+ end
20
+
21
+ def remap(map)
22
+ @mapping = map.map { |location, app|
23
+ if location =~ %r{\Ahttps?://(.*?)(/.*)}
24
+ host, location = $1, $2
25
+ else
26
+ host = nil
27
+ end
28
+
29
+ unless location[0] == ?/
30
+ raise ArgumentError, "paths need to start with /"
31
+ end
32
+ location = location.chomp('/')
33
+ match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n')
34
+
35
+ [host, location, match, app]
36
+ }.sort_by { |(h, l, m, a)| [h ? -h.size : (-1.0 / 0.0), -l.size] } # Longest path first
37
+ end
38
+
39
+ def call(env)
40
+ path = env["PATH_INFO"].to_s
41
+ script_name = env['SCRIPT_NAME']
42
+ hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT')
43
+ @mapping.each { |host, location, match, app|
44
+ next unless (hHost == host || sName == host \
45
+ || (host.nil? && (hHost == sName || hHost == sName+':'+sPort)))
46
+ next unless path =~ match && rest = $1
47
+ next unless rest.empty? || rest[0] == ?/
48
+
49
+ return app.new.call(
50
+ env.merge(
51
+ 'SCRIPT_NAME' => (script_name + location),
52
+ 'PATH_INFO' => rest))
53
+ }
54
+ [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]]
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,6 +1,7 @@
1
1
  module Capcode
2
2
  module Helpers
3
3
  def render_text( f, _ ) #:nodoc:
4
+ @response['Content-Type'] = 'text/plain'
4
5
  f
5
6
  end
6
7
  end
@@ -1,3 +1,3 @@
1
1
  module Capcode
2
- CAPCOD_VERION="0.9.3"
2
+ CAPCOD_VERION="0.9.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Capcode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ hash: 51
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 9
9
+ - 4
10
+ version: 0.9.4
5
11
  platform: ruby
6
12
  authors:
7
13
  - "Gr\xC3\xA9goire Lejeune"
@@ -9,19 +15,37 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-02-10 00:00:00 +01:00
18
+ date: 2010-05-28 00:00:00 +02:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: rack
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
17
33
  type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: activesupport
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
20
40
  requirements:
21
41
  - - ">="
22
42
  - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
23
46
  version: "0"
24
- version:
47
+ type: :runtime
48
+ version_requirements: *id002
25
49
  description: Capcode is a web microframework
26
50
  email: gregoire.lejeune@free.fr
27
51
  executables: []
@@ -67,6 +91,7 @@ files:
67
91
  - lib/capcode/base/db.rb
68
92
  - lib/capcode/configuration.rb
69
93
  - lib/capcode/core_ext.rb
94
+ - lib/capcode/ext/rack/urlmap.rb
70
95
  - lib/capcode/filters.rb
71
96
  - lib/capcode/helpers/auth.rb
72
97
  - lib/capcode/render/text.rb
@@ -89,6 +114,7 @@ files:
89
114
  - examples/rest-run.rb
90
115
  - examples/rest.rb
91
116
  - examples/rest.ru
117
+ - examples/route.rb
92
118
  - examples/sample.rb
93
119
  - examples/session.rb
94
120
  - examples/soapbox/public/jquery.js
@@ -144,21 +170,29 @@ rdoc_options:
144
170
  require_paths:
145
171
  - lib
146
172
  required_ruby_version: !ruby/object:Gem::Requirement
173
+ none: false
147
174
  requirements:
148
175
  - - ">="
149
176
  - !ruby/object:Gem::Version
177
+ hash: 53
178
+ segments:
179
+ - 1
180
+ - 8
181
+ - 1
150
182
  version: 1.8.1
151
- version:
152
183
  required_rubygems_version: !ruby/object:Gem::Requirement
184
+ none: false
153
185
  requirements:
154
186
  - - ">="
155
187
  - !ruby/object:Gem::Version
188
+ hash: 3
189
+ segments:
190
+ - 0
156
191
  version: "0"
157
- version:
158
192
  requirements: []
159
193
 
160
194
  rubyforge_project: capcode
161
- rubygems_version: 1.3.5
195
+ rubygems_version: 1.3.7
162
196
  signing_key:
163
197
  specification_version: 3
164
198
  summary: Capcode is a web microframework