reststop 0.4.1 → 0.5.1

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