zorglub 0.1.0 → 0.1.1

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.
data/lib/zorglub/node.rb CHANGED
@@ -1,334 +1,334 @@
1
- # -*- coding: UTF-8 -*-
2
-
3
1
  require 'fileutils'
4
2
 
5
3
  module Zorglub
4
+ class Node
5
+ UNDEFINED = -1
6
6
 
7
- class Node
8
-
9
- UNDEFINED=-1
10
-
11
- # class level engine, layout, static, layout_base_path, view_base_path configuration
7
+ # class level engine, layout, static, layout_base_path, view_base_path configuration
12
8
 
13
- class << self
9
+ class << self
10
+ attr_reader :static, :cache_lifetime
14
11
 
15
- attr_reader :static, :cache_lifetime
12
+ def engine!(engine)
13
+ @engine = engine
14
+ end
16
15
 
17
- def engine! engine
18
- @engine = engine
19
- end
16
+ def engine
17
+ @engine = @app.opt(:engine) if @engine == UNDEFINED && @app
18
+ @engine
19
+ end
20
20
 
21
- def engine
22
- @engine = @app.opt(:engine) if @engine==UNDEFINED and @app
23
- @engine
24
- end
21
+ def no_layout!
22
+ layout! nil
23
+ end
25
24
 
26
- def no_layout!
27
- layout! nil
28
- end
25
+ def layout!(layout)
26
+ @layout = layout
27
+ end
29
28
 
30
- def layout! layout
31
- @layout = layout
32
- end
29
+ def layout
30
+ @layout = @app.opt(:layout) if @layout == UNDEFINED && @app
31
+ @layout
32
+ end
33
33
 
34
- def layout
35
- @layout = @app.opt(:layout) if @layout==UNDEFINED and @app
36
- @layout
37
- end
34
+ def static!(val, lifetime = 0)
35
+ @static = [true, false].include?(val) ? val : false
36
+ @cache_lifetime = lifetime
37
+ end
38
38
 
39
- def static! val, lifetime=0
40
- @static = ( (val==true or val==false) ? val : false )
41
- @cache_lifetime = lifetime
42
- end
39
+ def layout_base_path!(path)
40
+ @layout_base_path = path
41
+ end
43
42
 
44
- def layout_base_path! path
45
- @layout_base_path = path
46
- end
43
+ def layout_base_path
44
+ @layout_base_path ||= @app.layout_base_path
45
+ end
47
46
 
48
- def layout_base_path
49
- @layout_base_path ||= @app.layout_base_path
50
- end
47
+ def view_base_path!(path)
48
+ @view_base_path = path
49
+ end
51
50
 
52
- def view_base_path! path
53
- @view_base_path = path
54
- end
55
-
56
- def view_base_path
57
- @view_base_path ||= @app.view_base_path
58
- end
59
- end
60
-
61
- # instance level engine, layout, view, static configuration
51
+ def view_base_path
52
+ @view_base_path ||= @app.view_base_path
53
+ end
54
+ end
62
55
 
63
- def engine! engine
64
- @engine = engine
65
- end
56
+ # instance level engine, layout, view, static configuration
66
57
 
67
- def no_layout!
68
- layout! nil
69
- end
58
+ def engine!(engine)
59
+ @engine = engine
60
+ end
70
61
 
71
- def layout! layout
72
- @layout = layout
73
- end
62
+ def no_layout!
63
+ layout! nil
64
+ end
74
65
 
75
- def layout
76
- return nil if @layout.nil?
77
- File.join(self.class.layout_base_path, @layout) + ext
78
- end
66
+ def layout!(layout)
67
+ @layout = layout
68
+ end
79
69
 
80
- def no_view!
81
- view! nil
82
- end
70
+ def layout
71
+ return nil if @layout.nil?
83
72
 
84
- def view! view
85
- @view = view
86
- end
73
+ File.join(self.class.layout_base_path, @layout) + ext
74
+ end
87
75
 
88
- def view
89
- return nil if @view.nil?
90
- File.join(self.class.view_base_path, @view) + ext
91
- end
76
+ def no_view!
77
+ view! nil
78
+ end
92
79
 
93
- def static! val, lifetime=0
94
- @static = ( (val==true or val==false) ? val : false )
95
- @cache_lifetime = lifetime
96
- end
80
+ def view!(view)
81
+ @view = view
82
+ end
97
83
 
98
- def static
99
- return nil if not @static or @view.nil?
100
- File.join(app.static_base_path, @view) + ext
101
- end
84
+ def view
85
+ return nil if @view.nil?
102
86
 
103
- def ext! ext
104
- @ext = ( (ext.nil? or ext.empty?) ? nil : (ext[0]=='.' ? (ext.length==1 ? nil : ext) : '.' + ext) )
105
- end
87
+ File.join(self.class.view_base_path, @view) + ext
88
+ end
106
89
 
107
- def ext
108
- @ext || ''
109
- end
90
+ def static!(val, lifetime = 0)
91
+ @static = [true, false].include?(val) ? val : false
92
+ @cache_lifetime = lifetime
93
+ end
110
94
 
111
- def mime! mime
112
- @mime = mime
113
- end
95
+ def static
96
+ return nil if !@static || @view.nil?
114
97
 
115
- # class level basic node functions
98
+ File.join(app.static_base_path, @view) + ext
99
+ end
116
100
 
117
- class << self
101
+ def ext!(ext)
102
+ @ext = if ext.nil? || ext.empty?
103
+ nil
104
+ elsif ext[0] == '.'
105
+ ext.length == 1 ? nil : ext
106
+ else
107
+ ".#{ext}"
108
+ end
109
+ end
118
110
 
119
- attr_accessor :app
120
- def map app, location
121
- @app = app
122
- @app.map location, self
123
- end
111
+ def ext
112
+ @ext || ''
113
+ end
124
114
 
125
- def r *args
126
- @r ||= @app.to self
127
- (args.empty? ? @r : File.join( @r, args.map { |x| x.to_s } ) )
128
- end
115
+ def mime!(mime)
116
+ @mime = mime
117
+ end
129
118
 
130
- end
119
+ # class level basic node functions
131
120
 
132
- # instance level basic node functions
121
+ class << self
122
+ attr_accessor :app
133
123
 
134
- def app
135
- self.class.app
136
- end
124
+ def map(app, location)
125
+ @app = app
126
+ @app.map location, self
127
+ end
137
128
 
138
- def map
139
- self.class.r
140
- end
129
+ def r *args
130
+ @r ||= @app.to self
131
+ args.empty? ? @r : File.join(@r, args.map(&:to_s))
132
+ end
133
+ end
141
134
 
142
- def r *args
143
- File.join map, (args.empty? ? meth : args.map { |x| x.to_s } )
144
- end
135
+ # instance level basic node functions
145
136
 
146
- def html
147
- [ :map, :r, :args, :engine, :layout, :view ].inject('') { |s,sym| s+="<p>#{sym} => #{self.send sym}</p>"; s }
148
- end
137
+ def app
138
+ self.class.app
139
+ end
149
140
 
150
- def redirect target, options={}, &block
151
- status = options[:status] || 302
152
- body = options[:body] || redirect_body(target)
153
- header = response.header.merge('Location' => target.to_s)
154
- throw :stop_realize, Rack::Response.new(body, status, header, &block)
155
- end
141
+ def map
142
+ self.class.r
143
+ end
156
144
 
157
- def redirect_body target
158
- "You are being redirected, please follow this link to: <a href='#{target}'>#{target}</a>!"
159
- end
145
+ def r *args
146
+ File.join map, (args.empty? ? meth : args.map(&:to_s))
147
+ end
160
148
 
161
- # class level inherited values are key=>array, copied at inheritance
162
- # so they can be extanded at class level
163
- # values are copied from class into instance at object creation
164
- # so that can be extanded without modifying class level values
165
- # typical usage are css or js inclusions
149
+ def html
150
+ %i[map r args engine layout view].inject('') { |s, sym| s + "<p>#{sym} => #{send sym}</p>" }
151
+ end
166
152
 
167
- @cli_vals = { }
153
+ def redirect(target, options = {}, &block)
154
+ status = options[:status] || 302
155
+ body = options[:body] || redirect_body(target)
156
+ header = response.headers.merge('Location' => target.to_s)
157
+ throw :stop_realize, Rack::Response.new(body, status, header, &block)
158
+ end
168
159
 
169
- class << self
160
+ def redirect_body(target)
161
+ "You are being redirected, please follow this link to: <a href='#{target}'>#{target}</a>!"
162
+ end
170
163
 
171
- attr_reader :cli_vals
164
+ # class level inherited values are key=>array, copied at inheritance
165
+ # so they can be extanded at class level
166
+ # values are copied from class into instance at object creation
167
+ # so that can be extanded without modifying class level values
168
+ # typical usage are css or js inclusions
172
169
 
173
- def cli_val sym, *args
174
- vals = @cli_vals[sym] ||= []
175
- unless args.empty?
176
- vals.concat args
177
- vals.uniq!
178
- end
179
- vals
180
- end
170
+ @cli_vals = {}
181
171
 
182
- end
172
+ class << self
173
+ attr_reader :cli_vals
183
174
 
184
- def cli_val sym, *args
185
- vals = @cli_vals[sym] ||= []
186
- unless args.empty?
187
- vals.concat args
188
- vals.uniq!
189
- end
190
- vals
175
+ def cli_val(sym, *args)
176
+ vals = @cli_vals[sym] ||= []
177
+ unless args.empty?
178
+ vals.concat args
179
+ vals.uniq!
191
180
  end
181
+ vals
182
+ end
183
+ end
192
184
 
193
- # before_all and after_all hooks
194
-
195
- @cli_vals[:before_all] = []
196
- @cli_vals[:after_all] = []
197
- class << self
198
-
199
- def call_before_hooks obj
200
- @cli_vals[:before_all].each do |blk| blk.call obj end
201
- end
202
-
203
- def before_all meth=nil, &blk
204
- @cli_vals[:before_all]<< ( meth.nil? ? blk : meth )
205
- @cli_vals[:before_all].uniq!
206
- end
207
-
208
- def call_after_hooks obj
209
- @cli_vals[:after_all].each do |blk| blk.call obj end
210
- end
185
+ def cli_val(sym, *args)
186
+ vals = @cli_vals[sym] ||= []
187
+ unless args.empty?
188
+ vals.concat args
189
+ vals.uniq!
190
+ end
191
+ vals
192
+ end
211
193
 
212
- def after_all meth=nil, &blk
213
- @cli_vals[:after_all]<< ( meth.nil? ? blk : meth )
214
- @cli_vals[:after_all].uniq!
215
- end
194
+ # before_all and after_all hooks
216
195
 
217
- end
196
+ @cli_vals[:before_all] = []
197
+ @cli_vals[:after_all] = []
198
+ class << self
199
+ def call_before_hooks(obj)
200
+ @cli_vals[:before_all].each { |blk| blk.call obj }
201
+ end
218
202
 
219
- # rack entry point, page computation methods
220
-
221
- class << self
222
-
223
- def inherited sub
224
- sub.engine! ( engine || (self==Zorglub::Node ? UNDEFINED : nil ) )
225
- sub.layout! ( layout || (self==Zorglub::Node ? UNDEFINED : nil ) )
226
- sub.instance_variable_set :@cli_vals, {}
227
- @cli_vals.each do |s,v| sub.cli_val s, *v end
228
- end
229
-
230
- def call env
231
- meth, *args = env['PATH_INFO'].sub(/^\/+/,'').split(/\//)
232
- meth ||= 'index'
233
- $stderr << "=> #{meth}(#{args.join ','})\n" if app.opt :debug
234
- node = self.new env, meth, args
235
- return error_404 node, meth if not node.respond_to? meth
236
- node.realize!
237
- end
238
-
239
- def partial env, meth, *args
240
- node = self.new env, meth.to_s, args, true
241
- return error_404 node, meth if not node.respond_to? meth
242
- node.feed! env[:no_hooks]
243
- node.content
244
- end
245
-
246
- def error_404 node, meth
247
- $stderr << " !! #{node.class.name}::#{meth} not found\n" if app.opt :debug
248
- resp = node.response
249
- resp.status = 404
250
- resp['Content-Type'] = 'text/plain'
251
- resp.write "%s mapped at %p can't respond to : %p" % [ node.class.name, node.map, node.meth ]
252
- resp
253
- end
203
+ def before_all(meth = nil, &blk)
204
+ @cli_vals[:before_all] << (meth.nil? ? blk : meth)
205
+ @cli_vals[:before_all].uniq!
206
+ end
254
207
 
255
- end
208
+ def call_after_hooks(obj)
209
+ @cli_vals[:after_all].each { |blk| blk.call obj }
210
+ end
256
211
 
257
- attr_reader :request, :response, :content, :mime, :state, :engine, :meth, :args
258
-
259
- def initialize env, meth, args, partial=false
260
- @meth = meth
261
- @args = args
262
- @partial = partial
263
- @request = Rack::Request.new env
264
- @response = Rack::Response.new
265
- @cli_vals ={}
266
- @debug = app.opt :debug
267
- @engine = self.class.engine
268
- @layout = ( partial ? nil : self.class.layout )
269
- @view = r(meth)
270
- @static = self.class.static
271
- @cache_lifetime = self.class.cache_lifetime
272
- self.class.cli_vals.each do |s,v| cli_val s, *v end
273
- end
212
+ def after_all(meth = nil, &blk)
213
+ @cli_vals[:after_all] << (meth.nil? ? blk : meth)
214
+ @cli_vals[:after_all].uniq!
215
+ end
216
+ end
274
217
 
275
- def realize!
276
- catch(:stop_realize) {
277
- feed!
278
- response.write @content
279
- response.header['Content-Type'] ||= ( @mime || 'text/html' )
280
- response.finish
281
- response
282
- }
283
- end
218
+ # rack entry point, page computation methods
219
+
220
+ class << self
221
+ def inherited(sub)
222
+ super
223
+ sub.engine!(engine || (self == Zorglub::Node ? UNDEFINED : nil))
224
+ sub.layout!(layout || (self == Zorglub::Node ? UNDEFINED : nil))
225
+ sub.instance_variable_set :@cli_vals, {}
226
+ @cli_vals.each { |s, v| sub.cli_val s, *v }
227
+ end
228
+
229
+ def call(env)
230
+ meth, *args = env['PATH_INFO'].sub(%r{^/+}, '').split(%r{/})
231
+ meth ||= 'index'
232
+ $stderr << "=> #{meth}(#{args.join ','})\n" if app.opt :debug
233
+ node = new(env, meth, args)
234
+ return error404 node, meth unless node.respond_to? meth
235
+
236
+ node.realize!
237
+ end
238
+
239
+ def partial(env, meth, *args)
240
+ node = new env, meth.to_s, args, true
241
+ return error404 node, meth unless node.respond_to? meth
242
+
243
+ node.feed! env[:no_hooks]
244
+ node.content
245
+ end
246
+
247
+ def error404(node, meth)
248
+ $stderr << " !! #{node.class.name}::#{meth} not found\n" if app.opt :debug
249
+ resp = node.response
250
+ resp.status = 404
251
+ resp['Content-Type'] = 'text/plain'
252
+ resp.write "%<node.class.name>s mapped at %<node.map>p can't respond to : %<node.meth>p"
253
+ resp
254
+ end
255
+ end
284
256
 
285
- def feed! no_hooks=false
286
- @state = :pre_cb
287
- self.class.call_before_hooks self unless no_hooks
288
- @state = :meth
289
- @content = self.send @meth, *@args
290
- static_path = static
291
- if static_path.nil?
292
- compile_page!
293
- else
294
- static_page! static_path
295
- end
296
- @state = :post_cb
297
- self.class.call_after_hooks self unless no_hooks
298
- @state = :finished
299
- return @content, @mime
300
- end
257
+ attr_reader :request, :response, :content, :mime, :state, :engine, :meth, :args
258
+
259
+ def initialize(env, meth, args, partial = false)
260
+ @meth = meth
261
+ @args = args
262
+ @partial = partial
263
+ @request = Rack::Request.new env
264
+ @response = Rack::Response.new
265
+ @cli_vals = {}
266
+ @debug = app.opt :debug
267
+ @engine = self.class.engine
268
+ @layout = (partial ? nil : self.class.layout)
269
+ @view = r(meth)
270
+ @static = self.class.static
271
+ @cache_lifetime = self.class.cache_lifetime
272
+ self.class.cli_vals.each { |s, v| cli_val s, *v }
273
+ end
301
274
 
302
- def static_page! path
303
- if File.exists?(path) and ( @cache_lifetime.nil? or @cache_lifetime==0 or ( (Time.now-File.stat(path).mtime) < @cache_lifetime ) )
304
- $stderr << " * use cache file : #{path}\n" if @debug
305
- content = File.open(path, 'r') {|f| f.read }
306
- @content = content.sub /^@mime:(.*)\n/,''
307
- @mime = $1
308
- else
309
- compile_page!
310
- FileUtils.mkdir_p File.dirname(path)
311
- File.open(path, 'w') {|f| f.write("@mime:"+@mime+"\n"); f.write(@content); }
312
- $stderr << " * cache file created : #{path}\n" if @debug
313
- end
314
- end
275
+ def realize!
276
+ catch(:stop_realize) do
277
+ feed!
278
+ response.write @content
279
+ response.headers['Content-Type'] ||= @mime || 'text/html'
280
+ response.finish
281
+ response
282
+ end
283
+ end
315
284
 
316
- def compile_page!
317
- e, @ext = app.engine_proc_ext @engine, @ext
318
- v, l = view, layout
319
- if @debug
320
- $stderr << " * "+(e ? 'use engine' : 'no engine ')+" : "+(e ? e.to_s : '')+"\n"
321
- $stderr << " * "+((l and File.exists?(l)) ? 'use layout' : 'no layout ')+" : "+(l ? l : '')+"\n"
322
- $stderr << " * "+((v and File.exists?(v)) ? 'use view ' : 'no view ')+" : "+(v ? v : '')+"\n"
323
- end
324
- @state = ( @partial ? :partial : :view )
325
- @content, mime = e.call v, self if e and v and File.exists? v
326
- @mime ||= mime
327
- @state = :layout
328
- @content, mime = e.call l, self if e and l and File.exists? l
329
- @mime = mime if @mime.nil? and not mime.nil?
330
- end
285
+ def feed!(no_hooks = false)
286
+ @state = :pre_cb
287
+ self.class.call_before_hooks self unless no_hooks
288
+ @state = :meth
289
+ @content = send @meth, *@args
290
+ static_path = static
291
+ if static_path.nil?
292
+ compile_page!
293
+ else
294
+ static_page! static_path
295
+ end
296
+ @state = :post_cb
297
+ self.class.call_after_hooks self unless no_hooks
298
+ @state = :finished
299
+ [@content, @mime]
300
+ end
331
301
 
302
+ def static_page!(path)
303
+ if File.exist?(path) && (@cache_lifetime.nil? || @cache_lifetime.zero? ||
304
+ (Time.now - File.stat(path).mtime) < @cache_lifetime)
305
+ $stderr << " * use cache file : #{path}\n" if @debug
306
+ content = File.read(path)
307
+ @content = content.sub(/^@mime:(.*)\n/, '')
308
+ @mime = ::Regexp.last_match(1)
309
+ else
310
+ compile_page!
311
+ FileUtils.mkdir_p File.dirname(path)
312
+ File.open(path, 'w') { |f| f.write("@mime:#{@mime}\n#{@content}") }
313
+ $stderr << " * cache file created : #{path}\n" if @debug
314
+ end
332
315
  end
333
316
 
317
+ def compile_page!
318
+ e, @ext = app.engine_proc_ext @engine, @ext
319
+ v = view
320
+ l = layout
321
+ if @debug
322
+ $stderr << " * #{e ? 'use engine' : 'no engine '} : #{e ? e.to_s : ''}\n"
323
+ $stderr << " * #{l && File.exist?(l) ? 'use layout' : 'no layout '} : #{l || ''}\n"
324
+ $stderr << " * #{v && File.exist?(v) ? 'use view ' : 'no view '} : #{v || ''}\n"
325
+ end
326
+ @state = @partial ? :partial : :view
327
+ @content, mime = e.call(v, self) if e && v && File.exist?(v)
328
+ @mime ||= mime
329
+ @state = :layout
330
+ @content, mime = e.call(l, self) if e && l && File.exist?(l)
331
+ @mime = mime if @mime.nil? && !mime.nil?
332
+ end
333
+ end
334
334
  end
@@ -1,9 +1,7 @@
1
- # -*- coding: UTF-8 -*-
2
-
3
1
  module Zorglub
4
- class Node
5
- def session
6
- @request.session
7
- end
2
+ class Node
3
+ def session
4
+ @request.session
8
5
  end
6
+ end
9
7
  end