picnic 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +10 -0
- data/Manifest.txt +27 -27
- data/lib/picnic.rb +1 -1
- data/lib/picnic/cli.rb +2 -0
- data/lib/picnic/conf.rb +30 -6
- data/lib/picnic/server.rb +18 -21
- data/lib/picnic/version.rb +1 -1
- data/picnic.gemspec +3 -3
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/CHANGELOG +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/COPYING +0 -0
- data/vendor/zuk-camping-2.0.20090429/README +82 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/Rakefile +9 -3
- data/vendor/zuk-camping-2.0.20090429/bin/camping +97 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/doc/camping.1.gz +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/examples/README +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/examples/blog.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/examples/campsh.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/examples/tepee.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/extras/Camping.gif +0 -0
- data/vendor/zuk-camping-2.0.20090429/extras/flipbook.rb +357 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/extras/permalink.gif +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/lib/camping-unabridged.rb +53 -61
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/lib/camping.rb +23 -25
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/lib/camping/ar.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/lib/camping/ar/session.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/lib/camping/mab.rb +0 -0
- data/vendor/zuk-camping-2.0.20090429/lib/camping/reloader.rb +188 -0
- data/vendor/zuk-camping-2.0.20090429/lib/camping/server.rb +159 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/lib/camping/session.rb +1 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/setup.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/test/apps/env_debug.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/test/apps/forms.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/test/apps/misc.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/test/apps/sessions.rb +0 -0
- data/vendor/{camping-2.0.20090212 → zuk-camping-2.0.20090429}/test/test_camping.rb +0 -0
- metadata +29 -29
- data/vendor/camping-2.0.20090212/README +0 -119
- data/vendor/camping-2.0.20090212/bin/camping +0 -99
- data/vendor/camping-2.0.20090212/extras/flipbook_rdoc.rb +0 -491
- data/vendor/camping-2.0.20090212/lib/camping/reloader.rb +0 -163
- data/vendor/camping-2.0.20090212/lib/camping/server.rb +0 -158
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,357 @@
|
|
1
|
+
CAMPING_EXTRAS_DIR = File.expand_path(File.dirname(__FILE__))
|
2
|
+
require 'rdoc/generator/html'
|
3
|
+
|
4
|
+
module RDoc::Generator
|
5
|
+
[Class, File].each do |klass|
|
6
|
+
old = klass.instance_method(:value_hash)
|
7
|
+
klass.send(:define_method, :value_hash) {
|
8
|
+
old.bind(self).call
|
9
|
+
@values['root'] = @path.split("/").map { ".." }[1..-1].join("/")
|
10
|
+
@values
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
module HTML::FLIPBOOK
|
15
|
+
######################################################################
|
16
|
+
#
|
17
|
+
# The following is used for the -1 option
|
18
|
+
#
|
19
|
+
|
20
|
+
FONTS = "verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif"
|
21
|
+
|
22
|
+
STYLE = %{
|
23
|
+
body, th, td {
|
24
|
+
font: normal 14px verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif;
|
25
|
+
line-height: 160%;
|
26
|
+
padding: 0; margin: 0;
|
27
|
+
margin-bottom: 30px;
|
28
|
+
/* background-color: #402; */
|
29
|
+
background-color: #694;
|
30
|
+
}
|
31
|
+
h1, h2, h3, h4 {
|
32
|
+
font-family: Utopia, Georgia, serif;
|
33
|
+
font-weight: bold;
|
34
|
+
letter-spacing: -0.018em;
|
35
|
+
}
|
36
|
+
h1 { font-size: 24px; margin: .15em 1em 0 0 }
|
37
|
+
h2 { font-size: 24px }
|
38
|
+
h3 { font-size: 19px }
|
39
|
+
h4 { font-size: 17px; font-weight: normal; }
|
40
|
+
h4.ruled { border-bottom: solid 1px #CC9; }
|
41
|
+
h2.ruled { padding-top: 35px; border-top: solid 1px #AA5; }
|
42
|
+
|
43
|
+
/* Link styles */
|
44
|
+
:link, :visited {
|
45
|
+
color: #00b;
|
46
|
+
}
|
47
|
+
:link:hover, :visited:hover {
|
48
|
+
background-color: #eee;
|
49
|
+
color: #B22;
|
50
|
+
}
|
51
|
+
#fullpage {
|
52
|
+
width: 720px;
|
53
|
+
margin: 0 auto;
|
54
|
+
}
|
55
|
+
.page_shade, .page {
|
56
|
+
padding: 0px 5px 5px 0px;
|
57
|
+
background-color: #fcfcf9;
|
58
|
+
border: solid 1px #983;
|
59
|
+
}
|
60
|
+
.page {
|
61
|
+
margin-left: -5px;
|
62
|
+
margin-top: -5px;
|
63
|
+
padding: 20px 35px;
|
64
|
+
}
|
65
|
+
.page .header {
|
66
|
+
float: right;
|
67
|
+
color: #777;
|
68
|
+
font-size: 10px;
|
69
|
+
}
|
70
|
+
.page h1, .page h2, .page h3 {
|
71
|
+
clear: both;
|
72
|
+
text-align: center;
|
73
|
+
}
|
74
|
+
#pager {
|
75
|
+
padding: 10px 4px;
|
76
|
+
color: white;
|
77
|
+
font-size: 11px;
|
78
|
+
}
|
79
|
+
#pager :link, #pager :visited {
|
80
|
+
color: #bfb;
|
81
|
+
padding: 0px 5px;
|
82
|
+
}
|
83
|
+
#pager :link:hover, #pager :visited:hover {
|
84
|
+
background-color: #262;
|
85
|
+
color: white;
|
86
|
+
}
|
87
|
+
#logo { float: left; }
|
88
|
+
#menu { background-color: #dfa; padding: 4px 12px; margin: 0; }
|
89
|
+
#menu h3 { padding: 0; margin: 0; }
|
90
|
+
#menu #links { float: right; }
|
91
|
+
pre { font-weight: bold; color: #730; }
|
92
|
+
tt { color: #703; font-size: 12pt; }
|
93
|
+
.dyn-source { background-color: #775915; padding: 4px 8px; margin: 0; display: none; }
|
94
|
+
.dyn-source pre { color: #DDDDDD; font-size: 8pt; }
|
95
|
+
.source-link { text-align: right; font-size: 8pt; }
|
96
|
+
.ruby-comment { color: green; font-style: italic }
|
97
|
+
.ruby-constant { color: #CCDDFF; font-weight: bold; }
|
98
|
+
.ruby-identifier { color: #CCCCCC; }
|
99
|
+
.ruby-ivar { color: #BBCCFF; }
|
100
|
+
.ruby-keyword { color: #EEEEFF; font-weight: bold }
|
101
|
+
.ruby-node { color: #FFFFFF; }
|
102
|
+
.ruby-operator { color: #CCCCCC; }
|
103
|
+
.ruby-regexp { color: #DDFFDD; }
|
104
|
+
.ruby-value { color: #FFAAAA; font-style: italic }
|
105
|
+
.kw { color: #DDDDFF; font-weight: bold }
|
106
|
+
.cmt { color: #CCFFCC; font-style: italic }
|
107
|
+
.str { color: #EECCCC; font-style: italic }
|
108
|
+
.re { color: #EECCCC; }
|
109
|
+
}
|
110
|
+
|
111
|
+
CONTENTS_XML = %q{
|
112
|
+
<%= values['description'] if values['description'] %>
|
113
|
+
|
114
|
+
<% if values['requires'] %>
|
115
|
+
<h4>Requires:</h4>
|
116
|
+
<ul>
|
117
|
+
<% values['requires'].each do |req| %>
|
118
|
+
<li><%= href(req['aref'], req['name']) %></li>
|
119
|
+
<% end %>
|
120
|
+
<% end %>
|
121
|
+
|
122
|
+
<% if values['attributes'] %>
|
123
|
+
<h4>Attributes</h4>
|
124
|
+
<table>
|
125
|
+
<% values['attribtes'].each do |attr| %>
|
126
|
+
<tr><td><%= attr['name'] %></td><td><%= attr['rw'] %></td><td><%= attr['a_desc'] %></td></tr>
|
127
|
+
<% end %>
|
128
|
+
</table>
|
129
|
+
<% end %>
|
130
|
+
|
131
|
+
<% if values['includes'] %>
|
132
|
+
<h4>Includes</h4>
|
133
|
+
<ul>
|
134
|
+
<% values['includes'].each do |i| %>
|
135
|
+
<li><%= href i['aref'], i['name'] %></li>
|
136
|
+
<% end %>
|
137
|
+
</ul>
|
138
|
+
<% end %>
|
139
|
+
|
140
|
+
<% values['sections'].each do |sec| %>
|
141
|
+
<% if sec['method_list'] %>
|
142
|
+
<h2 class="ruled">Methods</h2>
|
143
|
+
<% sec['method_list'].each do |ml| %>
|
144
|
+
<% if ml['methods'] %>
|
145
|
+
<% ml['methods'].each do |m| %>
|
146
|
+
<h4 class="ruled"><%= m['type'] %> <%= m['category'] %> method:
|
147
|
+
<% c = m['callseq'] %>
|
148
|
+
<strong id="<%= m['aref'] %>"><%= c ? c : m['name'] + m['params'] %></strong>
|
149
|
+
<a href="#<%= m['aref'] %>"><img src="<%= values['root'] %>/permalink.gif" border="0" title="Permalink to <%= c ? c : "#{m['type']} #{m['category']} method: #{m['name']}" %>" /></a></h4>
|
150
|
+
|
151
|
+
<%= m['m_desc'] if m['m_desc'] %>
|
152
|
+
|
153
|
+
<% if m['sourcecode'] %>
|
154
|
+
<div class="sourcecode">
|
155
|
+
<p class="source-link">[ <a href="javascript:toggleSource('<%= m['aref'] %>_source')" id="l_<%= m['aref'] %>_source">show source</a> ]</p>
|
156
|
+
<div id="<%= m['aref'] %>_source" class="dyn-source">
|
157
|
+
<pre>
|
158
|
+
<%= m['sourcecode'] %>
|
159
|
+
</pre>
|
160
|
+
</div>
|
161
|
+
</div>
|
162
|
+
<% end %>
|
163
|
+
<% end %>
|
164
|
+
<% end %>
|
165
|
+
<% end %>
|
166
|
+
<% end %>
|
167
|
+
<% end %>
|
168
|
+
}
|
169
|
+
|
170
|
+
############################################################################
|
171
|
+
|
172
|
+
|
173
|
+
BODY = %q{
|
174
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
175
|
+
<html>
|
176
|
+
<head>
|
177
|
+
<title>
|
178
|
+
<% if values['title'] %>
|
179
|
+
<%= values['realtitle'] %> » <%= values['title'] %>
|
180
|
+
<% else %>
|
181
|
+
<%= values['realtitle'] %>
|
182
|
+
<% end %>
|
183
|
+
</title>
|
184
|
+
<meta http-equiv="Content-Type" content="text/html; charset=<%= values['charset'] %>" />
|
185
|
+
<link rel="stylesheet" href="<%= values['style_url'] %>" type="text/css" media="screen" />
|
186
|
+
<script language="JavaScript" type="text/javascript">
|
187
|
+
// <![CDATA[
|
188
|
+
|
189
|
+
function toggleSource( id )
|
190
|
+
{
|
191
|
+
var elem
|
192
|
+
var link
|
193
|
+
|
194
|
+
if( document.getElementById )
|
195
|
+
{
|
196
|
+
elem = document.getElementById( id )
|
197
|
+
link = document.getElementById( "l_" + id )
|
198
|
+
}
|
199
|
+
else if ( document.all )
|
200
|
+
{
|
201
|
+
elem = eval( "document.all." + id )
|
202
|
+
link = eval( "document.all.l_" + id )
|
203
|
+
}
|
204
|
+
else
|
205
|
+
return false;
|
206
|
+
|
207
|
+
if( elem.style.display == "block" )
|
208
|
+
{
|
209
|
+
elem.style.display = "none"
|
210
|
+
link.innerHTML = "show source"
|
211
|
+
}
|
212
|
+
else
|
213
|
+
{
|
214
|
+
elem.style.display = "block"
|
215
|
+
link.innerHTML = "hide source"
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
function openCode( url )
|
220
|
+
{
|
221
|
+
window.open( url, "SOURCE_CODE", "width=400,height=400,scrollbars=yes" )
|
222
|
+
}
|
223
|
+
// ]]>
|
224
|
+
</script>
|
225
|
+
</head>
|
226
|
+
<body>
|
227
|
+
<div id="menu">
|
228
|
+
<div id="links">
|
229
|
+
<a href="http://redhanded.hobix.com/bits/campingAMicroframework.html">backstory</a> |
|
230
|
+
<a href="http://code.whytheluckystiff.net/camping/">wiki</a> |
|
231
|
+
<a href="http://code.whytheluckystiff.net/camping/newticket">bugs</a> |
|
232
|
+
<a href="http://code.whytheluckystiff.net/svn/camping/">svn</a>
|
233
|
+
</div>
|
234
|
+
<h3 class="title"><%= values['title'] %></h3>
|
235
|
+
</div>
|
236
|
+
<div id="fullpage">
|
237
|
+
<div id="logo"><img src="<%= values['root'] %>/Camping.gif" /></div>
|
238
|
+
<div id="pager">
|
239
|
+
<strong>Files:</strong>
|
240
|
+
<% values['file_list'].each do |file| %>
|
241
|
+
<%= href "#{file['href']}", file['name'] %>
|
242
|
+
<% end %>
|
243
|
+
<% if values['class_list'] %>
|
244
|
+
|
|
245
|
+
<strong>classes:</strong>
|
246
|
+
<% values['class_list'].each do |klass| %>
|
247
|
+
<%= href "#{klass['href']}", klass['name'] %>
|
248
|
+
<% end %>
|
249
|
+
<% end %>
|
250
|
+
</ul>
|
251
|
+
</div>
|
252
|
+
|
253
|
+
<%= template_include %>
|
254
|
+
|
255
|
+
</div>
|
256
|
+
</body>
|
257
|
+
</html>
|
258
|
+
}
|
259
|
+
|
260
|
+
###############################################################################
|
261
|
+
|
262
|
+
FILE_PAGE = <<_FILE_PAGE_
|
263
|
+
<div id="<%= values['full_path'] %>" class="page_shade">
|
264
|
+
<div class="page">
|
265
|
+
<div class="header">
|
266
|
+
<div class="path"><%= values['full_path'] %> / <%= values['dtm_modified'] %></div>
|
267
|
+
</div>
|
268
|
+
#{CONTENTS_XML}
|
269
|
+
</div>
|
270
|
+
</div>
|
271
|
+
_FILE_PAGE_
|
272
|
+
|
273
|
+
###################################################################
|
274
|
+
|
275
|
+
CLASS_PAGE = %{
|
276
|
+
<div id="<%= values['full_name'] %>" class="page_shade">
|
277
|
+
<div class="page">
|
278
|
+
<% if values['parent'] %>
|
279
|
+
<h3><%= values['classmod'] %> <%= values['full_name'] %> < <%= href values['par_url'], values['parent'] %></h3>
|
280
|
+
<% else %>
|
281
|
+
<h3><%= values['classmod'] %> <%= values['full_name'] %></h3>
|
282
|
+
<% end %>
|
283
|
+
|
284
|
+
<% if values['infiles'] %>
|
285
|
+
(in files
|
286
|
+
<% values['infiles'].each do |file| %>
|
287
|
+
<%= href file['full_path_url'], file['full_path'] %>
|
288
|
+
<% end %>
|
289
|
+
)
|
290
|
+
<% end %>
|
291
|
+
} + CONTENTS_XML + %{
|
292
|
+
</div>
|
293
|
+
</div>
|
294
|
+
}
|
295
|
+
|
296
|
+
METHOD_LIST = ""
|
297
|
+
########################## Index ################################
|
298
|
+
|
299
|
+
FR_INDEX_BODY = %{
|
300
|
+
<%= template_include %>
|
301
|
+
}
|
302
|
+
|
303
|
+
FILE_INDEX = %{
|
304
|
+
<html>
|
305
|
+
<head>
|
306
|
+
<meta http-equiv="Content-Type" content="text/html; charset=<%= values['charset'] %>">
|
307
|
+
<style>
|
308
|
+
<!--
|
309
|
+
body {
|
310
|
+
background-color: #ddddff;
|
311
|
+
font-family: #{FONTS};
|
312
|
+
font-size: 11px;
|
313
|
+
font-style: normal;
|
314
|
+
line-height: 14px;
|
315
|
+
color: #000040;
|
316
|
+
}
|
317
|
+
div.banner {
|
318
|
+
background: #0000aa;
|
319
|
+
color: white;
|
320
|
+
padding: 1;
|
321
|
+
margin: 0;
|
322
|
+
font-size: 90%;
|
323
|
+
font-weight: bold;
|
324
|
+
line-height: 1.1;
|
325
|
+
text-align: center;
|
326
|
+
width: 100%;
|
327
|
+
}
|
328
|
+
|
329
|
+
-->
|
330
|
+
</style>
|
331
|
+
<base target="docwin">
|
332
|
+
</head>
|
333
|
+
<body>
|
334
|
+
<div class="banner"><%= values['list_title'] %></div>
|
335
|
+
<% values['entries'].each do |entry| %>
|
336
|
+
<%= href entry['href'], entry['name'] %><br>
|
337
|
+
<% end %>
|
338
|
+
</body></html>
|
339
|
+
}
|
340
|
+
|
341
|
+
CLASS_INDEX = FILE_INDEX
|
342
|
+
METHOD_INDEX = FILE_INDEX
|
343
|
+
|
344
|
+
INDEX = %{
|
345
|
+
<HTML>
|
346
|
+
<HEAD>
|
347
|
+
<META HTTP-EQUIV="refresh" content="0;URL=<%= values['initial_page'] %>">
|
348
|
+
<TITLE><%= values['realtitle'] %></TITLE>
|
349
|
+
</HEAD>
|
350
|
+
<BODY>
|
351
|
+
Click <a href="<%= values['initial_page'] %>">here</a> to open the Camping docs.
|
352
|
+
</BODY>
|
353
|
+
</HTML>
|
354
|
+
}
|
355
|
+
|
356
|
+
end
|
357
|
+
end
|
File without changes
|
@@ -9,23 +9,6 @@
|
|
9
9
|
# nicely with piles of documentation everywhere. This documentation is entirely
|
10
10
|
# generated from lib/camping-unabridged.rb using RDoc and our "flipbook" template
|
11
11
|
# found in the extras directory of any camping distribution.
|
12
|
-
#
|
13
|
-
# == Requirements
|
14
|
-
#
|
15
|
-
# Camping requires at least Ruby 1.8.2.
|
16
|
-
#
|
17
|
-
# Camping depends on the following libraries. If you install through RubyGems,
|
18
|
-
# these will be automatically installed for you.
|
19
|
-
#
|
20
|
-
# * ActiveRecord, used in your models.
|
21
|
-
# ActiveRecord is an object-to-relational database mapper with adapters
|
22
|
-
# for SQLite3, MySQL, PostgreSQL, SQL Server and more.
|
23
|
-
# * Markaby, used in your views to describe HTML in plain Ruby.
|
24
|
-
#
|
25
|
-
# Camping also works well with Mongrel, the swift Ruby web server.
|
26
|
-
# http://rubyforge.org/projects/mongrel Mongrel comes with examples
|
27
|
-
# in its <tt>examples/camping</tt> directory.
|
28
|
-
#
|
29
12
|
%w[uri stringio rack].map { |l| require l }
|
30
13
|
|
31
14
|
class Object #:nodoc:
|
@@ -34,7 +17,11 @@ class Object #:nodoc:
|
|
34
17
|
end
|
35
18
|
end
|
36
19
|
|
37
|
-
# == Camping
|
20
|
+
# == Camping
|
21
|
+
# TODO: Tutorial: Camping.goes, MVC (link to Controllers, Models, Views where
|
22
|
+
# they're described in detail), Camping Server (for development), Rack
|
23
|
+
# (for production). the create-method. Service overload too, perhaps?
|
24
|
+
# Overriding r404, r500 and r501.
|
38
25
|
#
|
39
26
|
# The camping module contains three modules for separating your application:
|
40
27
|
#
|
@@ -47,6 +34,7 @@ end
|
|
47
34
|
# * Camping::Helpers which can be used in controllers and views.
|
48
35
|
#
|
49
36
|
# == The Camping Server
|
37
|
+
# TODO: Only for development.
|
50
38
|
#
|
51
39
|
# How do you run Camping apps? Oh, uh... The Camping Server!
|
52
40
|
#
|
@@ -84,6 +72,7 @@ end
|
|
84
72
|
# end
|
85
73
|
# end
|
86
74
|
#
|
75
|
+
# TODO: Wiki is down.
|
87
76
|
# For more tips, see http://code.whytheluckystiff.net/camping/wiki/GiveUsTheCreateMethod.
|
88
77
|
module Camping
|
89
78
|
C = self
|
@@ -91,6 +80,7 @@ module Camping
|
|
91
80
|
P = "<h1>Cam\ping Problem!</h1><h2>%s</h2>"
|
92
81
|
U = Rack::Utils
|
93
82
|
Apps = []
|
83
|
+
# TODO: @input[:page] != @input['page']
|
94
84
|
# An object-like Hash.
|
95
85
|
# All Camping query string and cookie variables are loaded as this.
|
96
86
|
#
|
@@ -125,7 +115,8 @@ module Camping
|
|
125
115
|
end
|
126
116
|
undef id, type
|
127
117
|
end
|
128
|
-
|
118
|
+
|
119
|
+
# TODO: Fair enough. Maybe complete the ActionPack example?
|
129
120
|
# Helpers contains methods available in your controllers and views. You may add
|
130
121
|
# methods of your own to this module, including many helper methods from Rails.
|
131
122
|
# This is analogous to Rails' <tt>ApplicationHelper</tt> module.
|
@@ -190,7 +181,7 @@ module Camping
|
|
190
181
|
# is assigned to route <tt>/logout</tt>. The HTML will come out as:
|
191
182
|
#
|
192
183
|
# <div id="menu">
|
193
|
-
# <a href="
|
184
|
+
# <a href="http://localhost:3301/frodo/">Home</a>
|
194
185
|
# <a href="/frodo/profile">Profile</a>
|
195
186
|
# <a href="/frodo/logout">Logout</a>
|
196
187
|
# <a href="http://google.com">Google</a>
|
@@ -251,6 +242,7 @@ module Camping
|
|
251
242
|
# Forgivable, considering that it's only really a handful of methods and accessors.
|
252
243
|
#
|
253
244
|
# == Treating controller methods like Response objects
|
245
|
+
# TODO: I don't think this belongs here. Either Controllers or Camping.
|
254
246
|
#
|
255
247
|
# Camping originally came with a barebones Response object, but it's often much more readable
|
256
248
|
# to just use your controller as the response.
|
@@ -279,6 +271,7 @@ module Camping
|
|
279
271
|
#
|
280
272
|
module Base
|
281
273
|
attr_accessor :input, :cookies, :headers, :body, :status, :root
|
274
|
+
M = proc { |_, o, n| o.merge(n, &M) }
|
282
275
|
|
283
276
|
# Display a view, calling it by its method name +m+. If a <tt>layout</tt>
|
284
277
|
# method is found in Camping::Views, it will be used to wrap the HTML.
|
@@ -328,6 +321,7 @@ module Camping
|
|
328
321
|
# You can also switch the body and the header in order to support Rack:
|
329
322
|
#
|
330
323
|
# r(302, {'Location' => self / "/view/12"}, '')
|
324
|
+
# r(another_app.call(@env))
|
331
325
|
#
|
332
326
|
# See also: #r404, #r500 and #r501
|
333
327
|
def r(s, b, h = {})
|
@@ -367,8 +361,8 @@ module Camping
|
|
367
361
|
# end
|
368
362
|
#
|
369
363
|
# See: I
|
370
|
-
def r404(p
|
371
|
-
|
364
|
+
def r404(p)
|
365
|
+
P % "#{p} not found"
|
372
366
|
end
|
373
367
|
|
374
368
|
# If there is a parse error in Camping or in your application's source code, it will not be caught
|
@@ -378,15 +372,15 @@ module Camping
|
|
378
372
|
# You can overide it, but if you have an error in here, it will be uncaught !
|
379
373
|
#
|
380
374
|
# See: I
|
381
|
-
def r500(k,m,
|
382
|
-
|
375
|
+
def r500(k,m,e)
|
376
|
+
raise e
|
383
377
|
end
|
384
378
|
|
385
379
|
# Called if an undefined method is called on a Controller, along with the request method +m+ (GET, POST, etc.)
|
386
380
|
#
|
387
381
|
# See: I
|
388
|
-
def r501(m
|
389
|
-
|
382
|
+
def r501(m)
|
383
|
+
P % "#{m.upcase} not implemented"
|
390
384
|
end
|
391
385
|
|
392
386
|
# Turn a controller into an array. This is designed to be used to pipe
|
@@ -401,46 +395,41 @@ module Camping
|
|
401
395
|
# end
|
402
396
|
# end
|
403
397
|
def to_a
|
404
|
-
|
405
|
-
@response.status = @status
|
406
|
-
@response.headers.merge!(@headers)
|
398
|
+
r = Rack::Response.new(@body, @status, @headers)
|
407
399
|
@cookies.each do |k, v|
|
408
400
|
v = {:value => v, :path => self / "/"} if String===v
|
409
|
-
|
401
|
+
r.set_cookie(k, v)
|
410
402
|
end
|
411
|
-
|
403
|
+
r.to_a
|
412
404
|
end
|
413
405
|
|
414
|
-
def initialize(env) #:nodoc:
|
415
|
-
@request
|
416
|
-
|
417
|
-
@
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
if k[-2..-1] == "[]"
|
425
|
-
@input[k[0..-3]] = @input.delete(k)
|
426
|
-
elsif k =~ /(.*)\[([^\]]+)\]$/
|
427
|
-
(@input[$1] ||= H[])[$2] = @input.delete(k)
|
428
|
-
end
|
406
|
+
def initialize(env, m) #:nodoc:
|
407
|
+
r = @request = Rack::Request.new(@env = env)
|
408
|
+
@root, p, @cookies,
|
409
|
+
@headers, @status, @method =
|
410
|
+
(env.SCRIPT_NAME||'').sub(/\/$/,''),
|
411
|
+
H[r.params], H[r.cookies],
|
412
|
+
{}, m =~ /r(\d+)/ ? $1.to_i : 200, m
|
413
|
+
|
414
|
+
@input = p.inject(H[]) do |h, (k, v)|
|
415
|
+
h.merge(k.split(/[\]\[]+/).reverse.inject(v) { |x, i| H[i => x] }, &M)
|
429
416
|
end
|
430
417
|
end
|
431
418
|
|
419
|
+
# TODO: The wiki is down. Service overload should probably go in Camping.
|
432
420
|
# All requests pass through this method before going to the controller. Some magic
|
433
421
|
# in Camping can be performed by overriding this method.
|
434
422
|
#
|
435
423
|
# See http://code.whytheluckystiff.net/camping/wiki/BeforeAndAfterOverrides for more
|
436
424
|
# on before and after overrides with Camping.
|
437
425
|
def service(*a)
|
438
|
-
r = catch(:halt){send(@
|
426
|
+
r = catch(:halt){send(@method, *a)}
|
439
427
|
@body ||= r
|
440
428
|
self
|
441
429
|
end
|
442
430
|
end
|
443
|
-
|
431
|
+
|
432
|
+
# TODO: @input & @cookies at least.
|
444
433
|
# Controllers is a module for placing classes which handle URLs. This is done
|
445
434
|
# by defining a route to each class using the Controllers::R method.
|
446
435
|
#
|
@@ -510,7 +499,7 @@ module Camping
|
|
510
499
|
[I, 'r404', p]
|
511
500
|
end
|
512
501
|
|
513
|
-
N = H.new { |_,x| x.downcase }.merge! "N" => '(\d+)', "X" => '(
|
502
|
+
N = H.new { |_,x| x.downcase }.merge! "N" => '(\d+)', "X" => '([^/]+)', "Index" => ''
|
514
503
|
# The route maker, this is called by Camping internally, you shouldn't need to call it.
|
515
504
|
#
|
516
505
|
# Still, it's worth know what this method does. Since Ruby doesn't keep track of class
|
@@ -533,8 +522,7 @@ module Camping
|
|
533
522
|
end
|
534
523
|
|
535
524
|
# Internal controller with no route. Used by #D and C.call to show internal messages.
|
536
|
-
|
537
|
-
end
|
525
|
+
I = R()
|
538
526
|
end
|
539
527
|
X = Controllers
|
540
528
|
|
@@ -559,10 +547,12 @@ module Camping
|
|
559
547
|
# And array with [statuc, headers, body] is expected at the output.
|
560
548
|
def call(e)
|
561
549
|
X.M
|
562
|
-
e = H[e
|
563
|
-
|
564
|
-
e.REQUEST_METHOD
|
565
|
-
k.new(e).service(*a).to_a
|
550
|
+
e = H[e]
|
551
|
+
p = e.PATH_INFO = U.unescape(e.PATH_INFO)
|
552
|
+
k,m,*a=X.D p,(e.REQUEST_METHOD||'get').downcase
|
553
|
+
k.new(e,m).service(*a).to_a
|
554
|
+
rescue
|
555
|
+
r500(:I, k, m, $!, :env => e).to_a
|
566
556
|
end
|
567
557
|
|
568
558
|
# The Camping scriptable dispatcher. Any unhandled method call to the app module will
|
@@ -585,14 +575,15 @@ module Camping
|
|
585
575
|
#
|
586
576
|
def method_missing(m, c, *a)
|
587
577
|
X.M
|
588
|
-
h=Hash===a[-1]?
|
589
|
-
e=H[h[:env]||{}]
|
590
|
-
k = X.const_get(c).new(
|
591
|
-
k.send("input=",h[:input]) if h[:input]
|
578
|
+
h = Hash === a[-1] ? a.pop : {}
|
579
|
+
e = H[Rack::MockRequest.env_for('',h[:env]||{})]
|
580
|
+
k = X.const_get(c).new(e,m.to_s)
|
581
|
+
k.send("input=", h[:input]) if h[:input]
|
592
582
|
k.service(*a)
|
593
583
|
end
|
594
584
|
end
|
595
|
-
|
585
|
+
|
586
|
+
# TODO: More examples.
|
596
587
|
# Views is an empty module for storing methods which create HTML. The HTML is described
|
597
588
|
# using the Markaby language.
|
598
589
|
#
|
@@ -601,7 +592,8 @@ module Camping
|
|
601
592
|
# If your Views module has a <tt>layout</tt> method defined, it will be called with a block
|
602
593
|
# which will insert content from your view.
|
603
594
|
module Views; include X, Helpers end
|
604
|
-
|
595
|
+
|
596
|
+
# TODO: Migrations
|
605
597
|
# Models is an empty Ruby module for housing model classes derived
|
606
598
|
# from ActiveRecord::Base. As a shortcut, you may derive from Base
|
607
599
|
# which is an alias for ActiveRecord::Base.
|