cuca 0.01 → 0.02

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,7 +14,7 @@ class IndexController < ApplicationController
14
14
  br
15
15
  text "Thank you for installing the cuca framework.";br;
16
16
  br
17
- h2 { "If you want to lean cuca" }
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
20
  li { text "Checkout the cuca website: "; SLink("http://cuca.rubyforge.net") }
@@ -32,7 +32,7 @@ class IndexController < ApplicationController
32
32
  end
33
33
  br
34
34
  h2 { "Good Luck..." }
35
- text "If you like cuca use the rubyforge to give any type of feedback."
35
+ text "If you like cuca use rubyforge to give any type of feedback."
36
36
  end
37
37
  end
38
38
  end
data/lib/cuca/app.rb CHANGED
@@ -20,6 +20,9 @@ class Sandbox
20
20
  when 'GET'
21
21
  controller.send('_do'.intern, 'get', subcall)
22
22
  end
23
+
24
+ controller.run_after_filters
25
+
23
26
  return controller.send(:to_s)
24
27
  end
25
28
  end
@@ -68,7 +71,7 @@ class App
68
71
  self['session_key'] = 'cuca_session'
69
72
  self['session_prefix'] = 'cuca.'
70
73
  self['session_valid'] = 3600*24
71
- self['view_directoru'] = 'app/_view' # where to find views for the view/erb generator
74
+ self['view_directory'] = 'app/_view' # where to find views for the view/erb generator
72
75
 
73
76
  end
74
77
 
@@ -77,6 +80,7 @@ class App
77
80
  attr_reader :conf, :cgi, :logger, :urlmap
78
81
 
79
82
  @@app_config = Config.new
83
+ @@oncall = []
80
84
 
81
85
  ## Application configuration
82
86
  public
@@ -88,6 +92,13 @@ class App
88
92
  @@app_config
89
93
  end
90
94
 
95
+ # if you should need to get notified on every
96
+ # (cgi)-call you can register a proc here.
97
+ # The SessionFlash/Page is makeing use of this
98
+ def self.oncall(&block)
99
+ @@oncall << block
100
+ end
101
+
91
102
 
92
103
  # cgi implementation test
93
104
  private
@@ -257,6 +268,8 @@ class App
257
268
  return
258
269
  end
259
270
 
271
+ # Notify who needs to know
272
+ @@oncall.each { |p| p.call }
260
273
 
261
274
  # 3rd: Load additional files
262
275
  load_support_files
data/lib/cuca/const.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cuca
2
- VERSION = '0.0.1'
2
+ VERSION = '0.02'
3
3
  end
@@ -85,53 +85,83 @@ class Controller < Widget
85
85
  attr_reader :cancel_execution # this can be set by anyone,
86
86
  # methods get/post/run will not be executed
87
87
 
88
- def self.def_layout
89
- begin
90
- self.def_layout_name
91
- rescue
92
- nil
93
- end
88
+
89
+ # get layout
90
+ def self.def_layout
91
+ self.run_attr_method('def_layout_name')
94
92
  end
95
93
 
94
+ # define a layout
96
95
  def self.layout(name)
97
96
  define_attr_method(:def_layout_name, name)
98
97
  end
99
98
 
100
- def self.before_filter(method)
99
+ private
100
+ def self.define_filter_method(chain_name, method_name)
101
101
  begin
102
- filters = self.def_before_filter
103
- filters = "#{filters};#{method}"
104
- define_attr_method(:def_before_filter, filters)
105
- rescue => e
106
- define_attr_method(:def_before_filter, method)
102
+ filters = self.send(chain_name)
103
+ filters = "#{filters};#{method_name}"
104
+ define_attr_method(chain_name, filters)
105
+ rescue NoMethodError => e
106
+ define_attr_method(chain_name, method_name)
107
107
  end
108
108
  end
109
109
 
110
- def run_before_filters
111
- # $stderr.puts "Run before filters"
112
- begin
113
- before_filter = self.class.def_before_filter
114
- rescue NoMethodError => e
115
- # == no filters defined at all
116
- # $stderr.puts " No before filters defined for #{self.class}"
117
- return
118
- end
119
- before_filter.split(';').each do |filter|
120
- begin
121
- if (!self.methods.include?(filter)) then
122
- raise ApplicationException.new("Before filter method not defined: '#{filter}'")
123
- end
124
- ret = self.send(filter)
125
- @cancel_execution = true if ret == false
126
- # rescue NoMethodError => e
127
- # raise ApplicationException.new "Before filter method not defined: '#{filter}'"
128
- rescue BreakControllerException => bc
110
+ # One or more before filter can set by an application Controller
111
+ # The instance methods will be run before the action get ran (get/post/run)
112
+ public
113
+ def self.before_filter(method)
114
+ define_filter_method(:def_before_filter, method)
115
+ end
116
+
117
+ # Priority before filters will be ran before any before filters
118
+ # this should be only used internally
119
+ public
120
+ def self.priority_before_filter(method)
121
+ define_filter_method(:def_priority_before_filter, method)
122
+ end
123
+
124
+ # after_filter - get run after the controller action has be executed
125
+ public
126
+ def self.after_filter(method)
127
+ define_filter_method(:def_after_filter, method)
128
+ end
129
+
130
+ private
131
+ def run_filters(chain_name, debug_filter_names)
132
+ filters = self.class.run_attr_method(chain_name.to_s)
133
+ return if filters.nil?
134
+ filters.split(';').each do |filter|
135
+ next if filter.strip == ''
136
+
137
+ begin
138
+ if (!self.methods.include?(filter)) then
139
+ raise ApplicationException.new("Filter not found in chain #{debug_filter_names}: #{filter}")
140
+ end
141
+ # $stderr.puts "Running Filter (#{debug_filter_names}): #{filter}"
142
+ ret = self.send(filter.intern)
143
+ @cancel_execution = true if ret == false
144
+ rescue BreakControllerException => bc
129
145
  handle_exception(bc)
130
- end
146
+ end
131
147
  end
132
148
  end
133
149
 
134
150
 
151
+ # this will run defined before filters on a controller instance
152
+ public
153
+ def run_before_filters
154
+ run_filters(:def_priority_before_filter, 'Priority Before Filters')
155
+ run_filters(:def_before_filter, 'Before Filters')
156
+ end
157
+
158
+ # run defined after_filters
159
+ public
160
+ def run_after_filters
161
+ run_filters(:def_after_filter, 'After Filters')
162
+ end
163
+
164
+
135
165
  # this method will stop execution of the controller
136
166
  # it's usefull to break somewhere in the middle or to
137
167
  # set a different layout
@@ -86,7 +86,7 @@ module View
86
86
  def viewtext(filename=nil)
87
87
  view_dir = $cuca_path + '/' + App::config['view_directory']
88
88
  begin
89
- f = File.open(VIEW_DIR + "/#{filename}", 'r')
89
+ f = File.open(view_dir + "/#{filename}", 'r')
90
90
  rescue => e
91
91
  return "Error opening template: #{e}"
92
92
  end
data/lib/cuca/session.rb CHANGED
@@ -86,6 +86,7 @@ class Session
86
86
  make_session
87
87
  end
88
88
 
89
+
89
90
  # returns true/false if a session exists
90
91
  def exists?
91
92
  begin
@@ -126,18 +127,39 @@ class Session
126
127
  @sess.close
127
128
  end
128
129
 
130
+ def update
131
+ @sess.update
132
+ end
133
+
134
+ def delete
135
+ @sess.delete
136
+ end
137
+
138
+
129
139
  end
130
140
 
131
- class Widget
141
+ class Controller
142
+ # This will create filters that initialize the session before the action and
143
+ # close it afterwards.
132
144
  def self.use_session
133
- @@session ||= Session.new($cgi)
145
+ priority_before_filter('ses_initialize_session')
146
+ after_filter('ses_close_session')
134
147
  end
135
- def session
136
- @@session
148
+
149
+ def ses_initialize_session
150
+ $session = Session.new($cgi)
151
+ end
152
+ def ses_close_session
153
+ $session.close
137
154
  end
138
155
  end
139
156
 
140
157
 
158
+ class Widget
159
+ def session
160
+ $session
161
+ end
162
+ end
141
163
 
142
164
  end
143
165
 
@@ -1,10 +1,10 @@
1
1
  module Cuca
2
2
 
3
3
  # Whatever you write into flash will be valid for the current and for the
4
- # next action. You can keep the content for another cycle by calling the
4
+ # next http request. You can keep the content for another cycle by calling the
5
5
  # keep method. Access via session.flash. (See Cuca::Session)
6
6
  class SessionFlash
7
- class SessionFlashItem # :nodoc:
7
+ class SessionFlashItem # :nodoc:
8
8
  def value
9
9
  @value
10
10
  end
@@ -49,7 +49,10 @@ class SessionFlash
49
49
 
50
50
  private
51
51
  def expire
52
- flashmem.each_pair { |k,v| v.inc; flashmem.delete(k) if v.expired? }
52
+ flashmem.each_pair do |k,v|
53
+ v.inc
54
+ flashmem.delete(k) if v.expired?
55
+ end
53
56
  end
54
57
  end
55
58
 
@@ -13,7 +13,6 @@ class SessionPage
13
13
  @ses[:SessionPage]
14
14
  end
15
15
 
16
-
17
16
  public
18
17
  def initialize(session)
19
18
  @ses = session
@@ -1,13 +1,14 @@
1
- module Cuca::Stdlib
2
-
3
- require 'form'
1
+ require 'cuca/stdlib/form'
4
2
  require 'cuca/generator/markaby'
5
3
 
6
4
  # == Form's for ActiveRecord
7
5
  # AR Form can work just by providing one model of ActiveRecord.
8
6
  # Likly that you want to overwrite the form method to
9
7
  # run a custom layout. You can use the fe* methods to
10
- # build form elements for the model columns
8
+ # build form elements for the model columns definition.
9
+ #
10
+ # This Widget will call <form_name>_submit(model) if Form is submitted
11
+ # and validation passed. You still have to ::save the model.
11
12
  #
12
13
  # = Example:
13
14
  #
@@ -43,15 +44,11 @@ class ARFormWidget < FormWidget
43
44
  p.delete(@submit_name)
44
45
 
45
46
  # don't save empty passwords!!
46
- $stderr.puts "Before validate: #{@password_fields.inspect}"
47
47
  @password_fields ||= []
48
48
  @password_fields.each do |pwf|
49
- $stderr.puts "PWS: #{pwf} - #{p[pwf]}"
50
49
  p.delete(pwf) if p[pwf].chomp.empty?
51
- $stderr.puts "PWS: #{p.inspect}"
52
50
  end
53
51
 
54
- $stderr.puts "ARFORM Validate #{p.inspect}"
55
52
  @model.attributes = p
56
53
 
57
54
  return true if @model.valid?
@@ -203,6 +200,3 @@ end
203
200
 
204
201
  end
205
202
 
206
-
207
-
208
- end
@@ -1,8 +1,16 @@
1
1
 
2
- # This is a small widget to display an ActiveRecord Record
2
+ # == ARViewWidget - Display an ActiveRecord record.
3
+ #
4
+ # This is a small widget to quick&dirty display the content
5
+ # of a record.
6
+ #
7
+ # = Example
8
+ #
9
+ # mab { ARView(User.find(:id=>123)) }
10
+ #
3
11
  class ARViewWidget < Cuca::Widget
4
12
 
5
- def output(model, headline='')
13
+ def output(model)
6
14
  @model = model
7
15
 
8
16
  r = "<table>"
@@ -1,11 +1,3 @@
1
- #
2
- # == Cuca Standard Widget Library
3
- # This namespace should contain a standard widget library.
4
- #
5
- # <b>Warning: The widgets you find here are fairly untested and might not work!!</b>
6
- # Any request and patches - Welcome
7
- # module Cuca::Stdlib
8
-
9
1
  # == FormWidget
10
2
  #
11
3
  # To implement a form inherit this class and overwrite:
@@ -30,8 +22,7 @@ class FormWidget < Cuca::Widget
30
22
 
31
23
  # get from params and set instance variables
32
24
  def load_variables
33
- $stderr.puts "\n\nLoad Variables: #{$cgi.params.inspect}\n\n"
34
- params.each_pair { |k,v| instance_variable_set('@'+k, v) ; $stderr.puts "Form: Setting #{k} - #{v}" }
25
+ params.each_pair { |k,v| instance_variable_set('@'+k, v) }
35
26
  end
36
27
 
37
28
  # get from params and return them as hash
@@ -1,7 +1,14 @@
1
1
  require 'cuca/generator/markaby'
2
2
 
3
3
 
4
- # A markaby link - Please use with care!! it's slow! Better to use SLinkWidget.
4
+ # == A markaby link
5
+ # WARNING: This is a very slow way of creating a link. Better to use
6
+ # SLinkWidget if you call this many times per page!
7
+ #
8
+ # = Example:
9
+ #
10
+ # mab { Link('http://cuca.rubyforge.org') { b { "Click here" } }
11
+ #
5
12
  class LinkWidget < Cuca::Widget
6
13
 
7
14
  include Cuca::Generator::Markaby
@@ -1,3 +1,2 @@
1
- require 'cuca/stdlib/listwidget/list'
2
1
  require 'cuca/stdlib/listwidget/dblist'
3
2
  require 'cuca/stdlib/listwidget/staticdatalist'
@@ -55,9 +55,8 @@ class DBListWidget < BaseList
55
55
  ar_res.each do |r|
56
56
  c = []
57
57
  columns.each do |col|
58
- # fixme: this doesn't catch join table results!!!
59
- if @model_class.column_methods_hash[col[:id].intern] then
60
- c << r.send(col[:id].to_sym)
58
+ if r.attributes[col[:id]] then
59
+ c << r.send(col[:id].intern)
61
60
  else
62
61
  c << ''
63
62
  end
@@ -69,7 +68,7 @@ class DBListWidget < BaseList
69
68
 
70
69
  def query(query_def)
71
70
  findstuff = {:conditions => where_clause(query_def) }
72
- findstuff[:order] = query_def.order_by unless (query_def.order_by.nil? || query_def.order_by == '')
71
+ findstuff[:order] = "#{query_def.order_by} #{query_def.order}" unless (query_def.order_by.nil? || query_def.order_by == '')
73
72
  findstuff[:offset] = query_def.range.first
74
73
  findstuff[:limit] = query_def.range.last-query_def.range.first+1
75
74
  findstuff[:joins] = @joins || nil
@@ -83,6 +82,7 @@ class DBListWidget < BaseList
83
82
  @data = @model_class.find(:all, findstuff)
84
83
  @data = normalize_result(@data)
85
84
  @total_rows= @model_class.count(:conditions => where_clause(query_def), :joins => @joins)
85
+
86
86
  # $stderr.puts "Query: #{@data.inspect} - #{query_def.order_by.inspect}"
87
87
  end
88
88
 
@@ -46,17 +46,37 @@ class BaseList < Cuca::Widget
46
46
  return
47
47
  end
48
48
 
49
- # TODO: Load from Session
49
+ # TODO: Load from Session?
50
50
  def load_query_definition
51
51
  qd = QueryDef.new(@list_name)
52
52
  qd.from_params(params)
53
+ if request_method == 'POST' then
54
+ qd.range = nil # reset pagination if someone submitted a filter
55
+ end
56
+ qd
53
57
  end
54
58
 
59
+ # check query_def was makes sense ... raise error if manipulated!
60
+ def check_query_def
61
+ # check if filters match possible column names
62
+ cn = columns.collect { |c| c[:id] }
63
+ @query_def.filters.each_pair do |f,v|
64
+ raise Cuca::ApplicationException.new("Unknown column in filters: #{f}") unless cn.include?(f)
65
+ end
66
+
67
+ return if @query_def.order_by == ''
68
+ # check if order_by is a valid column
69
+ raise Cuca::ApplicationException.new("Unknown sort order: #{@query_def.order_by}") \
70
+ unless cn.include?(@query_def.order_by)
71
+ end
72
+
55
73
  def output(list_name)
56
74
  @list_name = list_name
57
75
 
58
76
  @columns = columns
59
77
  @query_def = load_query_definition
78
+ check_query_def
79
+ # $stderr.puts "Query: Range #{@query_def.range.inspect} Filters: #{@query_def.filters.inspect} Order: #{@query_def.order.inspect} By: #{@query_def.order_by.inspect}"
60
80
  query(@query_def)
61
81
  @paginate = paginate_links()
62
82
  @params = params
@@ -64,9 +84,8 @@ class BaseList < Cuca::Widget
64
84
 
65
85
  callback_method = "#{@list_name}_data"
66
86
 
67
- # $stderr.puts "Callback check: #{controller.nil?.inspect} \n\n -- #{controller.methods.sort.inspect} --\n\n NAME #{controller.class.inspect}"
68
87
  if !controller.nil? && controller.methods.include?(callback_method)
69
- controller.send(callback_method, @data)
88
+ controller.send(callback_method, @data, @total_rows)
70
89
  end
71
90
 
72
91
  view_p(erb_template)
@@ -119,8 +138,19 @@ end
119
138
 
120
139
  <% @columns.each do |c| %>
121
140
  <td class='hl'>
122
- <%= (@query_def.order_by == c[:id] || (c[:sortable] == false)) ?
123
- c[:display] : SLink('',c[:display],@query_def.to_h('order_by', c[:id]))
141
+ <%
142
+ # this will swap the sort order if the same columns is clicked
143
+ if @query_def.order_by == c[:id] then
144
+ order = @query_def.order == 'ASC' ? 'DESC' : 'ASC'
145
+ display = "#{c[:display]} (#{@query_def.order})"
146
+ else
147
+ order = 'ASC'
148
+ display = c[:display]
149
+ end
150
+ %>
151
+ <%= (c[:sortable] == false) ? display : SLink('',display,
152
+ @query_def.to_h('order_by', c[:id],
153
+ 'order', order))
124
154
  %>
125
155
  </td>
126
156
  <% end %>
@@ -156,7 +186,7 @@ ENDTEMPLATE
156
186
  end
157
187
 
158
188
 
159
- # This would be a markaby template for the listwidget. I find it less readable so will not
189
+ # This was the old markaby template for the listwidget. I find it less readable so will not
160
190
  # continue working on it.
161
191
  #
162
192
  #
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # FIXME: Change name or put into namespace
5
5
  class QueryDef
6
- ATTRIBS = ['order_by','range', 'filters']
6
+ ATTRIBS = ['order_by', 'order','range', 'filters']
7
7
  ATTRIBS_ENCODE =
8
8
  {
9
9
  'range' =>
@@ -15,6 +15,10 @@ class QueryDef
15
15
  s = '';
16
16
  e.each_pair { |k,v| s << "#{k}:#{v};" };
17
17
  s
18
+ end,
19
+ 'order' =>
20
+ Proc.new do |e|
21
+ ['ASC', 'DESC'].include?(e) ? e : 'ASC'
18
22
  end
19
23
  }
20
24
  ATTRIBS_DECODE =
@@ -31,10 +35,15 @@ class QueryDef
31
35
  h[vals[0]] = vals[1] if (vals.size == 2)
32
36
  end
33
37
  h
34
- end
38
+ end,
39
+ 'order' =>
40
+ Proc.new do |e|
41
+ ['ASC', 'DESC'].include?(e) ? e : 'ASC'
42
+ end
35
43
  }
36
44
  ATTRIBS_DEFAULTS = { 'range' => 0..9,
37
45
  'order_by' => '',
46
+ 'order' => 'ASC',
38
47
  'filters' => {} }
39
48
 
40
49
  # take from CGI class
@@ -54,7 +63,7 @@ class QueryDef
54
63
 
55
64
  #getter
56
65
  if (ATTRIBS.include?(met)) then
57
- return @data[met] || ATTRIBS_DEFAULT[met].dup
66
+ return @data[met] || ATTRIBS_DEFAULTS[met].dup
58
67
  end
59
68
 
60
69
  #setter
@@ -103,10 +112,11 @@ class QueryDef
103
112
 
104
113
  # returns an hash with the values and escaped names and attributes
105
114
  # attr and newval with swap a value for this return without changing the actual data
106
- def to_h(attr=nil, newval=nil)
115
+ def to_h(attr=nil, newval=nil, attr2=nil, newval2=nil)
107
116
  if attr then
108
117
  @backup = @data.dup
109
118
  @data[attr] = newval
119
+ @data[attr2] = newval2 unless attr2.nil?
110
120
  end
111
121
 
112
122
  u = {}
@@ -60,6 +60,7 @@ class StaticDataListWidget < BaseList
60
60
  cidx = col_idx_by_id(query_def.order_by) || 0
61
61
 
62
62
  @data = @sd_data.sort { |a,b| a[cidx] <=> b[cidx] }
63
+ @data = @data.reverse if query_def.order == 'DESC'
63
64
  apply_filters(query_def)
64
65
  @total_rows = @data.size
65
66
  @data = @data[query_def.range]
@@ -1,5 +1,8 @@
1
- # Simple, fast link - no markaby as block
2
-
1
+ # == Simple, fast link - no markaby as block
2
+ #
3
+ # = Example:
4
+ # mab { SLink('http://cuca.rubyforge.net', 'click') }
5
+ #
3
6
  class SLinkWidget < Cuca::Widget
4
7
  private
5
8
  def build_href(target, params)
data/lib/cuca/widget.rb CHANGED
@@ -207,6 +207,13 @@ class Widget
207
207
  # $stderr.puts "def #{name}; #{value.to_s.inspect}; end"
208
208
  end
209
209
 
210
+ # tries to run a class method if defined and return it
211
+ def self.run_attr_method(name)
212
+ return nil unless self.methods.include?(name)
213
+ self.send(name.intern)
214
+ end
215
+
216
+
210
217
  end
211
218
 
212
219
  end # Module
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.01"
4
+ version: "0.02"
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-05-08 00:00:00 +01:00
12
+ date: 2008-05-11 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency