manveru-ramaze 2008.09 → 2008.10
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/examples/app/rapaste/model/paste.rb +3 -0
- data/examples/app/rapaste/start.rb +1 -1
- data/examples/app/rapaste/view/view.xhtml +3 -0
- data/examples/helpers/httpdigest.rb +68 -10
- data/lib/proto/controller/init.rb +2 -1
- data/lib/proto/model/init.rb +3 -3
- data/lib/proto/start.rb +4 -0
- data/lib/ramaze/adapter/base.rb +2 -2
- data/lib/ramaze/contrib.rb +1 -1
- data/lib/ramaze/controller/resolve.rb +8 -3
- data/lib/ramaze/controller.rb +3 -0
- data/lib/ramaze/current/request.rb +2 -4
- data/lib/ramaze/dispatcher/action.rb +2 -2
- data/lib/ramaze/dispatcher/file.rb +2 -1
- data/lib/ramaze/dispatcher.rb +1 -1
- data/lib/ramaze/helper/formatting.rb +1 -1
- data/lib/ramaze/helper/httpdigest.rb +64 -24
- data/lib/ramaze/helper/paginate.rb +2 -3
- data/lib/ramaze/helper/partial.rb +1 -1
- data/lib/ramaze/helper/user.rb +4 -4
- data/lib/ramaze/helper.rb +3 -2
- data/lib/ramaze/log/rotatinginformer.rb +168 -0
- data/lib/ramaze/option/holder.rb +3 -3
- data/lib/ramaze/snippets/divide.rb +2 -0
- data/lib/ramaze/snippets/numeric/time.rb +1 -1
- data/lib/ramaze/snippets/object/acquire.rb +3 -6
- data/lib/ramaze/snippets/ordered_set.rb +21 -14
- data/lib/ramaze/snippets/ramaze/deprecated.rb +2 -1
- data/lib/ramaze/tool/localize.rb +8 -4
- data/lib/ramaze/tool/mime.rb +1 -1
- data/lib/ramaze/tool/project_creator.rb +2 -1
- data/lib/ramaze/version.rb +1 -1
- data/lib/ramaze.rb +2 -0
- data/rake_tasks/coverage.rake +4 -5
- data/rake_tasks/spec.rake +6 -6
- data/ramaze.gemspec +2 -1
- data/spec/contrib/profiling.rb +2 -2
- metadata +3 -2
- data/lib/ramaze/contrib/auto_params/get_args.rb +0 -58
- data/lib/ramaze/contrib/auto_params.rb +0 -135
- data/spec/contrib/auto_params.rb +0 -121
- data/spec/snippets/divide.rb +0 -19
- data/spec/snippets/object/acquire.rb +0 -71
@@ -1,6 +1,9 @@
|
|
1
1
|
#{@pager}
|
2
2
|
<script type="text/javascript" src="/js/jquery.js"></script>
|
3
3
|
<script type="text/javascript">
|
4
|
+
$(function() {
|
5
|
+
$('#paste_body').dblclick(function(){ $('.line-numbers').toggle() });
|
6
|
+
});
|
4
7
|
function change_style(name){
|
5
8
|
$('link')[1].href = '/css/' + name + '.css';
|
6
9
|
$('pre')[0].className = name;
|
@@ -4,12 +4,61 @@ require 'ramaze'
|
|
4
4
|
REALM = 'ramaze authentication required'
|
5
5
|
|
6
6
|
class MainController < Ramaze::Controller
|
7
|
+
|
8
|
+
helper :httpdigest
|
9
|
+
|
7
10
|
def index
|
8
11
|
%|
|
12
|
+
<p><a href="#{Rs(:eyes_only)}">eyes only</a></p>
|
9
13
|
<p><a href="#{R(SecretController,'/')}">secret area</a></p>
|
10
|
-
<p><a href="#{R(GuestController,'/')}">guest area</a>
|
14
|
+
<p><a href="#{R(GuestController,'/')}">guest area</a> username is <em>guest</em> password is <em>access</em></p>
|
11
15
|
|
|
12
16
|
end
|
17
|
+
|
18
|
+
def eyes_only
|
19
|
+
httpdigest('eyes only',REALM) do |username|
|
20
|
+
password = username.reverse
|
21
|
+
MD5.hexdigest([username,REALM,password].join(':'))
|
22
|
+
end
|
23
|
+
"Shhhh don't tell anyone"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class LoginController < Ramaze::Controller
|
29
|
+
map '/login'
|
30
|
+
|
31
|
+
helper :httpdigest
|
32
|
+
|
33
|
+
def index
|
34
|
+
@username ||= session[:username]
|
35
|
+
@username ||= httpdigest('login area',REALM)
|
36
|
+
"Hi there #@username!"
|
37
|
+
end
|
38
|
+
|
39
|
+
def login
|
40
|
+
%|<form action="#{Rs(:post)}" method="post"><input type="text" name="username"/><input type="password" name="password"/><input type="submit"/></form>|
|
41
|
+
end
|
42
|
+
|
43
|
+
def post
|
44
|
+
username = request.params["username"]
|
45
|
+
password = request.params["password"]
|
46
|
+
if password == "entry"
|
47
|
+
session[:username] = username
|
48
|
+
destination = session[ :redirect_after_login ]
|
49
|
+
session.delete( :redirect_after_login )
|
50
|
+
redirect destination
|
51
|
+
end
|
52
|
+
redirect Rs(:login)
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def httpdigest_failure
|
58
|
+
session[ :redirect_after_login ] = Rs(Ramaze::Action.current.method)
|
59
|
+
redirect Rs(:login)
|
60
|
+
end
|
61
|
+
|
13
62
|
end
|
14
63
|
|
15
64
|
class SecretController < Ramaze::Controller
|
@@ -17,17 +66,22 @@ class SecretController < Ramaze::Controller
|
|
17
66
|
helper :aspect
|
18
67
|
helper :httpdigest
|
19
68
|
|
69
|
+
USERS = { 'admin' => 'secret', 'root' => 'password' }
|
70
|
+
|
20
71
|
before_all do
|
21
|
-
@username = httpdigest('secret area',REALM)
|
22
|
-
{ 'admin' => MD5.hexdigest("admin:#{REALM}:secret"),
|
23
|
-
'root' => MD5.hexdigest("root:#{REALM}:access"),
|
24
|
-
}[ username ]
|
25
|
-
end
|
72
|
+
@username = httpdigest('secret area',REALM)
|
26
73
|
end
|
27
74
|
|
28
75
|
def index
|
29
76
|
"Hello <em>#@username</em>, welcome to SECRET world"
|
30
77
|
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
def httpdigest_lookup_plaintext_password username
|
82
|
+
USERS[ username ]
|
83
|
+
end
|
84
|
+
|
31
85
|
end
|
32
86
|
|
33
87
|
class GuestController < Ramaze::Controller
|
@@ -36,15 +90,19 @@ class GuestController < Ramaze::Controller
|
|
36
90
|
helper :httpdigest
|
37
91
|
|
38
92
|
before_all do
|
39
|
-
@username = httpdigest('guest area',REALM)
|
40
|
-
username_used = username
|
41
|
-
MD5.hexdigest([username,REALM,username].join(':'))
|
42
|
-
end
|
93
|
+
@username = httpdigest('guest area',REALM)
|
43
94
|
end
|
44
95
|
|
45
96
|
def index
|
46
97
|
"Hello <em>#@username</em>, welcome to GUEST world."
|
47
98
|
end
|
99
|
+
|
100
|
+
protected
|
101
|
+
|
102
|
+
def httpdigest_lookup_password username
|
103
|
+
return "b71f15b2f6dd4834224fbe02169ed94c" if username == "guest"
|
104
|
+
end
|
105
|
+
|
48
106
|
end
|
49
107
|
|
50
108
|
Ramaze.start
|
data/lib/proto/model/init.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Here goes your database connection and options
|
1
|
+
# Here goes your database connection and options:
|
2
2
|
|
3
|
-
#
|
4
|
-
|
3
|
+
# Here go your requires for models:
|
4
|
+
# require 'model/user'
|
data/lib/proto/start.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'ramaze'
|
3
3
|
|
4
|
+
# Add directory start.rb is in to the load path, so you can run the app from
|
5
|
+
# any other working path
|
6
|
+
$LOAD_PATH.unshift(__DIR__)
|
7
|
+
|
4
8
|
# Initialize controllers and models
|
5
9
|
require 'controller/init'
|
6
10
|
require 'model/init'
|
data/lib/ramaze/adapter/base.rb
CHANGED
data/lib/ramaze/contrib.rb
CHANGED
@@ -49,7 +49,7 @@ module Ramaze
|
|
49
49
|
const.startup if const.respond_to?(:startup)
|
50
50
|
Log.dev "Loaded contrib: #{const}"
|
51
51
|
rescue NameError
|
52
|
-
files = Dir["{contrib,#{BASEDIR
|
52
|
+
files = Dir["{contrib,#{BASEDIR}/ramaze/contrib}/#{name}.{so,bundle,rb}"]
|
53
53
|
raise LoadError, "#{mod_name} not found" unless files.any?
|
54
54
|
require(files.first) ? retry : raise
|
55
55
|
end
|
@@ -136,10 +136,15 @@ module Ramaze
|
|
136
136
|
|
137
137
|
def resolve_template(path)
|
138
138
|
path = path.to_s
|
139
|
-
path_converted = path.split('__').inject{|s,v| s
|
139
|
+
path_converted = path.split('__').inject{|s,v| File.join(s, v) }
|
140
140
|
possible_paths = [path, path_converted].compact
|
141
141
|
|
142
|
-
paths = template_paths.map{|pa|
|
142
|
+
paths = template_paths.map{|pa|
|
143
|
+
possible_paths.map{|a|
|
144
|
+
File.join(pa, a)
|
145
|
+
}
|
146
|
+
}.flatten.uniq
|
147
|
+
|
143
148
|
glob = "{#{paths.join(',')}}.{#{extension_order.join(',')}}"
|
144
149
|
|
145
150
|
Dir[glob].first
|
@@ -153,7 +158,7 @@ module Ramaze
|
|
153
158
|
if paths = view_root
|
154
159
|
paths
|
155
160
|
else
|
156
|
-
view_root(Global.view_root
|
161
|
+
view_root(File.join(Global.view_root, Global.mapping.invert[self]))
|
157
162
|
end
|
158
163
|
end
|
159
164
|
|
data/lib/ramaze/controller.rb
CHANGED
@@ -71,9 +71,12 @@ module Ramaze
|
|
71
71
|
|
72
72
|
def mapping
|
73
73
|
global_mapping = Global.mapping.invert[self]
|
74
|
+
|
74
75
|
return global_mapping if global_mapping
|
76
|
+
|
75
77
|
if ancestral_trait[:automap] && self.to_s !~ /#<Class:/
|
76
78
|
name = self.to_s.gsub('Controller', '').gsub('::', '/').clone
|
79
|
+
return if name.empty?
|
77
80
|
name == 'Main' ? '/' : "/#{name.snake_case}"
|
78
81
|
end
|
79
82
|
end
|
@@ -59,10 +59,8 @@ module Ramaze
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def [](key, *rest)
|
62
|
-
|
63
|
-
|
64
|
-
keys = rest.flatten.map{|k| k.to_s}
|
65
|
-
Array[value, *params.values_at(*keys)]
|
62
|
+
return params[key.to_s] if rest.empty?
|
63
|
+
[key, *rest].map{|k| params[k.to_s] }
|
66
64
|
end
|
67
65
|
|
68
66
|
def to_ivs(*args)
|
@@ -11,9 +11,9 @@ module Ramaze
|
|
11
11
|
|
12
12
|
# The response is passed to each filter by sending .call(response) to it.
|
13
13
|
|
14
|
-
FILTER = OrderedSet
|
14
|
+
FILTER = OrderedSet[
|
15
15
|
# Ramaze::Tool::Localize,
|
16
|
-
|
16
|
+
] unless defined?(FILTER)
|
17
17
|
|
18
18
|
class << self
|
19
19
|
include Trinity
|
@@ -64,7 +64,8 @@ module Ramaze
|
|
64
64
|
joined = ::File.join(Global.public_root, path)
|
65
65
|
|
66
66
|
if ::File.directory?(joined)
|
67
|
-
|
67
|
+
glob = ::File.join(joined, "{#{INDICES.join(',')}}")
|
68
|
+
Dir[glob].first || joined
|
68
69
|
else
|
69
70
|
joined
|
70
71
|
end
|
data/lib/ramaze/dispatcher.rb
CHANGED
@@ -20,7 +20,7 @@ module Ramaze
|
|
20
20
|
end
|
21
21
|
|
22
22
|
# requests are passed to every
|
23
|
-
FILTER = OrderedSet[ Dispatcher::File, Dispatcher::Action
|
23
|
+
FILTER = OrderedSet[ Dispatcher::File, Dispatcher::Action ]
|
24
24
|
|
25
25
|
# Response codes to cache the output of for repeated requests.
|
26
26
|
trait :shielded => [ STATUS_CODE["Not Found"] ]
|
@@ -4,45 +4,85 @@ require 'md5'
|
|
4
4
|
module Ramaze
|
5
5
|
module Helper
|
6
6
|
module HttpDigest
|
7
|
+
|
8
|
+
UUID_GENERATOR = UUID.new
|
9
|
+
|
10
|
+
SESSION_NONCE = 'httpdigest_authentication_nonce'
|
11
|
+
SESSION_OPAQUE = 'httpdigest_authentication_opaque'
|
12
|
+
|
13
|
+
def httpdigest_logout
|
14
|
+
session.delete( SESSION_NONCE )
|
15
|
+
session.delete( SESSION_OPAQUE )
|
16
|
+
end
|
17
|
+
|
18
|
+
def httpdigest_headers uid, realm
|
19
|
+
session[ SESSION_NONCE ] = UUID_GENERATOR.generate
|
20
|
+
session[ SESSION_OPAQUE ][ realm ][ uid ] = UUID_GENERATOR.generate
|
21
|
+
response['WWW-Authenticate'] =
|
22
|
+
%|Digest realm="#{realm}",| +
|
23
|
+
%|qop="auth,auth-int",| +
|
24
|
+
%|nonce="#{session[SESSION_NONCE]}",| +
|
25
|
+
%|opaque="#{session[SESSION_OPAQUE][realm][uid]}"|
|
26
|
+
end
|
27
|
+
|
7
28
|
def httpdigest(uid, realm)
|
8
|
-
|
9
|
-
|
29
|
+
session[ SESSION_OPAQUE ] ||= {}
|
30
|
+
session[ SESSION_OPAQUE ][ realm ] ||= {}
|
31
|
+
|
32
|
+
if request.env['HTTP_AUTHORIZATION']
|
10
33
|
|
11
|
-
|
34
|
+
authorized = false
|
12
35
|
|
13
|
-
|
36
|
+
if session[ SESSION_NONCE ] and session[ SESSION_OPAQUE ][ realm ][ uid ]
|
14
37
|
|
15
|
-
|
38
|
+
auth_split = request.env['HTTP_AUTHORIZATION'].split
|
39
|
+
authentication_type = auth_split[0]
|
40
|
+
authorization = Rack::Auth::Digest::Params.parse( auth_split[1..-1].join(' ') )
|
16
41
|
|
17
|
-
|
18
|
-
|
19
|
-
authorization = Rack::Auth::Digest::Params.parse( auth_split[1..-1].join(' ') )
|
20
|
-
digest_response, username, nonce, nc, cnonce, qop =
|
21
|
-
authorization.values_at(*%w[response username nonce nc cnonce qop])
|
42
|
+
digest_response, username, nonce, nc, cnonce, qop, opaque =
|
43
|
+
authorization.values_at(*%w[response username nonce nc cnonce qop opaque])
|
22
44
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
45
|
+
if authentication_type == 'Digest'
|
46
|
+
if nonce == session[SESSION_NONCE] and opaque == session[SESSION_OPAQUE][realm][uid]
|
47
|
+
h1 = nil
|
48
|
+
if respond_to?( :httpdigest_lookup_password )
|
49
|
+
ha1 = httpdigest_lookup_password( username )
|
50
|
+
else
|
51
|
+
if respond_to?( :httpdigest_lookup_plaintext_password )
|
52
|
+
ha1 = MD5.hexdigest( "#{username}:#{realm}:#{httpdigest_lookup_plaintext_password( username )}" )
|
53
|
+
else
|
54
|
+
if block_given?
|
55
|
+
ha1 = yield( username )
|
56
|
+
else
|
57
|
+
raise "No password lookup handler found"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
ha2 = MD5.hexdigest([request.request_method,request.fullpath].join(':'))
|
62
|
+
md5 = MD5.hexdigest([ha1, nonce, nc, cnonce, qop, ha2].join(':'))
|
28
63
|
|
29
|
-
|
64
|
+
authorized = digest_response == md5
|
65
|
+
end
|
30
66
|
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
unless authorized
|
71
|
+
httpdigest_headers( uid, realm )
|
72
|
+
respond('Unauthorized', 401)
|
31
73
|
end
|
32
|
-
end
|
33
74
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
%|qop="auth,auth-int",| +
|
39
|
-
%|nonce="#{session[session_nonce]}",| +
|
40
|
-
%|opaque="#{session[session_opaque]}"|
|
75
|
+
else
|
76
|
+
|
77
|
+
httpdigest_headers( uid, realm )
|
78
|
+
httpdigest_failure if respond_to?( :httpdigest_failure )
|
41
79
|
respond('Unauthorized', 401)
|
80
|
+
|
42
81
|
end
|
43
82
|
|
44
83
|
authorization["username"]
|
45
84
|
end
|
85
|
+
|
46
86
|
end
|
47
87
|
end
|
48
88
|
end
|
@@ -165,9 +165,8 @@ module Ramaze
|
|
165
165
|
text = h(text.to_s)
|
166
166
|
|
167
167
|
params = Ramaze::Request.current.params.merge(@var.to_s => n)
|
168
|
-
name = Ramaze::
|
169
|
-
|
170
|
-
hash[:href] = Rs(name, params)
|
168
|
+
name = Ramaze::Request.current.request_path
|
169
|
+
hash[:href] = R(name, params)
|
171
170
|
|
172
171
|
g.a(hash){ text }
|
173
172
|
end
|
@@ -69,7 +69,7 @@ module Ramaze
|
|
69
69
|
else
|
70
70
|
roots = [options[:controller].template_paths].flatten
|
71
71
|
|
72
|
-
if (files = Dir["{#{roots.join(',')}}"
|
72
|
+
if (files = Dir[File.join("{#{roots.join(',')}}","{#{file},#{file}.*}")]).any?
|
73
73
|
options[:template] = files.first.squeeze '/'
|
74
74
|
else
|
75
75
|
Log.warn "render_template: #{file} does not exist in the following directories: #{roots.join(',')}."
|
data/lib/ramaze/helper/user.rb
CHANGED
@@ -8,10 +8,10 @@ module Ramaze
|
|
8
8
|
#
|
9
9
|
# class MainController < Ramaze::Controller
|
10
10
|
# def index
|
11
|
-
# if
|
12
|
-
# A('login', :href => Rs(:login))
|
13
|
-
# else
|
11
|
+
# if logged_in?
|
14
12
|
# "Hello #{user.name}"
|
13
|
+
# else
|
14
|
+
# A('login', :href => Rs(:login))
|
15
15
|
# end
|
16
16
|
# end
|
17
17
|
#
|
@@ -77,7 +77,7 @@ module Ramaze
|
|
77
77
|
elsif _model.respond_to?(:authenticate)
|
78
78
|
_model.authenticate(creds)
|
79
79
|
else
|
80
|
-
Log.warn("Helper::User has no callback and
|
80
|
+
Log.warn("Helper::User has no callback and there is no %p::authenticate" % _model)
|
81
81
|
nil
|
82
82
|
end
|
83
83
|
end
|
data/lib/ramaze/helper.rb
CHANGED
@@ -12,8 +12,9 @@ module Ramaze
|
|
12
12
|
module Helper
|
13
13
|
LOOKUP = Set.new
|
14
14
|
PATH = ['']
|
15
|
+
path = File.expand_path("#{BASEDIR}/../spec/ramaze/helper/")
|
15
16
|
trait :ignore => [
|
16
|
-
/#{Regexp.escape(
|
17
|
+
/#{Regexp.escape(path)}\//
|
17
18
|
]
|
18
19
|
|
19
20
|
module Methods
|
@@ -61,7 +62,7 @@ module Ramaze
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def require_helper(name)
|
64
|
-
paths = (PATH + [Global.root, BASEDIR
|
65
|
+
paths = (PATH + [Global.root, "#{BASEDIR}/ramaze"]).join(',')
|
65
66
|
glob = "{#{paths}}/helper/#{name}.{so,bundle,rb}"
|
66
67
|
files = Dir[glob]
|
67
68
|
ignore = Helper.trait[:ignore]
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module Ramaze
|
2
|
+
|
3
|
+
module Logger
|
4
|
+
|
5
|
+
# A customized logger (based on Informer) that creates multiple log files based on time
|
6
|
+
|
7
|
+
class RotatingInformer
|
8
|
+
|
9
|
+
include Logging
|
10
|
+
|
11
|
+
attr_accessor :time_format, :log_levels
|
12
|
+
attr_reader :base_dir
|
13
|
+
|
14
|
+
# parameter for Time.now.strftime
|
15
|
+
trait :timestamp => "%Y-%m-%d %H:%M:%S"
|
16
|
+
|
17
|
+
# This is how the final output is arranged.
|
18
|
+
trait :format => "[%time] %prefix %text"
|
19
|
+
|
20
|
+
# Create a new instance of RotatingInformer.
|
21
|
+
#
|
22
|
+
# base_dir is the directory where all log files will be stored
|
23
|
+
#
|
24
|
+
# time_format is the time format used to name the log files.
|
25
|
+
# Possible formats are identical to those
|
26
|
+
# accepted by Time.strftime
|
27
|
+
#
|
28
|
+
# log_levelse is an array describing what kind of messages
|
29
|
+
# that the log receives. The array may contain
|
30
|
+
# any or all of the symbols :debug, :error, :info and/or :warn
|
31
|
+
#
|
32
|
+
# Examples:
|
33
|
+
# RotatingInformer.new('logs')
|
34
|
+
# #=> Creates logs in directory called logs.
|
35
|
+
# The generated filenames will be in the
|
36
|
+
# form YYYY-MM-DD.log
|
37
|
+
# RotatingInformer.new('logs', '%Y-%m.txt')
|
38
|
+
# #=> Creates logs in directory called logs.
|
39
|
+
# The generated filenames will be in the
|
40
|
+
# form YYYY-MM.txt
|
41
|
+
# RotatingInformer.new('logs', '%Y-%m.txt', [:error])
|
42
|
+
# #=> Creates logs in directory called logs.
|
43
|
+
# The generated filenames will be in the
|
44
|
+
# form YYYY-MM.txt. Only errors will be
|
45
|
+
# logged to the files.
|
46
|
+
|
47
|
+
def initialize(base_dir, time_format = '%Y-%m-%d.log', log_levels = [:debug, :error, :info, :warn])
|
48
|
+
# Verify and set base directory
|
49
|
+
send :base_dir=, base_dir, true
|
50
|
+
|
51
|
+
@time_format = time_format
|
52
|
+
@log_levels = log_levels
|
53
|
+
|
54
|
+
# Keep track of log shutdown (to prevent StackErrors due to recursion)
|
55
|
+
@in_shutdown = false
|
56
|
+
end
|
57
|
+
|
58
|
+
# Set the base directory for log files
|
59
|
+
#
|
60
|
+
# If this method is called with the raise_exception
|
61
|
+
# parameter set to true the method will raise an exception
|
62
|
+
# if the specified directory does not exist or is unwritable.
|
63
|
+
#
|
64
|
+
# If raise_exception is set to false, the method will just
|
65
|
+
# silently fail if the specified directory does not exist
|
66
|
+
# or is unwritable
|
67
|
+
|
68
|
+
def base_dir=(directory, raise_exception = false)
|
69
|
+
# Expand directory path
|
70
|
+
base_dir = File.expand_path(directory)
|
71
|
+
# Verify that directory path exists
|
72
|
+
if File.exist?(base_dir)
|
73
|
+
# Verify that directory path is a directory
|
74
|
+
if File.directory?(base_dir)
|
75
|
+
# Verify that directory path is writable
|
76
|
+
if File.writable?(base_dir)
|
77
|
+
@base_dir = base_dir
|
78
|
+
else
|
79
|
+
raise Exception.new("#{base_dir} is not writable") if raise_exception
|
80
|
+
end
|
81
|
+
else
|
82
|
+
raise Exception.new("#{base_dir} is not a directory") if raise_exception
|
83
|
+
end
|
84
|
+
else
|
85
|
+
raise Exception.new("#{base_dir} does not exist.") if raise_exception
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Close the file we log to if it isn't closed already.
|
90
|
+
|
91
|
+
def shutdown
|
92
|
+
if @out.respond_to?(:close)
|
93
|
+
unless @in_shutdown
|
94
|
+
@in_shutdown = true
|
95
|
+
Log.debug("close, #{@out.inspect}")
|
96
|
+
@in_shutdown = false
|
97
|
+
end
|
98
|
+
@out.close
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Integration to Logging.
|
103
|
+
|
104
|
+
def log tag, *messages
|
105
|
+
|
106
|
+
return unless @log_levels.include?(tag)
|
107
|
+
|
108
|
+
# Update current log
|
109
|
+
update_current_log
|
110
|
+
|
111
|
+
messages.flatten!
|
112
|
+
|
113
|
+
prefix = tag.to_s.upcase.ljust(5)
|
114
|
+
|
115
|
+
messages.each do |message|
|
116
|
+
@out.puts(log_interpolate(prefix, message))
|
117
|
+
end
|
118
|
+
|
119
|
+
@out.flush if @out.respond_to?(:flush)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Takes the prefix (tag), text and timestamp and applies it to
|
123
|
+
# the :format trait.
|
124
|
+
|
125
|
+
def log_interpolate prefix, text, time = timestamp
|
126
|
+
message = class_trait[:format].dup
|
127
|
+
|
128
|
+
vars = { '%time' => time, '%prefix' => prefix, '%text' => text }
|
129
|
+
vars.each{|from, to| message.gsub!(from, to) }
|
130
|
+
|
131
|
+
message
|
132
|
+
end
|
133
|
+
|
134
|
+
# This uses Global.inform_timestamp or a date in the format of
|
135
|
+
# %Y-%m-%d %H:%M:%S
|
136
|
+
# # => "2007-01-19 21:09:32"
|
137
|
+
|
138
|
+
def timestamp
|
139
|
+
mask = class_trait[:timestamp]
|
140
|
+
Time.now.strftime(mask || "%Y-%m-%d %H:%M:%S")
|
141
|
+
end
|
142
|
+
|
143
|
+
# is @out closed?
|
144
|
+
|
145
|
+
def closed?
|
146
|
+
@out.respond_to?(:closed?) && @out.closed?
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
# Checks whether current filename is still valid.
|
152
|
+
# If not, update the current log to point at the new
|
153
|
+
# filename
|
154
|
+
|
155
|
+
def update_current_log
|
156
|
+
out = File.join(@base_dir, Time.now.strftime(@time_format))
|
157
|
+
if @out.nil? || @out.path != out
|
158
|
+
# Close old log if necessary
|
159
|
+
shutdown unless @out.nil? || closed?
|
160
|
+
|
161
|
+
# Start new log
|
162
|
+
@out = File.open(out, 'ab+')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
data/lib/ramaze/option/holder.rb
CHANGED
@@ -78,7 +78,7 @@ module Ramaze
|
|
78
78
|
# currently set one.
|
79
79
|
def public_root
|
80
80
|
[ @public_root,
|
81
|
-
root
|
81
|
+
File.join(root, @public_root)
|
82
82
|
].find{|path| File.directory?(path) } || @public_root
|
83
83
|
end
|
84
84
|
|
@@ -90,8 +90,8 @@ module Ramaze
|
|
90
90
|
# the currently set one.
|
91
91
|
def view_root
|
92
92
|
[ @view_root,
|
93
|
-
root
|
94
|
-
root
|
93
|
+
File.join(root, @view_root),
|
94
|
+
File.join(root, 'template'),
|
95
95
|
].find{|path| File.directory?(path) } || @view_root
|
96
96
|
end
|
97
97
|
|