aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRhenium <rhenium@rhe.jp>2014-02-09 18:27:31 +0900
committerRhenium <rhenium@rhe.jp>2014-02-09 18:27:31 +0900
commit5975ed19470c2eac079024fcafb56e18d6ecec74 (patch)
tree6c90ba08c94ab5f4f620f8c314c6b7d0425517e3
parent606054adb73efed232935073a219313e15aa4bba (diff)
downloadaclog-5975ed19470c2eac079024fcafb56e18d6ecec74.tar.gz
rewrite APIs with Grape and RABL
-rw-r--r--Gemfile3
-rw-r--r--Gemfile.lock73
-rw-r--r--app/api/api.rb48
-rw-r--r--app/api/api_deprecated.rb81
-rw-r--r--app/api/api_tweets.rb111
-rw-r--r--app/api/api_users.rb48
-rw-r--r--app/api/concerns/twitter_oauth_echo_authentication.rb (renamed from app/controllers/concerns/twitter_oauth_echo_authentication.rb)0
-rw-r--r--app/api/templates/tweet.rabl6
-rw-r--r--app/api/templates/tweets.rabl3
-rw-r--r--app/api/templates/user_discovored_by_and_users.rabl6
-rw-r--r--app/api/templates/user_stats.rabl5
-rw-r--r--app/assets/javascripts/apidocs.js12
-rw-r--r--app/controllers/apidocs_controller.rb30
-rw-r--r--app/controllers/application_controller.rb30
-rw-r--r--app/controllers/tweets_controller.rb105
-rw-r--r--app/controllers/users_controller.rb47
-rw-r--r--app/helpers/apidocs_helper.rb5
-rw-r--r--app/models/user.rb6
-rw-r--r--app/views/about/api.html.haml12
-rw-r--r--app/views/about/index.html.haml2
-rw-r--r--app/views/apidocs/endpoint.html.haml34
-rw-r--r--app/views/apidocs/index.html.haml30
-rw-r--r--app/views/errors/render_error.json.jbuilder5
-rw-r--r--app/views/shared/sidebar/_i.html.haml1
-rw-r--r--app/views/tweets/_tweet.json.jbuilder9
-rw-r--r--app/views/tweets/_tweets.json.jbuilder1
-rw-r--r--app/views/tweets/show.json.jbuilder1
-rw-r--r--app/views/users/_users_list.json.jbuilder6
-rw-r--r--app/views/users/stats.json.jbuilder2
-rw-r--r--config/application.rb9
-rw-r--r--config/initializers/rabl.rb3
-rw-r--r--config/routes.rb11
-rw-r--r--lib/aclog/exceptions.rb5
-rw-r--r--lib/apidoc.rb17
-rw-r--r--lib/apidoc/controller_dsl.rb38
-rw-r--r--lib/apidoc/controller_dsl/endpoint.rb30
-rw-r--r--lib/apidoc/controller_dsl/parameters.rb27
-rw-r--r--lib/apidoc/controller_dsl/resources.rb12
-rw-r--r--lib/apidoc/endpoint.rb18
-rw-r--r--lib/apidoc/exceptions.rb17
-rw-r--r--lib/apidoc/parameter.rb13
-rw-r--r--lib/apidoc/railtie.rb9
-rw-r--r--lib/apidoc/resource.rb12
43 files changed, 492 insertions, 451 deletions
diff --git a/Gemfile b/Gemfile
index 8b5d380..772aee0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,11 +4,12 @@ gem "rails", "~> 4.0.2"
gem "mysql2"
gem "settingslogic"
gem "yajl-ruby", require: "yajl"
+gem "grape"
+gem "grape-rabl"
gem "twitter"
gem "twitter-text"
gem "omniauth-twitter"
gem "haml-rails"
-gem "jbuilder"
gem "sass-rails"
gem "coffee-rails"
gem "uglifier"
diff --git a/Gemfile.lock b/Gemfile.lock
index 10ebc25..0b3328b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -26,20 +26,25 @@ GEM
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
addressable (2.3.5)
- arel (4.0.1)
+ arel (4.0.2)
atomic (1.1.14)
- bootstrap-sass (3.0.3.0)
+ axiom-types (0.0.5)
+ descendants_tracker (~> 0.0.1)
+ ice_nine (~> 0.9)
+ bootstrap-sass (3.1.0.2)
sass (~> 3.2)
buftok (0.2.0)
builder (3.1.4)
coderay (1.1.0)
+ coercible (1.0.0)
+ descendants_tracker (~> 0.0.1)
coffee-rails (4.0.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
coffee-script (2.2.0)
coffee-script-source
execjs
- coffee-script-source (1.6.3)
+ coffee-script-source (1.7.0)
cool.io (1.1.1)
iobuffer (>= 1.0.0)
coveralls (0.7.0)
@@ -48,14 +53,14 @@ GEM
simplecov (>= 0.7)
term-ansicolor
thor
- crack (0.4.1)
- safe_yaml (~> 0.9.0)
+ crack (0.4.2)
+ safe_yaml (~> 1.0.0)
daemon-spawn (0.4.2)
daemons (1.1.9)
dalli (2.7.0)
descendants_tracker (0.0.3)
diff-lcs (1.2.5)
- docile (1.1.2)
+ docile (1.1.3)
em-work_queue (0.0.1)
eventmachine
equalizer (0.0.9)
@@ -69,6 +74,21 @@ GEM
railties (>= 3.0.0)
faraday (0.9.0)
multipart-post (>= 1.2, < 3)
+ grape (0.6.1)
+ activesupport
+ builder
+ hashie (>= 1.2.0)
+ multi_json (>= 1.3.2)
+ multi_xml (>= 0.5.2)
+ rack (>= 1.3.0)
+ rack-accept
+ rack-mount
+ virtus (>= 1.0.0)
+ grape-rabl (0.2.2)
+ grape
+ i18n
+ rabl
+ tilt
haml (4.0.5)
tilt
haml-rails (0.5.3)
@@ -82,15 +102,13 @@ GEM
http_parser.rb
http_parser.rb (0.6.0)
i18n (0.6.9)
+ ice_nine (0.11.0)
iobuffer (1.1.2)
- jbuilder (2.0.2)
- activesupport (>= 3.0.0)
- multi_json (>= 1.2.0)
- jquery-rails (3.0.4)
+ jquery-rails (3.1.0)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.1)
- kgio (2.8.1)
+ kgio (2.9.1)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
@@ -104,6 +122,7 @@ GEM
cool.io (~> 1.1.1)
msgpack (~> 0.5.8)
multi_json (1.8.4)
+ multi_xml (0.5.5)
multipart-post (2.0.0)
mysql2 (0.3.15)
naught (1.0.0)
@@ -118,7 +137,7 @@ GEM
multi_json (~> 1.3)
omniauth-oauth (~> 1.0)
polyglot (0.3.3)
- pry (0.9.12.5)
+ pry (0.9.12.6)
coderay (~> 1.0)
method_source (~> 0.8)
slop (~> 3.4)
@@ -126,7 +145,13 @@ GEM
pry (>= 0.9.10)
quiet_assets (1.0.2)
railties (>= 3.1, < 5.0)
+ rabl (0.9.3)
+ activesupport (>= 2.3.14)
rack (1.5.2)
+ rack-accept (0.4.5)
+ rack (>= 0.4)
+ rack-mount (0.8.3)
+ rack (>= 1.0.0)
rack-test (0.6.2)
rack (>= 1.0)
rails (4.0.2)
@@ -151,9 +176,9 @@ GEM
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.7)
- rspec-expectations (2.14.4)
+ rspec-expectations (2.14.5)
diff-lcs (>= 1.1.3, < 2.0)
- rspec-mocks (2.14.4)
+ rspec-mocks (2.14.5)
rspec-rails (2.14.1)
actionpack (>= 3.0)
activemodel (>= 3.0)
@@ -162,7 +187,7 @@ GEM
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
- safe_yaml (0.9.7)
+ safe_yaml (1.0.1)
sass (3.2.14)
sass-rails (4.0.1)
railties (>= 4.0.0, < 5.0)
@@ -185,8 +210,8 @@ GEM
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (~> 2.8)
- term-ansicolor (1.2.2)
- tins (~> 0.8)
+ term-ansicolor (1.3.0)
+ tins (~> 1.0)
thin (1.6.1)
daemons (>= 1.0.9)
eventmachine (>= 1.0.0)
@@ -195,7 +220,7 @@ GEM
thread_safe (0.1.3)
atomic
tilt (1.4.1)
- tins (0.13.1)
+ tins (1.0.0)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
@@ -220,13 +245,18 @@ GEM
unf (0.1.3)
unf_ext
unf_ext (0.0.6)
- unicorn (4.8.0)
+ unicorn (4.8.2)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
unicorn-worker-killer (0.4.2)
unicorn (~> 4)
- webmock (1.17.1)
+ virtus (1.0.1)
+ axiom-types (~> 0.0.5)
+ coercible (~> 1.0)
+ descendants_tracker (~> 0.0.1)
+ equalizer (~> 0.0.7)
+ webmock (1.17.2)
addressable (>= 2.2.7)
crack (>= 0.3.2)
yajl-ruby (1.2.0)
@@ -242,8 +272,9 @@ DEPENDENCIES
dalli
em-work_queue
factory_girl_rails
+ grape
+ grape-rabl
haml-rails
- jbuilder
jquery-rails
msgpack
msgpack-rpc
diff --git a/app/api/api.rb b/app/api/api.rb
new file mode 100644
index 0000000..d7ada1d
--- /dev/null
+++ b/app/api/api.rb
@@ -0,0 +1,48 @@
+class Api < Grape::API
+ extend TwitterOauthEchoAuthentication
+
+ format :json
+ formatter :json, Grape::Formatter::Rabl
+ error_formatter :json, ->(message, backtrace, options, env) do
+ { error: { message: message } }.to_json
+ end
+
+ rescue_from ActiveRecord::RecordNotFound, Aclog::Exceptions::NotFound do
+ error_response message: "That page does not exists.", status: 404
+ end
+ rescue_from Aclog::Exceptions::Forbidden do
+ error_response message: "You do not have permission to access this page.", status: 403
+ end
+ rescue_from Aclog::Exceptions::OAuthEchoError do
+ error_response message: "Invalid OAuth Echo data.", status: 401
+ end
+
+ rescue_from :all
+
+ helpers do
+ def current_user
+ @_current_user ||= begin
+ if request.headers["X-Verify-Credentials-Authorization"]
+ user_id = authenticate_with_twitter_oauth_echo
+ User.find(user_id)
+ end
+ end
+ rescue
+ raise Aclog::Exceptions::OAuthEchoError
+ end
+
+ def permitted_to_see?(user_or_tweet)
+ user_or_tweet.is_a?(User) ?
+ !user_or_tweet.protected? || current_user.try(:permitted_to_see?, user_or_tweet) :
+ !user_or_tweet.user.protected? || current_user.try(:permitted_to_see?, user_or_tweet.user)
+ end
+ end
+
+ mount ApiTweets
+ mount ApiUsers
+ mount ApiDeprecated
+
+ route :any, "*path", ignore: true do
+ raise Aclog::Exceptions::NotFound
+ end
+end
diff --git a/app/api/api_deprecated.rb b/app/api/api_deprecated.rb
new file mode 100644
index 0000000..9af04fb
--- /dev/null
+++ b/app/api/api_deprecated.rb
@@ -0,0 +1,81 @@
+class ApiDeprecated < Grape::API
+ resource :tweets do
+ params_user = -> do
+ params do
+ optional :user_id, type: Integer
+ optional :screen_name, type: String
+ end
+ end
+
+ params_user_b = -> do
+ params do
+ optional :user_id_b, type: Integer
+ optional :screen_name_b, type: String
+ end
+ end
+
+ params_pagination = -> do
+ params do
+ optional :count, type: Integer
+ optional :page, type: Integer
+ end
+ end
+
+ params_pagination_with_ids = -> do
+ params_pagination[]
+ params do
+ optional :since_id, type: Integer
+ optional :max_id, type: Integer
+ end
+ end
+
+ helpers do
+ def user
+ @_user ||= begin
+ user = User.find(id: params[:user_id], screen_name: params[:screen_name])
+ raise Aclog::Exceptions::Forbidden unless permitted_to_see?(user)
+ user
+ end
+ end
+
+ def paginate(tweets)
+ count = [(params[:count] || Settings.tweets.count.default).to_i, Settings.tweets.count.max].min
+ tweets.limit(count).page((params[:page] || 1).to_i)
+ end
+
+ def paginate_with_ids(tweets)
+ paginate(tweets).max_id(params[:max_id]).since_id(params[:since_id])
+ end
+ end
+
+ desc "Deprecated. Use GET tweets/user_best"
+ params_user[]
+ params_pagination[]
+ get "best", rabl: "tweets" do
+ @tweets = paginate user.tweets.reacted.order_by_reactions
+ end
+
+ desc "Deprecated. Use GET tweets/user_timeline"
+ params_user[]
+ params_pagination_with_ids[]
+ get "timeline", rabl: "tweets" do
+ @tweets = paginate_with_ids user.tweets.reacted.order_by_id
+ end
+
+ desc "Deprecated. Use GET tweets/user_discoveries"
+ params_user[]
+ params_pagination_with_ids[]
+ get "discoveries", rabl: "tweets" do
+ @tweets = paginate_with_ids(Tweet).discovered_by(user).order_by_id
+ end
+
+ desc "Deprecated. Use GET tweets/user_discovered_by"
+ params_user[]
+ params_user_b[]
+ params_pagination_with_ids[]
+ get "discovered_by", rabl: "tweets" do
+ @tweets = paginate_with_ids(user.tweets).discovered_by(user_b).order_by_id
+ end
+ end
+end
+
diff --git a/app/api/api_tweets.rb b/app/api/api_tweets.rb
new file mode 100644
index 0000000..168fef3
--- /dev/null
+++ b/app/api/api_tweets.rb
@@ -0,0 +1,111 @@
+class ApiTweets < Grape::API
+ resource :tweets do
+ params_user = -> do
+ params do
+ optional :user_id, type: Integer, desc: "The numerical ID of the user for whom to return results for."
+ optional :screen_name, type: String, desc: "The username of the user for whom to return results for."
+ end
+ end
+
+ params_source_user = -> do
+ params do
+ optional :source_user_id, type: Integer, desc: "The numerical ID of the user for whom to return results for."
+ optional :source_screen_name, type: String, desc: "The username of the user for whom to return results for."
+ end
+ end
+
+ params_pagination = -> do
+ params do
+ optional :count, type: Integer, desc: "The number of tweets to retrieve. Must be less than or equal to #{Settings.tweets.count.max}, defaults to #{Settings.tweets.count.default}."
+ optional :page, type: Integer, desc: "The page number of results to retrieve."
+ end
+ end
+
+ params_pagination_with_ids = -> do
+ params_pagination[]
+ params do
+ optional :since_id, type: Integer, desc: "Returns results with an ID greater than the specified ID."
+ optional :max_id, type: Integer, desc: "Returns results with an ID less than or equal to the specified ID."
+ end
+ end
+
+ params_threshold = -> do
+ params do
+ optional :reactions, type: Integer, desc: "Returns Tweets which has received reactions more than (or equal to) the specified number of times."
+ end
+ end
+
+ helpers do
+ def user
+ @_user ||= begin
+ user = User.find(id: params[:user_id], screen_name: params[:screen_name])
+ raise Aclog::Exceptions::Forbidden unless permitted_to_see?(user)
+ user
+ end
+ end
+
+ def source_user
+ user = User.find(id: params[:source_user_id], screen_name: params[:source_screen_name])
+ raise Aclog::Exceptions::Forbidden unless permitted_to_see?(user)
+ user
+ end
+
+ def paginate(tweets)
+ count = [(params[:count] || Settings.tweets.count.default).to_i, Settings.tweets.count.max].min
+ tweets.limit(count).page((params[:page] || 1).to_i)
+ end
+
+ def paginate_with_ids(tweets)
+ paginate(tweets).max_id(params[:max_id]).since_id(params[:since_id])
+ end
+ end
+
+ desc "Returns a single Tweet, specified by ID.", example_params: { id: 43341783446466560 }
+ params do
+ requires :id, type: Integer, desc: "The numerical ID of the desired Tweet."
+ end
+ get "show", rabl: "tweet" do
+ @tweet = Tweet.find(params[:id])
+ raise Aclog::Exceptions::Forbidden unless permitted_to_see?(@tweet)
+ end
+
+ desc "Returns Tweets, specified by comma-separated IDs.", example_params: { ids: "43341783446466560,50220624609685505" }
+ params do
+ requires :ids, type: String, regexp: /^\d+(,\d+)*$/, desc: "A comma-separated list of Tweet IDs, up to #{Settings.tweets.count.max} are allowed in a single request."
+ end
+ get "lookup", rabl: "tweets" do
+ @tweets = Tweet.where(id: params[:ids].split(",").map(&:to_i))
+ @tweets = @tweets.select {|tweet| permitted_to_see?(tweet) }
+ end
+
+ desc "Returns the best Tweets of a user, specified by username or user ID.", example_params: { user_id: 280414022, count: 2, page: 3 }
+ params_user[]
+ params_pagination[]
+ get "user_best", rabl: "tweets" do
+ @tweets = paginate user.tweets.reacted.order_by_reactions
+ end
+
+ desc "Returns the newest Tweets of a user, specified by username or user ID.", example_params: { screen_name: "toshi_a", count: 3, max_id: 432112694871605249 }
+ params_user[]
+ params_pagination_with_ids[]
+ params_threshold[]
+ get "user_timeline", rabl: "tweets" do
+ @tweets = paginate_with_ids user.tweets.reacted(params[:reactions]).order_by_id
+ end
+
+ desc "Returns the Tweets which a user specified by username or user ID discovered.", example_params: { user_id: 120726371, count: 2 }
+ params_user[]
+ params_pagination_with_ids[]
+ get "user_discoveries", rabl: "tweets" do
+ @tweets = paginate_with_ids(Tweet).discovered_by(user).order_by_id
+ end
+
+ desc "Returns the specified user's Tweets which another specified user discovered.", example_params: { user_id: 120726371, count: 2, source_screen_name: "cn" }
+ params_user[]
+ params_source_user[]
+ params_pagination_with_ids[]
+ get "user_discovered_by", rabl: "tweets" do
+ @tweets = paginate_with_ids(user.tweets).discovered_by(source_user).order_by_id
+ end
+ end
+end
diff --git a/app/api/api_users.rb b/app/api/api_users.rb
new file mode 100644
index 0000000..898856e
--- /dev/null
+++ b/app/api/api_users.rb
@@ -0,0 +1,48 @@
+class ApiUsers < Grape::API
+ resource :users do
+ params_user = -> do
+ params do
+ optional :id, type: Integer, desc: "The numerical ID of the user for whom to return results for."
+ optional :screen_name, type: String, desc: "The username of the user for whom to return results for."
+ end
+ end
+
+ helpers do
+ def user
+ @_user ||= begin
+ user = User.find(id: params[:id] || params[:user_id], screen_name: params[:screen_name])
+ raise Aclog::Exceptions::Forbidden unless permitted_to_see?(user)
+ user
+ end
+ end
+ end
+
+ desc "Returns the stats of a user, specified by username or user ID.", example_params: { user_id: 280414022 }
+ params_user[]
+ get "stats", rabl: "user_stats" do
+ @user = user
+ end
+
+ desc "Returns the list of the users who discovored the Tweets of a user, specified by username or user ID.", example_params: { user_id: 99008565 }
+ params_user[]
+ get "discovored_by", rabl: "user_discovored_by_and_users" do
+ @result = user.count_discovered_by.take(Settings.users.count)
+ end
+
+ desc "Returns the list of the users discovored by a user, specified by username or user ID.", example_params: { screen_name: "cn" }
+ params_user[]
+ get "discovored_users", rabl: "user_discovored_by_and_users" do
+ @result = user.count_discovered_users.take(Settings.users.count)
+ end
+
+ desc "", nodoc: true, example_params: { id: "280414022,99008565" }
+ params do
+ requires :id, type: String
+ end
+ get "screen_name" do
+ # does not use RABL
+ user_ids = (params[:id] || params[:ids] || params[:user_id] || params[:user_ids]).split(",").map { |i| i.to_i }
+ User.where(id: user_ids).pluck(:id, :screen_name).map { |id, screen_name| { id: id, screen_name: screen_name } }
+ end
+ end
+end
diff --git a/app/controllers/concerns/twitter_oauth_echo_authentication.rb b/app/api/concerns/twitter_oauth_echo_authentication.rb
index 21a9613..21a9613 100644
--- a/app/controllers/concerns/twitter_oauth_echo_authentication.rb
+++ b/app/api/concerns/twitter_oauth_echo_authentication.rb
diff --git a/app/api/templates/tweet.rabl b/app/api/templates/tweet.rabl
new file mode 100644
index 0000000..494e790
--- /dev/null
+++ b/app/api/templates/tweet.rabl
@@ -0,0 +1,6 @@
+object @tweet
+
+attributes :id, :user_id, :favorites_count, :retweets_count
+node(:favoriters) {|obj| obj.favoriters.pluck(:user_id) }
+node(:retweeters) {|obj| obj.retweeters.pluck(:user_id) }
+
diff --git a/app/api/templates/tweets.rabl b/app/api/templates/tweets.rabl
new file mode 100644
index 0000000..1017230
--- /dev/null
+++ b/app/api/templates/tweets.rabl
@@ -0,0 +1,3 @@
+collection @tweets
+extends "tweet"
+
diff --git a/app/api/templates/user_discovored_by_and_users.rabl b/app/api/templates/user_discovored_by_and_users.rabl
new file mode 100644
index 0000000..54b7360
--- /dev/null
+++ b/app/api/templates/user_discovored_by_and_users.rabl
@@ -0,0 +1,6 @@
+collection @result
+
+node(:id) {|obj| obj[0] }
+node(:favorites_count) {|obj| obj[1] }
+node(:retweets_count) {|obj| obj[2] }
+
diff --git a/app/api/templates/user_stats.rabl b/app/api/templates/user_stats.rabl
new file mode 100644
index 0000000..cd28dc9
--- /dev/null
+++ b/app/api/templates/user_stats.rabl
@@ -0,0 +1,5 @@
+object @user
+
+attributes :id
+node(:reactions_count) {|obj| obj.stats.reactions_count }
+
diff --git a/app/assets/javascripts/apidocs.js b/app/assets/javascripts/apidocs.js
new file mode 100644
index 0000000..fa17510
--- /dev/null
+++ b/app/assets/javascripts/apidocs.js
@@ -0,0 +1,12 @@
+$(function() {
+ var loading = $("#example_request_loading");
+ if (loading) {
+ var code = loading.parent();
+ $.ajax($("#example_request_uri").text()).done(function(data) {
+ code.text(JSON.stringify(data, null, 2));
+ }).fail(function() {
+ code.text("failed to load example....");
+ });
+ }
+});
+
diff --git a/app/controllers/apidocs_controller.rb b/app/controllers/apidocs_controller.rb
index a24a2f2..003e71b 100644
--- a/app/controllers/apidocs_controller.rb
+++ b/app/controllers/apidocs_controller.rb
@@ -2,26 +2,46 @@ class ApidocsController < ApplicationController
before_action :reload_docs
def index
- @resources = Apidoc.resources
+ @routes = @@routes
end
def endpoint
- @resource = Apidoc.resources[params[:resource].to_sym]
+ @routes = @@routes
- unless @resource
+ method = @@routes[params[:method]]
+ unless method
raise Aclog::Exceptions::DocumentNotFound
end
- @endpoint = @resource.endpoints[params[:name].to_sym]
+ @resource = method[params[:namespace]]
+ unless @resource
+ raise Aclog::Exceptions::DocumentNotFound
+ end
+ @endpoint = @resource[params[:path]]
unless @endpoint
raise Aclog::Exceptions::DocumentNotFound
end
+
+ if @endpoint.route_example_params
+ @example_request_uri = api_url + @endpoint.route_path.sub(/\(\.:format\)$/, ".json")
+ @example_request_uri += "?" + @endpoint.route_example_params.to_param
+ end
end
private
def reload_docs
- Apidoc.reload! if Rails.env.development?
+ @@routes ||= begin
+ h = {}
+ Api.routes.reject {|r| r.route_ignore }.each {|route|
+ # /tweets/show(.:format) -> tweets, show
+ method = route.route_method.downcase
+ namespace = route.route_namespace[1..-1]
+ path = route.route_path.sub(route.route_namespace, "")[1..-11] # 10: "(.:format)".size
+ ((h[method] ||= {})[namespace] ||= {})[path] = route
+ }
+ h
+ end
end
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index b756c2f..fb738a0 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,37 +1,31 @@
class ApplicationController < ActionController::Base
- include TwitterOauthEchoAuthentication
-
protect_from_forgery
+
after_action :set_content_type_to_xhtml, :tidy_response_body
- helper_method :current_user, :logged_in?
+ helper_method :logged_in?, :current_user
helper_method :authorized_to_show_user?, :authorized_to_show_user_best?
protected
- def current_user
- return @_current_user if defined? @_current_user
+ def logged_in?
+ !!session[:user_id]
+ end
- @_current_user = begin
- if session[:user_id]
+ def current_user
+ @_current_user ||= begin
+ if logged_in?
User.find(session[:user_id])
- elsif request.headers["X-Verify-Credentials-Authorization"]
- user_id = authenticate_with_twitter_oauth_echo
- User.find(user_id)
+ else
+ nil
end
- rescue
- nil
end
end
- def logged_in?
- !!current_user
- end
-
def authorized_to_show_user?(user)
- !user.protected? || current_user == user || current_user.try(:following?, user) || false
+ !user.protected? || (logged_in? && current_user.permitted_to_see?(user))
end
def authorized_to_show_user_best?(user)
- !user.private? || current_user == user
+ (!user.private? || current_user == user) && authorized_to_show_user?(user)
end
def authorize_to_show_user!(user)
diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb
index f25a7e2..078830b 100644
--- a/app/controllers/tweets_controller.rb
+++ b/app/controllers/tweets_controller.rb
@@ -1,24 +1,4 @@
class TweetsController < ApplicationController
- param_group :pagination_with_page_number do
- optional :count, 5, "The number of tweets to retrieve. Must be less than or equal to #{Settings.tweets.count.max}, defaults to #{Settings.tweets.count.default}."
- optional :page, 2, "The page number of results to retrieve."
- end
-
- param_group :pagination_with_ids do
- param_group :pagination_with_page_number
- optional :since_id, 12345, "Returns results with an ID greater than the specified ID."
- optional :max_id, 54321, "Returns results with an ID less than or equal to the specified ID."
- end
-
- param_group :user do
- optional :user_id, 15926668, "The numerical ID of the user for whom to return results for."
- optional :screen_name, "toshi_a", "The username of the user for whom to return results for."
- end
-
- param_group :threshold do
- optional :reactions, 5, "Returns Tweets which has received reactions more than (or equal to) the specified number of times."
- end
-
def index
begin
best
@@ -29,26 +9,12 @@ class TweetsController < ApplicationController
end
end
- get "tweets/show"
- description "Returns a single Tweet, specified by ID."
- requires :id, 43341783446466560, "The numerical ID of the desired Tweet."
def show
@tweet = Tweet.find(params[:id])
@user = @tweet.user
authorize_to_show_user! @user
end
- get "tweets/lookup"
- description "Returns Tweets, specified by comma-separated IDs."
- requires :ids, "43341783446466560,50220624609685505", "A comma-separated list of Tweet IDs, up to #{Settings.tweets.count.max} are allowed in a single request."
- def lookup
- @tweets = Tweet.where(id: (params[:ids] || params[:id]).split(",").map(&:to_i))
- end
-
- get "tweets/best"
- description "Returns the best Tweets of a user, specified by username or user ID."
- param_group :user
- param_group :pagination_with_page_number
def best
@user = require_user
authorize_to_show_user! @user
@@ -56,11 +22,6 @@ class TweetsController < ApplicationController
@tweets = paginate_with_page_number(@user.tweets.reacted.order_by_reactions)
end
- get "tweets/recent"
- nodoc
- description "Returns the best Tweets in the recent three days of a user, specified by username or user ID."
- param_group :user
- param_group :pagination_with_page_number
def recent
@user = require_user
authorize_to_show_user! @user
@@ -68,55 +29,30 @@ class TweetsController < ApplicationController
@tweets = paginate_with_page_number(@user.tweets.reacted.recent.order_by_reactions)
end
- get "tweets/timeline"
- description "Returns the newest Tweets of a user, specified by username or user ID."
- param_group :user
- param_group :pagination_with_ids
- param_group :threshold
def timeline
@user = require_user
authorize_to_show_user! @user
@tweets = paginate(@user.tweets.reacted(params[:reactions]).order_by_id)
end
- get "tweets/discoveries"
- description "Returns the Tweets which a user specified by username or user ID discovered."
- param_group :user
- param_group :pagination_with_ids
def discoveries
@user = require_user
authorize_to_show_user! @user
@tweets = paginate(Tweet).discovered_by(@user).order_by_id
end
- get "tweets/favorites"
- nodoc
- description "Returns the Tweets which a user specified by username or user ID favorited."
- param_group :user
- param_group :pagination_with_ids
def favorites
@user = require_user
authorize_to_show_user! @user
@tweets = paginate(Tweet).favorited_by(@user).order_by_id
end
- get "tweets/retweets"
- nodoc
- description "Returns the Tweets which a user specified by username or user ID retweeted."
- param_group :user
- param_group :pagination_with_ids
def retweets
@user = require_user
authorize_to_show_user! @user
@tweets = paginate(Tweet).retweeted_by(@user).order_by_id
end
- get "tweets/discovered_by"
- description "Returns the Tweets which a user specified by username or user ID retweeted."
- param_group :user
- optional :user_id_b, 280414022, "The numerical ID of the subject user."
- optional :screen_name_b, "cn", "The username of the subject user."
- param_group :pagination_with_ids
def discovered_by
@user = require_user
authorize_to_show_user! @user
@@ -125,38 +61,22 @@ class TweetsController < ApplicationController
@tweets = paginate(@user.tweets.discovered_by(@source_user).order_by_id)
end
- get "tweets/all_best"
- nodoc
- param_group :pagination_with_page_number
def all_best
@tweets = paginate_with_page_number(Tweet.reacted.order_by_reactions)
end
- get "tweets/all_recent"
- nodoc
- param_group :pagination_with_page_number
def all_recent
@tweets = paginate_with_page_number(Tweet.recent.reacted.order_by_reactions)
end
- get "tweets/all_timeline"
- nodoc
- param_group :pagination_with_ids
- param_group :threshold
def all_timeline
@tweets = paginate(Tweet.reacted(params[:reactions]).order_by_id)
end
- get "tweets/filter"
- nodoc
- param_group :pagination_with_ids
def filter
@tweets = paginate(Tweet.reacted.recent(7).filter_by_query(params[:q].to_s).not_protected.order_by_id)
end
- get "tweets/import"
- nodoc
- requires :id, 43341783446466560, "The numerical ID of the desired Tweet."
def import
raise Aclog::Exceptions::LoginRequired unless logged_in?
tweet = current_user.account.import(params[:id])
@@ -193,27 +113,12 @@ class TweetsController < ApplicationController
end
def render(*args)
- if !request.xhr? && request.format == :json
- # JSON API / Atom
- begin
- super(*args)
- rescue ActionView::MissingTemplate
- if @tweets
- super("_tweets")
- elsif @tweet
- super("_tweet")
- else
- raise
- end
- end
+ if @tweets && request.xhr?
+ super(json: { html: render_to_string(partial: "tweet", collection: @tweets, as: :tweet, formats: :html),
+ next_url: @next_url,
+ prev_url: @prev_url })
else
- if @tweets && request.xhr?
- super(json: { html: render_to_string(partial: "tweet", collection: @tweets, as: :tweet, formats: :html),
- next_url: @next_url,
- prev_url: @prev_url })
- else
- super(*args)
- end
+ super(*args)
end
end
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 95b4626..611e106 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,63 +1,20 @@
class UsersController < ApplicationController
- param_group :user do
- optional :id, 15926668, "The numerical ID of the user for whom to return results for."
- optional :screen_name, "toshi_a", "The username of the user for whom to return results for."
- end
-
- get "users/stats"
- description "Returns the stats of a user, specified by username or user ID."
- param_group :user
def stats
@user = require_user
end
- get "users/discovered_by"
- description "Returns the list of the users who discovored the Tweets of a user, specified by username or user ID."
- param_group :user
def discovered_by
@user = require_user
authorize_to_show_user_best! @user
@result = @user.count_discovered_by.take(Settings.users.count)
-
- respond_to do |format|
- format.html do
- @cached_users = Hash[User.find(@result.map {|user_id, count| user_id }).map {|user| [user.id, user] }]
- end
-
- format.json do
- render "_users_list"
- end
- end
+ @cached_users = Hash[User.find(@result.map {|user_id, count| user_id }).map {|user| [user.id, user] }]
end
- get "users/discovered_users"
- description "Returns the list of the users discovored by a user, specified by username or user ID."
- param_group :user
def discovered_users
@user = require_user
authorize_to_show_user_best! @user
@result = @user.count_discovered_users.take(Settings.users.count)
-
- respond_to do |format|
- format.html do
- @cached_users = Hash[User.find(@result.map {|user_id, count| user_id }).map {|user| [user.id, user] }]
- end
-
- format.json do
- render "_users_list"
- end
- end
- end
-
- get "users/screen_name"
- nodoc
- [:id, :ids, :user_id, :user_ids].each do |n|
- optional n, "230367516,280414022", "A comma-separated list of User IDs."
- end
- def screen_name
- user_ids = (params[:id] || params[:ids] || params[:user_id] || params[:user_ids]).split(",").map { |i| i.to_i }
- result = User.where(id: user_ids).pluck(:id, :screen_name).map { |id, screen_name| { id: id, screen_name: screen_name } }
- render json: result
+ @cached_users = Hash[User.find(@result.map {|user_id, count| user_id }).map {|user| [user.id, user] }]
end
private
diff --git a/app/helpers/apidocs_helper.rb b/app/helpers/apidocs_helper.rb
new file mode 100644
index 0000000..dc3892b
--- /dev/null
+++ b/app/helpers/apidocs_helper.rb
@@ -0,0 +1,5 @@
+module ApidocsHelper
+ def format_endpoint_name(endpoint)
+ endpoint.route_method + " " + endpoint.route_path[1..-11]
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 001f783..45a9b30 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -24,7 +24,7 @@ class User < ActiveRecord::Base
key, value = hash.delete_if {|k, v| v.nil? }.first
- where(key => value).order(updated_at: :desc).first || raise(ActiveRecord::RecordNotFound, "Couldn't find User with #{key}=#{value}")
+ key && where(key => value).order(updated_at: :desc).first || raise(ActiveRecord::RecordNotFound, "Couldn't find User with #{key}=#{value}")
end
def self.from_json(json)
@@ -54,6 +54,10 @@ class User < ActiveRecord::Base
!!account
end
+ def permitted_to_see?(user)
+ !user.protected? || user.id == self.id || self.account.try(:following?, user.id) || false
+ end
+
def account
Account.where(user_id: id).first
end
diff --git a/app/views/about/api.html.haml b/app/views/about/api.html.haml
deleted file mode 100644
index 441f34d..0000000
--- a/app/views/about/api.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-- title "API"
-- caption :title
-- sidebar :i
-%p
- aclog では JSON 形式の API を提供しています。
-%p
- = link_to "API ドキュメント", api_docs_path
-%p
- 非公開アカウントのデータを取得するために OAuth Echo を使う場合はこれを使用してください。<br />
- X-Auth-Service-Provider: https://api.twitter.com/1.1/account/verify_credentials.json
-
-
diff --git a/app/views/about/index.html.haml b/app/views/about/index.html.haml
index 736e5ec..03a7f2c 100644
--- a/app/views/about/index.html.haml
+++ b/app/views/about/index.html.haml
@@ -5,7 +5,5 @@
- if Rails.env.development?
%span.text-error (dev)
%p
- is a clone service of Favstar.
- %p
= link_to "Tweet", "https://twitter.com/share", class: "twitter-share-button", data: {text: "aclog - Twitter ふぁぼられ収集サービス", count: "none", url: "http://aclog.koba789.com/"}
diff --git a/app/views/apidocs/endpoint.html.haml b/app/views/apidocs/endpoint.html.haml
index ef15417..f84d0cc 100644
--- a/app/views/apidocs/endpoint.html.haml
+++ b/app/views/apidocs/endpoint.html.haml
@@ -2,27 +2,35 @@
- caption nil
- sidebar :i
%ul.breadcrumb
- %li= link_to "Documentation", api_docs_path
- %li.active= @endpoint
-%h1.page-header= @endpoint
+ %li= link_to "Documentation", about_api_path
+ %li.active= format_endpoint_name(@endpoint)
+%h1.page-header= format_endpoint_name(@endpoint)
%div
- %div= @endpoint.description
+ %div= @endpoint.route_description
%h2 Resource URL
- %div= url_for(controller: params[:resource], action: params[:name], only_path: false)
+ %div= api_url + @endpoint.route_path
%h2 Parameters
%table.table
%tbody
- - @endpoint.parameters.each do |parameter|
+ - @endpoint.route_params.each do |name, options|
%tr
%td
- %strong= parameter.name
- - if parameter.required?
+ %strong= name
+ - if options[:required]
%small required
- else
%small optional
%td
- %p= parameter.description
- - if parameter.example
- %p
- Example Value:
- = parameter.example
+ %p= options[:desc]
+ %p
+ Type:
+ = options[:type]
+ - if @example_request_uri
+ %h2 Example Request
+ .request
+ %span= @endpoint.route_method
+ %code#example_request_uri= @example_request_uri
+ .response
+ %pre
+ %code
+ #example_request_loading= image_tag "loading.gif", alt: "loading..."
diff --git a/app/views/apidocs/index.html.haml b/app/views/apidocs/index.html.haml
index 198e9f8..2f37d73 100644
--- a/app/views/apidocs/index.html.haml
+++ b/app/views/apidocs/index.html.haml
@@ -3,16 +3,34 @@
- sidebar :i
%ul.breadcrumb
%li.active Documentation
-%h2.page-header Resources
-- @resources.each do |name, resource|
- %h3= resource.name
+%h1.page-header Aclog API
+%p
+ Aclog では JSON 形式の API を提供しています。
+%hr
+%p
+ ツイートを非公開にしているアカウントの情報にアクセスするには本人であるか、対象のアカウントをフォローしている必要があります。Aclog API では、その認証に OAuth Echo を使用します。
+%p
+ OAuth Echo を使用するには以下のリクエストヘッダを使用します。
+ %pre
+ %code
+ :preserve
+ X-Auth-Service-Provider: https://api.twitter.com/1.1/account/verify_credentials.json
+ X-Verify-Credentials-Authorization: OAuth rea...
+%p
+ OAuth Echo の詳細については
+ = link_to "Twitter のドキュメント", "https://dev.twitter.com/pages/oauth_echo"
+ を参照してください。
+
+%h2.page-header Endpoints
+- @routes.values.inject(:merge).each do |namespace, endpoints|
+ %h3= namespace.titleize
%table.table
%thead
%th Resource
%th Description
%tbody
- - resource.endpoints.reject {|a, e| e.nodoc }.each do |action, endpoint|
+ - endpoints.select {|_, e| !e.route_nodoc }.each do |path, endpoint|
%tr
- %td= link_to endpoint, api_docs_endpoint_path(name, action)
- %td= endpoint.description
+ %td= link_to format_endpoint_name(endpoint), about_api_endpoint_path(endpoint.route_method.downcase, namespace, path)
+ %td= endpoint.route_description
diff --git a/app/views/errors/render_error.json.jbuilder b/app/views/errors/render_error.json.jbuilder
deleted file mode 100644
index ebbeb4d..0000000
--- a/app/views/errors/render_error.json.jbuilder
+++ /dev/null
@@ -1,5 +0,0 @@
-json.error do |json|
- json.status response.status
- json.message @message
-end
-
diff --git a/app/views/shared/sidebar/_i.html.haml b/app/views/shared/sidebar/_i.html.haml
index 776cde6..04150c2 100644
--- a/app/views/shared/sidebar/_i.html.haml
+++ b/app/views/shared/sidebar/_i.html.haml
@@ -5,4 +5,3 @@
= link_to "best", best_path, class: "list-group-item"
= link_to "recent", recent_path, class: "list-group-item"
= link_to "timeline", timeline_path, class: "list-group-item"
- = link_to "filter", filter_path, class: "list-group-item"
diff --git a/app/views/tweets/_tweet.json.jbuilder b/app/views/tweets/_tweet.json.jbuilder
deleted file mode 100644
index 993b824..0000000
--- a/app/views/tweets/_tweet.json.jbuilder
+++ /dev/null
@@ -1,9 +0,0 @@
-json.(tweet, :id, :favorites_count, :retweets_count)
-
-json.user_id tweet.user_id
-
-user_limit = Integer(params[:limit]) rescue nil
-
-json.favoriters tweet.favorites.limit(user_limit).pluck(:user_id)
-json.retweeters tweet.retweets.limit(user_limit).pluck(:user_id)
-
diff --git a/app/views/tweets/_tweets.json.jbuilder b/app/views/tweets/_tweets.json.jbuilder
deleted file mode 100644
index c5bcd47..0000000
--- a/app/views/tweets/_tweets.json.jbuilder
+++ /dev/null
@@ -1 +0,0 @@
-json.array!(@tweets, partial: "tweet", as: :tweet)
diff --git a/app/views/tweets/show.json.jbuilder b/app/views/tweets/show.json.jbuilder
deleted file mode 100644
index c92aaa0..0000000
--- a/app/views/tweets/show.json.jbuilder
+++ /dev/null
@@ -1 +0,0 @@
-json.partial! "tweet", tweet: @tweet
diff --git a/app/views/users/_users_list.json.jbuilder b/app/views/users/_users_list.json.jbuilder
deleted file mode 100644
index 57bcb32..0000000
--- a/app/views/users/_users_list.json.jbuilder
+++ /dev/null
@@ -1,6 +0,0 @@
-json.array! @result do |user_id, favorites_count, retweets_count|
- json.user_id user_id
- json.favorites_count favorites_count
- json.retweets_count retweets_count
-end
-
diff --git a/app/views/users/stats.json.jbuilder b/app/views/users/stats.json.jbuilder
deleted file mode 100644
index 46f07b6..0000000
--- a/app/views/users/stats.json.jbuilder
+++ /dev/null
@@ -1,2 +0,0 @@
-json.id @user.id
-json.(@user.stats, :reactions_count)
diff --git a/config/application.rb b/config/application.rb
index 8844010..8e8204f 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -6,7 +6,6 @@ require "action_controller/railtie"
require "action_mailer/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"
-require "./lib/apidoc"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
@@ -18,6 +17,10 @@ module Aclog
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
+ # Configure grape
+ config.paths.add "app/api", eager_load: true
+ config.paths.add "app/api/concerns", eager_load: true
+
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += Dir["#{config.root}/lib/", "#{config.root}/lib/**/"]
@@ -42,5 +45,9 @@ module Aclog
g.test_framework :rspec
g.fixture_replacement :factory_girl
end
+
+ config.middleware.use(Rack::Config) do |env|
+ env["api.tilt.root"] = "#{config.root}/app/api/templates"
+ end
end
end
diff --git a/config/initializers/rabl.rb b/config/initializers/rabl.rb
new file mode 100644
index 0000000..f11eb19
--- /dev/null
+++ b/config/initializers/rabl.rb
@@ -0,0 +1,3 @@
+Rabl.configure do |config|
+ config.include_json_root = false
+end
diff --git a/config/routes.rb b/config/routes.rb
index e43d793..067ea79 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,11 +1,7 @@
Aclog::Application.routes.draw do
root to: "about#index"
- # JSON API
- scope "/api", format: false, defaults: { format: "json" } do
- get "/users/:action.json", controller: "users"
- get "/tweets/:action.json", controller: "tweets"
- end
+ mount Aclog::Api => "/api"
# Internals / SessionsController
get "/i/callback" => "sessions#create"
@@ -25,9 +21,8 @@ Aclog::Application.routes.draw do
get "/i/filter" => "tweets#filter", as: "filter"
get "/about" => "about#about", as: "about"
- get "/about/api" => "about#api", as: "about_api"
- get "/about/api/docs" => "apidocs#index", as: "api_docs"
- get "/about/api/docs/:resource/:name" => "apidocs#endpoint", as: "api_docs_endpoint"
+ get "/about/api" => "apidocs#index", as: "about_api"
+ get "/about/api/:method/:namespace/:path" => "apidocs#endpoint", as: "about_api_endpoint", constraints: { namespace: /[\w\/]+/ }
# User pages
scope "/:screen_name" do
diff --git a/lib/aclog/exceptions.rb b/lib/aclog/exceptions.rb
index 9b7078f..5eafc99 100644
--- a/lib/aclog/exceptions.rb
+++ b/lib/aclog/exceptions.rb
@@ -17,5 +17,10 @@ module Aclog
class AccountPrivate < UserError; end
class DocumentNotFound < StandardError; end
+
+ class AclogError < StandardError; end
+ class NotFound < AclogError; end
+ class Forbidden < AclogError; end
+ class OAuthEchoError < AclogError; end
end
end
diff --git a/lib/apidoc.rb b/lib/apidoc.rb
deleted file mode 100644
index c85eceb..0000000
--- a/lib/apidoc.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-Dir.glob(File.expand_path("../apidoc/**/*.rb", __FILE__)) {|file| require file }
-
-module Apidoc
- extend self
-
- def resources
- @@resources ||= {}
- end
-
- def reload!
- @@resources = nil
- dir = "#{Rails.root}/app/controllers/"
- Dir.glob("#{dir}**/*.rb") do |path|
- ActiveSupport::Dependencies.load_file path
- end
- end
-end
diff --git a/lib/apidoc/controller_dsl.rb b/lib/apidoc/controller_dsl.rb
deleted file mode 100644
index 38b1727..0000000
--- a/lib/apidoc/controller_dsl.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-module Apidoc
- module ControllerDsl
- include Resources
- include Endpoints
- include Parameters
-
- private
- def method_added(method_name)
- super(method_name)
-
- if _apidoc_endpoint_started?
- _apidoc_resource.endpoints[method_name] = _apidoc_current_endpoint
- self._apidoc_current_endpoint = nil
- end
- end
-
- def _apidoc_resource
- name = self.name.sub(/Controller$/, "").underscore
- Apidoc.resources[name.to_sym] ||= Resource.new(name.titleize)
- end
-
- def _apidoc_current_endpoint
- @_apidoc_current_endpoint || raise(DslError, "Endpoint definition is not started.")
- end
-
- def _apidoc_current_endpoint=(value)
- @_apidoc_current_endpoint = value
- end
-
- def _apidoc_endpoint_started?
- @_apidoc_current_endpoint.present?
- end
-
- def _apidoc_param_groups
- @_apidoc_param_groups ||= {}
- end
- end
-end
diff --git a/lib/apidoc/controller_dsl/endpoint.rb b/lib/apidoc/controller_dsl/endpoint.rb
deleted file mode 100644
index 18d4fe2..0000000
--- a/lib/apidoc/controller_dsl/endpoint.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module Apidoc
- module ControllerDsl
- module Endpoints
- def get(endpoint)
- _apidoc_endpoint(:get, endpoint)
- end
-
- def post(endpoint)
- _apidoc_endpoint(:post, endpoint)
- end
-
- def _apidoc_endpoint(method, endpoint)
- if _apidoc_endpoint_started?
- raise DslError, "Previous endpoint #{_apidoc_current_endpoint} definition is not completed."
- end
-
- self._apidoc_current_endpoint = Endpoint.new(method, endpoint)
- end
-
- def description(description)
- _apidoc_current_endpoint.description = description
- end
-
- def nodoc
- _apidoc_current_endpoint.nodoc = true
- end
- end
- end
-end
-
diff --git a/lib/apidoc/controller_dsl/parameters.rb b/lib/apidoc/controller_dsl/parameters.rb
deleted file mode 100644
index c3d285f..0000000
--- a/lib/apidoc/controller_dsl/parameters.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-module Apidoc
- module ControllerDsl
- module Parameters
- def requires(name, example, description)
- _apidoc_current_endpoint.parameters << Parameter.new(name, example, description, required: true)
- end
-
- def optional(name, example, description)
- _apidoc_current_endpoint.parameters << Parameter.new(name, example, description, required: false)
- end
-
- def param_group(name, &blk)
- if block_given?
- _apidoc_param_groups[name] = blk
- else
- blk = _apidoc_param_groups[name]
- if blk
- blk.call
- else
- raise DslError, "Parameters group #{name} is not defined."
- end
- end
- end
- end
- end
-end
-
diff --git a/lib/apidoc/controller_dsl/resources.rb b/lib/apidoc/controller_dsl/resources.rb
deleted file mode 100644
index 110b564..0000000
--- a/lib/apidoc/controller_dsl/resources.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module Apidoc
- module ControllerDsl
- module Resources
- private
- def resource_description(description)
- _apidoc_resource.description = description
- end
- end
- end
-end
-
-
diff --git a/lib/apidoc/endpoint.rb b/lib/apidoc/endpoint.rb
deleted file mode 100644
index 14dedeb..0000000
--- a/lib/apidoc/endpoint.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-module Apidoc
- class Endpoint
- attr_reader :method, :name, :parameters
- attr_accessor :description, :nodoc
-
- def initialize(method, name)
- @method = method
- @name = name
- @parameters = []
- @description = nil
- @nodoc = false
- end
-
- def to_s
- "#{method.to_s.upcase} #{name}"
- end
- end
-end
diff --git a/lib/apidoc/exceptions.rb b/lib/apidoc/exceptions.rb
deleted file mode 100644
index ee4685f..0000000
--- a/lib/apidoc/exceptions.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module Apidoc
- class Error < StandardError; end
-
- class ParameterMissing < Error
- def initialize(param)
- super("Parameter is missing or the value is empty: #{param}")
- end
- end
-
- class ParameterInvalid < Error
- def initialize(param)
- super("Parameter is invalid: #{param}")
- end
- end
-
- class DslError < SyntaxError; end
-end
diff --git a/lib/apidoc/parameter.rb b/lib/apidoc/parameter.rb
deleted file mode 100644
index 58b3d26..0000000
--- a/lib/apidoc/parameter.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Apidoc
- class Parameter
- attr_reader :name, :example, :description, :required
- alias required? required
-
- def initialize(name, example, description, required: false)
- @name = name
- @example = example
- @description = description
- @required = required
- end
- end
-end
diff --git a/lib/apidoc/railtie.rb b/lib/apidoc/railtie.rb
deleted file mode 100644
index 9e992a3..0000000
--- a/lib/apidoc/railtie.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Apidoc
- class Railtie < Rails::Railtie
- initializer "apidoc.controller_injections" do
- ActiveSupport.on_load :action_controller do
- extend ControllerDsl
- end
- end
- end
-end
diff --git a/lib/apidoc/resource.rb b/lib/apidoc/resource.rb
deleted file mode 100644
index b9afdf3..0000000
--- a/lib/apidoc/resource.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module Apidoc
- class Resource
- attr_reader :endpoints, :name
- attr_accessor :description
-
- def initialize(name)
- @name = name
- @description = nil
- @endpoints = {}
- end
- end
-end