kiss 1.1 → 1.7

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.
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