ramaze 2010.06.18 → 2011.01

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.
Files changed (95) hide show
  1. data/.gitignore +1 -0
  2. data/MANIFEST +9 -16
  3. data/README.md +37 -30
  4. data/Rakefile +5 -1
  5. data/TODO.md +19 -0
  6. data/doc/AUTHORS +5 -1
  7. data/doc/CHANGELOG +3553 -3272
  8. data/doc/tutorial/todolist.html +1512 -1512
  9. data/examples/app/blog/app.rb +2 -0
  10. data/examples/app/todolist/controller/init.rb +1 -2
  11. data/examples/app/wiktacular/mkd/main/2007-07-20_19-21-12.mkd +1 -1
  12. data/examples/app/wiktacular/mkd/main/2007-07-20_19-23-10.mkd +1 -1
  13. data/examples/app/wiktacular/mkd/main/2007-07-20_19-45-07.mkd +1 -1
  14. data/examples/app/wiktacular/mkd/main/current.mkd +1 -1
  15. data/examples/app/wiktacular/mkd/testing/2007-07-20_16-43-46.mkd +1 -1
  16. data/examples/app/wiktacular/mkd/testing/2007-07-20_19-43-50.mkd +2 -2
  17. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-08.mkd +16 -16
  18. data/examples/app/wiktacular/mkd/testing/2007-07-21_18-47-54.mkd +16 -16
  19. data/examples/app/wiktacular/mkd/testing/current.mkd +16 -16
  20. data/lib/proto/model/init.rb +1 -1
  21. data/lib/proto/public/js/jquery.js +2034 -1095
  22. data/lib/proto/start.rb +2 -0
  23. data/lib/proto/view/index.xhtml +3 -3
  24. data/lib/ramaze.rb +1 -2
  25. data/lib/ramaze/cache.rb +1 -0
  26. data/lib/ramaze/cache/sequel.rb +131 -37
  27. data/lib/ramaze/controller.rb +1 -0
  28. data/lib/ramaze/gestalt.rb +75 -46
  29. data/lib/ramaze/helper.rb +1 -0
  30. data/lib/ramaze/helper/auth.rb +38 -4
  31. data/lib/ramaze/helper/blue_form.rb +498 -78
  32. data/lib/ramaze/helper/cache.rb +2 -2
  33. data/lib/ramaze/helper/csrf.rb +225 -0
  34. data/lib/ramaze/helper/erector.rb +67 -9
  35. data/lib/ramaze/helper/flash.rb +4 -2
  36. data/lib/ramaze/helper/gestalt.rb +2 -0
  37. data/lib/ramaze/helper/gravatar.rb +1 -1
  38. data/lib/ramaze/helper/localize.rb +4 -0
  39. data/lib/ramaze/helper/send_file.rb +30 -0
  40. data/lib/ramaze/helper/thread.rb +5 -0
  41. data/lib/ramaze/helper/user.rb +4 -3
  42. data/lib/ramaze/helper/xhtml.rb +87 -8
  43. data/lib/ramaze/log.rb +13 -0
  44. data/lib/ramaze/log/analogger.rb +15 -5
  45. data/lib/ramaze/log/growl.rb +28 -13
  46. data/lib/ramaze/log/hub.rb +12 -4
  47. data/lib/ramaze/log/informer.rb +28 -11
  48. data/lib/ramaze/log/knotify.rb +7 -2
  49. data/lib/ramaze/log/logger.rb +12 -4
  50. data/lib/ramaze/log/logging.rb +40 -14
  51. data/lib/ramaze/log/rotatinginformer.rb +47 -23
  52. data/lib/ramaze/log/syslog.rb +37 -31
  53. data/lib/ramaze/log/xosd.rb +7 -4
  54. data/lib/ramaze/middleware_compiler.rb +2 -2
  55. data/lib/ramaze/snippets/fiber.rb +63 -63
  56. data/lib/ramaze/snippets/ramaze/lru_hash.rb +1 -1
  57. data/lib/ramaze/tool/bin.rb +1 -1
  58. data/lib/ramaze/version.rb +1 -1
  59. data/lib/ramaze/view.rb +4 -4
  60. data/lib/ramaze/view/erector.rb +88 -13
  61. data/ramaze.gemspec +65 -65
  62. data/spec/ramaze/bin/ramaze.rb +1 -1
  63. data/spec/ramaze/cache/localmemcache.rb +20 -12
  64. data/spec/ramaze/cache/sequel.rb +19 -19
  65. data/spec/ramaze/helper/blue_form.rb +549 -257
  66. data/spec/ramaze/helper/csrf.rb +109 -0
  67. data/spec/ramaze/helper/httpdigest.rb +31 -29
  68. data/spec/ramaze/helper/user.rb +1 -1
  69. data/spec/ramaze/helper/xhtml.rb +17 -0
  70. data/spec/ramaze/log/growl.rb +34 -0
  71. data/spec/ramaze/log/informer.rb +1 -0
  72. data/spec/ramaze/view/erector.rb +49 -71
  73. data/spec/ramaze/view/erector/external_view.erector +5 -0
  74. data/spec/ramaze/view/erector/index.erector +5 -0
  75. data/spec/ramaze/view/erector/layout.erector +13 -3
  76. data/spec/ramaze/view/erector/tables.erector +23 -0
  77. data/spec/ramaze/view/erector/view.erector +6 -0
  78. data/tasks/git.rake +2 -2
  79. metadata +133 -176
  80. data/examples/helpers/form_with_sequel.rb +0 -24
  81. data/examples/helpers/nitro_form.rb +0 -23
  82. data/lib/ramaze/helper/form.rb +0 -133
  83. data/lib/ramaze/helper/nitroform.rb +0 -14
  84. data/lib/ramaze/helper/pager.rb +0 -367
  85. data/lib/ramaze/helper/partial.rb +0 -100
  86. data/lib/ramaze/helper/sequel.rb +0 -55
  87. data/lib/ramaze/helper/sequel_form.rb +0 -284
  88. data/lib/vendor/etag.rb +0 -22
  89. data/spec/ramaze/helper/form.rb +0 -360
  90. data/spec/ramaze/helper/pager.rb +0 -96
  91. data/spec/ramaze/helper/sequel_form.rb +0 -94
  92. data/spec/ramaze/view/erector/external.erector +0 -1
  93. data/spec/ramaze/view/erector/invoke_helper_method.erector +0 -1
  94. data/spec/ramaze/view/erector/strict_xhtml.erector +0 -3
  95. data/spec/ramaze/view/erector/sum.erector +0 -1
@@ -1,100 +0,0 @@
1
- # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
- # All files in this distribution are subject to the terms of the Ruby license.
3
-
4
- module Ramaze
5
- module Helper
6
-
7
- # = Helper::Partial
8
- #
9
- # Please note that this helper is deprecated in favor of # Helper::Render,
10
- # it has been removed from Innate and remains in Ramaze until 2009.05.
11
- #
12
- # === Example Usage
13
- #
14
- # class MyController
15
- # def index
16
- # end
17
- #
18
- # def list
19
- # plain = request['plain']
20
- # "Hello World from List! Plain List == #{plain}"
21
- # end
22
- # end
23
- #
24
- #
25
- # <html>
26
- # <head><title>Partial Render Index</title></head>
27
- # <body>
28
- # #{render_partial(Rs(:list), 'plain' => true)}
29
- # </body>
30
- # </html>
31
- module Partial
32
- module_function
33
-
34
- # Renders a url 'inline'.
35
- #
36
- # +url+ normal URL, like you'd use for redirecting.
37
- # +options+ optional, will be used as request parameters.
38
- #
39
- # Issues a mock request to the given +url+ with +options+ turned into
40
- # query arguments.
41
- def render_partial(url, options = {})
42
- Ramaze.deprecated('Helper::Partial#render_partial', 'Helper::Render#render_full')
43
-
44
- uri = URI(url)
45
- query = options # Innate::Current.request.params.merge(options)
46
- uri.query = Rack::Utils.build_query(query)
47
-
48
- body = nil
49
-
50
- Innate::Mock.session do |session|
51
- cookie = Innate::Current.session.cookie
52
- session.cookie = cookie
53
- body = session.get(uri.to_s, options).body
54
- end
55
-
56
- body
57
- end
58
-
59
- # Render the template file in view_root of the
60
- # current controller.
61
- #
62
- # TODO:
63
- # * Doesn't work for absolute paths, but there are no specs for that yet.
64
- # * the local variable hack isn't working because innate allocates a new
65
- # binding.
66
- # For now one can simply use instance variables, which I prefer anyway.
67
- #
68
- # the local binding hack:
69
- #
70
- # variables.each do |key, value|
71
- # value = "ObjectSpace._id2ref(#{value.object_id})"
72
- # eval "#{key} = #{value}", action.binding
73
- # end
74
-
75
- def render_template(path, variables = {})
76
- Ramaze.deprecated('Helper::Partial#render_template')
77
- path = path.to_s
78
-
79
- ext = File.extname(path)
80
- basename = File.basename(path, ext)
81
-
82
- action = Innate::Current.action.dup
83
- action.layout = nil
84
- action.view = action.node.find_view(basename, 'html')
85
- action.method = action.node.find_method(basename, action.params)
86
-
87
- action.variables = action.variables.merge(variables)
88
- action.sync_variables(action)
89
-
90
- return action.call if action.valid?
91
- raise(ArgumentError, "cannot render %p" % path)
92
- end
93
-
94
- def render_action(method, *params)
95
- Ramaze.deprecated('Helper::Partial#render_action', 'Helper::Render#render_full')
96
- render_partial(r(method), *params)
97
- end
98
- end
99
- end
100
- end
@@ -1,55 +0,0 @@
1
- # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
- # All files in this distribution are subject to the terms of the Ruby license.
3
-
4
- module Ramaze
5
- module Helper::Sequel
6
-
7
- # Very crude paginator, may contain serious bugs, please fix :)
8
- # pass it the result of YourModel.paginate, target is where links point to.
9
- def paginator(paginated, target)
10
- page_count = paginated.page_count
11
- prev_page = paginated.prev_page
12
- current_page = paginated.current_page
13
- next_page = paginated.next_page
14
-
15
- lower = (current_page - 3).abs
16
- lower = lower == 0 ? 1 : lower
17
-
18
- out = ['<div class="paginator">']
19
-
20
- if prev_page
21
- out << %(<a class="paginator_prev" href="#{Rs(target, prev_page)}">&lt;&nbsp;Prev</a>)
22
- else
23
- out << %(<span class="paginator_prev">&lt;&nbsp;Prev</span>)
24
- end
25
-
26
- if current_page > 3
27
- out << %(<a class="paginator_page" href="#{Rs(target, 1)}">#{1}</a> ... )
28
- end
29
-
30
- lower.upto(current_page) do |pc|
31
- next if pc == current_page
32
- out << %(<a class="paginator_page" href="#{Rs(target, pc)}">#{pc}</a>)
33
- end
34
-
35
- out << %(<span class="paginator_current">#{current_page}</span>)
36
-
37
- current_page.upto([page_count, current_page + 3].min) do |pc|
38
- next if pc == current_page
39
- out << %(<a class="paginator_page" href="#{Rs(target, pc)}">#{pc}</a>)
40
- end
41
-
42
- if current_page < (page_count - 3)
43
- out << %(.. <a class="paginator_page" href="#{Rs(target, page_count)}">#{page_count}</a>)
44
- end
45
-
46
- if next_page
47
- out << %(<a class="paginator_next" href="#{Rs(target, next_page)}">Next&nbsp;&gt;</a>)
48
- else
49
- out << %(<span class="paginator_next">Next&nbsp;&gt;</span>)
50
- end
51
- out << '</div>'
52
- out.join(" ")
53
- end
54
- end
55
- end
@@ -1,284 +0,0 @@
1
- module Ramaze
2
- module Helper
3
- module SequelForm
4
- # Pass it an object for your ORM and options for the <form> tag
5
- # Usage:
6
- # sequel_form(User, :action => '/create')
7
- # sequel_form(Tag, :action => '/find', :method => 'post')
8
- def sequel_form(object, options = {})
9
- Ramaze::Form.pick(object, options)
10
- end
11
- end
12
- end
13
-
14
- class Form
15
- attr_accessor :object, :options
16
-
17
- YEARS, MONTHS, DAYS, HOURS, MINUTES, SECONDS =
18
- (1900..2100), (1..12), (1..31), (0..23), (0..59), (0..59)
19
-
20
- DATE_GENERIC = [
21
- [ :day, DAYS ],
22
- [ :month, MONTHS ],
23
- [ :year, YEARS ] ]
24
-
25
- TIME_GENERIC = [
26
- [ :day, DAYS ],
27
- [ :month, MONTHS ],
28
- [ :year, YEARS ],
29
- [ :hour, HOURS ],
30
- [ :min, MINUTES ],
31
- [ :sec, SECONDS ] ]
32
-
33
- # TODO:
34
- # How _elegant_ ...
35
- # Tries to find the right module for extending the Form instance.
36
- # It's problematic since the boundaries of what an model instance or model
37
- # class looks like is very fuzzy, also a problem is that the ORM may not be
38
- # available/required.
39
- #
40
- # Maybe we can abstract that a bit by going through an array of procs for
41
- # testing?
42
- def self.pick(object, options = {})
43
- if defined?(Sequel::Model)
44
- if object.is_a?(Sequel::Model)
45
- options[:layer] ||= Layer::Sequel
46
- InstanceForm.new(object, options)
47
- elsif object.ancestors.include?(Sequel::Model)
48
- options[:layer] ||= Layer::Sequel
49
- ClassForm.new(object, options)
50
- end
51
- else
52
- raise "Unknown ORM for: %p" % object
53
- end
54
- end
55
-
56
- # Create new instance of Form plus the layer for the ORM
57
- def initialize(object, options = {})
58
- @object, @options = object, options
59
- if layer = options.delete(:layer)
60
- extend layer
61
- end
62
- end
63
-
64
- # Generate and return the final form
65
- def to_s
66
- out = "<form #{form_attributes}>"
67
- out << "<fieldset>"
68
- out << generate
69
- out << "</fieldset>"
70
- out << '<input type="submit" />'
71
- out << '<input type="reset" />'
72
- out << "</form>"
73
- end
74
-
75
- # Decide on the strucuture of the tag based on the hash
76
- def field_for(hash)
77
- return if hash[:primary_key]
78
- args = args_for(hash)
79
-
80
- inner =
81
- case type = hash[:type]
82
- when :integer
83
- field_integer(*args)
84
- when :boolean
85
- field_boolean(*args)
86
- when :text
87
- field_textarea(*args)
88
- when :varchar
89
- field_input(*args)
90
- when :date
91
- field_date(*args)
92
- when :time
93
- field_time(*args)
94
- else
95
- Log.warn "Unknown field: %p" % hash
96
- field_input(*args)
97
- end
98
-
99
- "<label>#{args.first}: </label>\n#{inner}"
100
- end
101
-
102
- private
103
-
104
- # inject to attributes for the <form>
105
- def form_attributes
106
- options.inject([]){|s,(k,v)| s << "#{k}='#{v}'" }.join(' ')
107
- end
108
-
109
- # Start tag with name and attributes
110
- def start_tag(name, hash)
111
- hash.inject("<#{name}"){|s,(k,v)| s << " #{k}='#{v}'" }
112
- end
113
-
114
- # Make a closed tag with name and attributes
115
- def closed_tag(name, hash)
116
- start_tag(name, hash) << ' />'
117
- end
118
-
119
- # Textarea with attributes from hash and the value from @object
120
- def textarea(value, hash = {})
121
- start_tag(:textarea, hash) << ">#{value}</textarea>"
122
- end
123
-
124
- # <input> with optional attributes from hash
125
- def input(hash = {})
126
- closed_tag(:input, hash)
127
- end
128
-
129
- # <input type="checkbox" with optional attributes from hash.
130
- def checkbox(hash = {})
131
- hash[:type] = :checkbox
132
- input(hash)
133
- end
134
-
135
- # <option value="value"> with optional attributes from hash
136
- def option(value, hash = {})
137
- start_tag(:option, hash) << ">#{value}</option>"
138
- end
139
-
140
- # Yield method names and values for the Date instance
141
- def field_date_generic
142
- DATE_GENERIC.map{|(sel, range)|
143
- yield(sel, range).join
144
- }.join("\n")
145
- end
146
-
147
- # Yield method names and values for the Time/DateTime instance
148
- def field_time_generic
149
- TIME_GENERIC.map{|(sel, range)|
150
- yield(sel, range).join
151
- }.join("\n")
152
- end
153
-
154
- # Here go all the layers that are extended for specific ORMs
155
- module Layer
156
- # Layer for Sequel, only generate needs to be implemented, may change in
157
- # future if we abstract more for different ORMs
158
- module Sequel
159
- # A bit nasty, get the @columns of the object and generate its
160
- # field_for
161
- def generate
162
- columns = object_class.schema.instance_variable_get('@columns')
163
- columns.map{|hash| field_for(hash) }.flatten.join("<br />\n")
164
- end
165
- end
166
- end
167
- end
168
-
169
- # Form for the model class itself, very similar to an empty instance.
170
- class ClassForm < Form
171
- # <input name="name" />
172
- def field_input(name)
173
- input :name => name
174
- end
175
-
176
- # <textarea name="name"></textarea>
177
- def field_textarea(name)
178
- textarea '', :name => name
179
- end
180
-
181
- # <input name="name" />
182
- def field_integer(name)
183
- input :name => name
184
- end
185
-
186
- # <input type="checkbox" name="name" />
187
- def field_boolean(name)
188
- checkbox :name => name
189
- end
190
-
191
- # <select> with lots of <option>s
192
- def field_date(name)
193
- field_date_generic{|sel, range|
194
- [ "<select name='#{name}[#{sel}]'>",
195
- range.map{|d| option(d, :value => d) },
196
- "</select>" ]
197
- }
198
- end
199
-
200
- # <select> with lots of <option>s
201
- def field_time(name)
202
- field_time_generic{|sel, range|
203
- [ "<select name='#{name}[#{sel}]'>",
204
- range.map{|d| option(d, :value => d) },
205
- "</select>" ]
206
- }
207
- end
208
-
209
- # picks the :name
210
- def args_for(hash)
211
- [ hash[:name] ]
212
- end
213
-
214
- # Should be that way, at least for Sequel
215
- def object_class
216
- @object
217
- end
218
- end
219
-
220
- # Form for instances of the model class
221
- class InstanceForm < Form
222
- # returns <input type='text' name='name' value='value' />
223
- def field_input(name, value)
224
- "<input type='text' name='#{name}' value='#{value}'/>"
225
- end
226
-
227
- # returns <textarea name='name'>#{value}</textarea>
228
-
229
- def field_textarea(name, value)
230
- "<textarea name='#{name}'>#{value}</textarea>"
231
- end
232
-
233
- # returns <input type="text" name="name" value="value" />
234
-
235
- def field_integer(name, value)
236
- field_input(name, value)
237
- end
238
-
239
- # <input type="checkbox" ...
240
- def field_boolean(name, value)
241
- if value
242
- checkbox :name => name, :value => value, :checked => :checked
243
- else
244
- checkbox :name => name, :value => value
245
- end
246
- end
247
-
248
- def field_date(name, value)
249
- field_date_generic do |sel, range|
250
- [ "<select name='#{name}[#{sel}]'>",
251
- option_range_selected(range, value.send(sel)),
252
- "</select>" ]
253
- end
254
- end
255
-
256
- def field_time(name, value)
257
- field_time_generic do |sel, range|
258
- [ "<select name='#{name}[#{sel}]'>",
259
- option_range_selected(range, value.send(sel)),
260
- "</select>" ]
261
- end
262
- end
263
-
264
- def option_range_selected(range, value)
265
- range.map do |r|
266
- if r == value
267
- option(r, :value => r, :selected => :selected)
268
- else
269
- option(r, :value => r)
270
- end
271
- end
272
- end
273
-
274
- def args_for(hash)
275
- name = hash[:name]
276
- [ name, @object.send(name) ]
277
- end
278
-
279
- # Class for @object, atm Sequel specific?
280
- def object_class
281
- @object.class
282
- end
283
- end
284
- end
data/lib/vendor/etag.rb DELETED
@@ -1,22 +0,0 @@
1
- require 'digest/md5'
2
-
3
- module Rack
4
- # Automatically sets the ETag header on all String bodies
5
- class ETag
6
- def initialize(app)
7
- @app = app
8
- end
9
-
10
- def call(env)
11
- status, headers, body = @app.call(env)
12
-
13
- unless headers.key?('Etag')
14
- hashes = []
15
- body.each{|chunk| hashes << chunk.hash }
16
- headers['Etag'] = %("#{Digest::MD5.hexdigest(hashes.join)}")
17
- end
18
-
19
- [status, headers, body]
20
- end
21
- end
22
- end