zuk-picnic 0.7.999.20090212
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/CHANGELOG.txt +1 -0
- data/History.txt +68 -0
- data/LICENSE.txt +165 -0
- data/Manifest.txt +29 -0
- data/README.txt +31 -0
- data/Rakefile +62 -0
- data/lib/picnic/authentication.rb +218 -0
- data/lib/picnic/cli.rb +165 -0
- data/lib/picnic/conf.rb +135 -0
- data/lib/picnic/controllers.rb +4 -0
- data/lib/picnic/logger.rb +41 -0
- data/lib/picnic/server.rb +98 -0
- data/lib/picnic/service_control.rb +274 -0
- data/lib/picnic/version.rb +9 -0
- data/lib/picnic.rb +48 -0
- data/setup.rb +1585 -0
- data/test/picnic_test.rb +11 -0
- data/test/test_helper.rb +2 -0
- data/vendor/camping-2.0.20090212/CHANGELOG +118 -0
- data/vendor/camping-2.0.20090212/COPYING +18 -0
- data/vendor/camping-2.0.20090212/README +119 -0
- data/vendor/camping-2.0.20090212/Rakefile +174 -0
- data/vendor/camping-2.0.20090212/bin/camping +99 -0
- data/vendor/camping-2.0.20090212/doc/camping.1.gz +0 -0
- data/vendor/camping-2.0.20090212/examples/README +5 -0
- data/vendor/camping-2.0.20090212/examples/blog.rb +375 -0
- data/vendor/camping-2.0.20090212/examples/campsh.rb +629 -0
- data/vendor/camping-2.0.20090212/examples/tepee.rb +242 -0
- data/vendor/camping-2.0.20090212/extras/Camping.gif +0 -0
- data/vendor/camping-2.0.20090212/extras/flipbook_rdoc.rb +491 -0
- data/vendor/camping-2.0.20090212/extras/permalink.gif +0 -0
- data/vendor/camping-2.0.20090212/lib/camping/ar/session.rb +132 -0
- data/vendor/camping-2.0.20090212/lib/camping/ar.rb +78 -0
- data/vendor/camping-2.0.20090212/lib/camping/mab.rb +26 -0
- data/vendor/camping-2.0.20090212/lib/camping/reloader.rb +163 -0
- data/vendor/camping-2.0.20090212/lib/camping/server.rb +158 -0
- data/vendor/camping-2.0.20090212/lib/camping/session.rb +74 -0
- data/vendor/camping-2.0.20090212/lib/camping-unabridged.rb +638 -0
- data/vendor/camping-2.0.20090212/lib/camping.rb +54 -0
- data/vendor/camping-2.0.20090212/setup.rb +1551 -0
- data/vendor/camping-2.0.20090212/test/apps/env_debug.rb +65 -0
- data/vendor/camping-2.0.20090212/test/apps/forms.rb +95 -0
- data/vendor/camping-2.0.20090212/test/apps/misc.rb +86 -0
- data/vendor/camping-2.0.20090212/test/apps/sessions.rb +38 -0
- data/vendor/camping-2.0.20090212/test/test_camping.rb +54 -0
- metadata +128 -0
@@ -0,0 +1,375 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
4
|
+
require 'camping'
|
5
|
+
require 'camping/ar'
|
6
|
+
require 'camping/session'
|
7
|
+
require 'redcloth'
|
8
|
+
|
9
|
+
Camping.goes :Blog
|
10
|
+
|
11
|
+
module Blog
|
12
|
+
include Camping::Session
|
13
|
+
|
14
|
+
module Models
|
15
|
+
class Post < Base
|
16
|
+
belongs_to :user
|
17
|
+
|
18
|
+
before_save do |record|
|
19
|
+
cloth = RedCloth.new(record.body)
|
20
|
+
cloth.hard_breaks = false
|
21
|
+
record.html_body = cloth.to_html
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Comment < Base; belongs_to :user; end
|
26
|
+
class User < Base; end
|
27
|
+
|
28
|
+
class BasicFields < V 1.1
|
29
|
+
def self.up
|
30
|
+
create_table :blog_posts, :force => true do |t|
|
31
|
+
t.integer :user_id, :null => false
|
32
|
+
t.string :title, :limit => 255
|
33
|
+
t.text :body, :html_body
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
create_table :blog_users, :force => true do |t|
|
37
|
+
t.string :username, :password
|
38
|
+
end
|
39
|
+
create_table :blog_comments, :force => true do |t|
|
40
|
+
t.integer :post_id, :null => false
|
41
|
+
t.string :username
|
42
|
+
t.text :body, :html_body
|
43
|
+
t.timestamps
|
44
|
+
end
|
45
|
+
User.create :username => 'admin', :password => 'camping'
|
46
|
+
end
|
47
|
+
def self.down
|
48
|
+
drop_table :blog_posts
|
49
|
+
drop_table :blog_users
|
50
|
+
drop_table :blog_comments
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module Controllers
|
56
|
+
class Index
|
57
|
+
def get
|
58
|
+
@posts = Post.all(:order => 'updated_at DESC')
|
59
|
+
render :index
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class PostNew
|
64
|
+
def get
|
65
|
+
require_login!
|
66
|
+
@post = Post.new
|
67
|
+
render :add
|
68
|
+
end
|
69
|
+
|
70
|
+
def post
|
71
|
+
require_login!
|
72
|
+
post = Post.create(:title => input.post_title, :body => input.post_body,
|
73
|
+
:user_id => @state.user_id)
|
74
|
+
redirect PostN, post
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class PostN
|
79
|
+
def get(post_id)
|
80
|
+
@post = Post.find(post_id)
|
81
|
+
render :view
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class Edit < R '/post/(\d+)/edit'
|
86
|
+
def get(post_id)
|
87
|
+
require_login!
|
88
|
+
@post = Post.find(post_id)
|
89
|
+
render :edit
|
90
|
+
end
|
91
|
+
|
92
|
+
def post(post_id)
|
93
|
+
require_login!
|
94
|
+
@post = Post.find(post_id)
|
95
|
+
@post.update_attributes :title => input.post_title, :body => input.post_body
|
96
|
+
redirect PostN, @post
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class Login
|
101
|
+
def get
|
102
|
+
@to = input.to
|
103
|
+
render :login
|
104
|
+
end
|
105
|
+
|
106
|
+
def post
|
107
|
+
@user = User.find_by_username_and_password(input.username, input.password)
|
108
|
+
@to = input.to
|
109
|
+
|
110
|
+
if @user
|
111
|
+
@state.user_id = @user.id
|
112
|
+
if @to
|
113
|
+
redirect @to
|
114
|
+
else
|
115
|
+
redirect R(Index)
|
116
|
+
end
|
117
|
+
else
|
118
|
+
@info = 'Wrong username or password'
|
119
|
+
end
|
120
|
+
render :login
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class Logout
|
125
|
+
def get
|
126
|
+
@state.user_id = nil
|
127
|
+
redirect Index
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class Style < R '/styles\.css'
|
132
|
+
STYLE = File.read(__FILE__).gsub(/.*__END__/m, '')
|
133
|
+
|
134
|
+
def get
|
135
|
+
@headers['Content-Type'] = 'text/css; charset=utf-8'
|
136
|
+
STYLE
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
module Helpers
|
142
|
+
def logged_in?
|
143
|
+
!!@state.user_id
|
144
|
+
end
|
145
|
+
|
146
|
+
def require_login!
|
147
|
+
unless logged_in?
|
148
|
+
redirect X::Login, :to => @env.REQUEST_URI
|
149
|
+
throw :halt
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
module Views
|
155
|
+
def layout
|
156
|
+
html do
|
157
|
+
head do
|
158
|
+
title 'My Blog'
|
159
|
+
link :rel => 'stylesheet', :type => 'text/css',
|
160
|
+
:href => '/styles.css', :media => 'screen'
|
161
|
+
end
|
162
|
+
body do
|
163
|
+
h1 { a 'My Blog', :href => R(Index) }
|
164
|
+
|
165
|
+
div.wrapper! do
|
166
|
+
text yield
|
167
|
+
end
|
168
|
+
|
169
|
+
hr
|
170
|
+
|
171
|
+
p.footer! do
|
172
|
+
if logged_in?
|
173
|
+
_admin_menu
|
174
|
+
else
|
175
|
+
a 'Login', :href => R(Login, :to => @env.REQUEST_URI)
|
176
|
+
text ' to the adminpanel'
|
177
|
+
end
|
178
|
+
text ' – Powered by '
|
179
|
+
a 'Camping', :href => 'http://code.whytheluckystiff.net/camping'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def index
|
186
|
+
if @posts.empty?
|
187
|
+
h2 'No posts'
|
188
|
+
p do
|
189
|
+
text 'Could not find any posts. Feel free to '
|
190
|
+
a 'add one', :href => R(PostNew)
|
191
|
+
text ' yourself'
|
192
|
+
end
|
193
|
+
else
|
194
|
+
@posts.each do |post|
|
195
|
+
_post(post)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def login
|
201
|
+
h2 'Login'
|
202
|
+
p.info @info if @info
|
203
|
+
|
204
|
+
form :action => R(Login), :method => 'post' do
|
205
|
+
input :name => 'to', :type => 'hidden', :value => @to if @to
|
206
|
+
|
207
|
+
label 'Username', :for => 'username'
|
208
|
+
input :name => 'username', :id => 'username', :type => 'text'
|
209
|
+
|
210
|
+
label 'Password', :for => 'password'
|
211
|
+
input :name => 'password', :id => 'password', :type => 'password'
|
212
|
+
|
213
|
+
input :type => 'submit', :class => 'submit', :value => 'Login'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def add
|
218
|
+
_form(@post, :action => R(PostNew))
|
219
|
+
end
|
220
|
+
|
221
|
+
def edit
|
222
|
+
_form(@post, :action => R(Edit, @post))
|
223
|
+
end
|
224
|
+
|
225
|
+
def view
|
226
|
+
_post(@post)
|
227
|
+
end
|
228
|
+
|
229
|
+
# partials
|
230
|
+
def _admin_menu
|
231
|
+
text [['Log out', R(Logout)], ['New', R(PostNew)]].map { |name, to|
|
232
|
+
capture { a name, :href => to}
|
233
|
+
}.join(' – ')
|
234
|
+
end
|
235
|
+
|
236
|
+
def _post(post)
|
237
|
+
h2 post.title
|
238
|
+
p.info do
|
239
|
+
text "Written by <strong>#{post.user.username}</strong> "
|
240
|
+
text post.updated_at.strftime('%B %M, %Y @ %H:%M ')
|
241
|
+
_post_menu(post)
|
242
|
+
end
|
243
|
+
text post.html_body
|
244
|
+
end
|
245
|
+
|
246
|
+
def _post_menu(post)
|
247
|
+
text '('
|
248
|
+
a 'view', :href => R(PostN, post)
|
249
|
+
if logged_in?
|
250
|
+
text ', '
|
251
|
+
a 'edit', :href => R(Edit, post)
|
252
|
+
end
|
253
|
+
text ')'
|
254
|
+
end
|
255
|
+
|
256
|
+
def _form(post, opts)
|
257
|
+
form({:method => 'post'}.merge(opts)) do
|
258
|
+
label 'Title', :for => 'post_title'
|
259
|
+
input :name => 'post_title', :id => 'post_title', :type => 'text',
|
260
|
+
:value => post.title
|
261
|
+
|
262
|
+
label 'Body', :for => 'post_body'
|
263
|
+
textarea post.body, :name => 'post_body', :id => 'post_body'
|
264
|
+
|
265
|
+
input :type => 'hidden', :name => 'post_id', :value => post.id
|
266
|
+
input :type => 'submit', :class => 'submit', :value => 'Submit'
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def Blog.create
|
273
|
+
Blog::Models.create_schema :assume => (Blog::Models::Post.table_exists? ? 1.0 : 0.0)
|
274
|
+
end
|
275
|
+
|
276
|
+
__END__
|
277
|
+
* {
|
278
|
+
margin: 0;
|
279
|
+
padding: 0;
|
280
|
+
}
|
281
|
+
|
282
|
+
body {
|
283
|
+
font: normal 14px Arial, 'Bitstream Vera Sans', Helvetica, sans-serif;
|
284
|
+
line-height: 1.5;
|
285
|
+
}
|
286
|
+
|
287
|
+
h1, h2, h3, h4 {
|
288
|
+
font-family: Georgia, serif;
|
289
|
+
font-weight: normal;
|
290
|
+
}
|
291
|
+
|
292
|
+
h1 {
|
293
|
+
background-color: #EEE;
|
294
|
+
border-bottom: 5px solid #6F812D;
|
295
|
+
outline: 5px solid #9CB441;
|
296
|
+
font-weight: normal;
|
297
|
+
font-size: 3em;
|
298
|
+
padding: 0.5em 0;
|
299
|
+
text-align: center;
|
300
|
+
}
|
301
|
+
|
302
|
+
h1 a { color: #143D55; text-decoration: none }
|
303
|
+
h1 a:hover { color: #143D55; text-decoration: underline }
|
304
|
+
|
305
|
+
h2 {
|
306
|
+
font-size: 2em;
|
307
|
+
color: #287AA9;
|
308
|
+
}
|
309
|
+
|
310
|
+
#wrapper {
|
311
|
+
margin: 3em auto;
|
312
|
+
width: 700px;
|
313
|
+
}
|
314
|
+
|
315
|
+
p {
|
316
|
+
margin-bottom: 1em;
|
317
|
+
}
|
318
|
+
|
319
|
+
p.info, p#footer {
|
320
|
+
color: #999;
|
321
|
+
margin-left: 1em;
|
322
|
+
}
|
323
|
+
|
324
|
+
p.info a, p#footer a {
|
325
|
+
color: #999;
|
326
|
+
}
|
327
|
+
|
328
|
+
p.info a:hover, p#footer a:hover {
|
329
|
+
text-decoration: none;
|
330
|
+
}
|
331
|
+
|
332
|
+
a {
|
333
|
+
color: #6F812D;
|
334
|
+
}
|
335
|
+
|
336
|
+
a:hover {
|
337
|
+
color: #9CB441;
|
338
|
+
}
|
339
|
+
|
340
|
+
hr {
|
341
|
+
border-width: 5px 0;
|
342
|
+
border-style: solid;
|
343
|
+
border-color: #9CB441;
|
344
|
+
border-bottom-color: #6F812D;
|
345
|
+
height: 0;
|
346
|
+
}
|
347
|
+
|
348
|
+
p#footer {
|
349
|
+
font-size: 0.9em;
|
350
|
+
margin: 0;
|
351
|
+
padding: 1em;
|
352
|
+
text-align: center;
|
353
|
+
}
|
354
|
+
|
355
|
+
label {
|
356
|
+
display: inline-block;
|
357
|
+
width: 100%;
|
358
|
+
}
|
359
|
+
|
360
|
+
input, textarea {
|
361
|
+
margin-bottom: 1em;
|
362
|
+
width: 200px;
|
363
|
+
}
|
364
|
+
|
365
|
+
input.submit {
|
366
|
+
float: left;
|
367
|
+
width: auto;
|
368
|
+
}
|
369
|
+
|
370
|
+
textarea {
|
371
|
+
font: normal 14px Arial, 'Bitstream Vera Sans', Helvetica, sans-serif;
|
372
|
+
height: 300px;
|
373
|
+
width: 400px;
|
374
|
+
}
|
375
|
+
|