cuca 0.04 → 0.05

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,5 +1,15 @@
1
1
 
2
- * xxxx/xx/xx - 0.04
2
+ * 2009/08/20 - 0.05
3
+ - Widget can be defined within the action controller file.
4
+ - Fixed minor typos in application skeleton conf/config.rb
5
+ - Fix to catch exceptions in conf/config and conf/environment
6
+ - Fixes & minor changes in stdlib/form
7
+ - Stdlib listwidget rewrite_hooks will pass named hash instead of plain array
8
+ as row data
9
+ - fixed script/console to load support files
10
+ - Fixed bad error rescueing in generators that displayed irritating errors
11
+
12
+ * 2008/06/17 - 0.04
3
13
  - Fixed error-message displaying traceback but not the actual exception
4
14
  - Display trace if enabled on 'stop :error' events
5
15
  - Option for autoloading support files (instead of bulk 'require')
@@ -12,7 +22,6 @@
12
22
  - Added some unit tests
13
23
  - Minor fixes in stdlib
14
24
  - Some fixes in dispatchers
15
- -
16
25
 
17
26
 
18
27
  * 2008/05/18 - 0.03
@@ -17,7 +17,7 @@ class IndexController < ApplicationController
17
17
  h2 { "If you want to learn cuca" }
18
18
  ul do
19
19
  li { text "Have a look at the Demo Widgets: "; SLink('demo', 'Here') }
20
- li { text "Checkout the cuca website: "; SLink("http://cuca.rubyforge.net") }
20
+ li { text "Checkout the cuca website: "; SLink("http://cuca.rubyforge.org") }
21
21
  li { text "Read the source code of these examples" }
22
22
  end
23
23
 
@@ -26,14 +26,14 @@ Cuca::App.configure do |config|
26
26
 
27
27
  ### This would be an autoload configuration
28
28
  # config.include_directories = [
29
- # { :dir => '_controllers', :class_naming = Proc.new { |f| f.capitalize+'Controller' } },
30
- # { :dir => '_widgets', :class_naming = Proc.new { |f| f.capitalize+'Widget' } },
31
- # { :dir => '_layouts', :class_naming = Proc.new { |f| f.capitalize+'Layout' } }
32
- # { :dir => '_models', :class_naming = Proc.new { |f| f.capitalize } }
29
+ # { :dir => '_controllers', :class_naming => lambda { |f| f.capitalize+'Controller' } },
30
+ # { :dir => '_widgets', :class_naming => lambda { |f| f.capitalize+'Widget' } },
31
+ # { :dir => '_layouts', :class_naming => lambda { |f| f.capitalize+'Layout' } },
32
+ # { :dir => '_models', :class_naming => lambda { |f| f.capitalize } }
33
33
  # ]
34
34
 
35
35
  ### For pretty url mapping
36
- # config.magic_action_prefix = '__default_'
36
+ # config.magic_action_prefix = '__'
37
37
 
38
38
  ### This defines the session cookie definitions
39
39
  # config.session_key = 'cuca_session'
data/lib/cuca.rb CHANGED
@@ -35,6 +35,7 @@ require 'rubygems'
35
35
  # All Classes are defined under this namespace
36
36
  module Cuca
37
37
 
38
+
38
39
  class CucaException < Exception # :nodoc:
39
40
  end
40
41
 
@@ -44,6 +45,24 @@ end
44
45
 
45
46
  end
46
47
 
48
+ # To require config and environment
49
+ def init_save_require(filename)
50
+ begin
51
+ require filename
52
+ rescue => e
53
+ title = "INIT Error [#{filename}]: #{e}"
54
+ $stderr.puts title
55
+ err = ''
56
+ e.backtrace.each do |b|
57
+ err << " #{b}\n"
58
+ end
59
+ $stderr.puts err
60
+ c = CGI.new
61
+ c.out { "<b>#{title}<br><br>#{err.gsub(/\n/,'<br>')}" }
62
+ end
63
+ end
64
+
65
+
47
66
 
48
67
  if $cuca_path.nil? then
49
68
  $stderr.puts "WARN: $cuca_path not found, assuming #{Dir.pwd}"
@@ -57,23 +76,12 @@ $cuca_path = File.expand_path($cuca_path) + '/'
57
76
  require 'cuca/app'
58
77
 
59
78
  $LOAD_PATH << $cuca_path+'/lib'
60
- begin
61
- require $cuca_path+'/conf/config'
62
- rescue LoadError => e
63
- $stderr.puts "WARN: Error loading conf/config: #{e}"
64
- end
79
+
80
+ init_save_require($cuca_path+'/conf/config')
65
81
 
66
82
  require 'cuca/widget'
67
83
  require 'cuca/controller'
68
84
  require 'cuca/layout'
69
85
 
70
- begin
71
- require $cuca_path+'/conf/environment'
72
- rescue LoadError => e
73
- $stderr.puts "WARN: Error loading conf/environment: #{e}"
74
- rescue => e
75
- e.backtrace.each do |b|
76
- $stderr.puts" #{b}\n"
77
- end
78
- end
86
+ init_save_require($cuca_path+'/conf/environment')
79
87
 
data/lib/cuca/app.rb CHANGED
@@ -232,7 +232,7 @@ class App
232
232
  # 3rd: Load additional files
233
233
  load_support_files(@urlmap)
234
234
 
235
- test = ApplicationController.new
235
+ # test = ApplicationController.new
236
236
 
237
237
 
238
238
  # 4th: Now let's run the actual page script code
data/lib/cuca/const.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cuca
2
- VERSION = '0.04'
2
+ VERSION = '0.05'
3
3
  end
@@ -65,9 +65,8 @@ end
65
65
  #
66
66
  # == Interrupting the program
67
67
  #
68
- # If you want to stop your program you can call the 'stop' method. Stop has
69
- # function to do most function, like redirect or setting a different layout or
70
- # raising an error message.
68
+ # If you want to stop your program you can call the 'stop' method. Stop take some arguments
69
+ # that allows you to redirect, display error or set a different layout.
71
70
  #
72
71
  #
73
72
  # == Examples
@@ -157,7 +156,7 @@ class Controller < Widget
157
156
  # One or more before filter can set by an application Controller
158
157
  # The instance methods will be run before the action get ran (get/post/run)
159
158
  # If you have many filters and need order you can set the priority option.
160
- # Lower priorities will be ran first.
159
+ # Lower priorities will run first.
161
160
  public
162
161
  def self.before_filter(method, priority = 50)
163
162
  define_filter_method(:def_before_filter, method, priority)
@@ -7,13 +7,22 @@ class ::Markaby::Builder # :nodoc:
7
7
 
8
8
  def method_missing(sym, *args, &block ) # :nodoc:
9
9
  class_name = sym.id2name
10
- begin
11
- c=Object::const_get(class_name+"Widget")
12
- rescue NameError => e
13
- return old_method_missing(sym,*args,&block)
10
+
11
+ # give up immediately if we don't have a Constant capable method
12
+ return old_method_missing(sym, *args, &block) if
13
+ class_name[0].chr.upcase != class_name[0].chr
14
+
15
+
16
+ widget_name = class_name+'Widget'
17
+
18
+ c=Object::const_get(widget_name) if Object::const_defined?(widget_name)
19
+
20
+ if (c.nil? && !$app.nil?) then
21
+ c = $app.urlmap.action_module.const_get(widget_name) if \
22
+ $app.urlmap.action_module.const_defined?(widget_name)
14
23
  end
15
24
 
16
- # $stderr.puts "Widget in markaby: Class: #{class_name}, \n\n assigns: #{@assigns.inspect} \n\n"
25
+ return old_method_missing(sym, *args, &block) if c.nil?
17
26
 
18
27
  widget = c.new({:args => args,
19
28
  :assigns => @assigns },
@@ -32,10 +41,11 @@ module Cuca
32
41
  # A generator is a mixin to Cuca::Widget. It should provide functions that generate
33
42
  # content.
34
43
  # Visible within a generator function should be all instance variables, all instance
35
- # methods and an easy accessor to widgets. For example the view and markaby generators
36
- # that come with cuca you can call a widget like:
44
+ # methods and an easy accessor to widgets defined on the root namespace and
45
+ # within the action namespace ($app.urlmap.action_namespace). For example the view and
46
+ # markaby generators that come with cuca you can call a widget like:
37
47
  # Link(a,b,c..) { block}
38
- # and it will initialize the LinkWidget
48
+ # and it will initialize the LinkWidget.
39
49
  module Generator
40
50
 
41
51
  # == Markaby Generator
@@ -52,30 +52,36 @@ module View
52
52
  @base = base_object
53
53
  end
54
54
 
55
+
56
+
55
57
  def method_missing(sym, *args, &block )
56
58
  class_name = sym.id2name
59
+
60
+ # $stderr.puts "View: Method missing: #{class_name}: #{@base.class.name}"
61
+
62
+ # 1st try to find method in the base widget
63
+ if @base.methods.include?(class_name) then
64
+ return @base.send(class_name, *args, &block)
65
+ end
57
66
 
58
- begin
59
- # 1st try to find method in the base widget
60
- if @base.methods.include?(class_name) then
61
- return @base.send(class_name, *args, &block)
62
- end
63
- # 2nd try to find a widget
64
- c=Object::const_get(class_name+"Widget")
65
- rescue NameError => e
66
- raise "Undefined method: #{sym.id2name}"
67
+ # 2nd try to find a widget in root namespace and the controllers
68
+ widget_name = class_name+'Widget'
69
+ c=Object::const_get(widget_name) if Object.const_defined?(widget_name)
70
+ if (c.nil? && !$app.nil?) then
71
+ c = $app.urlmap.action_module.const_get(widget_name) if \
72
+ $app.urlmap.action_module.const_defined?(widget_name)
67
73
  end
68
74
 
75
+ raise "Undefined method: #{sym.id2name}" if c.nil?
76
+
69
77
  widget = c.new({:args => args,
70
78
  :assigns => @assigns },
71
79
  &block)
72
80
 
73
- # $stderr.puts "Widget:" + widget.inspect
74
- return widget.to_s
75
81
 
76
- # $stderr.puts "Good"
82
+ return widget.to_s
77
83
  end
78
- end
84
+ end
79
85
 
80
86
 
81
87
  # VIEW_DIR = $cuca_path+'app/_views'
data/lib/cuca/session.rb CHANGED
@@ -57,6 +57,8 @@ module Cuca
57
57
  #
58
58
  # Page memory is a container to store data only valid for the current action.
59
59
  # It will be erased once you leave to a different action.
60
+ # Current request and query parameters (get/post) are automatically available in this
61
+ # container.
60
62
  #
61
63
  #
62
64
  #
@@ -31,11 +31,22 @@ class ARFormWidget < FormWidget
31
31
  @disabled_on_create = options[:disabled_on_create] || []
32
32
  @hidden_on_update = options[:hidden_on_update] || []
33
33
  @hidden_on_create = options[:hidden_on_create] || []
34
- super(form_name, options[:post_to])
34
+ super(form_name, options)
35
35
  end
36
36
 
37
37
  def on_submit
38
38
  controller.send(@form_name+'_submit', @model) unless controller.nil?
39
+
40
+ # this is to reload the form with the new values in case the formname_submit did
41
+ # save something:
42
+ clear
43
+ form
44
+ end
45
+
46
+ # overwrite this method to perform modifications
47
+ # before validateing the data
48
+ def before_validate(variables)
49
+ variables
39
50
  end
40
51
 
41
52
  def validate
@@ -44,6 +55,10 @@ class ARFormWidget < FormWidget
44
55
  p = request_parameters.dup
45
56
  p.delete(@submit_name)
46
57
 
58
+
59
+ p = before_validate(p)
60
+
61
+
47
62
  if @model.new_record? then
48
63
  @disabled_on_create.each { |d| p.delete(d) }
49
64
  @hidden_on_create.each { |d| p.delete(d) }
@@ -58,7 +73,7 @@ class ARFormWidget < FormWidget
58
73
  @password_fields.each do |pwf|
59
74
  p.delete(pwf) if p[pwf].chomp.empty?
60
75
  end
61
- $stderr.puts p.inspect
76
+ # $stderr.puts p.inspect
62
77
  @model.attributes = p
63
78
 
64
79
  return true if @model.valid?
@@ -95,6 +110,12 @@ class ARFormWidget < FormWidget
95
110
  "<input type='text' name='#{name}' value='#{value}' #{'disabled' unless enabled}>"
96
111
  end
97
112
 
113
+ private
114
+ def fe_textarea(name, value, enabled, rows=4, cols = 50)
115
+ "<textarea name='#{name}' rows='#{rows}' cols='#{cols}'>#{value}</textarea>"
116
+ end
117
+
118
+
98
119
  # the fe-password is special: will never contain a value and will not save the
99
120
  # password if nothing was typed into the field
100
121
  private
@@ -130,8 +151,9 @@ end
130
151
 
131
152
  def fe_datetime(name, v,enabled)
132
153
  v = Time.now unless v
154
+ v = "#{v.year}/#{twodig(v.month)}/#{twodig(v.day)} #{v.hour}:#{v.min}" if v.instance_of?(Time)
133
155
  r = <<-EOS
134
- <input type='text' name='#{name}' id='i_#{name}' value='#{v.year}/#{twodig(v.month)}/#{twodig(v.day)} #{v.hour}:#{v.min}' #{'disabled' unless enabled}>
156
+ <input type='text' name='#{name}' id='i_#{name}' value='#{v}' #{'disabled' unless enabled}>
135
157
  EOS
136
158
  if enabled then
137
159
  r << <<-EOS
@@ -152,6 +174,35 @@ end
152
174
  return r
153
175
  end
154
176
 
177
+ # select date.. no time
178
+ def fe_date(name, v,enabled)
179
+ v = Time.now unless v
180
+ r = <<-EOS
181
+ <input type='text' name='#{name}' id='i_#{name}' value='#{v.year}/#{twodig(v.month)}/#{twodig(v.day)}' #{'disabled' unless enabled}>
182
+ EOS
183
+ if enabled then
184
+ r << <<-EOS
185
+ <input type='submit' id='s_#{name}' value='...'>
186
+ <script type="text/javascript">
187
+ Calendar.setup({
188
+ inputField : "i_#{name}", // id of the input field
189
+ ifFormat : "%Y/%m/%d", // format of the input field
190
+ showsTime : false, // will display a time selector
191
+ button : "s_#{name}", // trigger for the calendar (button ID)
192
+ singleClick : true, // double-click mode
193
+ step : 1 // show all years in drop-down boxes (instead of every other year as default)
194
+ });
195
+ </script>
196
+ </input>
197
+ EOS
198
+ end
199
+ return r
200
+ end
201
+
202
+ def fe_time(name,v,enabled)
203
+ "<input name='#{name}' size=5 type='text' value='#{v || '0:00'}'#{' disabled' unless enabled}>"
204
+ end
205
+
155
206
  def fe_bool(name,v,enabled)
156
207
  r = ''
157
208
  r << "<select name='#{name}' #{'disabled' unless enabled}>\n"
@@ -177,6 +228,10 @@ end
177
228
  r << fe_int(name,value,enabled)
178
229
  when :datetime
179
230
  r << fe_datetime(name,value,enabled)
231
+ when :date
232
+ r << fe_date(name,value,enabled)
233
+ when :time
234
+ r << fe_time(name, value, enabled)
180
235
  when :password
181
236
  r << fe_password(name, enabled)
182
237
  end
@@ -189,6 +244,13 @@ end
189
244
  fe(col.type, col.name, @model.send(column_name.intern))
190
245
  end
191
246
 
247
+
248
+ # Load column values into instance variables
249
+ def setup
250
+ @model.class.columns.each do |col|
251
+ self.instance_variable_set("@#{col.name}", @model.send(col.name.intern))
252
+ end
253
+ end
192
254
 
193
255
  # you might want to replace this method
194
256
  public
@@ -53,25 +53,38 @@ class FormWidget < Cuca::Widget
53
53
  # {form_name}_submit(result) on the CONTROLLER.
54
54
  def on_submit
55
55
  controller.send(@form_name+'_submit', get_variables) unless controller.nil?
56
+ clear
57
+ form
56
58
  end
57
59
 
58
- def output(form_name, post_to = nil)
60
+ # options can be used for form specific stuff
61
+ # we only use :post_to to set @post_to atm
62
+ def output(form_name, options = {})
59
63
  @form_name = form_name
60
- @post_to = post_to || cgi.path_info
64
+
61
65
  @submit_name = 'submit_'+@form_name
62
66
  @form_errors = {}
63
67
 
68
+ @options = options
69
+
70
+ setup
71
+
72
+ @post_to = @options[:post_to] || cgi.path_info
73
+
74
+
75
+ # form
76
+
64
77
  if posted? then
65
78
  load_variables
66
79
  validate
67
80
  if @form_errors.empty? then
68
- clear # submitted forms should not have any content that might have been generated
81
+ # What was that thought about?
82
+ # clear # submitted forms should not have any content that might have been generated
69
83
  return on_submit
70
84
  else
71
85
  form
72
86
  end
73
87
  else
74
- setup
75
88
  form
76
89
  end
77
90
  end
@@ -20,10 +20,19 @@ class BaseList < Cuca::Widget
20
20
  @rewrite_hooks[field_id] = proc
21
21
  end
22
22
 
23
+ def row2hash(row)
24
+ res = {}
25
+ c = columns
26
+ c.each_index do |idx|
27
+ res[c[idx][:id]] = row[idx]
28
+ end
29
+ res
30
+ end
31
+
23
32
  def rewrite_field(row, field_id, content)
24
33
  # $stderr.puts "REwrite field(#{row.inspect}, #{field_id.inspect}, #{content.inspect} - hooks #{@rewrite_hooks.inspect}"
25
34
  return content unless @rewrite_hooks[field_id]
26
- return @rewrite_hooks[field_id].call(row, content)
35
+ return @rewrite_hooks[field_id].call(row2hash(row), content)
27
36
  end
28
37
 
29
38
 
@@ -0,0 +1,12 @@
1
+ # This file is -r required when runnung script/console to load
2
+ # support files automatically.
3
+ # Only for the CLI irb console
4
+
5
+ require 'cuca/urlmap'
6
+
7
+ puts "Cuca console: type: url [/some/path] to load support files of your app"
8
+ $app = Cuca::App.new
9
+
10
+ def url(some_path)
11
+ $app.load_support_files(Cuca::URLMap.new($cuca_path+'/app', some_path))
12
+ end
@@ -1 +1 @@
1
- This directory is for the unit tests, it doesn't make sense for anything else.
1
+ This directory is for the unit tests, it doesn't make sense for anything else.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuca
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.04"
4
+ version: "0.05"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Boese
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-17 00:00:00 +01:00
12
+ date: 2008-08-20 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -41,12 +41,11 @@ extra_rdoc_files:
41
41
  files:
42
42
  - bin/cuca
43
43
  - lib/cuca.rb
44
+ - lib/cuca_console.rb
44
45
  - lib/cuca
45
46
  - lib/cuca/cgi_fix.rb
46
47
  - lib/cuca/controller.rb
47
48
  - lib/cuca/config.rb
48
- - lib/cuca/urlmap2.rb
49
- - lib/cuca/urlmap-original.rb
50
49
  - lib/cuca/stdlib
51
50
  - lib/cuca/stdlib/arview.rb
52
51
  - lib/cuca/stdlib/form.rb
@@ -1,324 +0,0 @@
1
-
2
- if __FILE__ == $0 then
3
- require 'rubygems'
4
- require 'cuca'
5
- end
6
-
7
- module Cuca
8
-
9
- # URLMap will throw this in case we can't find a controller
10
- # file for a URL.
11
- class RoutingError < StandardError # :nodoc:
12
- end
13
-
14
-
15
- # == URLMap
16
- #
17
- # URLMap is used internally to match a URL to a controller file.
18
- # Call with ds = URLMap.new('/path/to/app', 'path/from/url')
19
- # URLMap.new(base_path, url)
20
- #
21
- # You can then fetch the following values:
22
- #
23
- # * script - path to the controller file
24
- # * url - unmodified URL as passed to initializer
25
- # * assigns - hash with variable assigns from the url (magick prefixes)
26
- # * subcall - name of subcall or nil if a normal call was made
27
- # * action - Action name (Note: action.capitalize+"Controller" is your controller class name)
28
- # * base_url - Base URL to the action (e.g.: /user/someone/show is -> /user/someone/)
29
- # * base_path - Unmodified base_path
30
- # * action_path - Path to the action script
31
- # * action_path_full - Full path to action script
32
- # * path_tree - an array of each directory on the way from /path/to/app to the script
33
- # (to look for include_directories in - see Cuca::Config)
34
- # * action_module - The module the action should be loaded into (to avoid name conflicts, depends on action_path)
35
- #
36
- #
37
- # == Match on other URL
38
- #
39
- # A widget/controller can make use of the URLMap object to scan on other directories (example to find out if a
40
- # link url will be withing the same controller).
41
- #
42
- # See match? / submatch? and usubmatch?
43
- #
44
- #
45
- # == Notes
46
- #
47
- # URL's ending with '/' will be scanned for default index files.
48
- #
49
- # URL's where last part (action) starts with '-' will be scanned for
50
- # subcalls
51
- #
52
- # If no script is found or any other error it will raise a RoutingError exception
53
- #
54
- #
55
- # == Example
56
- #
57
- # u = URLMap.new('/home/bones/src/cuca_app/app', 'customer/southwind_lda/show'
58
- #
59
- # u.script => '/home/bones/src/cuca_app/app/customer/__customer/show.rb'
60
- # u.action => 'show'
61
- # u.base_url => '/customer/__customer/'
62
- # u.assigns => { 'customer' => 'southwind_lda' }
63
- # u.action_path => 'customer/southwind_lda/'
64
- #
65
- class URLMap
66
- attr_reader :url # current url
67
- attr_reader :assigns
68
- attr_reader :script
69
- attr_reader :subcall
70
- attr_reader :base_url
71
- attr_reader :base_path
72
- attr_reader :action
73
- attr_reader :action_path
74
- attr_reader :action_path_full
75
- attr_reader :action_module
76
- attr_reader :path_tree
77
-
78
- DEF_ACT = Cuca::App::config['magic_action_prefix'] || '__'
79
- DEF_IDX = [ 'index', 'default' ]
80
-
81
- private
82
- def scan_file(base, file)
83
-
84
- if (file == '') then # check for default index file
85
- DEF_IDX.each do |idxfile|
86
- if File.exist?("#{base}/#{idxfile}.rb")
87
- @action = idxfile
88
- return "#{idxfile}.rb"
89
- end
90
- end
91
- raise RoutingError.new("No default index file found in #{base}")
92
- end
93
-
94
- @action = file
95
-
96
- # check if a regular file exists:
97
- # puts "Checking file on #{check}"
98
- return (file+".rb") if File.exist?("#{base}/#{file}.rb")
99
-
100
- # check if the subcall file exists:
101
- if (file[0].chr == '-') then
102
- (action,subcall) = file.scan(/^\-(.*)\-(.*)$/).flatten
103
- if action.nil? || subcall.nil? || action.strip.empty? then
104
- raise RoutingError.new("Bad format on subcall: #{file}")
105
- end
106
- raise RoutingError.new("Script not found for subcall: #{file}: #{action}.rb") if !File.exist?("#{base}/#{action}.rb")
107
- @subcall = subcall
108
- @action = action
109
- return "#{action}.rb"
110
- end
111
- end
112
-
113
-
114
- # scan_dir will look within a realdirectory for an unparsed url 'file' and return
115
- # it's real path
116
- private
117
- def scan_dir(base, file)
118
-
119
- striped = "#{base}/#{file}"[@base_path.length..-1]
120
- mount = Cuca::App.config['mount'] || {}
121
- $stderr.puts "SCAN DIR: #{striped}"
122
- $stderr.puts "MOUNTS: #{mount.inspect}"
123
-
124
-
125
- if mount["#{striped}/"] then
126
- $stderr.puts "Found mount point, returning: #{mount["#{striped}/"]}"
127
- return mount["#{striped}/"]
128
- end
129
-
130
- if File.directory?("#{base}/#{file}") then
131
- return file.empty? ? base : "#{base}/#{file}" # avoid returning double //
132
- end
133
-
134
- d = Dir["#{base}/#{DEF_ACT}*"].collect { |f| f.split('/').last }
135
-
136
- # puts "Directory not found, checking for default in #{base} - #{file}"
137
-
138
- # puts d.inspect
139
- #
140
-
141
- raise RoutingError.new("Multiple default actions defined in #{base}") if d.size > 1
142
- raise RoutingError.new("Routing Error in #{base}") if d.empty?
143
-
144
-
145
- @assigns[d[0][DEF_ACT.size..-1]] = file
146
- "#{base}/#{d[0]}"
147
- end
148
-
149
-
150
- private
151
- def make_module(path)
152
- const_name = "Appmod_#{path.gsub(/[\/\\]/, '_')}"
153
-
154
- if Cuca::Objects::const_defined?(const_name.intern) then
155
- return Cuca::Objects::const_get(const_name.intern)
156
- end
157
-
158
- m = Module.new
159
- Cuca::Objects::const_set(const_name.intern, m)
160
- return m
161
- end
162
-
163
-
164
- # scan will match an URI to a script and set assigns. (called from initialize)
165
- private
166
- def scan
167
- files = @path_info.split('/')
168
-
169
- files << '' if @path_info[@path_info.size-1].chr == '/' # add empty element if we point to a directory
170
-
171
- # files now contains something like:
172
- # [users, show, martin, contacts]
173
-
174
- # puts files.inspect
175
- real_path = @base_path.dup
176
-
177
- # scan directory
178
- files.each_index do |idx|
179
- next if idx >= (files.size-1) # skip last element
180
- r = scan_dir(real_path, files[idx])
181
- raise RoutingError.new("Routing Error at #{real_path} - #{files[idx]}") if !r
182
- @path_tree << r
183
- real_path = r
184
- end
185
-
186
- @url = @path_info
187
- @base_url = "#{files[0..-2].join('/')}/"
188
- @action_path = real_path[@base_path.length..-1]
189
- @action_path_full = real_path
190
- @action_module = make_module(@action_path)
191
-
192
- # scan file (last element)
193
- r = scan_file(real_path, files.last)
194
-
195
- raise RoutingError.new("Routing Error - script not found at #{real_path} - #{files.last}") if !r
196
-
197
- real_path = "#{real_path}/#{r}"
198
-
199
- @script = File.expand_path(real_path)
200
- # @path_tree = _tree(@base_path, @script)
201
- self
202
- end
203
-
204
-
205
- # match will check if the supplied url maches with a script
206
- # returns boolean
207
- #
208
- # Example:
209
- # URLMap('/path/to/app', '/customer/southwind_lda/').match?('/path/to/app/customer/__custid/index.rb') => true
210
- public
211
- def match?(script)
212
- m_script = @script
213
- p_script = File.expand_path(script)
214
-
215
- # $stderr.puts "URLMap::match - #{m_script} - #{p_script}"
216
- return (m_script == p_script)
217
- rescue RoutingError
218
- false
219
- end
220
-
221
-
222
- # this will match if the current script can be found within a path
223
- # from the parameters.
224
- #
225
- # Example:
226
- # URLMap('/path/to/app', '/customer/southwind_lda/').submatch?('/customer/__custid/') => true
227
- public
228
- def submatch?(some_path)
229
- # $stderr.puts "Submatch: #{some_path} with #{@script} - #{(@script.length < some_path.length).inspect} #{@script.include?(some_path)}"
230
- return false if @script.length < some_path.length
231
- return @script.include?(some_path)
232
- end
233
-
234
- # this will match the current script to a part of a url (link):
235
- #
236
- # Example:
237
- # URLMap('/path/to/app', '/customer/southwind_lda/').submatch?('/customer/other_customer/') => true
238
- public
239
- def usubmatch?(some_path)
240
- @path_info.include?(some_path)
241
- end
242
-
243
- # FIXME: needed?
244
- public
245
- def has_script?(script)
246
- return !(@script == '')
247
- end
248
-
249
-
250
- def initialize(base_path, path_info, default_actions = ['index'])
251
- @path_info = path_info
252
- @base_path = File.expand_path(base_path)
253
- @script = ''
254
- @subcall = nil
255
- @default_actions = default_actions
256
- @assigns = {}
257
- @action = ''
258
- @action_path = ''
259
- @path_tree = [base_path]
260
- scan
261
- self
262
- end
263
-
264
- end
265
-
266
- end
267
-
268
-
269
- #
270
- # Testings:
271
- #
272
-
273
- if __FILE__ == $0 then
274
- require 'app'
275
-
276
- BASE = '/home/bones/src/cuca/app'
277
- URL = 'user/martin/somewhere/notexist/'
278
-
279
- puts "Testing on '#{BASE}' - '#{URL}'"
280
-
281
- module Cuca
282
- ds = URLMap.new(BASE, URL)
283
- begin
284
- rescue RoutingError => e
285
- puts "E: Invalid request #{$!}"
286
- end
287
-
288
-
289
-
290
- puts "Match with: #{ds.match?('/home/bones/src/cuca/app/user/__default_username/index.rb')}"
291
- puts "Submatch with /user/__username/ #{ds.submatch?('/user/__username/')}"
292
- puts "Submatch with '/user/' #{ds.submatch?('/user/')}"
293
- puts "USubmatch with '/user/' #{ds.usubmatch?('/user/martin')}"
294
- puts
295
- puts "Script is: #{ds.script}"
296
- puts "Assigns are: #{ds.assigns.inspect}"
297
- puts "Subcall: #{ds.subcall.inspect}"
298
- puts "Action: #{ds.action}"
299
- puts "Action Path: #{ds.action_path}"
300
- puts "Action Path Full: #{ds.action_path_full}"
301
- puts "Action Module: #{ds.action_module.inspect}"
302
- puts "Path tree: #{ds.path_tree.inspect}"
303
- end
304
-
305
- end
306
-
307
-
308
-
309
-
310
-
311
-
312
-
313
- # URL: "/user/martin/show"
314
- # DIR: "/user/__userid/show'
315
- # MOUNT: "/user/__userid/" =>>> "/plugin/user" contains 'show'
316
- # MOUNT: "/user/__userid/" =>>> "/plugin/user2" contains 'see'
317
-
318
-
319
-
320
-
321
-
322
-
323
-
324
-
data/lib/cuca/urlmap2.rb DELETED
@@ -1,22 +0,0 @@
1
-
2
-
3
- class URLMap2
4
-
5
-
6
- def path2array(p)
7
- p.split('/')
8
- end
9
- def array2path(a)
10
- a.join('/')
11
- end
12
-
13
-
14
- def initialize(directory, options)
15
- @app_path = options[:app_path] || raise ArgumentError.new("app_path required")
16
- @mounts = options[:mounts] || []
17
- @url = options[:url] || raise ArgumentError.new("url required")
18
- end
19
-
20
-
21
-
22
- end