forked from mastodon/mastodon
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add REST API for managing and posting to circles
Circles are the conceptual opposite of lists. A list is a subdivision of your follows, a circle is a subdivision of your followers. Posting to a circle means making content available to only some of your followers. Circles have been internally supported in Mastodon for the purposes of federation since mastodon#8950, this adds the REST API necessary for making use of them in Mastodon itsef.
- Loading branch information
Showing
19 changed files
with
353 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# frozen_string_literal: true | ||
|
||
class Api::V1::Accounts::CirclesController < Api::BaseController | ||
before_action -> { doorkeeper_authorize! :read, :'read:circles' } | ||
before_action :require_user! | ||
before_action :set_account | ||
|
||
def index | ||
@circles = @account.circles.where(account: current_account) | ||
render json: @circles, each_serializer: REST::CircleSerializer | ||
end | ||
|
||
private | ||
|
||
def set_account | ||
@account = Account.find(params[:account_id]) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# frozen_string_literal: true | ||
|
||
class Api::V1::Circles::AccountsController < Api::BaseController | ||
before_action -> { doorkeeper_authorize! :read, :'read:circles' }, only: [:show] | ||
before_action -> { doorkeeper_authorize! :write, :'write:circles' }, except: [:show] | ||
|
||
before_action :require_user! | ||
before_action :set_circle | ||
|
||
after_action :insert_pagination_headers, only: :show | ||
|
||
def show | ||
@accounts = load_accounts | ||
render json: @accounts, each_serializer: REST::AccountSerializer | ||
end | ||
|
||
def create | ||
ApplicationRecord.transaction do | ||
circle_accounts.each do |account| | ||
@circle.accounts << account | ||
end | ||
end | ||
|
||
render_empty | ||
end | ||
|
||
def destroy | ||
CircleAccount.where(circle: @circle, account_id: account_ids).destroy_all | ||
render_empty | ||
end | ||
|
||
private | ||
|
||
def set_circle | ||
@circle = current_account.owned_circles.find(params[:circle_id]) | ||
end | ||
|
||
def load_accounts | ||
if unlimited? | ||
@circle.accounts.includes(:account_stat).all | ||
else | ||
@circle.accounts.includes(:account_stat).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id]) | ||
end | ||
end | ||
|
||
def circle_accounts | ||
Account.find(account_ids) | ||
end | ||
|
||
def account_ids | ||
Array(resource_params[:account_ids]) | ||
end | ||
|
||
def resource_params | ||
params.permit(account_ids: []) | ||
end | ||
|
||
def insert_pagination_headers | ||
set_pagination_headers(next_path, prev_path) | ||
end | ||
|
||
def next_path | ||
return if unlimited? | ||
|
||
api_v1_circle_accounts_url(pagination_params(max_id: pagination_max_id)) if records_continue? | ||
end | ||
|
||
def prev_path | ||
return if unlimited? | ||
|
||
api_v1_circle_accounts_url(pagination_params(since_id: pagination_since_id)) unless @accounts.empty? | ||
end | ||
|
||
def pagination_max_id | ||
@accounts.last.id | ||
end | ||
|
||
def pagination_since_id | ||
@accounts.first.id | ||
end | ||
|
||
def records_continue? | ||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) | ||
end | ||
|
||
def pagination_params(core_params) | ||
params.slice(:limit).permit(:limit).merge(core_params) | ||
end | ||
|
||
def unlimited? | ||
params[:limit] == '0' | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# frozen_string_literal: true | ||
|
||
class Api::V1::CirclesController < Api::BaseController | ||
before_action -> { doorkeeper_authorize! :read, :'read:circles' }, only: [:index, :show] | ||
before_action -> { doorkeeper_authorize! :write, :'write:circles' }, except: [:index, :show] | ||
|
||
before_action :require_user! | ||
before_action :set_circle, except: [:index, :create] | ||
|
||
after_action :insert_pagination_headers, only: :index | ||
|
||
def index | ||
@circles = current_account.owned_circles.paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id]) | ||
render json: @circles, each_serializer: REST::CircleSerializer | ||
end | ||
|
||
def show | ||
render json: @circle, serializer: REST::CircleSerializer | ||
end | ||
|
||
def create | ||
@circle = current_account.owned_circles.create!(circle_params) | ||
render json: @circle, serializer: REST::CircleSerializer | ||
end | ||
|
||
def update | ||
@circle.update!(circle_params) | ||
render json: @circle, serializer: REST::CircleSerializer | ||
end | ||
|
||
def destroy | ||
@circle.destroy! | ||
render_empty | ||
end | ||
|
||
private | ||
|
||
def set_circle | ||
@circle = current_account.owned_circles.find(params[:id]) | ||
end | ||
|
||
def circle_params | ||
params.permit(:title) | ||
end | ||
|
||
def insert_pagination_headers | ||
set_pagination_headers(next_path, prev_path) | ||
end | ||
|
||
def next_path | ||
api_v1_circles_url(pagination_params(max_id: pagination_max_id)) if records_continue? | ||
end | ||
|
||
def prev_path | ||
api_v1_circles_url(pagination_params(since_id: pagination_since_id)) unless @circles.empty? | ||
end | ||
|
||
def pagination_max_id | ||
@circles.last.id | ||
end | ||
|
||
def pagination_since_id | ||
@circles.first.id | ||
end | ||
|
||
def records_continue? | ||
@circles.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) | ||
end | ||
|
||
def pagination_params(core_params) | ||
params.slice(:limit).permit(:limit).merge(core_params) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# frozen_string_literal: true | ||
|
||
# == Schema Information | ||
# | ||
# Table name: circles | ||
# | ||
# id :bigint(8) not null, primary key | ||
# account_id :bigint(8) not null | ||
# title :string default(""), not null | ||
# created_at :datetime not null | ||
# updated_at :datetime not null | ||
# | ||
class Circle < ApplicationRecord | ||
include Paginable | ||
|
||
belongs_to :account | ||
|
||
has_many :circle_accounts, inverse_of: :circle, dependent: :destroy | ||
has_many :accounts, through: :circle_accounts | ||
|
||
validates :title, presence: true | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# frozen_string_literal: true | ||
|
||
# == Schema Information | ||
# | ||
# Table name: circle_accounts | ||
# | ||
# id :bigint(8) not null, primary key | ||
# circle_id :bigint(8) not null | ||
# account_id :bigint(8) not null | ||
# follow_id :bigint(8) not null | ||
# created_at :datetime not null | ||
# updated_at :datetime not null | ||
# | ||
class CircleAccount < ApplicationRecord | ||
belongs_to :circle | ||
belongs_to :account | ||
belongs_to :follow, optional: true | ||
|
||
validates :account_id, uniqueness: { scope: :circle_id } | ||
|
||
before_validation :set_follow | ||
|
||
private | ||
|
||
def set_follow | ||
self.follow = Follow.find_by!(target_account_id: circle.account_id, account_id: account.id) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class CreateCircles < ActiveRecord::Migration[5.2] | ||
def change | ||
create_table :circles do |t| | ||
t.belongs_to :account, foreign_key: { on_delete: :cascade }, null: false | ||
t.string :title, default: '', null: false | ||
|
||
t.timestamps | ||
end | ||
end | ||
end |
Oops, something went wrong.