kiss 1.1 → 1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/bin/kiss +151 -34
- data/data/scaffold.tgz +0 -0
- data/lib/kiss.rb +389 -742
- data/lib/kiss/accessors/controller.rb +47 -0
- data/lib/kiss/accessors/request.rb +106 -0
- data/lib/kiss/accessors/template.rb +23 -0
- data/lib/kiss/action.rb +502 -132
- data/lib/kiss/bench.rb +14 -5
- data/lib/kiss/debug.rb +14 -6
- data/lib/kiss/exception_report.rb +22 -299
- data/lib/kiss/ext/core.rb +700 -0
- data/lib/kiss/ext/rack.rb +33 -0
- data/lib/kiss/ext/sequel_database.rb +47 -0
- data/lib/kiss/ext/sequel_mysql_dataset.rb +23 -0
- data/lib/kiss/form.rb +404 -179
- data/lib/kiss/form/field.rb +183 -307
- data/lib/kiss/form/field_types.rb +239 -0
- data/lib/kiss/format.rb +88 -70
- data/lib/kiss/html/exception_report.css +222 -0
- data/lib/kiss/html/exception_report.html +210 -0
- data/lib/kiss/iterator.rb +14 -12
- data/lib/kiss/login.rb +8 -8
- data/lib/kiss/mailer.rb +68 -66
- data/lib/kiss/model.rb +323 -36
- data/lib/kiss/rack/bench.rb +16 -8
- data/lib/kiss/rack/email_errors.rb +25 -15
- data/lib/kiss/rack/errors_ok.rb +2 -2
- data/lib/kiss/rack/facebook.rb +6 -6
- data/lib/kiss/rack/file_not_found.rb +10 -8
- data/lib/kiss/rack/log_exceptions.rb +3 -3
- data/lib/kiss/rack/recorder.rb +2 -2
- data/lib/kiss/rack/show_debug.rb +2 -2
- data/lib/kiss/rack/show_exceptions.rb +2 -2
- data/lib/kiss/request.rb +435 -0
- data/lib/kiss/sequel_session.rb +15 -14
- data/lib/kiss/static_file.rb +20 -13
- data/lib/kiss/template.rb +327 -0
- metadata +60 -25
- data/lib/kiss/controller_accessors.rb +0 -81
- data/lib/kiss/hacks.rb +0 -188
- data/lib/kiss/sequel_mysql.rb +0 -25
- data/lib/kiss/template_methods.rb +0 -167
@@ -0,0 +1,222 @@
|
|
1
|
+
body {
|
2
|
+
margin: 0;
|
3
|
+
}
|
4
|
+
#container {
|
5
|
+
font-size: 12px;
|
6
|
+
padding: 8px;
|
7
|
+
background-color: #611;
|
8
|
+
}
|
9
|
+
#container * {
|
10
|
+
padding: 12px;
|
11
|
+
}
|
12
|
+
#container * * {
|
13
|
+
padding: 0;
|
14
|
+
}
|
15
|
+
#container {
|
16
|
+
font: small sans-serif;
|
17
|
+
}
|
18
|
+
#container > div {
|
19
|
+
border-bottom: 1px solid #cba;
|
20
|
+
}
|
21
|
+
a {
|
22
|
+
color: #b00;
|
23
|
+
}
|
24
|
+
code {
|
25
|
+
white-space: pre-wrap;
|
26
|
+
}
|
27
|
+
h1 {
|
28
|
+
margin: 0;
|
29
|
+
}
|
30
|
+
h2 {
|
31
|
+
font-size: 16px;
|
32
|
+
margin: 0 0 .8em 0;
|
33
|
+
}
|
34
|
+
h2 span {
|
35
|
+
font-size: 80%;
|
36
|
+
color: #000;
|
37
|
+
font-weight: normal;
|
38
|
+
}
|
39
|
+
h3 {
|
40
|
+
margin: 1em 0 .5em 0;
|
41
|
+
}
|
42
|
+
h4 {
|
43
|
+
margin: 0 0 .5em 0;
|
44
|
+
font-weight: normal;
|
45
|
+
}
|
46
|
+
small {
|
47
|
+
color: #444;
|
48
|
+
}
|
49
|
+
table {
|
50
|
+
border: 1px solid #ccc;
|
51
|
+
border-collapse: collapse;
|
52
|
+
background: white;
|
53
|
+
}
|
54
|
+
tbody td, tbody th {
|
55
|
+
vertical-align: top;
|
56
|
+
padding: 2px 3px;
|
57
|
+
}
|
58
|
+
thead th {
|
59
|
+
padding: 1px 6px 1px 3px;
|
60
|
+
background: #fefefe;
|
61
|
+
text-align: left;
|
62
|
+
font-weight: normal;
|
63
|
+
font-size: 9px;
|
64
|
+
border: 1px solid #ddd;
|
65
|
+
}
|
66
|
+
tbody th {
|
67
|
+
text-align: right;
|
68
|
+
padding-right: .5em;
|
69
|
+
}
|
70
|
+
table.vars {
|
71
|
+
margin: 5px 0 2px 40px;
|
72
|
+
}
|
73
|
+
table.vars td, table.req td {
|
74
|
+
font-family: monospace;
|
75
|
+
}
|
76
|
+
table td.code {
|
77
|
+
width: 100%;
|
78
|
+
}
|
79
|
+
table td.code div {
|
80
|
+
overflow: hidden;
|
81
|
+
}
|
82
|
+
table.source th {
|
83
|
+
color: #666;
|
84
|
+
}
|
85
|
+
table.source td {
|
86
|
+
font-family: monospace;
|
87
|
+
white-space: pre;
|
88
|
+
border-bottom: 1px solid #eee;
|
89
|
+
}
|
90
|
+
ul.traceback {
|
91
|
+
list-style-type: none;
|
92
|
+
}
|
93
|
+
ul.traceback li.frame {
|
94
|
+
padding: 8px 4px;
|
95
|
+
border-top: 1px solid #ccc;
|
96
|
+
}
|
97
|
+
div.context {
|
98
|
+
margin: 6px 0 2px 40px;
|
99
|
+
background-color: #fff;
|
100
|
+
}
|
101
|
+
div.context ol {
|
102
|
+
padding: 1px;
|
103
|
+
margin-bottom: -1px;
|
104
|
+
}
|
105
|
+
div.context ol li {
|
106
|
+
font-family: monospace;
|
107
|
+
white-space: pre-wrap;
|
108
|
+
color: #666;
|
109
|
+
cursor: pointer;
|
110
|
+
padding: 0 2px;
|
111
|
+
}
|
112
|
+
div.context ol.context-line li {
|
113
|
+
color: black;
|
114
|
+
background-color: #eca;
|
115
|
+
}
|
116
|
+
div.context ol.context-line li span {
|
117
|
+
float: right;
|
118
|
+
}
|
119
|
+
div.commands {
|
120
|
+
margin-left: 40px;
|
121
|
+
}
|
122
|
+
div.commands a {
|
123
|
+
color: black;
|
124
|
+
text-decoration: none;
|
125
|
+
}
|
126
|
+
#masthead {
|
127
|
+
background-color: #af1111;
|
128
|
+
border-top: 1px solid #d77;
|
129
|
+
padding: 3px 12px 6px 12px;
|
130
|
+
|
131
|
+
font-family: georgia,'times new roman','times',serif;
|
132
|
+
font-weight: normal;
|
133
|
+
font-size: 18px;
|
134
|
+
letter-spacing: -1px;
|
135
|
+
color: #fdc;
|
136
|
+
}
|
137
|
+
#masthead .kiss {
|
138
|
+
color: #fff;
|
139
|
+
font-size: 24px;
|
140
|
+
padding-right: 3px;
|
141
|
+
}
|
142
|
+
#summary {
|
143
|
+
background-color: #fdfbee;
|
144
|
+
}
|
145
|
+
#summary h1 {
|
146
|
+
font-size: 18px;
|
147
|
+
font-weight: normal;
|
148
|
+
font-style: italic;
|
149
|
+
color: #c65;
|
150
|
+
}
|
151
|
+
#summary h2 {
|
152
|
+
font-size: 14px;
|
153
|
+
font-weight: bold;
|
154
|
+
color: #b21;
|
155
|
+
}
|
156
|
+
#summary ul#quicklinks {
|
157
|
+
list-style-type: none;
|
158
|
+
margin: 0 -8px 2em -8px;
|
159
|
+
font-size: 12px
|
160
|
+
}
|
161
|
+
#summary ul#quicklinks li {
|
162
|
+
float: left;
|
163
|
+
padding: 0 8px;
|
164
|
+
}
|
165
|
+
#summary ul#quicklinks>li+li {
|
166
|
+
border-left: 1px #999 solid;
|
167
|
+
}
|
168
|
+
#summary .info td {
|
169
|
+
padding-top: 4px;
|
170
|
+
}
|
171
|
+
#summary .info th {
|
172
|
+
padding: 5px 7px 0 0;
|
173
|
+
font-size: 11px;
|
174
|
+
color: #444;
|
175
|
+
}
|
176
|
+
#template, #template-not-exist {
|
177
|
+
background: #f6f6f6;
|
178
|
+
}
|
179
|
+
#template-not-exist ul {
|
180
|
+
margin: 0 0 0 20px;
|
181
|
+
}
|
182
|
+
#traceback {
|
183
|
+
background: #fff6e0;
|
184
|
+
}
|
185
|
+
#traceback .frame {
|
186
|
+
padding: 6px 0;
|
187
|
+
}
|
188
|
+
#requestinfo {
|
189
|
+
background: #f9ebd4;
|
190
|
+
padding-left: 120px;
|
191
|
+
border: none;
|
192
|
+
}
|
193
|
+
#requestinfo p {
|
194
|
+
margin: 0;
|
195
|
+
}
|
196
|
+
#summary table {
|
197
|
+
border: none;
|
198
|
+
background: transparent;
|
199
|
+
}
|
200
|
+
#requestinfo h2, #requestinfo h3 {
|
201
|
+
position: relative;
|
202
|
+
left: -100px;
|
203
|
+
}
|
204
|
+
#requestinfo h3 {
|
205
|
+
width: 100px;
|
206
|
+
margin-right: -100px;
|
207
|
+
margin-bottom: -1.1em;
|
208
|
+
}
|
209
|
+
#explanation {
|
210
|
+
background: #c11;
|
211
|
+
color: #fed;
|
212
|
+
border-top: 1px solid #e77;
|
213
|
+
border-bottom-color: #711;
|
214
|
+
padding: 6px 12px;
|
215
|
+
}
|
216
|
+
.error {
|
217
|
+
background: #ffc;
|
218
|
+
}
|
219
|
+
.specific {
|
220
|
+
color: #cc3300;
|
221
|
+
font-weight: bold;
|
222
|
+
}
|
@@ -0,0 +1,210 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
2
|
+
|
3
|
+
<!--
|
4
|
+
# adapted from Rack::ShowExceptions
|
5
|
+
# Used under the MIT license
|
6
|
+
#
|
7
|
+
# adapted from Django <djangoproject.com>
|
8
|
+
# Copyright (c) 2005, the Lawrence Journal-World
|
9
|
+
# Used under the modified BSD license:
|
10
|
+
# http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
|
11
|
+
-->
|
12
|
+
|
13
|
+
<html lang="en">
|
14
|
+
<head>
|
15
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
16
|
+
<meta name="robots" content="NONE,NOARCHIVE" />
|
17
|
+
<title>Exception: <%=h exception.class %> - <%=h url %></title>
|
18
|
+
<meta http-equiv="exception-message" content="<%= (h exception.message).gsub(/\n/,' ') %>" />
|
19
|
+
<meta http-equiv="exception-where" content="<%= (h frames.first.filename) %>: in <%= h frames.first.function %>, line <%= h frames.first.lineno %>" />
|
20
|
+
<style type="text/css">
|
21
|
+
<%= File.read(template_dir + '/exception_report.css') %>
|
22
|
+
</style>
|
23
|
+
<script type="text/javascript">
|
24
|
+
//<!--
|
25
|
+
function toggle(object_id) {
|
26
|
+
var pre = document.getElementById('pre' + object_id);
|
27
|
+
document.getElementById('post' + object_id).style.display = pre.style.display =
|
28
|
+
pre.style.display == 'none' ? 'block' : 'none';
|
29
|
+
return false;
|
30
|
+
}
|
31
|
+
//-->
|
32
|
+
</script>
|
33
|
+
</head>
|
34
|
+
<body>
|
35
|
+
<div id="container">
|
36
|
+
<div id="masthead">
|
37
|
+
<span class="kiss">Kiss</span>
|
38
|
+
Exception Report
|
39
|
+
</div>
|
40
|
+
<div id="summary">
|
41
|
+
<a name="summary"></a>
|
42
|
+
<h1><%=h exception.class %></h1>
|
43
|
+
<h2><code><%=(h exception.message).gsub(/\n/,'<br>') %></code></h2>
|
44
|
+
<% if env %>
|
45
|
+
<table class="info"><tr>
|
46
|
+
<th>Where</th>
|
47
|
+
<td><code><%=h frames.first.filename %></code>: in <code><%=h frames.first.function %></code>, <a href="<%= textmate_href(frames.first) %>">line <%=h frames.first.lineno %></a></td>
|
48
|
+
</tr><tr>
|
49
|
+
<th><%=h req.request_method %> URL</th>
|
50
|
+
<td><code><%= h(url + (env['rack.request.query_string'] ? "?#{env['rack.request.query_string']}" : '')) %></code></td>
|
51
|
+
</tr><tr>
|
52
|
+
<th>Referer</th>
|
53
|
+
<td><code><%=h env['HTTP_REFERER'] || 'None' %></code></td>
|
54
|
+
</tr><tr>
|
55
|
+
<th>Context</th>
|
56
|
+
<td><ul id="quicklinks">
|
57
|
+
<li><a href="#get-info">GET</a></li>
|
58
|
+
<li><a href="#post-info">POST</a></li>
|
59
|
+
<li><a href="#cache">Cache</a></li>
|
60
|
+
<li><a href="#last-sql">Last SQL</a></li>
|
61
|
+
<li><a href="#cookie-info">Cookies</a></li>
|
62
|
+
<li><a href="#env-info">ENV</a></li>
|
63
|
+
</ul></td>
|
64
|
+
</tr></table>
|
65
|
+
<% end %>
|
66
|
+
</div>
|
67
|
+
|
68
|
+
<div id="traceback">
|
69
|
+
<h2>Traceback <span>(innermost first)</span></h2>
|
70
|
+
<ul class="traceback">
|
71
|
+
<% frames.each { |frame| %>
|
72
|
+
<li class="frame">
|
73
|
+
<a href="<%= textmate_href(frame) %>">line <%= h frame.lineno %></a> of <code><%=w h frame.filename %></code> (in <code><b><%=h frame.function %></b></code>)
|
74
|
+
|
75
|
+
<% if frame.context_line %>
|
76
|
+
<div class="context" id="c<%=h frame.object_id %>">
|
77
|
+
<% if frame.pre_context %>
|
78
|
+
<ol start="<%=h frame.pre_context_lineno+1 %>" class="pre-context" id="pre<%=h frame.object_id %>"<% unless frame == toggle_frame %> style="display: none"<% end %>>
|
79
|
+
<% frame.pre_context.each { |line| %>
|
80
|
+
<li onclick="toggle(<%=h frame.object_id %>)"><%=h line %></li>
|
81
|
+
<% } %>
|
82
|
+
</ol>
|
83
|
+
<% end %>
|
84
|
+
|
85
|
+
<ol start="<%=h frame.lineno %>" class="context-line">
|
86
|
+
<li onclick="toggle(<%=h frame.object_id %>)"><%=h frame.context_line %></li></ol>
|
87
|
+
|
88
|
+
<% if frame.post_context %>
|
89
|
+
<ol start='<%=h frame.lineno+1 %>' class="post-context" id="post<%=h frame.object_id %>"<% unless frame == toggle_frame %> style="display: none"<% end %>>
|
90
|
+
<% frame.post_context.each { |line| %>
|
91
|
+
<li onclick="toggle(<%=h frame.object_id %>)"><%=h line %></li>
|
92
|
+
<% } %>
|
93
|
+
</ol>
|
94
|
+
<% end %>
|
95
|
+
</div>
|
96
|
+
<% end %>
|
97
|
+
</li>
|
98
|
+
<% } %>
|
99
|
+
</ul>
|
100
|
+
</div>
|
101
|
+
|
102
|
+
<% if env %>
|
103
|
+
<div id="requestinfo">
|
104
|
+
<h2>Additional information</h2>
|
105
|
+
|
106
|
+
<a name="get-info"></a>
|
107
|
+
<h3 id="get-info">GET</h3>
|
108
|
+
<% unless req.GET.empty? %>
|
109
|
+
<table class="req">
|
110
|
+
<thead>
|
111
|
+
<tr>
|
112
|
+
<th>Variable</th>
|
113
|
+
<th>Value</th>
|
114
|
+
</tr>
|
115
|
+
</thead>
|
116
|
+
<tbody>
|
117
|
+
<% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
|
118
|
+
<tr>
|
119
|
+
<td><%=h key %></td>
|
120
|
+
<td class="code"><div><%=h val.inspect %></div></td>
|
121
|
+
</tr>
|
122
|
+
<% } %>
|
123
|
+
</tbody>
|
124
|
+
</table>
|
125
|
+
<% else %>
|
126
|
+
<p>No GET data.</p>
|
127
|
+
<% end %>
|
128
|
+
|
129
|
+
<a name="post-info"></a>
|
130
|
+
<h3 id="post-info">POST</h3>
|
131
|
+
<% unless req.POST.empty? %>
|
132
|
+
<table class="req">
|
133
|
+
<thead>
|
134
|
+
<tr>
|
135
|
+
<th>Variable</th>
|
136
|
+
<th>Value</th>
|
137
|
+
</tr>
|
138
|
+
</thead>
|
139
|
+
<tbody>
|
140
|
+
<% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
|
141
|
+
<tr>
|
142
|
+
<td><%=h key %></td>
|
143
|
+
<td class="code"><div><%=h val.inspect %></div></td>
|
144
|
+
</tr>
|
145
|
+
<% } %>
|
146
|
+
</tbody>
|
147
|
+
</table>
|
148
|
+
<% else %>
|
149
|
+
<p>No POST data.</p>
|
150
|
+
<% end %>
|
151
|
+
|
152
|
+
<a name="cache"></a>
|
153
|
+
<h3 id="cache">Cache</h3>
|
154
|
+
<p><code><%=h cache.inspect %></code></p>
|
155
|
+
|
156
|
+
<a name="last-sql"></a>
|
157
|
+
<h3 id="last-sql">Last SQL</h3>
|
158
|
+
<p><% if sql %><code><%=(h sql).gsub(/\n/,'<br/>') %></code><% else %>n/a<% end %></p>
|
159
|
+
|
160
|
+
<a name="cookie-info"></a>
|
161
|
+
<h3 id="cookie-info">Cookies</h3>
|
162
|
+
<% unless req.cookies.empty? %>
|
163
|
+
<table class="req">
|
164
|
+
<thead>
|
165
|
+
<tr>
|
166
|
+
<th>Variable</th>
|
167
|
+
<th>Value</th>
|
168
|
+
</tr>
|
169
|
+
</thead>
|
170
|
+
<tbody>
|
171
|
+
<% req.cookies.each { |key, val| %>
|
172
|
+
<tr>
|
173
|
+
<td><%=h key %></td>
|
174
|
+
<td class="code"><div><%=h val.inspect %></div></td>
|
175
|
+
</tr>
|
176
|
+
<% } %>
|
177
|
+
</tbody>
|
178
|
+
</table>
|
179
|
+
<% else %>
|
180
|
+
<p>No cookie data.</p>
|
181
|
+
<% end %>
|
182
|
+
|
183
|
+
<a name="env-info"></a>
|
184
|
+
<h3 id="env-info">Rack ENV</h3>
|
185
|
+
<table class="req">
|
186
|
+
<thead>
|
187
|
+
<tr>
|
188
|
+
<th>Variable</th>
|
189
|
+
<th>Value</th>
|
190
|
+
</tr>
|
191
|
+
</thead>
|
192
|
+
<tbody>
|
193
|
+
<% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
|
194
|
+
<tr>
|
195
|
+
<td><%=h key %></td>
|
196
|
+
<td class="code"><div><%=w h val %></div></td>
|
197
|
+
</tr>
|
198
|
+
<% } %>
|
199
|
+
</tbody>
|
200
|
+
</table>
|
201
|
+
|
202
|
+
</div>
|
203
|
+
<% end %>
|
204
|
+
|
205
|
+
<div id="explanation">
|
206
|
+
Generated at <%= Time.now.hm_mdy_full %> (<%= Time.now.zone %>).
|
207
|
+
</div>
|
208
|
+
</div>
|
209
|
+
</body>
|
210
|
+
</html>
|
data/lib/kiss/iterator.rb
CHANGED
@@ -2,55 +2,57 @@ class Kiss
|
|
2
2
|
# Enables `loop' features for certain template loops (while, for...in).
|
3
3
|
# Similar to features of Perl's Template::Iterator by Andy Wardley.
|
4
4
|
class Iterator
|
5
|
-
|
5
|
+
_attr_reader :index, :collection
|
6
6
|
|
7
7
|
# Creates a new loop iterator.
|
8
8
|
def initialize(collection = nil)
|
9
|
-
@
|
10
|
-
@
|
9
|
+
@_collection = collection
|
10
|
+
@_index = -1
|
11
11
|
end
|
12
12
|
|
13
13
|
# Return current iteration number, indexed from one instead of zero.
|
14
14
|
def count
|
15
|
-
@
|
15
|
+
@_index + 1
|
16
16
|
end
|
17
17
|
|
18
18
|
# Returns true if this is loop's first iteration.
|
19
|
-
def first
|
20
|
-
@
|
19
|
+
def first?
|
20
|
+
@_index == 0
|
21
21
|
end
|
22
|
+
alias_method :first, :first?
|
22
23
|
|
23
24
|
# Returns true if this is the last iteration of a
|
24
25
|
# loop over a collection.
|
25
|
-
def last
|
26
|
+
def last?
|
26
27
|
count == size
|
27
28
|
end
|
29
|
+
alias_method :last, :last?
|
28
30
|
|
29
31
|
# Return previous item in loop-iterated collection.
|
30
32
|
def prev
|
31
|
-
@
|
33
|
+
@_collection ? @_collection[index-1] : nil
|
32
34
|
end
|
33
35
|
|
34
36
|
# Return next item in loop-iterated collection.
|
35
37
|
def next
|
36
|
-
@
|
38
|
+
@_collection ? @_collection[index+1] : nil
|
37
39
|
end
|
38
40
|
|
39
41
|
# Returns index of loop's last iteration.
|
40
42
|
def max
|
41
|
-
@
|
43
|
+
@_collection ? @_collection.size-1 : nil
|
42
44
|
end
|
43
45
|
|
44
46
|
# Returns number of iterations in loop over a collection
|
45
47
|
# (size of the iterated collection).
|
46
48
|
def size
|
47
|
-
@
|
49
|
+
@_collection ? @_collection.size : nil
|
48
50
|
end
|
49
51
|
|
50
52
|
# Used by template erubis pre-processing voodoo to advance
|
51
53
|
# the iterator index. Not intended for any other use.
|
52
54
|
def increment
|
53
|
-
@
|
55
|
+
@_index = @_index + 1
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|