maveric 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/maveric.rb +350 -493
- data/maveric/extensions.rb +94 -0
- data/maveric/mongrel.rb +2 -2
- data/maveric/sessions.rb +73 -0
- metadata +5 -4
- data/maveric/stadik-impl.rb +0 -113
@@ -0,0 +1,94 @@
|
|
1
|
+
class Module
|
2
|
+
alias_method :__to_s, :to_s
|
3
|
+
private :__to_s
|
4
|
+
## Prepends a :: to the string represendation of itself.
|
5
|
+
def to_s; "::#{__to_s}"; end
|
6
|
+
## Build a string akin toa relative url of the nesting structure.
|
7
|
+
def nesting_path
|
8
|
+
self.to_s.
|
9
|
+
gsub(/([a-z])([A-Z])/, '\1_\2').
|
10
|
+
gsub(/::/, '/').
|
11
|
+
downcase
|
12
|
+
end
|
13
|
+
# ::nodoc::
|
14
|
+
def self.nesting_path_to_constant path
|
15
|
+
dig=proc{|c,n| c.const_get(n)}
|
16
|
+
path.gsub(/_([a-z])/){$1.upcase}.split('/')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Symbol
|
21
|
+
# #to_s makes sense, but #to_i is just as effective.
|
22
|
+
def <=> o; o.instance_of?(Symbol) ? self.to_i <=> o.to_i : super; end
|
23
|
+
end
|
24
|
+
|
25
|
+
module Enumerable
|
26
|
+
# blink> wtf do I call this? #find{|e| r = do_stuff(e) and break r }
|
27
|
+
# manveru> map.find
|
28
|
+
# LoganCapaldo> first_mapped
|
29
|
+
# LoganCapaldo> find_such_that
|
30
|
+
# tpope> Enumerable#eject
|
31
|
+
# blink> o.O
|
32
|
+
# tpope> returns on the first non-nil yield
|
33
|
+
# tpope> it rhymes with select and detect and reject and collect and inject
|
34
|
+
# tpope> it's a little confusing, but it's a confusing concept
|
35
|
+
|
36
|
+
##
|
37
|
+
# Used to return the first value for which the black evalutes as true.
|
38
|
+
# Think .map(&b).compact.first
|
39
|
+
def eject &b; find{|e| r=b[e] and break r }; end
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Extensions to StandardError to enable their usage in Maveric as responses.
|
44
|
+
class StandardError
|
45
|
+
DEFAULT_STATUS = 500
|
46
|
+
DEFAULT_HEADERS = {'Content-Type'=>'text/plain'}
|
47
|
+
attr_writer :status, :headers, :body
|
48
|
+
def status; @status or DEFAULT_STATUS; end
|
49
|
+
def headers; @headers or DEFAULT_HEADERS; end
|
50
|
+
## Unless @body is defined, a self inspect and backtrace is output.
|
51
|
+
def body; @body or [inspect, *backtrace]*"\n"; end
|
52
|
+
## See ::Maveric::Controller#to_http
|
53
|
+
def to_http
|
54
|
+
response = "Status: #{status}"+::Maveric::EOL
|
55
|
+
response << headers.map{|(k,v)| "#{k}: #{v}" }*::Maveric::EOL
|
56
|
+
response << ::Maveric::EOL*2 + body
|
57
|
+
end
|
58
|
+
alias_method :old_init, :initialize
|
59
|
+
##
|
60
|
+
# After a bit of experimenting with Exception and raise I determinee a fun
|
61
|
+
# and simple way to generate fast HTTP response error thingies. As long as
|
62
|
+
# you're within a call to dispatch (with no further rescue clauses) the
|
63
|
+
# StandardError will propogate up and be returned. As a StandardError has
|
64
|
+
# similar accessors as a Controller, they should be compatible with any
|
65
|
+
# outputting implimentation.
|
66
|
+
#
|
67
|
+
# raise StandardErrpr; # 500 error
|
68
|
+
# raise StandardError, 'Crap!'; # 500 error with message set to 'Crap!'
|
69
|
+
# raise StandardError, [status, headers, body, *other_data] # Magic!
|
70
|
+
#
|
71
|
+
# In the final example line an Array is passed to raise as a second argument
|
72
|
+
# rather than a String. This is taken as the HTTP status code. The next
|
73
|
+
# element is tested to be a Hash, if so then it's values are merged into
|
74
|
+
# the HTTP headers. Then next item is tested to be a String, if so it is
|
75
|
+
# appended to the response body. All remaining elements are appended to
|
76
|
+
# the response body in inspect format.
|
77
|
+
#
|
78
|
+
# A simple way of only including data that might be interpreted to being the
|
79
|
+
# status, headers, or body is to place a nil previous to the data you want
|
80
|
+
# apended to the response body.
|
81
|
+
def initialize data=nil
|
82
|
+
#consider autosettign @status, like 503 for NoMethodError
|
83
|
+
if data.is_a? Array and data[0].is_a? Integer
|
84
|
+
@body = ''
|
85
|
+
@status = data.shift if Integer === data.first
|
86
|
+
@headers = DEF_HEADERS.merge data.shift if Hash === data.first
|
87
|
+
@body << data.shift if String === data.first
|
88
|
+
msg = @body.dup
|
89
|
+
@body << "\n\n#{data.compact.map{|e|e.inspect}*"\n"}" unless data.empty?
|
90
|
+
data = msg
|
91
|
+
end
|
92
|
+
old_init data
|
93
|
+
end
|
94
|
+
end
|
data/maveric/mongrel.rb
CHANGED
@@ -13,7 +13,7 @@ class Maveric::MongrelHandler < Mongrel::HttpHandler
|
|
13
13
|
# NOTE: Update doc.
|
14
14
|
def process request, response
|
15
15
|
Maveric.log.info "Mongrel+#{self.class}#process"
|
16
|
-
reply = @maveric.
|
16
|
+
reply = @maveric.process request.body, request.params
|
17
17
|
# output the result
|
18
18
|
response.start reply.status do |head,out|
|
19
19
|
reply.headers.each {|k,v| head[k] = v }
|
@@ -25,7 +25,7 @@ class Maveric::MongrelHandler < Mongrel::HttpHandler
|
|
25
25
|
def request_begins params
|
26
26
|
begin
|
27
27
|
Maveric.log.info "Mongrel+#{self.class}#request_begins"
|
28
|
-
@maveric.
|
28
|
+
@maveric.prepare_environment params
|
29
29
|
rescue
|
30
30
|
Maveric.log.fatal "#{$!.inspect}\n#{$@[0..5]*"\n"}"
|
31
31
|
end
|
data/maveric/sessions.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
module Maveric
|
2
|
+
##
|
3
|
+
# Contains session data and provides conveniance in generating an appropriate
|
4
|
+
# cookie.
|
5
|
+
class Sessions < Set
|
6
|
+
COOKIE_NAME = 'SESSIONID'
|
7
|
+
|
8
|
+
def session id #wants stringed hex num
|
9
|
+
#ensure crusty old sessions don't linger
|
10
|
+
@__i += 1 rescue @__i = 1
|
11
|
+
reject!{|s| s.expire < Time.now-3 } if (@__i%=10) == 0
|
12
|
+
# now get the session
|
13
|
+
session = find{|s| s.id == id } and return session
|
14
|
+
#there isn't one? then make a new one!
|
15
|
+
push Session.new and return last
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Because apparently sessions are handy or helpful or something like that.
|
20
|
+
# Implemented as that the hex of their #object_id (the one you'd see in
|
21
|
+
# an Object#inspect) is treated as a session id.
|
22
|
+
class Session
|
23
|
+
DURATION = 15*60
|
24
|
+
## The default session length is 15 minutes. Simple to change.
|
25
|
+
def initialize duration=DURATION
|
26
|
+
::Maveric.type_check :duration, duration, Integer
|
27
|
+
@duration, @data = duration, {}
|
28
|
+
touch
|
29
|
+
::Maveric.log.debug self
|
30
|
+
end
|
31
|
+
attr_reader :expires, :data, :duration
|
32
|
+
## Returns an upcased hexed object_id, not #object_id.to_s(16) however.
|
33
|
+
def id; @id||=[object_id<<1].pack('i').unpack('I')[0].to_s(16).upcase; end
|
34
|
+
##
|
35
|
+
# One session is less than another if it expires sooner. Useful if we
|
36
|
+
# are managing in a manner akin to a priority stack.
|
37
|
+
def <=> obj; Session === obj ? self.expires <=> obj.expires : super; end
|
38
|
+
## Set this session's expiry to @duration+Time.now
|
39
|
+
def touch; @expires = Time.now.gmtime + Integer(@duration); end
|
40
|
+
## Perhaps better named as #to_cookie for clarity?
|
41
|
+
def to_s env=nil
|
42
|
+
touch
|
43
|
+
c = "#{::Maveric::Sessions::COOKIE_NAME}=#{id}" #required
|
44
|
+
c << "; expires=#{expires.httpdate}"
|
45
|
+
return c unless env
|
46
|
+
c << "; domain=#{env['SERVER_NAME']};"
|
47
|
+
# need to determine a good way to discern proper path.
|
48
|
+
# pertinant Maveric?
|
49
|
+
c << "; secure" if false
|
50
|
+
c
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
@sessions = Sessions.new
|
55
|
+
## Return the standard session set.
|
56
|
+
def self.sessions; @sessions; end
|
57
|
+
## Return a session via Session#session
|
58
|
+
def self.session id; @sessions.session id; end
|
59
|
+
##
|
60
|
+
# Uses env[:cookie] to find the session_id, and retrives the data to set the
|
61
|
+
# valuse or env[:session].
|
62
|
+
def env_1_session env
|
63
|
+
session_id = env[:cookies][::Maveric::Sessions::COOKIE_NAME].first
|
64
|
+
env[:session] = ::Maveric.session session_id
|
65
|
+
end
|
66
|
+
class Controller
|
67
|
+
## Touches the session and includes it into the http headers.
|
68
|
+
def cleanup_1_sessions
|
69
|
+
@env[:session].touch
|
70
|
+
@headers['Set-Cookie'] = [@env[:session].to_s(@env)]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
metadata
CHANGED
@@ -3,9 +3,9 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: maveric
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-01-
|
8
|
-
summary: A simple, non-magical, framework
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2007-01-22 00:00:00 -07:00
|
8
|
+
summary: A simple, non-magical, framework.
|
9
9
|
require_paths:
|
10
10
|
- .
|
11
11
|
email: blinketje@gmail.com
|
@@ -33,7 +33,8 @@ files:
|
|
33
33
|
- maveric/mongrel.rb
|
34
34
|
- maveric/fastcgi.rb
|
35
35
|
- maveric/webrick.rb
|
36
|
-
- maveric/
|
36
|
+
- maveric/sessions.rb
|
37
|
+
- maveric/extensions.rb
|
37
38
|
test_files: []
|
38
39
|
|
39
40
|
rdoc_options: []
|
data/maveric/stadik-impl.rb
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
%w~maveric maveric/mongrel erubis~.each{|m|require m}
|
3
|
-
Dir.chdir File.dirname __FILE__
|
4
|
-
|
5
|
-
class SDKNet < Maveric
|
6
|
-
def self.load_mime_map(file,mime={})
|
7
|
-
mime = mime.merge(YAML.load_file(file))
|
8
|
-
mime.each {|k,v| $log.warn{"WARNING: MIME type #{k} must start with '.'"} if k.index(".") != 0 }
|
9
|
-
mime
|
10
|
-
end
|
11
|
-
module Views
|
12
|
-
def standard content
|
13
|
-
menu = [
|
14
|
-
[path_to(Index, :page => 'about'), 'About', 'Myth/Truth'],
|
15
|
-
['http://blog.stadik.net', 'Blog', 'Finding('+%w(Thought Home Popularity Greatness Definition Meaning Happiness Reason Love Life Intelligence Worth).at(rand(12))+')'],
|
16
|
-
[path_to(Index, :page => 'resume'), 'Resumé', 'I work'],
|
17
|
-
[path_to(Index, :page => 'link'), 'Linkage', 'here we go']
|
18
|
-
]
|
19
|
-
std = <<-STD
|
20
|
-
<div class="tablist" id="pmenu">
|
21
|
-
<ul>
|
22
|
-
<li><a title="Home" href="<%= path_to(Index) %>"><img border="0" src="http://media.stadik.net/stadik.png" title="SDK | StaDiK" id="homelogo" alt="" /></a></li>
|
23
|
-
<% menu.each do |entry| %>
|
24
|
-
<li class='<%= 'here' if @page == entry[0] %>'><a href='<%= entry[0] %>' title='<%= entry[2] %>'><%= entry[1] %></a></li>
|
25
|
-
<% end %>
|
26
|
-
</ul>
|
27
|
-
</div>
|
28
|
-
|
29
|
-
<div id='pcontent'>
|
30
|
-
<!-- START CONTENT -->
|
31
|
-
|
32
|
-
<%= content %>
|
33
|
-
|
34
|
-
<!-- END CONTENT -->
|
35
|
-
</div>
|
36
|
-
|
37
|
-
<div class="tablist" id="pfoot">
|
38
|
-
<ul>
|
39
|
-
<li><a href="http://www.gvisit.com/map.php?sid=9e05735b2b78466e2fbc8538bf9b0c1c">where</a></li>
|
40
|
-
<li><a href="http://validator.w3.org/check?uri=referer">valid?</a></li>
|
41
|
-
<li><a>1995-2006©SDKm</a><a rel="licence" title="All content on this website (including text, photographs, audio files, and any other original works), unless otherwise noted, is licensed under a Creative Commons License." href="http://creativecommons.org/licenses/by-nc-nd/2.5/">CCL:2.5</a></li>
|
42
|
-
</ul>
|
43
|
-
</div>
|
44
|
-
STD
|
45
|
-
::Erubis::Eruby.new(std).result(binding)
|
46
|
-
end
|
47
|
-
def layout content
|
48
|
-
lyt = <<-LAYOUT
|
49
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
50
|
-
<!DOCTYPE html PUBLIC>
|
51
|
-
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
52
|
-
<head>
|
53
|
-
<title>StaDiK.net</title>
|
54
|
-
<link rel="stylesheet" href="/z/style.css" type="text/css" media="screen"/>
|
55
|
-
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
|
56
|
-
<meta name="DC.title" content="StaDiK Motions"/>
|
57
|
-
<meta name="DC.description" content="Scytrin&apos;s mucking about on the net."/>
|
58
|
-
<meta name="DC.creator.name" content="Scytrin dai Kinthra"/>
|
59
|
-
<meta name="geo.position" content="37.3069;-121.9271"/>
|
60
|
-
<meta name="geo.placename" content="San Jose"/>
|
61
|
-
<meta name="geo.region" content="US-CA"/>
|
62
|
-
<meta name="microid" content="5abf847090c9afe2172e0efe6636ba2c86e3d60d"/>
|
63
|
-
<% if @page and File.exists?(csf=@page+'.css') %>
|
64
|
-
<link rel='stylesheet' href='/z/<%= csf %>' type='text/css' media='screen' />
|
65
|
-
<% end %>
|
66
|
-
</head>
|
67
|
-
<body id="<%= @page || 'default' %>">
|
68
|
-
<%= content %>
|
69
|
-
</body>
|
70
|
-
</html>
|
71
|
-
LAYOUT
|
72
|
-
::Erubis::Eruby.new(lyt).result(binding)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
class Index < Controller
|
76
|
-
MIME_MAP = SDKNet.
|
77
|
-
load_mime_map('mime.yaml')
|
78
|
-
set_routes %w~/ /:page~
|
79
|
-
def get
|
80
|
-
@page = @env[:route_info][:page] || 'home'
|
81
|
-
|
82
|
-
fns = Dir[File.join(Dir.pwd,@page)+'.*'].
|
83
|
-
delete_if{|e| File.basename(e)[/^\./] }.
|
84
|
-
select{|e| MIME_MAP.include?(File.extname(e)) }
|
85
|
-
|
86
|
-
if fn = fns.inject do |f,e| # going to hell for this code.
|
87
|
-
%w{.wiki .erb .html .htm .txt}.include?(File.extname(e)) ? e : f
|
88
|
-
end
|
89
|
-
content = File.read(fn)
|
90
|
-
content = ::Erubis::Eruby.new(content).
|
91
|
-
result(binding) if File.extname(fn)=='.erb'
|
92
|
-
render :standard, content
|
93
|
-
else
|
94
|
-
raise ::Maveric::ServerError, [404, 'Fucking drop bears.']
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
h = Mongrel::HttpServer.new("0.0.0.0", "9081")
|
101
|
-
h.register("/", Maveric::MongrelHandler.new(SDKNet))
|
102
|
-
Signal.trap('INT') do
|
103
|
-
puts "Shutting down server."
|
104
|
-
h.acceptor.raise Mongrel::StopServer
|
105
|
-
end
|
106
|
-
h.run.join
|
107
|
-
|
108
|
-
__END__
|
109
|
-
|
110
|
-
require 'ruby-prof'
|
111
|
-
result = RubyProf.profile { h.run.join }
|
112
|
-
RubyProf::GraphHtmlPrinter.new(result).
|
113
|
-
print(File.open('prof.html','w'), 0)
|