cuca 0.01 → 0.02

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.
@@ -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