mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-22 18:45:41 +01:00
Add support for preview cards for local posts/accounts
This commit is contained in:
parent
b3d970bdb8
commit
77dd4b3341
9 changed files with 83 additions and 2 deletions
|
@ -32,6 +32,8 @@
|
||||||
# link_type :integer
|
# link_type :integer
|
||||||
# published_at :datetime
|
# published_at :datetime
|
||||||
# image_description :string default(""), not null
|
# image_description :string default(""), not null
|
||||||
|
# target_status_id :bigint(8)
|
||||||
|
# target_account_id :bigint(8)
|
||||||
#
|
#
|
||||||
|
|
||||||
class PreviewCard < ApplicationRecord
|
class PreviewCard < ApplicationRecord
|
||||||
|
@ -50,6 +52,9 @@ class PreviewCard < ApplicationRecord
|
||||||
enum :type, { link: 0, photo: 1, video: 2, rich: 3 }
|
enum :type, { link: 0, photo: 1, video: 2, rich: 3 }
|
||||||
enum :link_type, { unknown: 0, article: 1 }
|
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 :preview_cards_statuses, dependent: :delete_all, inverse_of: :preview_card
|
||||||
has_many :statuses, through: :preview_cards_statuses
|
has_many :statuses, through: :preview_cards_statuses
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ class FetchLinkCardService < BaseService
|
||||||
with_redis_lock("fetch:#{@original_url}") do
|
with_redis_lock("fetch:#{@original_url}") do
|
||||||
@card = PreviewCard.find_by(url: @url)
|
@card = PreviewCard.find_by(url: @url)
|
||||||
process_url if @card.nil? || @card.updated_at <= 2.weeks.ago || @card.missing_image?
|
process_url if @card.nil? || @card.updated_at <= 2.weeks.ago || @card.missing_image?
|
||||||
|
attach_local_resource_to_card!
|
||||||
end
|
end
|
||||||
|
|
||||||
attach_card if @card&.persisted?
|
attach_card if @card&.persisted?
|
||||||
|
@ -60,6 +61,22 @@ class FetchLinkCardService < BaseService
|
||||||
end
|
end
|
||||||
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
|
def attach_card
|
||||||
with_redis_lock("attach_card:#{@status.id}") do
|
with_redis_lock("attach_card:#{@status.id}") do
|
||||||
return if @status.with_preview_card?
|
return if @status.with_preview_card?
|
||||||
|
@ -85,7 +102,14 @@ class FetchLinkCardService < BaseService
|
||||||
|
|
||||||
def bad_url?(uri)
|
def bad_url?(uri)
|
||||||
# Avoid local instance URLs and invalid URLs
|
# 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
|
end
|
||||||
|
|
||||||
def mention_link?(anchor)
|
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.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
|
@ -874,6 +874,10 @@ ActiveRecord::Schema[7.1].define(version: 2024_03_22_161611) do
|
||||||
t.integer "link_type"
|
t.integer "link_type"
|
||||||
t.datetime "published_at"
|
t.datetime "published_at"
|
||||||
t.string "image_description", default: "", null: false
|
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
|
t.index ["url"], name: "index_preview_cards_on_url", unique: true
|
||||||
end
|
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", "accounts", on_delete: :cascade
|
||||||
add_foreign_key "polls", "statuses", 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_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", "accounts", on_delete: :cascade
|
||||||
add_foreign_key "report_notes", "reports", 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
|
add_foreign_key "reports", "accounts", column: "action_taken_by_account_id", name: "fk_bca45b75fd", on_delete: :nullify
|
||||||
|
|
Loading…
Reference in a new issue