mirror of
https://github.com/mastodon/mastodon.git
synced 2024-11-20 03:25:17 +01:00
Add support for preview cards for local posts/accounts
This commit is contained in:
parent
b3d970bdb8
commit
77dd4b3341
@ -32,6 +32,8 @@
|
||||
# link_type :integer
|
||||
# published_at :datetime
|
||||
# image_description :string default(""), not null
|
||||
# target_status_id :bigint(8)
|
||||
# target_account_id :bigint(8)
|
||||
#
|
||||
|
||||
class PreviewCard < ApplicationRecord
|
||||
@ -50,6 +52,9 @@ class PreviewCard < ApplicationRecord
|
||||
enum :type, { link: 0, photo: 1, video: 2, rich: 3 }
|
||||
enum :link_type, { unknown: 0, article: 1 }
|
||||
|
||||
belongs_to :target_status, class_name: 'Status', optional: true, dependent: :destroy
|
||||
belongs_to :target_account, class_name: 'Account', optional: true, dependent: :destroy
|
||||
|
||||
has_many :preview_cards_statuses, dependent: :delete_all, inverse_of: :preview_card
|
||||
has_many :statuses, through: :preview_cards_statuses
|
||||
|
||||
|
@ -26,6 +26,7 @@ class FetchLinkCardService < BaseService
|
||||
with_redis_lock("fetch:#{@original_url}") do
|
||||
@card = PreviewCard.find_by(url: @url)
|
||||
process_url if @card.nil? || @card.updated_at <= 2.weeks.ago || @card.missing_image?
|
||||
attach_local_resource_to_card!
|
||||
end
|
||||
|
||||
attach_card if @card&.persisted?
|
||||
@ -60,6 +61,22 @@ class FetchLinkCardService < BaseService
|
||||
end
|
||||
end
|
||||
|
||||
def attach_local_resource_to_card!
|
||||
return if @card.nil? || @card.target_account_id.present? || @card.target_status_id.present? || !TagManager.instance.local_url?(@card.url)
|
||||
|
||||
recognized_params = Rails.application.routes.recognize_path(@card.url)
|
||||
return if recognized_params[:action] != 'show'
|
||||
|
||||
case recognized_params[:controller]
|
||||
when 'accounts'
|
||||
account = Account.find_local(recognized_params[:username])
|
||||
@card.update!(target_account: account)
|
||||
when 'statuses'
|
||||
status = Status.find_by(id: recognized_params[:id])
|
||||
@card.update!(target_status: status)
|
||||
end
|
||||
end
|
||||
|
||||
def attach_card
|
||||
with_redis_lock("attach_card:#{@status.id}") do
|
||||
return if @status.with_preview_card?
|
||||
@ -85,7 +102,14 @@ class FetchLinkCardService < BaseService
|
||||
|
||||
def bad_url?(uri)
|
||||
# Avoid local instance URLs and invalid URLs
|
||||
uri.host.blank? || TagManager.instance.local_url?(uri.to_s) || !%w(http https).include?(uri.scheme)
|
||||
uri.host.blank? || bad_local_url?(uri.to_s) || !%w(http https).include?(uri.scheme)
|
||||
end
|
||||
|
||||
def bad_local_url?(uri)
|
||||
return false unless TagManager.instance.local_url?(uri.to_s)
|
||||
|
||||
recognized_params = Rails.application.routes.recognize_path(uri)
|
||||
recognized_params[:action] != 'show' || %w(accounts statuses).exclude?(recognized_params[:controller])
|
||||
end
|
||||
|
||||
def mention_link?(anchor)
|
||||
|
@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddTargetStatusIdToPreviewCards < ActiveRecord::Migration[7.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def change
|
||||
add_belongs_to :preview_cards, :target_status, null: true, index: { algorithm: :concurrently, where: 'target_status_id IS NOT NULL' }
|
||||
end
|
||||
end
|
@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddTargetStatusForeignKeyToPreviewCards < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
add_foreign_key :preview_cards, :statuses, column: :target_status_id, on_delete: :cascade, validate: false
|
||||
end
|
||||
end
|
@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ValidateTargetStatusForeignKeyOnPreviewCards < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
validate_foreign_key :preview_cards, column: :target_status_id
|
||||
end
|
||||
end
|
@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddTargetAccountIdToPreviewCards < ActiveRecord::Migration[7.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def change
|
||||
add_belongs_to :preview_cards, :target_account, null: true, index: { algorithm: :concurrently, where: 'target_account_id IS NOT NULL' }
|
||||
end
|
||||
end
|
@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddTargetAccountForeignKeyToPreviewCards < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
add_foreign_key :preview_cards, :accounts, column: :target_account_id, on_delete: :cascade, validate: false
|
||||
end
|
||||
end
|
@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ValidateTargetAccountForeignKeyOnPreviewCards < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
validate_foreign_key :preview_cards, column: :target_account_id
|
||||
end
|
||||
end
|
@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.1].define(version: 2024_03_22_161611) do
|
||||
ActiveRecord::Schema[7.1].define(version: 2024_03_26_161740) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
@ -874,6 +874,10 @@ ActiveRecord::Schema[7.1].define(version: 2024_03_22_161611) do
|
||||
t.integer "link_type"
|
||||
t.datetime "published_at"
|
||||
t.string "image_description", default: "", null: false
|
||||
t.bigint "target_status_id"
|
||||
t.bigint "target_account_id"
|
||||
t.index ["target_account_id"], name: "index_preview_cards_on_target_account_id", where: "(target_account_id IS NOT NULL)"
|
||||
t.index ["target_status_id"], name: "index_preview_cards_on_target_status_id", where: "(target_status_id IS NOT NULL)"
|
||||
t.index ["url"], name: "index_preview_cards_on_url", unique: true
|
||||
end
|
||||
|
||||
@ -1347,6 +1351,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_03_22_161611) do
|
||||
add_foreign_key "polls", "accounts", on_delete: :cascade
|
||||
add_foreign_key "polls", "statuses", on_delete: :cascade
|
||||
add_foreign_key "preview_card_trends", "preview_cards", on_delete: :cascade
|
||||
add_foreign_key "preview_cards", "accounts", column: "target_account_id", on_delete: :cascade
|
||||
add_foreign_key "preview_cards", "statuses", column: "target_status_id", on_delete: :cascade
|
||||
add_foreign_key "report_notes", "accounts", on_delete: :cascade
|
||||
add_foreign_key "report_notes", "reports", on_delete: :cascade
|
||||
add_foreign_key "reports", "accounts", column: "action_taken_by_account_id", name: "fk_bca45b75fd", on_delete: :nullify
|
||||
|
Loading…
Reference in New Issue
Block a user