maveric 0.3.0 → 0.3.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/maveric.rb +52 -28
- data/lib/maveric/extensions.rb +33 -15
- data/lib/maveric/sessions.rb +47 -11
- metadata +2 -2
data/lib/maveric.rb
CHANGED
@@ -150,16 +150,19 @@ require 'maveric/extensions'
|
|
150
150
|
# trickery.
|
151
151
|
class Maveric
|
152
152
|
## Implementation details.
|
153
|
-
VERSION='0.3.
|
153
|
+
VERSION='0.3.1'
|
154
154
|
|
155
155
|
## Standard end of line for HTTP
|
156
156
|
EOL="\r\n"
|
157
157
|
## Group 1 wil contain a boundary for multipart/form-data bodies.
|
158
158
|
MP_BOUND_REGEX = /\Amultipart\/form-data.*boundary=\"?([^\";, ]+)\"?/n
|
159
|
+
## Contains a list of environment preprocessors.
|
160
|
+
@adj_env = []
|
159
161
|
|
160
162
|
# I hate putting utility methods here, rather than in some module, but
|
161
163
|
# I don't see how to do it without getting messy.
|
162
164
|
class << self
|
165
|
+
|
163
166
|
## Builds a logging object if there's not one yet, then returns it.
|
164
167
|
def log
|
165
168
|
unless defined? @@maveric_logger
|
@@ -275,7 +278,7 @@ class Maveric
|
|
275
278
|
# their respective modules.
|
276
279
|
def inherited klass
|
277
280
|
::Maveric.log.info "#{klass} inherits from #{self}."
|
278
|
-
super
|
281
|
+
super
|
279
282
|
parent = self
|
280
283
|
klass.class_eval do
|
281
284
|
const_set(:Models, Module.new).
|
@@ -308,7 +311,6 @@ class Maveric
|
|
308
311
|
@adj_env << act
|
309
312
|
end
|
310
313
|
end
|
311
|
-
@adj_env = []
|
312
314
|
|
313
315
|
##
|
314
316
|
# When instantiated, the Maveric decends through its constants for
|
@@ -367,9 +369,16 @@ class Maveric
|
|
367
369
|
def prepare_environment env
|
368
370
|
::Maveric.type_check :env, env, Hash
|
369
371
|
env.update :maveric => self
|
370
|
-
self.class.adjust_env.
|
371
|
-
|
372
|
-
|
372
|
+
self.class.adjust_env.select do |act|
|
373
|
+
act[:test].nil? or act[:test][env]
|
374
|
+
end.each do |act|
|
375
|
+
::Maveric.log.debug "#{self.class} prep_env #{act[:name]}"
|
376
|
+
if act[:do]
|
377
|
+
act[:do].call env
|
378
|
+
else
|
379
|
+
__send__ act[:name], env
|
380
|
+
end
|
381
|
+
end
|
373
382
|
end
|
374
383
|
|
375
384
|
### Does this count as magic? No, just defaults.
|
@@ -396,9 +405,6 @@ class Maveric
|
|
396
405
|
|
397
406
|
##
|
398
407
|
# Holds views related methods and helpers
|
399
|
-
#
|
400
|
-
# As long as Controller#prepare_0_imports is not overridden, Views extends
|
401
|
-
# the Controller instance just before the action is called.
|
402
408
|
module Views
|
403
409
|
def path_to c, a={}
|
404
410
|
::Maveric.log.info "#{self.class}#path_to #{c} #{a.inspect}"
|
@@ -408,9 +414,6 @@ class Maveric
|
|
408
414
|
|
409
415
|
##
|
410
416
|
# Repository for models. Still not really utilized.
|
411
|
-
#
|
412
|
-
# As long as Controller#prepare_0_imports is not overridden, Models extends
|
413
|
-
# the Controller instance just before the action is called.
|
414
417
|
module Models
|
415
418
|
end
|
416
419
|
end
|
@@ -438,8 +441,14 @@ end
|
|
438
441
|
# Integer corresponding to a real HTTP status code, and @body should contain
|
439
442
|
# a String.
|
440
443
|
#
|
444
|
+
# The instance variable @action contains a Symbol corresponding to the
|
445
|
+
# Controller method to be called. The result of this call is assigned to
|
446
|
+
# @body.
|
447
|
+
#
|
441
448
|
# Those are the only instance variables you should be warned against playing
|
442
|
-
# with frivously.
|
449
|
+
# with frivously. All instance variables are initially assigned before the
|
450
|
+
# before actions have been run, with the exception of @body which is set
|
451
|
+
# after @action is called.
|
443
452
|
class Maveric::Controller
|
444
453
|
REQUEST_METHODS = [:post, :get, :put, :delete, :head] # CRUDY
|
445
454
|
@before = []
|
@@ -564,25 +573,36 @@ class Maveric::Controller
|
|
564
573
|
action ||= @env[:route][:action] rescue nil
|
565
574
|
action ||= @env['REQUEST_METHOD'].downcase rescue nil
|
566
575
|
action ||= 'get'
|
567
|
-
action = action.to_sym
|
576
|
+
@action = action.to_sym
|
568
577
|
|
569
|
-
|
570
|
-
REQUEST_METHODS.include? action and not respond_to? action
|
578
|
+
::Maveric.log.debug "#{self.class} action #{@action.inspect}"
|
571
579
|
|
572
580
|
self.class.before.select do |act|
|
573
|
-
(act[:only].nil? or act[:only].include? action) and \
|
574
|
-
(act[:exclude].nil? or not act[:exclude].include? action)
|
581
|
+
(act[:only].nil? or act[:only].include? @action) and \
|
582
|
+
(act[:exclude].nil? or not act[:exclude].include? @action)
|
575
583
|
end.each do |act|
|
576
|
-
|
584
|
+
::Maveric.log.debug "#{self.class} before #{act[:name]}"
|
585
|
+
if act[:do]
|
586
|
+
act[:do].call self
|
587
|
+
else
|
588
|
+
__send__ act[:name], self
|
589
|
+
end
|
577
590
|
end
|
578
591
|
|
579
|
-
@
|
592
|
+
raise NoMethodError, [503, "#{@action} not implemented.", nil, @env] if \
|
593
|
+
REQUEST_METHODS.include? @action and not respond_to? @action
|
594
|
+
@body = __send__ @action
|
580
595
|
|
581
596
|
self.class.after.select do |act|
|
582
|
-
(act[:only].nil? or act[:only].include? action) and \
|
583
|
-
(act[:exclude].nil? or not act[:exclude].include? action)
|
597
|
+
(act[:only].nil? or act[:only].include? @action) and \
|
598
|
+
(act[:exclude].nil? or not act[:exclude].include? @action)
|
584
599
|
end.each do |act|
|
585
|
-
|
600
|
+
::Maveric.log.debug "#{self.class} after #{act[:name]}"
|
601
|
+
if act[:do]
|
602
|
+
act[:do].call self
|
603
|
+
else
|
604
|
+
__send__ act[:name], self
|
605
|
+
end
|
586
606
|
end
|
587
607
|
|
588
608
|
::Maveric.log.debug self # omg, masochistic.
|
@@ -606,7 +626,7 @@ class Maveric::Controller
|
|
606
626
|
# just above the return. Controller#render calls itself. That is all.
|
607
627
|
def render view, s=''
|
608
628
|
::Maveric.log.debug "#{self.class}#render"+
|
609
|
-
" #{view.inspect}, #{s.inspect}"
|
629
|
+
" #{view.inspect}, #{s[0..100].inspect}"
|
610
630
|
::Maveric.type_check :view, view, Symbol, String
|
611
631
|
::Maveric.type_check :s, s, String
|
612
632
|
s = yield s if block_given?
|
@@ -706,7 +726,9 @@ class Maveric::Route < Regexp
|
|
706
726
|
::Maveric.log.debug "#{self.class}#build #{arg.inspect} : #{@params}"
|
707
727
|
::Maveric.type_check :arg, arg, Hash
|
708
728
|
if @params.sort == arg.keys.sort
|
709
|
-
|
729
|
+
@options.
|
730
|
+
merge(arg).
|
731
|
+
inject(@path){|r,(k,v)| r.sub /:#{k}:?/, v }
|
710
732
|
end
|
711
733
|
end
|
712
734
|
|
@@ -718,7 +740,9 @@ class Maveric::Route < Regexp
|
|
718
740
|
::Maveric.log.debug "#{self.class}#route #{path.inspect} : #{self}"
|
719
741
|
::Maveric.type_check :path, path, String
|
720
742
|
if self =~ path
|
721
|
-
|
743
|
+
@options.
|
744
|
+
merge( Hash[ *@params.zip($~.captures).flatten ] ).
|
745
|
+
update(nil => self) # should be safe enough.
|
722
746
|
end
|
723
747
|
end
|
724
748
|
|
@@ -736,7 +760,7 @@ class Maveric::Route < Regexp
|
|
736
760
|
end
|
737
761
|
|
738
762
|
##
|
739
|
-
# As Route is a subclass of a
|
763
|
+
# As Route is a subclass of a core lib class, the inspect isn't as
|
740
764
|
# informative as we'd like. So we override it.
|
741
765
|
def inspect
|
742
766
|
"#<%s:0x%x %s %s %s>" % [
|
@@ -745,7 +769,7 @@ class Maveric::Route < Regexp
|
|
745
769
|
super,
|
746
770
|
@params.inspect,
|
747
771
|
@path.inspect
|
748
|
-
]
|
772
|
+
] # we don't include @options, I know.
|
749
773
|
end
|
750
774
|
|
751
775
|
private
|
data/lib/maveric/extensions.rb
CHANGED
@@ -6,16 +6,22 @@ class Module
|
|
6
6
|
gsub(/(::)+/, '/').
|
7
7
|
downcase
|
8
8
|
end
|
9
|
+
|
9
10
|
# ::nodoc::
|
11
|
+
# Still deving this.
|
10
12
|
def self.nesting_path_to_constant path
|
11
|
-
dig=proc{|c,n| c.const_get(n)}
|
13
|
+
dig = proc{|c,n| c.const_get(n) }
|
12
14
|
path.gsub(/_([a-z])/){$1.upcase}.split('/')
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
18
|
class Symbol
|
17
19
|
# #to_s makes sense, but #to_i is just as effective.
|
18
|
-
def <=>
|
20
|
+
def <=> obj
|
21
|
+
obj.instance_of?(Symbol) ?
|
22
|
+
self.to_i <=> obj.to_i :
|
23
|
+
super
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
module Enumerable
|
@@ -30,9 +36,11 @@ module Enumerable
|
|
30
36
|
# tpope> it's a little confusing, but it's a confusing concept
|
31
37
|
|
32
38
|
##
|
33
|
-
# Used to return the first value for which the
|
39
|
+
# Used to return the first value for which the given block evalutes as true.
|
34
40
|
# Think .map(&b).compact.first
|
35
|
-
def eject &
|
41
|
+
def eject &block
|
42
|
+
find{|e| result = block[e] and break result }
|
43
|
+
end
|
36
44
|
end
|
37
45
|
|
38
46
|
##
|
@@ -41,24 +49,34 @@ class StandardError
|
|
41
49
|
DEFAULT_STATUS = 500
|
42
50
|
DEFAULT_HEADERS = {'Content-Type'=>'text/plain'}
|
43
51
|
attr_writer :status, :headers, :body
|
44
|
-
def status
|
45
|
-
|
52
|
+
def status
|
53
|
+
@status or DEFAULT_STATUS
|
54
|
+
end
|
55
|
+
|
56
|
+
def headers
|
57
|
+
@headers or DEFAULT_HEADERS
|
58
|
+
end
|
59
|
+
|
46
60
|
## Unless @body is defined, a self inspect and backtrace is output.
|
47
|
-
def body
|
61
|
+
def body
|
62
|
+
@body or [inspect, *backtrace]*"\n"
|
63
|
+
end
|
64
|
+
|
48
65
|
## See ::Maveric::Controller#to_http
|
49
66
|
def to_http
|
50
67
|
response = "Status: #{status}"+::Maveric::EOL
|
51
68
|
response << headers.map{|(k,v)| "#{k}: #{v}" }*::Maveric::EOL
|
52
69
|
response << ::Maveric::EOL*2 + body
|
53
70
|
end
|
71
|
+
|
54
72
|
alias_method :old_init, :initialize
|
55
73
|
##
|
56
|
-
# After a bit of experimenting with Exception and raise I
|
74
|
+
# After a bit of experimenting with Exception and raise I determined a fun
|
57
75
|
# and simple way to generate fast HTTP response error thingies. As long as
|
58
|
-
# you're within a call to dispatch (with no further rescue clauses)
|
59
|
-
# StandardError will propogate up and be returned. As a StandardError
|
60
|
-
# similar accessors as a Controller, they should be compatible with any
|
61
|
-
# outputting implimentation.
|
76
|
+
# you're within a call to Maveric#dispatch (with no further rescue clauses)
|
77
|
+
# the StandardError will propogate up and be returned. As a StandardError
|
78
|
+
# has similar accessors as a Controller, they should be compatible with any
|
79
|
+
# outputting implimentation for Maveric.
|
62
80
|
#
|
63
81
|
# raise StandardErrpr; # 500 error
|
64
82
|
# raise StandardError, 'Crap!'; # 500 error with message set to 'Crap!'
|
@@ -67,15 +85,15 @@ class StandardError
|
|
67
85
|
# In the final example line an Array is passed to raise as a second argument
|
68
86
|
# rather than a String. This is taken as the HTTP status code. The next
|
69
87
|
# element is tested to be a Hash, if so then it's values are merged into
|
70
|
-
# the HTTP headers.
|
88
|
+
# the HTTP headers. The next item is tested to be a String, if so it is
|
71
89
|
# appended to the response body. All remaining elements are appended to
|
72
90
|
# the response body in inspect format.
|
73
91
|
#
|
74
92
|
# A simple way of only including data that might be interpreted to being the
|
75
93
|
# status, headers, or body is to place a nil previous to the data you want
|
76
|
-
#
|
94
|
+
# appended to the response body.
|
77
95
|
def initialize data=nil
|
78
|
-
#consider
|
96
|
+
# consider autosetting @status, like 503 for NoMethodError
|
79
97
|
if data.is_a? Array and data[0].is_a? Integer
|
80
98
|
@body = ''
|
81
99
|
@status = data.shift if Integer === data.first
|
data/lib/maveric/sessions.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
class Maveric
|
2
4
|
##
|
3
5
|
# Contains session data and provides conveniance in generating an appropriate
|
@@ -5,14 +7,22 @@ class Maveric
|
|
5
7
|
class Sessions < Set
|
6
8
|
COOKIE_NAME = 'SESSIONID'
|
7
9
|
|
10
|
+
##
|
11
|
+
# Looks up a sessions by id given. The id argument should be a string of
|
12
|
+
# a hex number. (num.to_s(16) If id is not found a new Session is created
|
13
|
+
# and its Session#id is returned.
|
8
14
|
def session id #wants stringed hex num
|
15
|
+
::Maveric.type_check :id, id, String
|
16
|
+
|
9
17
|
#ensure crusty old sessions don't linger
|
10
18
|
@__i += 1 rescue @__i = 1
|
11
|
-
reject!{|s| s.expire < Time.now-3 } if (@__i%=10) == 0
|
19
|
+
reject!{|s| s.expire < Time.now-3 } if (@__i%=10) == 0 # 3 second grace
|
20
|
+
|
12
21
|
# now get the session
|
13
22
|
session = find{|s| s.id == id } and return session
|
14
|
-
|
15
|
-
|
23
|
+
|
24
|
+
# there isn't one? then make a new one!
|
25
|
+
add (session=Session.new) and return session
|
16
26
|
end
|
17
27
|
|
18
28
|
##
|
@@ -28,15 +38,28 @@ class Maveric
|
|
28
38
|
touch
|
29
39
|
::Maveric.log.debug self
|
30
40
|
end
|
41
|
+
|
31
42
|
attr_reader :expires, :data, :duration
|
43
|
+
|
32
44
|
## Returns an upcased hexed object_id, not #object_id.to_s(16) however.
|
33
|
-
def id
|
45
|
+
def id
|
46
|
+
@id||=[object_id<<1].pack('i').unpack('I')[0].to_s(16).upcase
|
47
|
+
end
|
48
|
+
|
34
49
|
##
|
35
50
|
# One session is less than another if it expires sooner. Useful if we
|
36
51
|
# are managing in a manner akin to a priority stack.
|
37
|
-
def <=> obj
|
52
|
+
def <=> obj
|
53
|
+
Session === obj ?
|
54
|
+
self.expires <=> obj.expires :
|
55
|
+
super
|
56
|
+
end
|
57
|
+
|
38
58
|
## Set this session's expiry to @duration+Time.now
|
39
|
-
def touch
|
59
|
+
def touch
|
60
|
+
@expires = Time.now.gmtime + Integer(@duration)
|
61
|
+
end
|
62
|
+
|
40
63
|
## Perhaps better named as #to_cookie for clarity?
|
41
64
|
def to_s env=nil
|
42
65
|
touch
|
@@ -51,23 +74,36 @@ class Maveric
|
|
51
74
|
end
|
52
75
|
end
|
53
76
|
end
|
77
|
+
|
54
78
|
@sessions = Sessions.new
|
79
|
+
|
55
80
|
## Return the standard session set.
|
56
|
-
def self.sessions
|
81
|
+
def self.sessions
|
82
|
+
@sessions
|
83
|
+
end
|
84
|
+
|
57
85
|
## Return a session via Session#session
|
58
|
-
def self.session id
|
86
|
+
def self.session id
|
87
|
+
@sessions.session id
|
88
|
+
end
|
89
|
+
|
59
90
|
##
|
60
91
|
# Uses env[:cookie] to find the session_id, and retrives the data to set the
|
61
|
-
#
|
62
|
-
def
|
92
|
+
# values or env[:session].
|
93
|
+
def set_session env
|
63
94
|
session_id = env[:cookies][::Maveric::Sessions::COOKIE_NAME].first
|
64
95
|
env[:session] = ::Maveric.session session_id
|
65
96
|
end
|
97
|
+
|
98
|
+
adjust_env :set_session
|
99
|
+
|
66
100
|
class Controller
|
67
101
|
## Touches the session and includes it into the http headers.
|
68
|
-
def
|
102
|
+
def session_cleanup controller
|
69
103
|
@env[:session].touch
|
70
104
|
@headers['Set-Cookie'] = [@env[:session].to_s(@env)]
|
71
105
|
end
|
106
|
+
|
107
|
+
after :session_cleanup
|
72
108
|
end
|
73
109
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: maveric
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.3.
|
7
|
-
date: 2007-01-
|
6
|
+
version: 0.3.1
|
7
|
+
date: 2007-01-28 00:00:00 -07:00
|
8
8
|
summary: A simple, non-magical, framework.
|
9
9
|
require_paths:
|
10
10
|
- lib/
|