Skip to content
Extraits de code Groupes Projets
Non vérifiée Valider 63c7fe8e rédigé par Eugen Rochko's avatar Eugen Rochko Validation de GitHub
Parcourir les fichiers

Refactor controllers for statuses, accounts, and more (#11249)

parent f1477647
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Affichage de
avec 236 ajouts et 96 suppressions
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
class AboutController < ApplicationController class AboutController < ApplicationController
layout 'public' layout 'public'
before_action :set_instance_presenter, only: [:show, :more, :terms] before_action :set_body_classes, only: :show
before_action :set_instance_presenter
before_action :set_expires_in
def show def show; end
@hide_navbar = true
end
def more; end def more; end
...@@ -27,4 +27,12 @@ class AboutController < ApplicationController ...@@ -27,4 +27,12 @@ class AboutController < ApplicationController
def set_instance_presenter def set_instance_presenter
@instance_presenter = InstancePresenter.new @instance_presenter = InstancePresenter.new
end end
def set_body_classes
@hide_navbar = true
end
def set_expires_in
expires_in 0, public: true
end
end end
...@@ -6,13 +6,13 @@ class AccountsController < ApplicationController ...@@ -6,13 +6,13 @@ class AccountsController < ApplicationController
include AccountControllerConcern include AccountControllerConcern
before_action :set_cache_headers before_action :set_cache_headers
before_action :set_body_classes
def show def show
respond_to do |format| respond_to do |format|
format.html do format.html do
mark_cacheable! unless user_signed_in? expires_in 0, public: true unless user_signed_in?
@body_classes = 'with-modals'
@pinned_statuses = [] @pinned_statuses = []
@endorsed_accounts = @account.endorsed_accounts.to_a.sample(4) @endorsed_accounts = @account.endorsed_accounts.to_a.sample(4)
...@@ -32,22 +32,25 @@ class AccountsController < ApplicationController ...@@ -32,22 +32,25 @@ class AccountsController < ApplicationController
end end
format.rss do format.rss do
mark_cacheable! expires_in 0, public: true
@statuses = cache_collection(default_statuses.without_reblogs.without_replies.limit(PAGE_SIZE), Status) @statuses = cache_collection(default_statuses.without_reblogs.without_replies.limit(PAGE_SIZE), Status)
render xml: RSS::AccountSerializer.render(@account, @statuses) render xml: RSS::AccountSerializer.render(@account, @statuses)
end end
format.json do format.json do
render_cached_json(['activitypub', 'actor', @account], content_type: 'application/activity+json') do expires_in 3.minutes, public: true
ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter) render json: @account, content_type: 'application/activity+json', serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter
end
end end
end end
end end
private private
def set_body_classes
@body_classes = 'with-modals'
end
def show_pinned_statuses? def show_pinned_statuses?
[replies_requested?, media_requested?, tag_requested?, params[:max_id].present?, params[:min_id].present?].none? [replies_requested?, media_requested?, tag_requested?, params[:max_id].present?, params[:min_id].present?].none?
end end
......
...@@ -2,29 +2,19 @@ ...@@ -2,29 +2,19 @@
class ActivityPub::CollectionsController < Api::BaseController class ActivityPub::CollectionsController < Api::BaseController
include SignatureVerification include SignatureVerification
include AccountOwnedConcern
before_action :set_account
before_action :set_size before_action :set_size
before_action :set_statuses before_action :set_statuses
before_action :set_cache_headers before_action :set_cache_headers
def show def show
render_cached_json(['activitypub', 'collection', @account, params[:id]], content_type: 'application/activity+json') do expires_in 3.minutes, public: true
ActiveModelSerializers::SerializableResource.new( render json: collection_presenter, content_type: 'application/activity+json', serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, skip_activities: true
collection_presenter,
serializer: ActivityPub::CollectionSerializer,
adapter: ActivityPub::Adapter,
skip_activities: true
)
end
end end
private private
def set_account
@account = Account.find_local!(params[:account_username])
end
def set_statuses def set_statuses
@statuses = scope_for_collection @statuses = scope_for_collection
@statuses = cache_collection(@statuses, Status) @statuses = cache_collection(@statuses, Status)
......
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
class ActivityPub::InboxesController < Api::BaseController class ActivityPub::InboxesController < Api::BaseController
include SignatureVerification include SignatureVerification
include JsonLdHelper include JsonLdHelper
include AccountOwnedConcern
before_action :set_account
def create def create
if unknown_deleted_account? if unknown_deleted_account?
...@@ -27,8 +26,8 @@ class ActivityPub::InboxesController < Api::BaseController ...@@ -27,8 +26,8 @@ class ActivityPub::InboxesController < Api::BaseController
false false
end end
def set_account def account_required?
@account = Account.find_local!(params[:account_username]) if params[:account_username] params[:account_username].present?
end end
def body def body
......
...@@ -4,8 +4,8 @@ class ActivityPub::OutboxesController < Api::BaseController ...@@ -4,8 +4,8 @@ class ActivityPub::OutboxesController < Api::BaseController
LIMIT = 20 LIMIT = 20
include SignatureVerification include SignatureVerification
include AccountOwnedConcern
before_action :set_account
before_action :set_statuses before_action :set_statuses
before_action :set_cache_headers before_action :set_cache_headers
...@@ -17,10 +17,6 @@ class ActivityPub::OutboxesController < Api::BaseController ...@@ -17,10 +17,6 @@ class ActivityPub::OutboxesController < Api::BaseController
private private
def set_account
@account = Account.find_local!(params[:account_username])
end
def outbox_presenter def outbox_presenter
if page_requested? if page_requested?
ActivityPub::CollectionPresenter.new( ActivityPub::CollectionPresenter.new(
......
# frozen_string_literal: true
class ActivityPub::RepliesController < Api::BaseController
include SignatureAuthentication
include Authorization
include AccountOwnedConcern
DESCENDANTS_LIMIT = 60
before_action :set_status
before_action :set_cache_headers
before_action :set_replies
def index
render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true
end
private
def set_status
@status = @account.statuses.find(params[:status_id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
raise ActiveRecord::RecordNotFound
end
def set_replies
@replies = page_params[:other_accounts] ? Status.where.not(account_id: @account.id) : @account.statuses
@replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
@replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
end
def replies_collection_presenter
page = ActivityPub::CollectionPresenter.new(
id: account_status_replies_url(@account, @status, page_params),
type: :unordered,
part_of: account_status_replies_url(@account, @status),
next: next_page,
items: @replies.map { |status| status.local ? status : status.id }
)
return page if page_requested?
ActivityPub::CollectionPresenter.new(
id: account_status_replies_url(@account, @status),
type: :unordered,
first: page
)
end
def page_requested?
params[:page] == 'true'
end
def next_page
account_status_replies_url(
@account,
@status,
page: true,
min_id: @replies&.last&.id,
other_accounts: !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT)
)
end
def page_params
params_slice(:other_accounts, :min_id).merge(page: true)
end
end
# frozen_string_literal: true # frozen_string_literal: true
class Api::ProofsController < Api::BaseController class Api::ProofsController < Api::BaseController
before_action :set_account include AccountOwnedConcern
before_action :set_provider before_action :set_provider
before_action :check_account_approval
before_action :check_account_suspension
def index def index
render json: @account, serializer: @provider.serializer_class render json: @account, serializer: @provider.serializer_class
...@@ -16,15 +15,7 @@ class Api::ProofsController < Api::BaseController ...@@ -16,15 +15,7 @@ class Api::ProofsController < Api::BaseController
@provider = ProofProvider.find(params[:provider]) || raise(ActiveRecord::RecordNotFound) @provider = ProofProvider.find(params[:provider]) || raise(ActiveRecord::RecordNotFound)
end end
def set_account def username_param
@account = Account.find_local!(params[:username]) params[:username]
end
def check_account_approval
not_found if @account.user_pending?
end
def check_account_suspension
gone if @account.suspended?
end end
end end
...@@ -154,8 +154,4 @@ class ApplicationController < ActionController::Base ...@@ -154,8 +154,4 @@ class ApplicationController < ActionController::Base
def set_cache_headers def set_cache_headers
response.headers['Vary'] = 'Accept' response.headers['Vary'] = 'Accept'
end end
def mark_cacheable!
expires_in 0, public: true
end
end end
...@@ -3,24 +3,19 @@ ...@@ -3,24 +3,19 @@
module AccountControllerConcern module AccountControllerConcern
extend ActiveSupport::Concern extend ActiveSupport::Concern
include AccountOwnedConcern
FOLLOW_PER_PAGE = 12 FOLLOW_PER_PAGE = 12
included do included do
layout 'public' layout 'public'
before_action :set_account
before_action :check_account_approval
before_action :check_account_suspension
before_action :set_instance_presenter before_action :set_instance_presenter
before_action :set_link_headers before_action :set_link_headers
end end
private private
def set_account
@account = Account.find_local!(username_param)
end
def set_instance_presenter def set_instance_presenter
@instance_presenter = InstancePresenter.new @instance_presenter = InstancePresenter.new
end end
...@@ -29,27 +24,15 @@ module AccountControllerConcern ...@@ -29,27 +24,15 @@ module AccountControllerConcern
response.headers['Link'] = LinkHeader.new( response.headers['Link'] = LinkHeader.new(
[ [
webfinger_account_link, webfinger_account_link,
atom_account_url_link,
actor_url_link, actor_url_link,
] ]
) )
end end
def username_param
params[:account_username]
end
def webfinger_account_link def webfinger_account_link
[ [
webfinger_account_url, webfinger_account_url,
[%w(rel lrdd), %w(type application/xrd+xml)], [%w(rel lrdd), %w(type application/jrd+json)],
]
end
def atom_account_url_link
[
account_url(@account, format: 'atom'),
[%w(rel alternate), %w(type application/atom+xml)],
] ]
end end
...@@ -63,15 +46,4 @@ module AccountControllerConcern ...@@ -63,15 +46,4 @@ module AccountControllerConcern
def webfinger_account_url def webfinger_account_url
webfinger_url(resource: @account.to_webfinger_s) webfinger_url(resource: @account.to_webfinger_s)
end end
def check_account_approval
not_found if @account.user_pending?
end
def check_account_suspension
if @account.suspended?
expires_in(3.minutes, public: true)
gone
end
end
end end
# frozen_string_literal: true
module AccountOwnedConcern
extend ActiveSupport::Concern
included do
before_action :set_account, if: :account_required?
before_action :check_account_approval, if: :account_required?
before_action :check_account_suspension, if: :account_required?
end
private
def account_required?
true
end
def set_account
@account = Account.find_local!(username_param)
end
def username_param
params[:account_username]
end
def check_account_approval
not_found if @account.local? && @account.user_pending?
end
def check_account_suspension
expires_in(3.minutes, public: true) && gone if @account.suspended?
end
end
# frozen_string_literal: true
module StatusControllerConcern
extend ActiveSupport::Concern
ANCESTORS_LIMIT = 40
DESCENDANTS_LIMIT = 60
DESCENDANTS_DEPTH_LIMIT = 20
def create_descendant_thread(starting_depth, statuses)
depth = starting_depth + statuses.size
if depth < DESCENDANTS_DEPTH_LIMIT
{
statuses: statuses,
starting_depth: starting_depth,
}
else
next_status = statuses.pop
{
statuses: statuses,
starting_depth: starting_depth,
next_status: next_status,
}
end
end
def set_ancestors
@ancestors = @status.reply? ? cache_collection(@status.ancestors(ANCESTORS_LIMIT, current_account), Status) : []
@next_ancestor = @ancestors.size < ANCESTORS_LIMIT ? nil : @ancestors.shift
end
def set_descendants
@max_descendant_thread_id = params[:max_descendant_thread_id]&.to_i
@since_descendant_thread_id = params[:since_descendant_thread_id]&.to_i
descendants = cache_collection(
@status.descendants(
DESCENDANTS_LIMIT,
current_account,
@max_descendant_thread_id,
@since_descendant_thread_id,
DESCENDANTS_DEPTH_LIMIT
),
Status
)
@descendant_threads = []
if descendants.present?
statuses = [descendants.first]
starting_depth = 0
descendants.drop(1).each_with_index do |descendant, index|
if descendants[index].id == descendant.in_reply_to_id
statuses << descendant
else
@descendant_threads << create_descendant_thread(starting_depth, statuses)
# The thread is broken, assume it's a reply to the root status
starting_depth = 0
# ... unless we can find its ancestor in one of the already-processed threads
@descendant_threads.reverse_each do |descendant_thread|
statuses = descendant_thread[:statuses]
index = statuses.find_index do |thread_status|
thread_status.id == descendant.in_reply_to_id
end
if index.present?
starting_depth = descendant_thread[:starting_depth] + index + 1
break
end
end
statuses = [descendant]
end
end
@descendant_threads << create_descendant_thread(starting_depth, statuses)
end
@max_descendant_thread_id = @descendant_threads.pop[:statuses].first.id if descendants.size >= DESCENDANTS_LIMIT
end
end
...@@ -6,6 +6,7 @@ class CustomCssController < ApplicationController ...@@ -6,6 +6,7 @@ class CustomCssController < ApplicationController
before_action :set_cache_headers before_action :set_cache_headers
def show def show
expires 3.minutes, public: true
render plain: Setting.custom_css || '', content_type: 'text/css' render plain: Setting.custom_css || '', content_type: 'text/css'
end end
end end
...@@ -7,9 +7,8 @@ class EmojisController < ApplicationController ...@@ -7,9 +7,8 @@ class EmojisController < ApplicationController
def show def show
respond_to do |format| respond_to do |format|
format.json do format.json do
render_cached_json(['activitypub', 'emoji', @emoji], content_type: 'application/activity+json') do expires_in 3.minutes, public: true
ActiveModelSerializers::SerializableResource.new(@emoji, serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter) render json: @emoji, content_type: 'application/activity+json', serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter
end
end end
end end
end end
......
...@@ -8,7 +8,7 @@ class FollowerAccountsController < ApplicationController ...@@ -8,7 +8,7 @@ class FollowerAccountsController < ApplicationController
def index def index
respond_to do |format| respond_to do |format|
format.html do format.html do
mark_cacheable! unless user_signed_in? expires_in 0, public: true unless user_signed_in?
next if @account.user_hides_network? next if @account.user_hides_network?
......
...@@ -8,7 +8,7 @@ class FollowingAccountsController < ApplicationController ...@@ -8,7 +8,7 @@ class FollowingAccountsController < ApplicationController
def index def index
respond_to do |format| respond_to do |format|
format.html do format.html do
mark_cacheable! unless user_signed_in? expires_in 0, public: true unless user_signed_in?
next if @account.user_hides_network? next if @account.user_hides_network?
......
...@@ -21,7 +21,7 @@ class HomeController < ApplicationController ...@@ -21,7 +21,7 @@ class HomeController < ApplicationController
when 'statuses' when 'statuses'
status = Status.find_by(id: matches[2]) status = Status.find_by(id: matches[2])
if status && (status.public_visibility? || status.unlisted_visibility?) if status&.distributable?
redirect_to(ActivityPub::TagManager.instance.url_for(status)) redirect_to(ActivityPub::TagManager.instance.url_for(status))
return return
end end
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
class IntentsController < ApplicationController class IntentsController < ApplicationController
before_action :check_uri before_action :check_uri
rescue_from Addressable::URI::InvalidURIError, with: :handle_invalid_uri rescue_from Addressable::URI::InvalidURIError, with: :handle_invalid_uri
def show def show
......
...@@ -4,6 +4,7 @@ class ManifestsController < ApplicationController ...@@ -4,6 +4,7 @@ class ManifestsController < ApplicationController
skip_before_action :store_current_location skip_before_action :store_current_location
def show def show
expires_in 3.minutes, public: true
render json: InstancePresenter.new, serializer: ManifestSerializer render json: InstancePresenter.new, serializer: ManifestSerializer
end end
end end
...@@ -31,7 +31,6 @@ class MediaController < ApplicationController ...@@ -31,7 +31,6 @@ class MediaController < ApplicationController
def verify_permitted_status! def verify_permitted_status!
authorize @media_attachment.status, :show? authorize @media_attachment.status, :show?
rescue Mastodon::NotPermittedError rescue Mastodon::NotPermittedError
# Reraise in order to get a 404 instead of a 403 error code
raise ActiveRecord::RecordNotFound raise ActiveRecord::RecordNotFound
end end
......
...@@ -8,20 +8,16 @@ class PublicTimelinesController < ApplicationController ...@@ -8,20 +8,16 @@ class PublicTimelinesController < ApplicationController
before_action :set_instance_presenter before_action :set_instance_presenter
def show def show
respond_to do |format| @initial_state_json = ActiveModelSerializers::SerializableResource.new(
format.html do InitialStatePresenter.new(settings: { known_fediverse: Setting.show_known_fediverse_at_about_page }, token: current_session&.token),
@initial_state_json = ActiveModelSerializers::SerializableResource.new( serializer: InitialStateSerializer
InitialStatePresenter.new(settings: { known_fediverse: Setting.show_known_fediverse_at_about_page }, token: current_session&.token), ).to_json
serializer: InitialStateSerializer
).to_json
end
end
end end
private private
def check_enabled def check_enabled
raise ActiveRecord::RecordNotFound unless Setting.timeline_preview not_found unless Setting.timeline_preview
end end
def set_body_classes def set_body_classes
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter