restapi 0.0.3 → 0.0.4

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 (41) hide show
  1. data/Gemfile +2 -1
  2. data/Gemfile.lock +83 -64
  3. data/README.rdoc +375 -2
  4. data/app/controllers/restapi/restapis_controller.rb +21 -3
  5. data/app/helpers/restapi/restapis_helper.rb +31 -0
  6. data/app/public/restapi/javascripts/bundled/prettify.js +28 -0
  7. data/app/public/restapi/javascripts/restapi.js +4 -13
  8. data/app/public/restapi/stylesheets/bundled/prettify.css +30 -0
  9. data/app/views/layouts/restapi/restapi.html.erb +36 -0
  10. data/app/views/restapi/restapis/index.html.erb +35 -33
  11. data/app/views/restapi/restapis/method.html.erb +59 -0
  12. data/app/views/restapi/restapis/resource.html.erb +71 -0
  13. data/app/views/restapi/restapis/static.html.erb +103 -0
  14. data/lib/restapi.rb +0 -10
  15. data/lib/restapi/application.rb +25 -10
  16. data/lib/restapi/dsl_definition.rb +38 -32
  17. data/lib/restapi/markup.rb +12 -12
  18. data/lib/restapi/method_description.rb +10 -8
  19. data/lib/restapi/param_description.rb +23 -10
  20. data/lib/restapi/resource_description.rb +1 -1
  21. data/lib/restapi/restapi_module.rb +15 -0
  22. data/lib/restapi/validator.rb +37 -14
  23. data/lib/restapi/version.rb +1 -1
  24. data/lib/tasks/restapi.rake +157 -0
  25. data/restapi.gemspec +1 -1
  26. data/spec/controllers/restapis_controller_spec.rb +84 -0
  27. data/spec/controllers/users_controller_spec.rb +273 -221
  28. data/spec/dummy/app/controllers/twitter_example_controller.rb +209 -208
  29. data/spec/dummy/app/controllers/users_controller.rb +23 -33
  30. data/spec/dummy/config/initializers/restapi.rb +45 -23
  31. data/spec/dummy/config/routes.rb +12 -7
  32. metadata +26 -15
  33. data/app/public/restapi/javascripts/bundled/backbone.js +0 -1431
  34. data/app/public/restapi/javascripts/bundled/json2.js +0 -487
  35. data/app/public/restapi/javascripts/bundled/underscore.js +0 -999
  36. data/app/public/restapi/javascripts/jst.js +0 -127
  37. data/app/public/restapi/javascripts/routers/documentation_router.js +0 -52
  38. data/app/public/restapi/stylesheets/bundled/bootstrap-responsive.css +0 -686
  39. data/app/public/restapi/stylesheets/bundled/bootstrap.css +0 -3990
  40. data/spec/dummy/app/controllers/dogs_controller.rb +0 -20
  41. data/spec/dummy/app/helpers/application_helper.rb +0 -2
@@ -3,12 +3,11 @@ class TwitterExampleController < ApplicationController
3
3
  resource_description do
4
4
  name 'Users'
5
5
  short_description 'Users are at the center of everything Twitter: they follow, they favorite, and tweet & retweet.'
6
- path '/users/'
6
+ path '/twitter_example/'
7
+ description "Long description of this resource."
7
8
  end
8
9
 
9
- api :desc => 'Return up to 100 users worth of extended information, specified by either ID, screen name, or combination of the two.',
10
- :path => '/users/lookup',
11
- :method => 'GET'
10
+ api :GET, '/twitter_example/lookup', 'Return up to 100 users worth of extended information, specified by either ID, screen name, or combination of the two.'
12
11
  param :screen_name, String, :desc => 'A comma separated list of screen names, up to 100 are allowed in a single request. You are strongly encouraged to use a POST for larger (up to 100 screen names) requests.'
13
12
  param :user_id, Integer, :desc => 'A comma separated list of user IDs, up to 100 are allowed in a single request. You are strongly encouraged to use a POST for larger requests.'
14
13
  param :include_entities, String, :desc => 'When set to either <code>true</code>, <code>t</code> or <code>1</code>, each tweet will include a node called "entities,". This node offers a variety of metadata about the tweet in a discreet structure, including: user_mentions, urls, and hashtags. While entities are opt-in on timelines at present, they will be made a default component of output in the future. See Tweet Entities for more detail on entities.'
@@ -30,9 +29,7 @@ class TwitterExampleController < ApplicationController
30
29
  render :text => "lookup"
31
30
  end
32
31
 
33
- api :desc => 'Access the profile image in various sizes for the user with the indicated screen_name.',
34
- :path => '/users/profile_image/:screen_name',
35
- :method => 'GET'
32
+ api :GET, '/twitter_example/profile_image/:screen_name', 'Access the profile image in various sizes for the user with the indicated screen_name.'
36
33
  param :screen_name, String, :required => true, :desc => 'The screen name of the user for whom to return results for. Helpful for disambiguating when a valid screen name is also a user ID.'
37
34
  param :size, ['bigger','normal','mini','original'], :desc => <<-EOS
38
35
  Specifies the size of image to fetch. Not specifying a size will give the default, normal size of 48px by 48px. Valid options include:
@@ -50,11 +47,10 @@ class TwitterExampleController < ApplicationController
50
47
  This method should only be used by application developers to lookup or check the profile image URL for a user. This method must not be used as the image source URL presented to users of your application.
51
48
  EOS
52
49
  def profile_image
53
- render :text => "profile_image"
50
+ render :text => "profile_image of '#{params[:screen_name]}'"
54
51
  end
55
52
 
56
- api :path => '/users/search', :method => 'GET',
57
- :desc => 'Runs a search for users similar to Find People button on Twitter.com.'
53
+ api :GET, '/twitter_example/search', 'Runs a search for users similar to Find People button on Twitter.com.'
58
54
  param :q, String, :desc => 'The search query to run against people search.', :required => true
59
55
  param :page, Integer, :desc => 'Specifies the page of results to retrieve.'
60
56
  param :per_page, Integer, :desc => 'The number of people to retrieve. Maxiumum of 20 allowed per page.'
@@ -66,93 +62,95 @@ class TwitterExampleController < ApplicationController
66
62
 
67
63
  === Extended description
68
64
  This method has a feature-specific rate limit of 60 calls per hour that is applied in conjunction with the main REST API rate limit. Calls to this method will count against the feature-specific rate limit and the main REST API rate limit. If either limit is exhausted, the request will fail. You can monitor the status of the feature-specific rate limit by inspecting the HTTP response headers <tt>X-FeatureRateLimit-Limit</tt>, <tt>X-FeatureRateLimit-Remaining</tt>, and <tt>X-FeatureRateLimit-Reset</tt>. These headers correspond to the <tt>X-RateLimit</tt> headers provided by the main REST API limit.
69
- [
70
- {
71
- "name": "Twitter API",
72
- "profile_sidebar_border_color": "87bc44",
73
- "profile_background_tile": false,
74
- "profile_sidebar_fill_color": "e0ff92",
75
- "location": "San Francisco, CA",
76
- "profile_image_url": "http://a3.twimg.com/profile_images/689684365/api_normal.png",
77
- "created_at": "Wed May 23 06:01:13 +0000 2007",
78
- "profile_link_color": "0000ff",
79
- "favourites_count": 2,
80
- "url": "http://apiwiki.twitter.com",
81
- "contributors_enabled": true,
82
- "utc_offset": -28800,
83
- "id": 6253282,
84
- "profile_use_background_image": true,
85
- "profile_text_color": "000000",
86
- "protected": false,
87
- "followers_count": 160753,
88
- "lang": "en",
89
- "verified": true,
90
- "profile_background_color": "c1dfee",
91
- "geo_enabled": true,
92
- "notifications": null,
93
- "description": "The Real Twitter API. I tweet about API changes, service issues and happily answer questions about Twitter and our API. Don't get an answer? It's on my website.",
94
- "time_zone": "Pacific Time (US & Canada)",
95
- "friends_count": 19,
96
- "statuses_count": 1858,
97
- "profile_background_image_url": "http://a3.twimg.com/profile_background_images/59931895/twitterapi-background-new.png",
98
- "status": {
99
- "coordinates": null,
100
- "favorited": false,
101
- "created_at": "Tue Jun 22 16:53:28 +0000 2010",
102
- "truncated": false,
103
- "text": "@Demonicpagan possible some part of your signature generation is incorrect & fails for real reasons.. follow up on the list if you suspect",
104
- "contributors": null,
105
- "id": 16783999399,
106
- "geo": null,
107
- "in_reply_to_user_id": 6339722,
108
- "place": null,
109
- "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",
110
- "in_reply_to_screen_name": "Demonicpagan",
111
- "in_reply_to_status_id": 16781827477
112
- },
113
- "screen_name": "twitterapi",
114
- "following": null
115
- },
116
- ...
117
- {
118
- "name": "twitterAPI",
119
- "profile_sidebar_border_color": "87bc44",
120
- "profile_background_tile": false,
121
- "profile_sidebar_fill_color": "e0ff92",
122
- "location": null,
123
- "profile_image_url": "http://s.twimg.com/a/1277162817/images/default_profile_6_normal.png",
124
- "created_at": "Fri Jun 04 12:07:25 +0000 2010",
125
- "profile_link_color": "0000ff",
126
- "favourites_count": 0,
127
- "url": null,
128
- "contributors_enabled": false,
129
- "utc_offset": null,
130
- "id": 151851125,
131
- "profile_use_background_image": true,
132
- "profile_text_color": "000000",
133
- "protected": false,
134
- "followers_count": 0,
135
- "lang": "ja",
136
- "verified": false,
137
- "profile_background_color": "9ae4e8",
138
- "geo_enabled": false,
139
- "notifications": false,
140
- "description": null,
141
- "time_zone": null,
142
- "friends_count": 0,
143
- "statuses_count": 0,
144
- "profile_background_image_url": "http://s.twimg.com/a/1277162817/images/themes/theme1/bg.png",
145
- "screen_name": "popoAPI",
146
- "following": false
147
- }
148
- ]
149
65
  EOS
66
+
67
+ example <<-EDOC
68
+ [
69
+ {
70
+ "name": "Twitter API",
71
+ "profile_sidebar_border_color": "87bc44",
72
+ "profile_background_tile": false,
73
+ "profile_sidebar_fill_color": "e0ff92",
74
+ "location": "San Francisco, CA",
75
+ "profile_image_url": "http://a3.twimg.com/profile_images/689684365/api_normal.png",
76
+ "created_at": "Wed May 23 06:01:13 +0000 2007",
77
+ "profile_link_color": "0000ff",
78
+ "favourites_count": 2,
79
+ "url": "http://apiwiki.twitter.com",
80
+ "contributors_enabled": true,
81
+ "utc_offset": -28800,
82
+ "id": 6253282,
83
+ "profile_use_background_image": true,
84
+ "profile_text_color": "000000",
85
+ "protected": false,
86
+ "followers_count": 160753,
87
+ "lang": "en",
88
+ "verified": true,
89
+ "profile_background_color": "c1dfee",
90
+ "geo_enabled": true,
91
+ "notifications": null,
92
+ "description": "The Real Twitter API. I tweet about API changes, service issues and happily answer questions about Twitter and our API. Don't get an answer? It's on my website.",
93
+ "time_zone": "Pacific Time (US & Canada)",
94
+ "friends_count": 19,
95
+ "statuses_count": 1858,
96
+ "profile_background_image_url": "http://a3.twimg.com/profile_background_images/59931895/twitterapi-background-new.png",
97
+ "status": {
98
+ "coordinates": null,
99
+ "favorited": false,
100
+ "created_at": "Tue Jun 22 16:53:28 +0000 2010",
101
+ "truncated": false,
102
+ "text": "@Demonicpagan possible some part of your signature generation is incorrect & fails for real reasons.. follow up on the list if you suspect",
103
+ "contributors": null,
104
+ "id": 16783999399,
105
+ "geo": null,
106
+ "in_reply_to_user_id": 6339722,
107
+ "place": null,
108
+ "source": "<a href="http://www.tweetdeck.com" rel="nofollow">TweetDeck</a>",
109
+ "in_reply_to_screen_name": "Demonicpagan",
110
+ "in_reply_to_status_id": 16781827477
111
+ },
112
+ "screen_name": "twitterapi",
113
+ "following": null
114
+ },
115
+ ...
116
+ {
117
+ "name": "twitterAPI",
118
+ "profile_sidebar_border_color": "87bc44",
119
+ "profile_background_tile": false,
120
+ "profile_sidebar_fill_color": "e0ff92",
121
+ "location": null,
122
+ "profile_image_url": "http://s.twimg.com/a/1277162817/images/default_profile_6_normal.png",
123
+ "created_at": "Fri Jun 04 12:07:25 +0000 2010",
124
+ "profile_link_color": "0000ff",
125
+ "favourites_count": 0,
126
+ "url": null,
127
+ "contributors_enabled": false,
128
+ "utc_offset": null,
129
+ "id": 151851125,
130
+ "profile_use_background_image": true,
131
+ "profile_text_color": "000000",
132
+ "protected": false,
133
+ "followers_count": 0,
134
+ "lang": "ja",
135
+ "verified": false,
136
+ "profile_background_color": "9ae4e8",
137
+ "geo_enabled": false,
138
+ "notifications": false,
139
+ "description": null,
140
+ "time_zone": null,
141
+ "friends_count": 0,
142
+ "statuses_count": 0,
143
+ "profile_background_image_url": "http://s.twimg.com/a/1277162817/images/themes/theme1/bg.png",
144
+ "screen_name": "popoAPI",
145
+ "following": false
146
+ }
147
+ ]
148
+ EDOC
150
149
  def search
151
150
  render :text => 'search'
152
151
  end
153
152
 
154
- api :path => '/users/show', :method => 'GET',
155
- :desc => 'Returns extended information of a given user, specified by ID or screen name as per the required id parameter.'
153
+ api :GET, '/twitter_example/show', 'Returns extended information of a given user, specified by ID or screen name as per the required id parameter.'
156
154
  param :user_id, Integer, :required => true, :desc => <<-EOS
157
155
  The ID of the user for whom to return results for. Either an id or screen_name is required for this method.
158
156
  _Note_: Specifies the ID of the user to befriend. Helpful for disambiguating when a valid user ID is also a valid screen name.
@@ -163,137 +161,140 @@ class TwitterExampleController < ApplicationController
163
161
 
164
162
  You must be following a protected user to be able to see their most recent status update. If you don't follow a protected user, or request this method without autenticating, the users status will be removed.
165
163
 
166
- The URL pattern <tt>/version/users/show/:screen_name_or_user_id.format</tt> is still accepted but not recommended. As a sequence of numbers is a valid screen name we recommend using the +screen_name+ or +user_id+ parameter instead.
164
+ The URL pattern <tt>/version/twitter_example/show/:screen_name_or_user_id.format</tt> is still accepted but not recommended. As a sequence of numbers is a valid screen name we recommend using the +screen_name+ or +user_id+ parameter instead.
167
165
  EDOC
168
166
  def show
169
167
  render :text => 'show'
170
168
  end
171
169
 
172
- api :path => '/users/contributors', :method => 'GET',
173
- :description => 'Returns an array of users who can contribute to the specified account.'
170
+ api :GET, '/twitter_example/contributors', 'Returns an array of users who can contribute to the specified account.'
174
171
  param :user_id, Integer, :desc => 'The ID of the user for whom to return results for. Helpful for disambiguating when a valid user ID is also a valid screen name.'
175
172
  param :screen_name, String, :desc => 'The screen name of the user for whom to return results for. Helpful for disambiguating when a valid screen name is also a user ID.'
176
173
  param :include_entities, String
177
174
  param :skip_status, ['t','true','1'],
178
175
  :description => 'When set to either true, t or 1 statuses will not be included in the returned user objects.'
179
-
180
- description <<-EDOC
181
- === Example request
182
- GET https://api.twitter.com/1/users/contributors.json?screen_name=twitterapi&include_entities=true&skip_status=true
183
- [
184
- {
185
- "profile_sidebar_border_color": "C0DEED",
186
- "profile_background_tile": false,
187
- "name": "Matt Harris",
188
- "profile_sidebar_fill_color": "DDEEF6",
189
- "expanded_url": "http://themattharris.com",
190
- "created_at": "Sat Feb 17 20:49:54 +0000 2007",
191
- "location": "SFO/LHR/YVR/JAX/IAD/AUS",
192
- "profile_image_url": "http://a1.twimg.com/profile_images/554181350/matt_normal.jpg",
193
- "follow_request_sent": false,
194
- "is_translator": false,
195
- "profile_link_color": "0084B4",
196
- "id_str": "777925",
197
- "entities": {
198
- "urls": [
199
176
 
200
- ],
201
- "hashtags": [
177
+ description "Look at examples."
178
+
179
+ example <<-EDOC
180
+ GET https://api.twitter.com/1/twitter_example/contributors.json?screen_name=twitterapi&include_entities=true&skip_status=true
181
+ [
182
+ {
183
+ "profile_sidebar_border_color": "C0DEED",
184
+ "profile_background_tile": false,
185
+ "name": "Matt Harris",
186
+ "profile_sidebar_fill_color": "DDEEF6",
187
+ "expanded_url": "http://themattharris.com",
188
+ "created_at": "Sat Feb 17 20:49:54 +0000 2007",
189
+ "location": "SFO/LHR/YVR/JAX/IAD/AUS",
190
+ "profile_image_url": "http://a1.twimg.com/profile_images/554181350/matt_normal.jpg",
191
+ "follow_request_sent": false,
192
+ "is_translator": false,
193
+ "profile_link_color": "0084B4",
194
+ "id_str": "777925",
195
+ "entities": {
196
+ "urls": [
197
+
198
+ ],
199
+ "hashtags": [
202
200
 
203
- ],
204
- "user_mentions": [
205
- {
206
- "name": "Cindy Li",
207
- "id_str": "29733",
208
- "id": 29733,
209
- "indices": [
210
- 45,
211
- 53
212
- ],
213
- "screen_name": "cindyli"
214
- }
215
- ]
216
- },
217
- "default_profile": true,
218
- "url": "http://t.co/292MnqA",
219
- "contributors_enabled": false,
220
- "favourites_count": 120,
221
- "id": 777925,
222
- "utc_offset": -28800,
223
- "listed_count": 271,
224
- "profile_use_background_image": true,
225
- "followers_count": 6242,
226
- "lang": "en",
227
- "protected": false,
228
- "profile_text_color": "333333",
229
- "profile_background_color": "C0DEED",
230
- "time_zone": "Pacific Time (US & Canada)",
231
- "geo_enabled": true,
232
- "description": "Developer Advocate at Twitter and married to @cindyli. NASA enthusiast, British expat and all around geek living in San Francisco.",
233
- "notifications": false,
234
- "verified": false,
235
- "profile_background_image_url": "http://a0.twimg.com/images/themes/theme1/bg.png",
236
- "statuses_count": 3835,
237
- "display_url": "themattharris.com",
238
- "friends_count": 360,
239
- "default_profile_image": false,
240
- "following": false,
241
- "show_all_inline_media": false,
242
- "screen_name": "themattharris"
201
+ ],
202
+ "user_mentions": [
203
+ {
204
+ "name": "Cindy Li",
205
+ "id_str": "29733",
206
+ "id": 29733,
207
+ "indices": [
208
+ 45,
209
+ 53
210
+ ],
211
+ "screen_name": "cindyli"
212
+ }
213
+ ]
243
214
  },
244
- ...
245
- {
246
- "profile_sidebar_border_color": "547980",
247
- "profile_background_tile": true,
248
- "name": "Ryan Sarver",
249
- "profile_sidebar_fill_color": "F8FCF2",
250
- "expanded_url": "http://sarver.org",
251
- "created_at": "Mon Feb 26 18:05:55 +0000 2007",
252
- "location": "San Francisco, CA",
253
- "profile_image_url": "http://a2.twimg.com/profile_images/644997837/ryan_sarver_twitter_big_normal.jpg",
254
- "follow_request_sent": false,
255
- "is_translator": false,
256
- "profile_link_color": "547980",
257
- "id_str": "795649",
258
- "entities": {
259
- "urls": [
215
+ "default_profile": true,
216
+ "url": "http://t.co/292MnqA",
217
+ "contributors_enabled": false,
218
+ "favourites_count": 120,
219
+ "id": 777925,
220
+ "utc_offset": -28800,
221
+ "listed_count": 271,
222
+ "profile_use_background_image": true,
223
+ "followers_count": 6242,
224
+ "lang": "en",
225
+ "protected": false,
226
+ "profile_text_color": "333333",
227
+ "profile_background_color": "C0DEED",
228
+ "time_zone": "Pacific Time (US & Canada)",
229
+ "geo_enabled": true,
230
+ "description": "Developer Advocate at Twitter and married to @cindyli. NASA enthusiast, British expat and all around geek living in San Francisco.",
231
+ "notifications": false,
232
+ "verified": false,
233
+ "profile_background_image_url": "http://a0.twimg.com/images/themes/theme1/bg.png",
234
+ "statuses_count": 3835,
235
+ "display_url": "themattharris.com",
236
+ "friends_count": 360,
237
+ "default_profile_image": false,
238
+ "following": false,
239
+ "show_all_inline_media": false,
240
+ "screen_name": "themattharris"
241
+ },
242
+ ...
243
+ ]
244
+ EDOC
245
+ example <<-EDOC
246
+ Another example...
247
+ {
248
+ "profile_sidebar_border_color": "547980",
249
+ "profile_background_tile": true,
250
+ "name": "Ryan Sarver",
251
+ "profile_sidebar_fill_color": "F8FCF2",
252
+ "expanded_url": "http://sarver.org",
253
+ "created_at": "Mon Feb 26 18:05:55 +0000 2007",
254
+ "location": "San Francisco, CA",
255
+ "profile_image_url": "http://a2.twimg.com/profile_images/644997837/ryan_sarver_twitter_big_normal.jpg",
256
+ "follow_request_sent": false,
257
+ "is_translator": false,
258
+ "profile_link_color": "547980",
259
+ "id_str": "795649",
260
+ "entities": {
261
+ "urls": [
260
262
 
261
- ],
262
- "hashtags": [
263
+ ],
264
+ "hashtags": [
263
265
 
264
- ],
265
- "user_mentions": [
266
+ ],
267
+ "user_mentions": [
266
268
 
267
- ]
268
- },
269
- "default_profile": false,
270
- "contributors_enabled": true,
271
- "url": "http://t.co/Lzsetyk",
272
- "favourites_count": 246,
273
- "id": 795649,
274
- "utc_offset": -28800,
275
- "profile_use_background_image": true,
276
- "listed_count": 1384,
277
- "followers_count": 280756,
278
- "lang": "en",
279
- "protected": false,
280
- "profile_text_color": "594F4F",
281
- "profile_background_color": "45ADA8",
282
- "time_zone": "Pacific Time (US & Canada)",
283
- "geo_enabled": true,
284
- "description": "platform/api at twitter",
285
- "notifications": false,
286
- "verified": false,
287
- "friends_count": 1022,
288
- "profile_background_image_url": "http://a0.twimg.com/profile_background_images/113854313/xa60e82408188860c483d73444d53e21.png",
289
- "display_url": "sarver.org",
290
- "default_profile_image": false,
291
- "statuses_count": 7031,
292
- "following": false,
293
- "show_all_inline_media": true,
294
- "screen_name": "rsarver"
295
- }
296
- ]
269
+ ]
270
+ },
271
+ "default_profile": false,
272
+ "contributors_enabled": true,
273
+ "url": "http://t.co/Lzsetyk",
274
+ "favourites_count": 246,
275
+ "id": 795649,
276
+ "utc_offset": -28800,
277
+ "profile_use_background_image": true,
278
+ "listed_count": 1384,
279
+ "followers_count": 280756,
280
+ "lang": "en",
281
+ "protected": false,
282
+ "profile_text_color": "594F4F",
283
+ "profile_background_color": "45ADA8",
284
+ "time_zone": "Pacific Time (US & Canada)",
285
+ "geo_enabled": true,
286
+ "description": "platform/api at twitter",
287
+ "notifications": false,
288
+ "verified": false,
289
+ "friends_count": 1022,
290
+ "profile_background_image_url": "http://a0.twimg.com/profile_background_images/113854313/xa60e82408188860c483d73444d53e21.png",
291
+ "display_url": "sarver.org",
292
+ "default_profile_image": false,
293
+ "statuses_count": 7031,
294
+ "following": false,
295
+ "show_all_inline_media": true,
296
+ "screen_name": "rsarver"
297
+ }
297
298
  EDOC
298
299
  def contributors
299
300
  render :text => 'contributors'
@@ -303,4 +304,4 @@ class TwitterExampleController < ApplicationController
303
304
  render :text => 'twitter example'
304
305
  end
305
306
 
306
- end
307
+ end