cuca 0.06 → 0.07

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ * 2009/xx/xx - 0.07
2
+ - 'stop' option :cancel_execution added. This can be raised in before filters
3
+ and will avoid that the run/get/post... methods are called.
4
+ - ARFormWidget will set attribites by the setter method which allows
5
+ overwriting within the model
6
+ - Minor Bugfixes
7
+ - Added subcall? method to controller to easily detect subcalls
8
+
9
+
1
10
  * 2009/03/04 - 0.06
2
11
  - Fixed sorting bug of filters with priority specified
3
12
  - Nicer pagination on listwidget for large lists
data/README CHANGED
@@ -1,34 +1,43 @@
1
-
2
- == Installing Cuca
3
-
4
- To use the source code you can simply run:
5
- sudo renew.sh
6
-
7
- To install the gem from the internet use
8
- gem install --remote cuca
9
-
10
- See http://cuca.rubyforge.org for more information how to get started.
11
-
12
-
13
- == Coding on the Framework
14
-
15
- You can tell your application to load the cuca framework from a
16
- different location instead from rubygems. For that create a new dispatcher
17
- cgi script, a minimal version would be:
18
-
19
- #!/usr/bin/ruby
20
-
21
- FRAMEWORK_PATH = '/home/bones/path/to/cuca-framework/lib'
22
- $: << FRAMEWORK_PATH
23
-
24
- require 'cuca'
25
- require 'rubygems'
26
-
27
- application = Cuca::App.new
28
- application.cgicall
29
-
30
-
31
- And tell your webserver to use this new handler (or edit the script/server*
32
- files).
33
-
34
-
1
+ # = Cuca - a web application framework
2
+ #
3
+ # Cuca is another web application framework written in Ruby. It's made to
4
+ # build applications with focus on functionality - less design. You can
5
+ # create and application without writing HTML. Once written Widgets
6
+ # (a smart screen element) can be reused thorough your project with
7
+ # minimum effort allowing to build fast and secure web applications.
8
+ #
9
+ # It implements the following concepts:
10
+ # * A Widget is a screen element. Can be a full page or part of it.
11
+ # The Controller and the Layout are Widgets, too.
12
+ # * A Controller deals with one request URI (get, post or both) and can set variables
13
+ # other widgets can make use of. It can also define a Layout and filters.
14
+ # * A Layout wraps the output of a controller and finally return the
15
+ # built web page.
16
+ # * A Generator (NOT "code generator") can be used within any Widget to help building the web content.
17
+ # Cuca comes with a Markaby and eruby Generator.
18
+ # * A Session can used optionally to keep stateful data.
19
+ #
20
+ #
21
+ # == Installation & Getting started
22
+ #
23
+ # Download and install from the internet:
24
+ #
25
+ # gem install --remote cuca
26
+ #
27
+ #
28
+ # Create an application skeleton:
29
+ #
30
+ # cuca my_project # this will create a new project
31
+ # cd my_project
32
+ # ruby ./script/server-webrick.rb
33
+ #
34
+ # Open http://localhost:2000/
35
+ #
36
+ #
37
+ # == Read on
38
+ #
39
+ # * Cuca::Widget
40
+ # * Cuca::Controller
41
+ # * Cuca::Layout
42
+ # * Cuca::Session
43
+ # * Cuca::App
@@ -11,7 +11,7 @@ class SimpleLayout < Cuca::Layout
11
11
  <BODY>
12
12
  #{@content_for_layout}
13
13
  <HR/>
14
- <SMALL>Generated by Cuca Framework #{Time.now} (using 'simple' demo layout on Cuca Version #{Cuca::VERSION})</SMALL>
14
+ <SMALL>Generated by Cuca Framework #{Time.now} (using 'simple' demo layout on Cuca Version #{Cuca::VERSION} on Ruby #{RUBY_VERSION})</SMALL>
15
15
  </BODY>
16
16
  </HTML>
17
17
  EOF
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/ruby1.9.1
2
+
3
+ FRAMEWORK_PATH = '/home/bones/workspace/cuca_svn/cuca/lib'
4
+
5
+ $cuca_path = File.dirname(__FILE__)+"/../"
6
+ $: << FRAMEWORK_PATH
7
+
8
+ require 'cuca'
9
+ require 'rubygems'
10
+
11
+ Signal.trap("INT") do
12
+ $stderr.puts "INT caught"
13
+ exit
14
+ end
15
+
16
+ start = (Time.now.to_f * 1000).to_i
17
+ application = Cuca::App.new
18
+ application.cgicall
19
+ stop = (Time.now.to_f * 1000).to_i
20
+ dur_msec = stop - start
21
+ application.logger.info("App::cgicall: #{dur_msec} msec [= #{(1000 / dur_msec).to_i} pages / second]")
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/ruby1.9
2
2
 
3
3
  $cuca_path = File.dirname(__FILE__)+"/../"
4
4
 
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $cuca_path = File.dirname(__FILE__)+"/../"
4
+
5
+ require 'rubygems'
6
+ require 'cuca'
7
+
8
+ Signal.trap("INT") do
9
+ $stderr.puts "INT caught"
10
+ exit
11
+ end
12
+
13
+ start = (Time.now.to_f * 1000).to_i
14
+ application = Cuca::App.new
15
+ application.cgicall
16
+ stop = (Time.now.to_f * 1000).to_i
17
+ dur_msec = stop - start
18
+ application.logger.info("App::cgicall: #{dur_msec} msec [= #{(1000 / dur_msec).to_i} pages / second]")
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/ruby
2
+
3
+
4
+ $cuca_path = File.dirname(__FILE__)+"/../"
5
+
6
+ require 'rubygems'
7
+ require 'cuca'
8
+
9
+ require "fcgi"
10
+
11
+ Signal.trap("INT") do
12
+ $stderr.puts "INT caught"
13
+ exit
14
+ end
15
+
16
+ application = Cuca::App.new
17
+
18
+ FCGI.each_cgi do |cgi|
19
+ CGI::fix_env(cgi.env_table)
20
+ start = (Time.now.to_f * 1000).to_i
21
+ application.cgicall(cgi)
22
+ stop = (Time.now.to_f * 1000).to_i
23
+ dur_msec = stop - start
24
+ application.logger.info("App::cgicall (#{cgi.path_info}: #{dur_msec} msec [= #{(1000 / dur_msec).to_i} pages / second]")
25
+ end
@@ -0,0 +1,52 @@
1
+
2
+ require 'rubygems'
3
+ require 'rack'
4
+ require 'rack/session/cookie'
5
+
6
+
7
+ class Middle
8
+ def initialize(app)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ $stderr.puts "CAll for MIDDLE"
14
+ status, headers, body = @app.call(env)
15
+ [400, headers, [body.first.upcase]]
16
+ end
17
+ end
18
+
19
+ class Cuca
20
+ def initialize(app)
21
+ @app = app
22
+ end
23
+
24
+ def call(env)
25
+ $stderr.puts "CAll for CUCA"
26
+ $stderr.puts "#{@app.inspect}"
27
+ @app.call(env)
28
+ [200, {'Content-Type' => 'text/html'}, ['some Dynamic Website']]
29
+ end
30
+ end
31
+
32
+
33
+
34
+ class App < Rack::Builder
35
+
36
+ end
37
+
38
+
39
+ app = App.new
40
+ app.use Cuca
41
+
42
+ app.use Middle
43
+ puts app.to_app.inspect
44
+
45
+
46
+ Rack::Handler::Thin.run(
47
+ Rack::ShowExceptions.new(
48
+ Rack::Lint.new(
49
+ app.to_app
50
+ )
51
+ ), :Port => 1234)
52
+
@@ -0,0 +1,40 @@
1
+ $: << '/home/bones/workspace/cuca_svn/cuca/lib'
2
+ require 'cuca'
3
+ require 'rubygems'
4
+ # require 'cuca'
5
+ require 'rack/request'
6
+ require 'rack/response'
7
+ require 'rack/showexceptions'
8
+ require 'rack/handler'
9
+ require 'rack/handler/thin'
10
+ require 'rack/lint'
11
+
12
+
13
+ class MakeError
14
+ def initialize(app)
15
+ @app = app
16
+ end
17
+
18
+ def call(env)
19
+ status, headers, body = @app.call(env)
20
+ [500, headers,body]
21
+ end
22
+ end
23
+
24
+
25
+
26
+ app = Cuca::App.new
27
+ app.use MakeError
28
+
29
+
30
+ Rack::Handler::Thin.run \
31
+ Rack::ShowExceptions.new(app),
32
+ :Port => 1234
33
+
34
+
35
+
36
+ # Rack::Handler::WEBrick.run \
37
+ # Rack::ShowExceptions.new(Rack::Lint.new(Cuca::App.new)),
38
+ # :Port => 1234
39
+
40
+
@@ -0,0 +1,22 @@
1
+ $: << '/home/bones/workspace/cuca_svn/cuca/lib'
2
+ require 'cuca'
3
+ require 'rubygems'
4
+ # require 'cuca'
5
+ require 'rack/request'
6
+ require 'rack/response'
7
+ require 'rack/showexceptions'
8
+ require 'rack/handler'
9
+ require 'rack/handler/webrick'
10
+ require 'rack/lint'
11
+
12
+ Rack::Handler::WEBrick.run \
13
+ Rack::ShowExceptions.new(Cuca::App.new),
14
+ :Port => 1234
15
+
16
+
17
+
18
+ # Rack::Handler::WEBrick.run \
19
+ # Rack::ShowExceptions.new(Rack::Lint.new(Cuca::App.new)),
20
+ # :Port => 1234
21
+
22
+
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'webrick'
4
+ require 'cgi'
5
+
6
+
7
+ # this is for http debugging
8
+ class CucaHandler < WEBrick::HTTPServlet::CGIHandler
9
+ alias :old_do_GET :do_GET
10
+
11
+ def do_GET(req, res)
12
+ # puts "------------ Request ----------\n #{req.to_s}"
13
+ start = (Time.now.to_f * 100).to_i
14
+ r = old_do_GET(req, res)
15
+ stop = (Time.now.to_f * 100).to_i
16
+ # $stderr.puts "WEBRICK: Time: #{stop - start} ms"
17
+ # puts "------------ RESPONSE ----------\n #{res.to_s}"
18
+ end
19
+
20
+ end
21
+
22
+ server = WEBrick::HTTPServer.new(:Port => 2000)
23
+ server.mount("/", CucaHandler, File.expand_path(File.dirname(__FILE__))+"/../public/dispatch.cgi")
24
+
25
+ trap("INT"){ server.shutdown }
26
+ server.start
@@ -20,7 +20,7 @@ class CucaHandler < WEBrick::HTTPServlet::CGIHandler
20
20
  end
21
21
 
22
22
  server = WEBrick::HTTPServer.new(:Port => 2000)
23
- server.mount("/", CucaHandler, File.expand_path(File.dirname(__FILE__))+"/../public/dispatch.cgi")
23
+ server.mount("/", CucaHandler, File.expand_path(File.dirname(__FILE__))+"/../public/dispatch-fwdev.cgi")
24
24
 
25
25
  trap("INT"){ server.shutdown }
26
26
  server.start
data/lib/cuca.rb CHANGED
@@ -1,33 +1,3 @@
1
- # == Cuca - a ruby web framework
2
- #
3
- # Cuca is a small web development framework mainly designed to build
4
- # applications - there is little focus on design but more on coding
5
- # efficiency.
6
- #
7
- # It implements the following concepts:
8
- # * A Widget is a screen element. Can be a full page or part of it.
9
- # The Controller and the Layout are Widgets, too.
10
- # * A Controller deals with one request URI (get, post or both) and can set variables
11
- # other widgets can make use of. It can also define a Layout and filters.
12
- # * A Layout wraps the output of a controller and finally return the
13
- # built web page.
14
- # * A Generator (NOT "code generator") can be used within any Widget to help building the web content.
15
- # Cuca comes with a Markaby and eruby Generator.
16
- # * A Session can used optionally to keep stateful data.
17
- #
18
- #
19
- # When you 'require' cuca you must set the global varibale $cuca_path to the root of your
20
- # application structure. This is normally done by your dispatch.cgi or dispatch.fcgi
21
- # script that comes with the cuca application skeleton.
22
- #
23
- # === See also
24
- #
25
- # * Cuca::Widget
26
- # * Cuca::Controller
27
- # * Cuca::Layout
28
- # * Cuca::Session
29
- # * Cuca::App
30
-
31
1
  require 'cgi'
32
2
  require 'cuca/cgi_fix'
33
3
  require 'rubygems'
@@ -73,6 +43,8 @@ require 'cuca/const'
73
43
 
74
44
  $cuca_path = File.expand_path($cuca_path) + '/'
75
45
 
46
+ $cuca_path.freeze
47
+
76
48
  require 'cuca/app'
77
49
 
78
50
  $LOAD_PATH << $cuca_path+'/lib'
data/lib/cuca/app.rb CHANGED
@@ -20,6 +20,8 @@ class Sandbox
20
20
  self.class.send(:include, mod)
21
21
  controller_class = mod::const_get(controller_class_name)
22
22
  controller = controller_class.send(:new, :assigns=>assigns)
23
+ $controller_object = controller
24
+
23
25
  controller.run_before_filters
24
26
 
25
27
 
@@ -33,7 +35,7 @@ class Sandbox
33
35
 
34
36
  controller.run_after_filters
35
37
 
36
- return [controller.http_status, controller.mime_type, controller.to_s]
38
+ return [controller.http_status, controller.mime_type, controller.to_s, controller.http_header]
37
39
  end
38
40
  end
39
41
 
@@ -41,9 +43,9 @@ end
41
43
  #
42
44
  # A Cuca::App object will be created directly by the dispatcher - which again is the
43
45
  # direct cgi or fastcgi script that get run by the webserver.
44
- # Normally you just create a Cuca::App object and run the cgicall function with optional with
46
+ # Normally you just create a Cuca::App object and run the cgicall method with optional with
45
47
  # a cgi object as paramenter.
46
- # Before doing that you must set $cuca_path to the root of your appication structure.
48
+ # Before doing that you must set $cuca_path to the root of your application directory structure.
47
49
  class App
48
50
 
49
51
 
@@ -70,6 +72,7 @@ class App
70
72
  @public_path.freeze
71
73
  @log_path.freeze
72
74
  @logger = Logger.new("#{@log_path}/messages")
75
+ @logger.level = App::config['logger_level'] || Logger::WARN
73
76
  end
74
77
 
75
78
 
@@ -104,14 +107,14 @@ class App
104
107
  # this will schedule all files for autoloading
105
108
  private
106
109
  def autoload_files(path, naming_proc)
107
- $app.logger.info "Autoload on #{path}"
110
+ $app.logger.debug "Autoload on #{path}"
108
111
  return unless File.exist?(path)
109
112
  pwd = Dir.pwd
110
113
  Dir.chdir(path)
111
114
  Dir['*.rb'].each do |f|
112
115
  fn = f.scan(/(.*)\.rb/)[0][0]
113
116
  classname = naming_proc.call(fn)
114
- $app.logger.info "Scheduling Autoload Object '#{classname}' ==> #{path}/#{f}"
117
+ $app.logger.debug "Scheduling Autoload Object '#{classname}' ==> #{path}/#{f}"
115
118
  cuca_register_autoload(classname.intern, "#{path}/#{f}")
116
119
  end
117
120
  Dir.chdir(pwd)
@@ -139,18 +142,7 @@ class App
139
142
 
140
143
  public
141
144
  def load_support_files(urlmap) # :nodoc:
142
- # $stderr.puts "======== load support files ========="
143
- # $stderr.puts "Inc Dir: #{App::config['include_directories'].inspect}"
144
- # $stderr.puts "Path tr: #{@conf['PATH_TREE'].inspect}"
145
- # $stderr.puts "====================================="
146
-
147
- # db = $:.dup
148
- # all_support_directories(@conf['APP_PATH']) { |d,p| $: << d }
149
-
150
- # all_support_directories(@app_path, @urlmap.path_tree) do |dir, proc|
151
- # $stderr.puts "PATH TREE: #{urlmap.path_tree.inspect}"
152
145
  all_support_directories(urlmap.path_tree) do |dir, proc|
153
- # $stderr.puts "Support Directory #{dir}"
154
146
  if proc then
155
147
  autoload_files(dir, proc)
156
148
  else
@@ -168,7 +160,7 @@ class App
168
160
  $stderr.puts "ERROR: #{title} - #{exception.class.to_s}: #{exception.to_s}"
169
161
  if (show_trace) then
170
162
  exception.backtrace.each do |b|
171
- $stderr.puts " #{b}"
163
+ $stderr.puts " #{b}"
172
164
  err +="<br/>#{b}"
173
165
  end
174
166
  else
@@ -185,7 +177,6 @@ class App
185
177
  def cgicall(cgi = nil)
186
178
  @cgi = cgi || CGI.new
187
179
 
188
-
189
180
  #
190
181
  # 1st priority: Serve a file if it exists in the 'public' folder
191
182
  #
@@ -197,7 +188,7 @@ class App
197
188
  extension = file.scan(/.*\.(.*)$/)[0][0] if file.include?('.')
198
189
  extension ||= 'html'
199
190
  mime = mt[extension] || 'text/html'
200
- @cgi.out('type' => mime,
191
+ @cgi.out('type' => mime,
201
192
  'expires' => (Time.now+App.config['http_static_content_expires'])) { f.read }
202
193
  f.close
203
194
  return
@@ -232,9 +223,6 @@ class App
232
223
  # 3rd: Load additional files
233
224
  load_support_files(@urlmap)
234
225
 
235
- test = ApplicationController.new
236
-
237
-
238
226
  # 4th: Now let's run the actual page script code
239
227
  controller_class_name = @urlmap.action.capitalize+"Controller"
240
228
 
@@ -248,8 +236,15 @@ class App
248
236
  # things fail in this block get error logged and/or displayed in browser
249
237
  begin
250
238
  # load controller
251
- controller_module.module_eval(File.open(script).read, script) unless \
252
- controller_module.const_defined?(controller_class_name.intern)
239
+ begin
240
+ controller_module.module_eval(File.open(script).read, script) unless \
241
+ controller_module.const_defined?(controller_class_name.intern)
242
+ rescue SyntaxError => e
243
+ err = get_error("Load Error", e,
244
+ Cuca::App.config['display_errors'], Cuca::App.config['http_500'])
245
+ @cgi.out('status' => 'SERVER_ERROR') { err }
246
+ return
247
+ end
253
248
 
254
249
  # Catch a common user error
255
250
  raise Cuca::ApplicationException.new("Could not find #{controller_class_name} defined in #{script}") \
@@ -257,22 +252,32 @@ class App
257
252
 
258
253
 
259
254
  # run controller
260
- (status, mime, content) = Sandbox.run(controller_class_name,
255
+ (status, mime, content, headers) = Sandbox.run(controller_class_name,
261
256
  @urlmap.action_module, @urlmap.assigns,
262
257
  @cgi.request_method, @urlmap.subcall)
263
-
264
- logger.info "CGICall OK"
265
- @cgi.out('type' => mime, 'status' => status) {content}
258
+
259
+ logger.debug "CGICall OK: #{status}/#{mime}"
260
+
261
+ @cgi.out(headers.merge( { 'type' => mime, 'status' => status} )) {content}
262
+
263
+ rescue SyntaxError => e
264
+ err = get_error("Syntax Error", e,
265
+ Cuca::App.config['display_errors'], Cuca::App.config['http_500'])
266
+ @cgi.out('status' => 'SERVER_ERROR') { err }
267
+
268
+ logger.info "CGICall Syntax Error"
269
+ return
270
+
266
271
 
267
272
  rescue Cuca::ApplicationException => e
268
273
  err = get_error("Application Error", e,
269
274
  Cuca::App.config['display_errors'], Cuca::App.config['http_500'])
270
275
  @cgi.out('status' => 'SERVER_ERROR') { err }
271
276
 
272
- logger.info "CGICall Application Error"
277
+ logger.info "CGICall Application Error"
273
278
  return
274
279
 
275
- rescue => e
280
+ rescue => e
276
281
  err = get_error("System Error", e,
277
282
  Cuca::App.config['display_errors'], Cuca::App.config['http_500'])
278
283
  @cgi.out('status' => 'SERVER_ERROR') { err }