kiss 1.1 → 1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/LICENSE +1 -1
  2. data/Rakefile +2 -1
  3. data/VERSION +1 -1
  4. data/bin/kiss +151 -34
  5. data/data/scaffold.tgz +0 -0
  6. data/lib/kiss.rb +389 -742
  7. data/lib/kiss/accessors/controller.rb +47 -0
  8. data/lib/kiss/accessors/request.rb +106 -0
  9. data/lib/kiss/accessors/template.rb +23 -0
  10. data/lib/kiss/action.rb +502 -132
  11. data/lib/kiss/bench.rb +14 -5
  12. data/lib/kiss/debug.rb +14 -6
  13. data/lib/kiss/exception_report.rb +22 -299
  14. data/lib/kiss/ext/core.rb +700 -0
  15. data/lib/kiss/ext/rack.rb +33 -0
  16. data/lib/kiss/ext/sequel_database.rb +47 -0
  17. data/lib/kiss/ext/sequel_mysql_dataset.rb +23 -0
  18. data/lib/kiss/form.rb +404 -179
  19. data/lib/kiss/form/field.rb +183 -307
  20. data/lib/kiss/form/field_types.rb +239 -0
  21. data/lib/kiss/format.rb +88 -70
  22. data/lib/kiss/html/exception_report.css +222 -0
  23. data/lib/kiss/html/exception_report.html +210 -0
  24. data/lib/kiss/iterator.rb +14 -12
  25. data/lib/kiss/login.rb +8 -8
  26. data/lib/kiss/mailer.rb +68 -66
  27. data/lib/kiss/model.rb +323 -36
  28. data/lib/kiss/rack/bench.rb +16 -8
  29. data/lib/kiss/rack/email_errors.rb +25 -15
  30. data/lib/kiss/rack/errors_ok.rb +2 -2
  31. data/lib/kiss/rack/facebook.rb +6 -6
  32. data/lib/kiss/rack/file_not_found.rb +10 -8
  33. data/lib/kiss/rack/log_exceptions.rb +3 -3
  34. data/lib/kiss/rack/recorder.rb +2 -2
  35. data/lib/kiss/rack/show_debug.rb +2 -2
  36. data/lib/kiss/rack/show_exceptions.rb +2 -2
  37. data/lib/kiss/request.rb +435 -0
  38. data/lib/kiss/sequel_session.rb +15 -14
  39. data/lib/kiss/static_file.rb +20 -13
  40. data/lib/kiss/template.rb +327 -0
  41. metadata +60 -25
  42. data/lib/kiss/controller_accessors.rb +0 -81
  43. data/lib/kiss/hacks.rb +0 -188
  44. data/lib/kiss/sequel_mysql.rb +0 -25
  45. 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>
@@ -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
- attr_reader :index, :collection
5
+ _attr_reader :index, :collection
6
6
 
7
7
  # Creates a new loop iterator.
8
8
  def initialize(collection = nil)
9
- @collection = collection
10
- @index = -1
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
- @index + 1
15
+ @_index + 1
16
16
  end
17
17
 
18
18
  # Returns true if this is loop's first iteration.
19
- def first
20
- @index == 0
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
- @collection ? @collection[index-1] : nil
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
- @collection ? @collection[index+1] : nil
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
- @collection ? @collection.size-1 : nil
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
- @collection ? @collection.size : nil
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
- @index = @index + 1
55
+ @_index = @_index + 1
54
56
  end
55
57
  end
56
58
  end