reststop 0.4.1 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,13 @@
1
+ === 0.5.1 :: 2010-06-09
2
+ * Update to align with the post 2.0 enhancements in Camping related to Tilt support.
3
+ Since Tilt support is now checking for the existing of view methods and Tilt views
4
+ RESTstop needs to ensure that view methods can be looked up in Views:HTML as opposed to Views.
5
+
6
+ === 0.5.0 :: 2010-04-07
7
+
8
+ * Major refactoring for compatibility with Camping 2.0. Thanks to Philippe Monnet
9
+ for completing the work.
10
+
1
11
  === 0.4.1 :: 2009-05-08
2
12
 
3
13
  * Custom actions should now work again (needed to make some more changes for
@@ -1,165 +1,22 @@
1
- GNU LESSER GENERAL PUBLIC LICENSE
2
- Version 3, 29 June 2007
3
-
4
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
- Everyone is permitted to copy and distribute verbatim copies
6
- of this license document, but changing it is not allowed.
7
-
8
-
9
- This version of the GNU Lesser General Public License incorporates
10
- the terms and conditions of version 3 of the GNU General Public
11
- License, supplemented by the additional permissions listed below.
12
-
13
- 0. Additional Definitions.
14
-
15
- As used herein, "this License" refers to version 3 of the GNU Lesser
16
- General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
- General Public License.
18
-
19
- "The Library" refers to a covered work governed by this License,
20
- other than an Application or a Combined Work as defined below.
21
-
22
- An "Application" is any work that makes use of an interface provided
23
- by the Library, but which is not otherwise based on the Library.
24
- Defining a subclass of a class defined by the Library is deemed a mode
25
- of using an interface provided by the Library.
26
-
27
- A "Combined Work" is a work produced by combining or linking an
28
- Application with the Library. The particular version of the Library
29
- with which the Combined Work was made is also called the "Linked
30
- Version".
31
-
32
- The "Minimal Corresponding Source" for a Combined Work means the
33
- Corresponding Source for the Combined Work, excluding any source code
34
- for portions of the Combined Work that, considered in isolation, are
35
- based on the Application, and not on the Linked Version.
36
-
37
- The "Corresponding Application Code" for a Combined Work means the
38
- object code and/or source code for the Application, including any data
39
- and utility programs needed for reproducing the Combined Work from the
40
- Application, but excluding the System Libraries of the Combined Work.
41
-
42
- 1. Exception to Section 3 of the GNU GPL.
43
-
44
- You may convey a covered work under sections 3 and 4 of this License
45
- without being bound by section 3 of the GNU GPL.
46
-
47
- 2. Conveying Modified Versions.
48
-
49
- If you modify a copy of the Library, and, in your modifications, a
50
- facility refers to a function or data to be supplied by an Application
51
- that uses the facility (other than as an argument passed when the
52
- facility is invoked), then you may convey a copy of the modified
53
- version:
54
-
55
- a) under this License, provided that you make a good faith effort to
56
- ensure that, in the event an Application does not supply the
57
- function or data, the facility still operates, and performs
58
- whatever part of its purpose remains meaningful, or
59
-
60
- b) under the GNU GPL, with none of the additional permissions of
61
- this License applicable to that copy.
62
-
63
- 3. Object Code Incorporating Material from Library Header Files.
64
-
65
- The object code form of an Application may incorporate material from
66
- a header file that is part of the Library. You may convey such object
67
- code under terms of your choice, provided that, if the incorporated
68
- material is not limited to numerical parameters, data structure
69
- layouts and accessors, or small macros, inline functions and templates
70
- (ten or fewer lines in length), you do both of the following:
71
-
72
- a) Give prominent notice with each copy of the object code that the
73
- Library is used in it and that the Library and its use are
74
- covered by this License.
75
-
76
- b) Accompany the object code with a copy of the GNU GPL and this license
77
- document.
78
-
79
- 4. Combined Works.
80
-
81
- You may convey a Combined Work under terms of your choice that,
82
- taken together, effectively do not restrict modification of the
83
- portions of the Library contained in the Combined Work and reverse
84
- engineering for debugging such modifications, if you also do each of
85
- the following:
86
-
87
- a) Give prominent notice with each copy of the Combined Work that
88
- the Library is used in it and that the Library and its use are
89
- covered by this License.
90
-
91
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
- document.
93
-
94
- c) For a Combined Work that displays copyright notices during
95
- execution, include the copyright notice for the Library among
96
- these notices, as well as a reference directing the user to the
97
- copies of the GNU GPL and this license document.
98
-
99
- d) Do one of the following:
100
-
101
- 0) Convey the Minimal Corresponding Source under the terms of this
102
- License, and the Corresponding Application Code in a form
103
- suitable for, and under terms that permit, the user to
104
- recombine or relink the Application with a modified version of
105
- the Linked Version to produce a modified Combined Work, in the
106
- manner specified by section 6 of the GNU GPL for conveying
107
- Corresponding Source.
108
-
109
- 1) Use a suitable shared library mechanism for linking with the
110
- Library. A suitable mechanism is one that (a) uses at run time
111
- a copy of the Library already present on the user's computer
112
- system, and (b) will operate properly with a modified version
113
- of the Library that is interface-compatible with the Linked
114
- Version.
115
-
116
- e) Provide Installation Information, but only if you would otherwise
117
- be required to provide such information under section 6 of the
118
- GNU GPL, and only to the extent that such information is
119
- necessary to install and execute a modified version of the
120
- Combined Work produced by recombining or relinking the
121
- Application with a modified version of the Linked Version. (If
122
- you use option 4d0, the Installation Information must accompany
123
- the Minimal Corresponding Source and Corresponding Application
124
- Code. If you use option 4d1, you must provide the Installation
125
- Information in the manner specified by section 6 of the GNU GPL
126
- for conveying Corresponding Source.)
127
-
128
- 5. Combined Libraries.
129
-
130
- You may place library facilities that are a work based on the
131
- Library side by side in a single library together with other library
132
- facilities that are not Applications and are not covered by this
133
- License, and convey such a combined library under terms of your
134
- choice, if you do both of the following:
135
-
136
- a) Accompany the combined library with a copy of the same work based
137
- on the Library, uncombined with any other library facilities,
138
- conveyed under the terms of this License.
139
-
140
- b) Give prominent notice with the combined library that part of it
141
- is a work based on the Library, and explaining where to find the
142
- accompanying uncombined form of the same work.
143
-
144
- 6. Revised Versions of the GNU Lesser General Public License.
145
-
146
- The Free Software Foundation may publish revised and/or new versions
147
- of the GNU Lesser General Public License from time to time. Such new
148
- versions will be similar in spirit to the present version, but may
149
- differ in detail to address new problems or concerns.
150
-
151
- Each version is given a distinguishing version number. If the
152
- Library as you received it specifies that a certain numbered version
153
- of the GNU Lesser General Public License "or any later version"
154
- applies to it, you have the option of following the terms and
155
- conditions either of that published version or of any later version
156
- published by the Free Software Foundation. If the Library as you
157
- received it does not specify a version number of the GNU Lesser
158
- General Public License, you may choose any version of the GNU Lesser
159
- General Public License ever published by the Free Software Foundation.
160
-
161
- If the Library as you received it specifies that a proxy can decide
162
- whether future versions of the GNU Lesser General Public License shall
163
- apply, that proxy's public statement of acceptance of any version is
164
- permanent authorization for you to choose that version for the
165
- Library.
1
+ Copyright (c) 2010 the Contributors (see http://github.com/zuk/reststop/commits/master)
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -10,5 +10,3 @@ examples/blog.rb
10
10
  lib/reststop.rb
11
11
  lib/reststop/version.rb
12
12
  setup.rb
13
- test/reststop_test.rb
14
- test/test_helper.rb
data/README.txt CHANGED
@@ -1,18 +1,18 @@
1
1
  = Reststop
2
2
 
3
3
  <b>Reststop makes it easy to write RESTful[http://en.wikipedia.org/wiki/Representational_State_Transfer]
4
- applications in Camping[http://camping.rubyforge.org/files/README.html].</b>
4
+ applications in Camping[http://github.com/camping/camping].</b>
5
5
 
6
- For info and downloads please see http://rubyforge.org/projects/reststop
6
+ For info and downloads please see http://github.com/camping/reststop
7
7
 
8
8
 
9
- *Author*:: Matt Zukowski (matt at roughest dot net)
10
- *Copyright*:: Copyright (c) 2007 Urbacon Ltd.
11
- *License*:: GNU Lesser General Public License Version 3
9
+ *Authors*:: Matt Zukowski and Philippe Monnet (see http://github.com/camping/reststop/commits/master)
10
+ *Copyright*:: Copyright (c) 2010 Urbacon Ltd.
11
+ *License*:: MIT License[http://en.wikipedia.org/wiki/MIT_License]
12
12
 
13
13
 
14
14
  For an example of a complete Reststop-based Camping app, have a look at
15
- http://reststop.rubyforge.org/svn/trunk/examples/blog.rb
15
+ http://github.com/zuk/reststop/blob/master/examples/blog.rb
16
16
 
17
17
  Reststop essentially gives you three things:
18
18
 
@@ -24,7 +24,7 @@ Reststop essentially gives you three things:
24
24
  * destroy (DELETE)
25
25
  * list (GET)
26
26
 
27
- Custom actions are also possible. See the Camping::Controllers#REST method documentation for usage info.
27
+ Custom actions are also possible. See the Reststop::Controllers#REST method documentation for usage info.
28
28
 
29
29
  <b>2. Camping views grouped by output format:</b>
30
30
 
@@ -102,15 +102,25 @@ but here's a simple example of RESTful interaction with Restr:
102
102
 
103
103
  == License
104
104
 
105
- Reststop is free software; you can redistribute it and/or modify
106
- it under the terms of the GNU Lesser General Public License as published
107
- by the Free Software Foundation; either version 3 of the License, or
108
- (at your option) any later version.
109
-
110
- Reststop is distributed in the hope that it will be useful,
111
- but WITHOUT ANY WARRANTY; without even the implied warranty of
112
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
113
- GNU General Public License for more details.
114
-
115
- You should have received a copy of the GNU Lesser General Public License
116
- along with this program. If not, see <http://www.gnu.org/licenses/>.
105
+ Copyright (c) 2010 the Contributors (see http://github.com/camping/reststop/commits/master)
106
+
107
+ Permission is hereby granted, free of charge, to any person
108
+ obtaining a copy of this software and associated documentation
109
+ files (the "Software"), to deal in the Software without
110
+ restriction, including without limitation the rights to use,
111
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
112
+ copies of the Software, and to permit persons to whom the
113
+ Software is furnished to do so, subject to the following
114
+ conditions:
115
+
116
+ The above copyright notice and this permission notice shall be
117
+ included in all copies or substantial portions of the Software.
118
+
119
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
120
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
121
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
122
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
123
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
124
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
125
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
126
+ OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,7 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
3
  require 'rake/clean'
4
- require 'rake/testtask'
5
4
  require 'rake/packagetask'
6
5
  require 'rake/gempackagetask'
7
6
  require 'rake/rdoctask'
@@ -46,7 +45,6 @@ hoe = Hoe.new(GEM_NAME, VERS) do |p|
46
45
  p.summary = DESCRIPTION
47
46
  p.url = HOMEPATH
48
47
  p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
49
- p.test_globs = ["test/**/*_test.rb"]
50
48
  p.clean_globs = CLEAN #An array of file patterns to delete on clean.
51
49
 
52
50
  # == Optional
@@ -1,345 +1,400 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- #
4
- # This is a RESTful version of the Camping-based Blog application.
5
- #
6
- # The original version can be found here:
7
- # http://code.whytheluckystiff.net/camping/browser/trunk/examples/blog.rb
8
- #
9
-
10
3
  require 'rubygems'
4
+ #require 'ruby-debug' # @techarch : commented out since only needed for local debugging
5
+
6
+ require 'markaby' # @techarch : added explicit require
7
+ require 'camping' # @techarch
8
+ require 'camping/session' # @techarch : added explicit require since session has changed in Camping 2.0
9
+
10
+ gem 'RedCloth' # @techarch : added since it is referenced in the Posts model
11
+ require 'redcloth' # @techarch : added
11
12
 
12
- gem 'camping', '~> 1.5'
13
- gem 'reststop', '~> 0.2'
13
+ #gem 'camping', '~> 2.0'
14
+ gem 'camping' , '>= 2.0' # @techarch : updated version
14
15
 
15
- require 'camping'
16
- require 'camping/db'
16
+ #gem 'reststop', '~> 0.3'
17
+
18
+ =begin # @techarch : commented out since only needed for local debugging
19
+ $: << '../../camping/lib'
20
+ $: << '../lib'
21
+ require 'camping-unabridged'
22
+ require 'camping/ar'
17
23
  require 'camping/session'
24
+ =end
18
25
 
19
- begin
26
+ #begin # @techarch : commented out since only needed for local debugging
20
27
  # try to use local copy of library
21
- require '../lib/reststop'
22
- rescue LoadError
23
- # ... otherwise default to rubygem
24
- require 'reststop'
25
- end
26
-
28
+ #require '../lib/reststop2'
29
+ $: << '../lib/'
30
+ require 'reststop.rb' # @techarch : adjusted so that it is located in the same current folder
31
+ #rescue LoadError
32
+ # # ... otherwise default to rubygem
33
+ # require 'reststop'
34
+ #end
35
+
27
36
  Camping.goes :Blog
28
37
 
29
38
  module Blog
30
- include Camping::Session
39
+ include Camping::Session
40
+ include Reststop
41
+
42
+ Controllers.extend Reststop::Controllers
31
43
  end
32
44
 
33
- module Blog::Models
34
- class Post < Base
35
- belongs_to :user
36
- has_many :comments
45
+ module Blog::Base
46
+ alias camping_render render
47
+ alias camping_lookup lookup # @techarch: required if camping > 2.0
48
+ alias camping_service service
49
+ include Reststop::Base
50
+ alias service reststop_service
51
+ alias render reststop_render
52
+
53
+ # Overrides the new Tilt-centric lookup method In camping
54
+ # RESTstop needs to have a first try at looking up the view
55
+ # located in the Views::HTML module.
56
+ def lookup(n)
57
+ T.fetch(n.to_sym) do |k|
58
+ t = Blog::Views::HTML.method_defined?(k) || camping_lookup(n)
59
+ end
37
60
  end
38
- class Comment < Base
39
- belongs_to :user
61
+ end
62
+
63
+ module Blog::Models
64
+ class Post < Base
65
+ belongs_to :user
66
+
67
+ before_save do |record|
68
+ cloth = RedCloth.new(record.body)
69
+ cloth.hard_breaks = false
70
+ record.html_body = cloth.to_html
40
71
  end
41
- class User < Base; end
42
-
43
- class CreateTheBasics < V 1.0
44
- def self.up
45
- create_table :blog_posts do |t|
46
- t.column :user_id, :integer, :null => false
47
- t.column :title, :string, :limit => 255
48
- t.column :body, :text
49
- end
50
- create_table :blog_users do |t|
51
- t.column :username, :string
52
- t.column :password, :string
53
- end
54
- create_table :blog_comments do |t|
55
- t.column :post_id, :integer, :null => false
56
- t.column :username, :string
57
- t.column :body, :text
58
- end
59
- User.create :username => 'admin', :password => 'camping'
72
+ end
73
+
74
+ class Comment < Base; belongs_to :user; end
75
+ class User < Base; end
76
+
77
+ class BasicFields < V 1.1
78
+ def self.up
79
+ create_table :blog_posts, :force => true do |t|
80
+ t.integer :user_id, :null => false
81
+ t.string :title, :limit => 255
82
+ t.text :body, :html_body
83
+ t.timestamps
84
+ end
85
+ create_table :blog_users, :force => true do |t|
86
+ t.string :username, :password
60
87
  end
61
- def self.down
62
- drop_table :blog_posts
63
- drop_table :blog_users
64
- drop_table :blog_comments
88
+ create_table :blog_comments, :force => true do |t|
89
+ t.integer :post_id, :null => false
90
+ t.string :username
91
+ t.text :body, :html_body
92
+ t.timestamps
65
93
  end
94
+ User.create :username => 'admin', :password => 'camping'
66
95
  end
96
+
97
+ def self.down
98
+ drop_table :blog_posts
99
+ drop_table :blog_users
100
+ drop_table :blog_comments
101
+ end
102
+ end
67
103
  end
68
104
 
69
105
  module Blog::Controllers
106
+ extend Reststop::Controllers
107
+ class Index
108
+ def get
109
+ redirect '/posts'
110
+ end
111
+ end
112
+
113
+ class Login < R '/login' # @techarch : added explicit login controller
114
+ def get
115
+ render :_login
116
+ end
117
+ end
118
+
70
119
  class Posts < REST 'posts'
120
+ # POST /posts
121
+ def create
122
+ require_login!
123
+ @post = Post.create :title => (input.post_title || input.title), # @techarch : allow for REST-client based update
124
+ :body => (input.post_body || input.body), # @techarch : allow for REST-client based update
125
+ :user_id => @state.user_id
126
+ redirect R(@post)
127
+ end
71
128
 
72
- # POST /posts
73
- def create
74
- unless @state.user_id.blank?
75
- post = Post.create :title => input.post_title, :body => input.post_body,
76
- :user_id => @state.user_id
77
- redirect R(Posts)
78
- else
79
- _error("Unauthorized", 401)
80
- end
81
- end
129
+ # GET /posts/1
130
+ # GET /posts/1.xml
131
+ def read(post_id)
132
+ @post = Post.find(post_id)
133
+ @comments = Models::Comment.find(:all, :conditions => ['post_id = ?', post_id])
134
+ render :view
135
+ end
82
136
 
83
- # GET /posts/1
84
- # GET /posts/1.xml
85
- def read(post_id)
86
- @post = Post.find post_id
87
- @comments = Models::Comment.find :all, :conditions => ['post_id = ?', post_id]
88
- render :view
89
- end
137
+ # PUT /posts/1
138
+ def update(post_id)
139
+ require_login!
140
+ @post = Post.find(post_id)
141
+ @post.update_attributes :title => (input.post_title || input.title), # @techarch : allow for REST-client based update
142
+ :body => (input.post_body || input.body) # @techarch : allow for REST-client based update
143
+ redirect R(@post)
144
+ end
90
145
 
91
- # PUT /posts/1
92
- def update(post_id)
93
- unless @state.user_id.blank?
94
- @post = Post.find post_id
95
- @post.update_attributes :title => input.post_title, :body => input.post_body
96
- redirect R(@post)
97
- else
98
- _error("Unauthorized", 401)
99
- end
100
- end
146
+ # DELETE /posts/1
147
+ def delete(post_id)
148
+ require_login!
149
+ @post = Post.find post_id
101
150
 
102
- # DELETE /posts/1
103
- def delete(post_id)
104
- unless @state.user_id.blank?
105
- @post = Post.find post_id
106
-
107
- if @post.destroy
108
- redirect R(Posts)
109
- else
110
- _error("Unable to delete post #{@post.id}", 500)
111
- end
112
- else
113
- _error("Unauthorized", 401)
114
- end
151
+ if @post.destroy
152
+ redirect R(Posts)
153
+ else
154
+ _error("Unable to delete post #{@post.id}", 500)
115
155
  end
156
+ end
116
157
 
117
- # GET /posts
118
- # GET /posts.xml
119
- def list
120
- @posts = Post.find :all
121
- render :index
122
- end
123
-
124
-
125
- # GET /posts/new
126
- def new
127
- unless @state.user_id.blank?
128
- @user = User.find @state.user_id
129
- @post = Post.new
130
- end
131
- render :add
132
- end
158
+ # GET /posts
159
+ # GET /posts.xml
160
+ def list
161
+ @posts = Post.all(:order => 'updated_at DESC')
162
+ s=render :index
163
+ s
164
+ end
133
165
 
134
- # GET /posts/1/edit
135
- def edit(post_id)
136
- unless @state.user_id.blank?
137
- @user = User.find @state.user_id
138
- end
139
- @post = Post.find post_id
140
- render :edit
141
- end
142
-
143
- # GET /posts/info
144
- def info
145
- div do
146
- code args.inspect; br; br
147
- code @env.inspect; br
148
- code "Link: #{R(Info, 1, 2)}"
149
- end
150
- end
166
+ # GET /posts/new
167
+ def new
168
+ #@state.user_id = 1 # @techarch : commented out as was probably hard-coded for testing purpose
169
+ require_login!
170
+ @user = User.find @state.user_id # @techarch : added since we need the user info
171
+ @post = Post.new
172
+ render :add
173
+ end
174
+
175
+ # GET /posts/1/edit
176
+ def edit(post_id)
177
+ require_login!
178
+ @user = User.find @state.user_id # @techarch : added since we need the user info
179
+ @post = Post.find(post_id)
180
+ render :edit
181
+ end
151
182
  end
152
183
 
153
184
  class Comments < REST 'comments'
154
- # POST /comments
155
- def create
156
- Models::Comment.create(:username => input.post_username,
157
- :body => input.post_body, :post_id => input.post_id)
158
- redirect R(Posts, input.post_id)
159
- end
185
+ # POST /comments
186
+ def create
187
+ Models::Comment.create(:username => (input.post_username || input.username), # @techarch : allow for REST-client based update
188
+ :body => (input.post_body || input.body), # @techarch : allow for REST-client based update
189
+ :post_id => input.post_id)
190
+ redirect R(Posts, input.post_id)
191
+ end
160
192
  end
161
-
193
+
162
194
  class Sessions < REST 'sessions'
163
195
  # POST /sessions
164
196
  def create
165
- @user = User.find :first, :conditions => ['username = ? AND password = ?', input.username, input.password]
166
-
167
- if @user
168
- @login = 'login success !'
169
- @state.user_id = @user.id
170
- else
171
- @login = 'wrong user name or password'
172
- end
173
- render :login
197
+ @user = User.find_by_username_and_password(input.username, input.password)
198
+
199
+ if @user
200
+ @state.user_id = @user.id
201
+ redirect R(Posts)
202
+ else
203
+ @info = 'Wrong username or password.'
204
+ end
205
+ render :login
174
206
  end
175
207
 
176
208
  # DELETE /sessions
177
209
  def delete
178
- @state.user_id = nil
179
- render :logout
210
+ @state.user_id = nil
211
+ redirect R(Posts) # @techarch : changed redirect from Index (does not exist) to Posts
180
212
  end
181
213
  end
182
214
 
183
215
  # You can use old-fashioned Camping controllers too!
184
216
  class Style < R '/styles.css'
185
- def get
186
- @headers["Content-Type"] = "text/css; charset=utf-8"
187
- @body = %{
188
- body {
189
- font-family: Utopia, Georga, serif;
190
- }
191
- h1.header {
192
- background-color: #fef;
193
- margin: 0; padding: 10px;
194
- }
195
- div.content {
196
- padding: 10px;
197
- }
198
- }
199
- end
217
+ def get
218
+ @headers["Content-Type"] = "text/css; charset=utf-8"
219
+ @body = %{
220
+ body {
221
+ font-family: Utopia, Georga, serif;
222
+ }
223
+ h1.header {
224
+ background-color: #fef;
225
+ margin: 0; padding: 10px;
226
+ }
227
+ div.content {
228
+ padding: 10px;
229
+ }
230
+ }
231
+ end
200
232
  end
201
233
  end
202
234
 
235
+ module Blog::Helpers
236
+ alias_method :_R, :R
237
+ remove_method :R
238
+ include Reststop::Helpers
239
+
240
+ def logged_in?
241
+ !!@state.user_id
242
+ end
243
+
244
+ def require_login!
245
+ unless logged_in?
246
+ redirect(R(Blog::Controllers::Login)) # @techarch: add explicit route
247
+ throw :halt
248
+ end
249
+ end
250
+ end
203
251
 
204
- Markaby::Builder.set(:indent, 2)
205
252
 
206
253
  module Blog::Views
207
- module HTML
208
- include Blog::Controllers
209
-
210
- def layout
211
- html do
212
- head do
213
- title 'blog'
214
- link :rel => 'stylesheet', :type => 'text/css',
215
- :href => self/'/styles.css', :media => 'screen'
216
- end
217
- body do
218
- h1.header { a 'blog', :href => R(Posts) }
219
- div.content do
220
- self << yield
221
- end
222
- end
223
- end
224
- end
225
-
226
- def index
227
- if @posts.empty?
228
- p 'No posts found.'
229
- else
230
- for post in @posts
231
- _post(post)
232
- end
233
- end
234
- p { a 'Add', :href => R(Posts, 'new') }
235
- end
236
-
237
- def login
238
- p { b @login }
239
- p { a 'Continue', :href => R(Posts, 'new') }
240
- end
241
-
242
- def logout
243
- p "You have been logged out."
244
- p { a 'Continue', :href => R(Posts) }
245
- end
246
-
247
- def add
248
- if @user
249
- _form(@post, :action => R(Posts))
250
- else
251
- _login
252
- end
253
- end
254
-
255
- def edit
256
- if @user
257
- _form(@post, :action => R(@post), :method => :put)
258
- else
259
- _login
260
- end
261
- end
262
-
263
- def view
264
- _post(@post)
265
-
266
- p "Comment for this post:"
267
- for c in @comments
268
- h1 c.username
269
- p c.body
270
- end
271
-
272
- form :action => R(Comments), :method => 'post' do
273
- label 'Name', :for => 'post_username'; br
274
- input :name => 'post_username', :type => 'text'; br
275
- label 'Comment', :for => 'post_body'; br
276
- textarea :name => 'post_body' do; end; br
277
- input :type => 'hidden', :name => 'post_id', :value => @post.id
278
- input :type => 'submit'
279
- end
280
- end
281
-
282
- # partials
283
- def _login
284
- form :action => R(Sessions), :method => 'post' do
285
- label 'Username', :for => 'username'; br
286
- input :name => 'username', :type => 'text'; br
287
-
288
- label 'Password', :for => 'password'; br
289
- input :name => 'password', :type => 'text'; br
290
-
291
- input :type => 'submit', :name => 'login', :value => 'Login'
292
- end
254
+ extend Reststop::Views
255
+
256
+ module HTML
257
+ include Blog::Controllers
258
+ include Blog::Views
259
+
260
+ def layout
261
+ html do
262
+ head do
263
+ title 'blog'
264
+ link :rel => 'stylesheet', :type => 'text/css',
265
+ :href => self/'/styles.css', :media => 'screen'
293
266
  end
294
-
295
- def _post(post)
296
- h1 post.title
297
- p post.body
298
- p do
299
- [a("Edit", :href => R(Posts, post.id, 'edit')), a("View", :href => R(Posts, post.id, 'edit'))].join " | "
267
+ body do
268
+ h1.header { a 'blog', :href => R(Posts) }
269
+ div.content do
270
+ self << yield
300
271
  end
301
272
  end
302
-
303
- def _form(post, opts)
304
- form(:action => R(Sessions), :method => 'delete') do
305
- p do
306
- span "You are logged in as #{@user.username}"
307
- span " | "
308
- button(:type => 'submit') {'Logout'}
309
- end
310
- end
311
- form({:method => 'post'}.merge(opts)) do
312
- label 'Title', :for => 'post_title'; br
313
- input :name => 'post_title', :type => 'text',
314
- :value => post.title; br
315
-
316
- label 'Body', :for => 'post_body'; br
317
- textarea post.body, :name => 'post_body'; br
318
-
319
- input :type => 'hidden', :name => 'post_id', :value => post.id
320
- input :type => 'submit'
321
- end
273
+ end
274
+ end
275
+
276
+ def index
277
+ if @posts.empty?
278
+ p 'No posts found.'
279
+ else
280
+ for post in @posts
281
+ _post(post)
322
282
  end
283
+ end
284
+ p { a 'Add', :href => R(Posts, 'new') }
285
+ end
286
+
287
+ def login
288
+ p { b @login }
289
+ p { a 'Continue', :href => R(Posts, 'new') }
323
290
  end
324
- default_format :HTML
325
291
 
326
- module XML
327
- def layout
328
- yield
292
+ def logout
293
+ p "You have been logged out."
294
+ p { a 'Continue', :href => R(Posts) }
295
+ end
296
+
297
+ def add
298
+ if @user
299
+ _form(@post, :action => R(Posts))
300
+ else
301
+ _login
302
+ end
303
+ end
304
+
305
+ def edit
306
+ if @user
307
+ _form(@post, :action => R(@post), :method => :put)
308
+ else
309
+ _login
310
+ end
311
+ end
312
+
313
+ def view
314
+ _post(@post)
315
+
316
+ p "Comment for this post:"
317
+ for c in @comments
318
+ h1 c.username
319
+ p c.body
320
+ end
321
+
322
+ form :action => R(Comments), :method => 'post' do
323
+ label 'Name', :for => 'post_username'; br
324
+ input :name => 'post_username', :type => 'text'; br
325
+ label 'Comment', :for => 'post_body'; br
326
+ textarea :name => 'post_body' do; end; br
327
+ input :type => 'hidden', :name => 'post_id', :value => @post.id
328
+ input :type => 'submit'
329
+ end
330
+ end
331
+
332
+ # partials
333
+ def _login
334
+ p do
335
+ "(default: admin/camping)"
336
+ end
337
+ form :action => R(Sessions), :method => 'post' do
338
+ label 'Username', :for => 'username'; br
339
+ input :name => 'username', :type => 'text'; br
340
+
341
+ label 'Password', :for => 'password'; br
342
+ input :name => 'password', :type => 'text'; br
343
+
344
+ input :type => 'submit', :name => 'login', :value => 'Login'
345
+ end
346
+ end
347
+
348
+ def _post(post)
349
+ h1 post.title
350
+ p post.body
351
+ p do
352
+ [a("Edit", :href => R(Posts, post.id, 'edit')), a("View", :href => R(Posts, post.id, 'edit'))].join " | "
353
+ end
354
+ end
355
+
356
+ def _form(post, opts)
357
+ form(:action => R(Sessions), :method => 'delete') do
358
+ p do
359
+ span "You are logged in as #{@user.username}"
360
+ span " | "
361
+ button(:type => 'submit') {'Logout'}
329
362
  end
330
-
331
- def index
332
- @posts.to_xml(:root => 'blog')
333
363
  end
334
-
335
- def view
336
- @post.to_xml(:root => 'post')
364
+ form({:method => 'post'}.merge(opts)) do
365
+ label 'Title', :for => 'post_title'; br
366
+ input :name => 'post_title', :type => 'text',
367
+ :value => post.title; br
368
+
369
+ label 'Body', :for => 'post_body'; br
370
+ textarea post.body, :name => 'post_body'; br
371
+
372
+ input :type => 'hidden', :name => 'post_id', :value => post.id
373
+ input :type => 'submit'
337
374
  end
338
375
  end
376
+ end
377
+ default_format :HTML
378
+
379
+ module XML
380
+ def layout
381
+ yield
382
+ end
383
+
384
+ def index
385
+ @posts.to_xml(:root => 'blog')
386
+ end
387
+
388
+ def view
389
+ @post.to_xml(:root => 'post')
390
+ end
391
+ end
339
392
  end
340
393
 
341
394
  def Blog.create
342
- Camping::Models::Session.create_schema
343
- Blog::Models.create_schema :assume => (Blog::Models::Post.table_exists? ? 1.0 : 0.0)
344
- end
395
+ raise "You must configure the database first in 'config/database.yml'!" unless File.exist?('config/database.yml')
396
+ dbconfig = YAML.load(File.read('config/database.yml')) # @techarch
397
+ Camping::Models::Base.establish_connection dbconfig['development'] # @techarch
345
398
 
399
+ Blog::Models.create_schema :assume => (Blog::Models::Post.table_exists? ? 1.0 : 0.0)
400
+ end