mongrel 0.2.0

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 (74) hide show
  1. data/COPYING +504 -0
  2. data/LICENSE +504 -0
  3. data/README +117 -0
  4. data/Rakefile +30 -0
  5. data/doc/rdoc/classes/Mongrel.html +144 -0
  6. data/doc/rdoc/classes/Mongrel/Error404Handler.html +171 -0
  7. data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000023.html +18 -0
  8. data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000024.html +18 -0
  9. data/doc/rdoc/classes/Mongrel/HeaderOut.html +167 -0
  10. data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000013.html +18 -0
  11. data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000014.html +21 -0
  12. data/doc/rdoc/classes/Mongrel/HttpHandler.html +159 -0
  13. data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000019.html +17 -0
  14. data/doc/rdoc/classes/Mongrel/HttpParser.html +271 -0
  15. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000001.html +28 -0
  16. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000002.html +29 -0
  17. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000003.html +29 -0
  18. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000004.html +41 -0
  19. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000005.html +27 -0
  20. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000006.html +27 -0
  21. data/doc/rdoc/classes/Mongrel/HttpParser.src/M000007.html +28 -0
  22. data/doc/rdoc/classes/Mongrel/HttpRequest.html +177 -0
  23. data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000025.html +30 -0
  24. data/doc/rdoc/classes/Mongrel/HttpResponse.html +202 -0
  25. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000020.html +21 -0
  26. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000021.html +20 -0
  27. data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000022.html +25 -0
  28. data/doc/rdoc/classes/Mongrel/HttpServer.html +336 -0
  29. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000008.html +26 -0
  30. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000009.html +58 -0
  31. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000010.html +22 -0
  32. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000011.html +18 -0
  33. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000012.html +18 -0
  34. data/doc/rdoc/classes/Mongrel/URIClassifier.html +257 -0
  35. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000015.html +54 -0
  36. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000016.html +50 -0
  37. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000017.html +36 -0
  38. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000018.html +73 -0
  39. data/doc/rdoc/created.rid +1 -0
  40. data/doc/rdoc/files/COPYING.html +756 -0
  41. data/doc/rdoc/files/LICENSE.html +756 -0
  42. data/doc/rdoc/files/README.html +273 -0
  43. data/doc/rdoc/files/ext/http11/http11_c.html +101 -0
  44. data/doc/rdoc/files/lib/mongrel_rb.html +111 -0
  45. data/doc/rdoc/fr_class_index.html +35 -0
  46. data/doc/rdoc/fr_file_index.html +31 -0
  47. data/doc/rdoc/fr_method_index.html +51 -0
  48. data/doc/rdoc/index.html +24 -0
  49. data/doc/rdoc/rdoc-style.css +208 -0
  50. data/examples/camping/blog.rb +300 -0
  51. data/examples/camping/tepee.rb +168 -0
  52. data/examples/simpletest.rb +16 -0
  53. data/examples/webrick_compare.rb +20 -0
  54. data/ext/http11/MANIFEST +0 -0
  55. data/ext/http11/ext_help.h +14 -0
  56. data/ext/http11/extconf.rb +6 -0
  57. data/ext/http11/http11.c +436 -0
  58. data/ext/http11/http11_parser.c +918 -0
  59. data/ext/http11/http11_parser.h +37 -0
  60. data/ext/http11/tst.h +40 -0
  61. data/ext/http11/tst_cleanup.c +24 -0
  62. data/ext/http11/tst_delete.c +146 -0
  63. data/ext/http11/tst_grow_node_free_list.c +38 -0
  64. data/ext/http11/tst_init.c +41 -0
  65. data/ext/http11/tst_insert.c +192 -0
  66. data/ext/http11/tst_search.c +54 -0
  67. data/lib/mongrel.rb +298 -0
  68. data/setup.rb +1360 -0
  69. data/test/test_http11.rb +38 -0
  70. data/test/test_response.rb +44 -0
  71. data/test/test_uriclassifier.rb +104 -0
  72. data/test/test_ws.rb +33 -0
  73. data/tools/rakehelp.rb +99 -0
  74. metadata +132 -0
@@ -0,0 +1,35 @@
1
+
2
+ <?xml version="1.0" encoding="iso-8859-1"?>
3
+ <!DOCTYPE html
4
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
+
7
+ <!--
8
+
9
+ Classes
10
+
11
+ -->
12
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13
+ <head>
14
+ <title>Classes</title>
15
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16
+ <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17
+ <base target="docwin" />
18
+ </head>
19
+ <body>
20
+ <div id="index">
21
+ <h1 class="section-bar">Classes</h1>
22
+ <div id="index-entries">
23
+ <a href="classes/Mongrel.html">Mongrel</a><br />
24
+ <a href="classes/Mongrel/Error404Handler.html">Mongrel::Error404Handler</a><br />
25
+ <a href="classes/Mongrel/HeaderOut.html">Mongrel::HeaderOut</a><br />
26
+ <a href="classes/Mongrel/HttpHandler.html">Mongrel::HttpHandler</a><br />
27
+ <a href="classes/Mongrel/HttpParser.html">Mongrel::HttpParser</a><br />
28
+ <a href="classes/Mongrel/HttpRequest.html">Mongrel::HttpRequest</a><br />
29
+ <a href="classes/Mongrel/HttpResponse.html">Mongrel::HttpResponse</a><br />
30
+ <a href="classes/Mongrel/HttpServer.html">Mongrel::HttpServer</a><br />
31
+ <a href="classes/Mongrel/URIClassifier.html">Mongrel::URIClassifier</a><br />
32
+ </div>
33
+ </div>
34
+ </body>
35
+ </html>
@@ -0,0 +1,31 @@
1
+
2
+ <?xml version="1.0" encoding="iso-8859-1"?>
3
+ <!DOCTYPE html
4
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
+
7
+ <!--
8
+
9
+ Files
10
+
11
+ -->
12
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13
+ <head>
14
+ <title>Files</title>
15
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16
+ <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17
+ <base target="docwin" />
18
+ </head>
19
+ <body>
20
+ <div id="index">
21
+ <h1 class="section-bar">Files</h1>
22
+ <div id="index-entries">
23
+ <a href="files/COPYING.html">COPYING</a><br />
24
+ <a href="files/LICENSE.html">LICENSE</a><br />
25
+ <a href="files/README.html">README</a><br />
26
+ <a href="files/ext/http11/http11_c.html">ext/http11/http11.c</a><br />
27
+ <a href="files/lib/mongrel_rb.html">lib/mongrel.rb</a><br />
28
+ </div>
29
+ </div>
30
+ </body>
31
+ </html>
@@ -0,0 +1,51 @@
1
+
2
+ <?xml version="1.0" encoding="iso-8859-1"?>
3
+ <!DOCTYPE html
4
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
+
7
+ <!--
8
+
9
+ Methods
10
+
11
+ -->
12
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13
+ <head>
14
+ <title>Methods</title>
15
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16
+ <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17
+ <base target="docwin" />
18
+ </head>
19
+ <body>
20
+ <div id="index">
21
+ <h1 class="section-bar">Methods</h1>
22
+ <div id="index-entries">
23
+ <a href="classes/Mongrel/HeaderOut.html#M000014">[]= (Mongrel::HeaderOut)</a><br />
24
+ <a href="classes/Mongrel/HttpParser.html#M000005">error? (Mongrel::HttpParser)</a><br />
25
+ <a href="classes/Mongrel/HttpParser.html#M000004">execute (Mongrel::HttpParser)</a><br />
26
+ <a href="classes/Mongrel/HttpParser.html#M000003">finish (Mongrel::HttpParser)</a><br />
27
+ <a href="classes/Mongrel/HttpResponse.html#M000022">finished (Mongrel::HttpResponse)</a><br />
28
+ <a href="classes/Mongrel/HttpParser.html#M000006">finished? (Mongrel::HttpParser)</a><br />
29
+ <a href="classes/Mongrel/Error404Handler.html#M000023">new (Mongrel::Error404Handler)</a><br />
30
+ <a href="classes/Mongrel/HttpServer.html#M000008">new (Mongrel::HttpServer)</a><br />
31
+ <a href="classes/Mongrel/HttpRequest.html#M000025">new (Mongrel::HttpRequest)</a><br />
32
+ <a href="classes/Mongrel/HttpResponse.html#M000020">new (Mongrel::HttpResponse)</a><br />
33
+ <a href="classes/Mongrel/URIClassifier.html#M000015">new (Mongrel::URIClassifier)</a><br />
34
+ <a href="classes/Mongrel/HttpParser.html#M000001">new (Mongrel::HttpParser)</a><br />
35
+ <a href="classes/Mongrel/HeaderOut.html#M000013">new (Mongrel::HeaderOut)</a><br />
36
+ <a href="classes/Mongrel/HttpParser.html#M000007">nread (Mongrel::HttpParser)</a><br />
37
+ <a href="classes/Mongrel/Error404Handler.html#M000024">process (Mongrel::Error404Handler)</a><br />
38
+ <a href="classes/Mongrel/HttpHandler.html#M000019">process (Mongrel::HttpHandler)</a><br />
39
+ <a href="classes/Mongrel/HttpServer.html#M000009">process_client (Mongrel::HttpServer)</a><br />
40
+ <a href="classes/Mongrel/HttpServer.html#M000011">register (Mongrel::HttpServer)</a><br />
41
+ <a href="classes/Mongrel/URIClassifier.html#M000016">register (Mongrel::URIClassifier)</a><br />
42
+ <a href="classes/Mongrel/HttpParser.html#M000002">reset (Mongrel::HttpParser)</a><br />
43
+ <a href="classes/Mongrel/URIClassifier.html#M000018">resolve (Mongrel::URIClassifier)</a><br />
44
+ <a href="classes/Mongrel/HttpServer.html#M000010">run (Mongrel::HttpServer)</a><br />
45
+ <a href="classes/Mongrel/HttpResponse.html#M000021">start (Mongrel::HttpResponse)</a><br />
46
+ <a href="classes/Mongrel/URIClassifier.html#M000017">unregister (Mongrel::URIClassifier)</a><br />
47
+ <a href="classes/Mongrel/HttpServer.html#M000012">unregister (Mongrel::HttpServer)</a><br />
48
+ </div>
49
+ </div>
50
+ </body>
51
+ </html>
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
5
+
6
+ <!--
7
+
8
+ RDoc Documentation
9
+
10
+ -->
11
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
12
+ <head>
13
+ <title>RDoc Documentation</title>
14
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
15
+ </head>
16
+ <frameset rows="20%, 80%">
17
+ <frameset cols="25%,35%,45%">
18
+ <frame src="fr_file_index.html" title="Files" name="Files" />
19
+ <frame src="fr_class_index.html" name="Classes" />
20
+ <frame src="fr_method_index.html" name="Methods" />
21
+ </frameset>
22
+ <frame src="files/README.html" name="docwin" />
23
+ </frameset>
24
+ </html>
@@ -0,0 +1,208 @@
1
+
2
+ body {
3
+ font-family: Verdana,Arial,Helvetica,sans-serif;
4
+ font-size: 90%;
5
+ margin: 0;
6
+ margin-left: 40px;
7
+ padding: 0;
8
+ background: white;
9
+ }
10
+
11
+ h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
12
+ h1 { font-size: 150%; }
13
+ h2,h3,h4 { margin-top: 1em; }
14
+
15
+ a { background: #eef; color: #039; text-decoration: none; }
16
+ a:hover { background: #039; color: #eef; }
17
+
18
+ /* Override the base stylesheet's Anchor inside a table cell */
19
+ td > a {
20
+ background: transparent;
21
+ color: #039;
22
+ text-decoration: none;
23
+ }
24
+
25
+ /* and inside a section title */
26
+ .section-title > a {
27
+ background: transparent;
28
+ color: #eee;
29
+ text-decoration: none;
30
+ }
31
+
32
+ /* === Structural elements =================================== */
33
+
34
+ div#index {
35
+ margin: 0;
36
+ margin-left: -40px;
37
+ padding: 0;
38
+ font-size: 90%;
39
+ }
40
+
41
+
42
+ div#index a {
43
+ margin-left: 0.7em;
44
+ }
45
+
46
+ div#index .section-bar {
47
+ margin-left: 0px;
48
+ padding-left: 0.7em;
49
+ background: #ccc;
50
+ font-size: small;
51
+ }
52
+
53
+
54
+ div#classHeader, div#fileHeader {
55
+ width: auto;
56
+ color: white;
57
+ padding: 0.5em 1.5em 0.5em 1.5em;
58
+ margin: 0;
59
+ margin-left: -40px;
60
+ border-bottom: 3px solid #006;
61
+ }
62
+
63
+ div#classHeader a, div#fileHeader a {
64
+ background: inherit;
65
+ color: white;
66
+ }
67
+
68
+ div#classHeader td, div#fileHeader td {
69
+ background: inherit;
70
+ color: white;
71
+ }
72
+
73
+
74
+ div#fileHeader {
75
+ background: #057;
76
+ }
77
+
78
+ div#classHeader {
79
+ background: #048;
80
+ }
81
+
82
+
83
+ .class-name-in-header {
84
+ font-size: 180%;
85
+ font-weight: bold;
86
+ }
87
+
88
+
89
+ div#bodyContent {
90
+ padding: 0 1.5em 0 1.5em;
91
+ }
92
+
93
+ div#description {
94
+ padding: 0.5em 1.5em;
95
+ background: #efefef;
96
+ border: 1px dotted #999;
97
+ }
98
+
99
+ div#description h1,h2,h3,h4,h5,h6 {
100
+ color: #125;;
101
+ background: transparent;
102
+ }
103
+
104
+ div#validator-badges {
105
+ text-align: center;
106
+ }
107
+ div#validator-badges img { border: 0; }
108
+
109
+ div#copyright {
110
+ color: #333;
111
+ background: #efefef;
112
+ font: 0.75em sans-serif;
113
+ margin-top: 5em;
114
+ margin-bottom: 0;
115
+ padding: 0.5em 2em;
116
+ }
117
+
118
+
119
+ /* === Classes =================================== */
120
+
121
+ table.header-table {
122
+ color: white;
123
+ font-size: small;
124
+ }
125
+
126
+ .type-note {
127
+ font-size: small;
128
+ color: #DEDEDE;
129
+ }
130
+
131
+ .xxsection-bar {
132
+ background: #eee;
133
+ color: #333;
134
+ padding: 3px;
135
+ }
136
+
137
+ .section-bar {
138
+ color: #333;
139
+ border-bottom: 1px solid #999;
140
+ margin-left: -20px;
141
+ }
142
+
143
+
144
+ .section-title {
145
+ background: #79a;
146
+ color: #eee;
147
+ padding: 3px;
148
+ margin-top: 2em;
149
+ margin-left: -30px;
150
+ border: 1px solid #999;
151
+ }
152
+
153
+ .top-aligned-row { vertical-align: top }
154
+ .bottom-aligned-row { vertical-align: bottom }
155
+
156
+ /* --- Context section classes ----------------------- */
157
+
158
+ .context-row { }
159
+ .context-item-name { font-family: monospace; font-weight: bold; color: black; }
160
+ .context-item-value { font-size: small; color: #448; }
161
+ .context-item-desc { color: #333; padding-left: 2em; }
162
+
163
+ /* --- Method classes -------------------------- */
164
+ .method-detail {
165
+ background: #efefef;
166
+ padding: 0;
167
+ margin-top: 0.5em;
168
+ margin-bottom: 1em;
169
+ border: 1px dotted #ccc;
170
+ }
171
+ .method-heading {
172
+ color: black;
173
+ background: #ccc;
174
+ border-bottom: 1px solid #666;
175
+ padding: 0.2em 0.5em 0 0.5em;
176
+ }
177
+ .method-signature { color: black; background: inherit; }
178
+ .method-name { font-weight: bold; }
179
+ .method-args { font-style: italic; }
180
+ .method-description { padding: 0 0.5em 0 0.5em; }
181
+
182
+ /* --- Source code sections -------------------- */
183
+
184
+ a.source-toggle { font-size: 90%; }
185
+ div.method-source-code {
186
+ background: #262626;
187
+ color: #ffdead;
188
+ margin: 1em;
189
+ padding: 0.5em;
190
+ border: 1px dashed #999;
191
+ overflow: hidden;
192
+ }
193
+
194
+ div.method-source-code pre { color: #ffdead; overflow: hidden; }
195
+
196
+ /* --- Ruby keyword styles --------------------- */
197
+
198
+ .standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
199
+
200
+ .ruby-constant { color: #7fffd4; background: transparent; }
201
+ .ruby-keyword { color: #00ffff; background: transparent; }
202
+ .ruby-ivar { color: #eedd82; background: transparent; }
203
+ .ruby-operator { color: #00ffee; background: transparent; }
204
+ .ruby-identifier { color: #ffdead; background: transparent; }
205
+ .ruby-node { color: #ffa07a; background: transparent; }
206
+ .ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
207
+ .ruby-regexp { color: #ffa07a; background: transparent; }
208
+ .ruby-value { color: #7fffd4; background: transparent; }
@@ -0,0 +1,300 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.dirname(__FILE__) + "/../../lib"
4
+ require 'rubygems'
5
+ require 'camping'
6
+
7
+ Camping.goes :Blog
8
+
9
+ module Blog::Models
10
+ def self.schema(&block)
11
+ @@schema = block if block_given?
12
+ @@schema
13
+ end
14
+
15
+ class Post < Base; belongs_to :user; end
16
+ class Comment < Base; belongs_to :user; end
17
+ class User < Base; end
18
+ end
19
+
20
+ Blog::Models.schema do
21
+ create_table :blog_posts, :force => true do |t|
22
+ t.column :id, :integer, :null => false
23
+ t.column :user_id, :integer, :null => false
24
+ t.column :title, :string, :limit => 255
25
+ t.column :body, :text
26
+ end
27
+ create_table :blog_users, :force => true do |t|
28
+ t.column :id, :integer, :null => false
29
+ t.column :username, :string
30
+ t.column :password, :string
31
+ end
32
+ create_table :blog_comments, :force => true do |t|
33
+ t.column :id, :integer, :null => false
34
+ t.column :post_id, :integer, :null => false
35
+ t.column :username, :string
36
+ t.column :body, :text
37
+ end
38
+ execute "INSERT INTO blog_users (username, password) VALUES ('admin', 'camping')"
39
+ end
40
+
41
+ module Blog::Controllers
42
+ class Index < R '/'
43
+ def get
44
+ @posts = Post.find :all
45
+ render :index
46
+ end
47
+ end
48
+
49
+ class Add
50
+ def get
51
+ unless cookies.user_id.blank?
52
+ @session = User.find cookies.user_id
53
+ @post = Post.new
54
+ end
55
+ render :add
56
+ end
57
+ def post
58
+ post = Post.create :title => input.post_title, :body => input.post_body,
59
+ :user_id => @cookies.user_id
60
+ redirect View, post
61
+ end
62
+ end
63
+
64
+ class Info < R '/info/(\d+)', '/info/(\w+)/(\d+)', '/info', '/info/(\d+)/(\d+)/(\d+)/([\w-]+)'
65
+ def get(*args)
66
+ div do
67
+ code args.inspect; br; br
68
+ code ENV.inspect; br
69
+ code "Link: #{R(Info, 1, 2)}"
70
+ end
71
+ end
72
+ end
73
+
74
+ class View < R '/view/(\d+)'
75
+ def get post_id
76
+ @post = Post.find post_id
77
+ @comments = Models::Comment.find :all, :conditions => ['post_id = ?', post_id]
78
+ render :view
79
+ end
80
+ end
81
+
82
+ class Edit < R '/edit/(\d+)', '/edit'
83
+ def get post_id
84
+ unless cookies.user_id.blank?
85
+ @session = User.find cookies.user_id
86
+ end
87
+ @post = Post.find post_id
88
+ render :edit
89
+ end
90
+
91
+ def post
92
+ @post = Post.find input.post_id
93
+ @post.update_attributes :title => input.post_title, :body => input.post_body
94
+ redirect View, @post
95
+ end
96
+ end
97
+
98
+ class Comment
99
+ def post
100
+ Models::Comment.create(:username => input.post_username,
101
+ :body => input.post_body, :post_id => input.post_id)
102
+ redirect View, input.post_id
103
+ end
104
+ end
105
+
106
+ class Login
107
+ def post
108
+ @user = User.find :first, :conditions => ['username = ? AND password = ?', input.username, input.password]
109
+
110
+ if @user
111
+ @login = 'login success !'
112
+ cookies.user_id = @user.id
113
+ else
114
+ @login = 'wrong user name or password'
115
+ end
116
+ render :login
117
+ end
118
+ end
119
+
120
+ class Logout
121
+ def get
122
+ cookies.user_id = nil
123
+ render :logout
124
+ end
125
+ end
126
+
127
+ class Style < R '/styles.css'
128
+ def get
129
+ @headers["Content-Type"] = "text/css; charset=utf-8"
130
+ @body = %{
131
+ body {
132
+ font-family: Utopia, Georga, serif;
133
+ }
134
+ h1.header {
135
+ background-color: #fef;
136
+ margin: 0; padding: 10px;
137
+ }
138
+ div.content {
139
+ padding: 10px;
140
+ }
141
+ }
142
+ end
143
+ end
144
+ end
145
+
146
+ module Blog::Views
147
+
148
+ def layout
149
+ html do
150
+ head do
151
+ title 'blog'
152
+ link :rel => 'stylesheet', :type => 'text/css',
153
+ :href => '/styles.css', :media => 'screen'
154
+ end
155
+ body do
156
+ h1.header { a 'blog', :href => R(Index) }
157
+ div.content do
158
+ self << yield
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ def index
165
+ if @posts.empty?
166
+ p 'No posts found.'
167
+ p { a 'Add', :href => R(Add) }
168
+ else
169
+ for post in @posts
170
+ _post(post)
171
+ end
172
+ end
173
+ end
174
+
175
+ def login
176
+ p { b @login }
177
+ p { a 'Continue', :href => R(Add) }
178
+ end
179
+
180
+ def logout
181
+ p "You have been logged out."
182
+ p { a 'Continue', :href => R(Index) }
183
+ end
184
+
185
+ def add
186
+ if @session
187
+ _form(post, :action => R(Add))
188
+ else
189
+ _login
190
+ end
191
+ end
192
+
193
+ def edit
194
+ if @session
195
+ _form(post, :action => R(Edit))
196
+ else
197
+ _login
198
+ end
199
+ end
200
+
201
+ def view
202
+ _post(post)
203
+
204
+ p "Comment for this post:"
205
+ for c in @comments
206
+ h1 c.username
207
+ p c.body
208
+ end
209
+
210
+ form :action => R(Comment), :method => 'post' do
211
+ label 'Name', :for => 'post_username'; br
212
+ input :name => 'post_username', :type => 'text'; br
213
+ label 'Comment', :for => 'post_body'; br
214
+ textarea :name => 'post_body' do; end; br
215
+ input :type => 'hidden', :name => 'post_id', :value => post.id
216
+ input :type => 'submit'
217
+ end
218
+ end
219
+
220
+ # partials
221
+ def _login
222
+ form :action => R(Login), :method => 'post' do
223
+ label 'Username', :for => 'username'; br
224
+ input :name => 'username', :type => 'text'; br
225
+
226
+ label 'Password', :for => 'password'; br
227
+ input :name => 'password', :type => 'text'; br
228
+
229
+ input :type => 'submit', :name => 'login', :value => 'Login'
230
+ end
231
+ end
232
+
233
+ def _post(post)
234
+ h1 post.title
235
+ p post.body
236
+ p do
237
+ a "Edit", :href => R(Edit, post)
238
+ a "View", :href => R(View, post)
239
+ end
240
+ end
241
+
242
+ def _form(post, opts)
243
+ p do
244
+ text "You are logged in as #{@session.username} | "
245
+ a 'Logout', :href => R(Logout)
246
+ end
247
+ form({:method => 'post'}.merge(opts)) do
248
+ label 'Title', :for => 'post_title'; br
249
+ input :name => 'post_title', :type => 'text',
250
+ :value => post.title; br
251
+
252
+ label 'Body', :for => 'post_body'; br
253
+ textarea post.body, :name => 'post_body'; br
254
+
255
+ input :type => 'hidden', :name => 'post_id', :value => post.id
256
+ input :type => 'submit'
257
+ end
258
+ end
259
+ end
260
+
261
+ def Blog.create
262
+ unless Blog::Models::Post.table_exists?
263
+ ActiveRecord::Schema.define(&Blog::Models.schema)
264
+ puts "** The blog.db file has been created."
265
+ puts "** When adding/editing posts -- username: admin, password: camping"
266
+ end
267
+ end
268
+
269
+ if __FILE__ == $0
270
+ require 'thread'
271
+
272
+ class CampingHandler < Mongrel::HttpHandler
273
+ def initialize(klass)
274
+ @klass = klass
275
+ end
276
+ def process(request, response)
277
+ req = StringIO.new(request.body)
278
+ controller = @klass.run(req, request.params)
279
+ response.start(controller.status) do |head,out|
280
+ controller.headers.each do |k, v|
281
+ [*v].each do |vi|
282
+ head[k] = vi
283
+ end
284
+ end
285
+ out << controller.body
286
+ end
287
+ end
288
+ end
289
+
290
+ Blog::Models::Base.establish_connection :adapter => 'sqlite3', :database => 'blog.db'
291
+ Blog::Models::Base.logger = Logger.new('camping.log')
292
+ Blog::Models::Base.threaded_connections=false
293
+ Blog.create
294
+
295
+ h = Mongrel::HttpServer.new("0.0.0.0", "3000")
296
+ puts "** Blog example is running at http://localhost:3000/blog"
297
+ h.register("/blog", CampingHandler.new(Blog))
298
+ h.register("/favicon.ico", Mongrel::Error404Handler.new(""))
299
+ h.run.join
300
+ end