maveric 0.1.0 → 0.2.0
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/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)
|