summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/models/preview_card.rb5
-rw-r--r--app/services/fetch_link_card_service.rb26
-rw-r--r--db/migrate/20240326155335_add_target_status_id_to_preview_cards.rb9
-rw-r--r--db/migrate/20240326160308_add_target_status_foreign_key_to_preview_cards.rb7
-rw-r--r--db/migrate/20240326160903_validate_target_status_foreign_key_on_preview_cards.rb7
-rw-r--r--db/migrate/20240326161252_add_target_account_id_to_preview_cards.rb9
-rw-r--r--db/migrate/20240326161607_add_target_account_foreign_key_to_preview_cards.rb7
-rw-r--r--db/migrate/20240326161740_validate_target_account_foreign_key_on_preview_cards.rb7
-rw-r--r--db/schema.rb8
9 files changed, 83 insertions, 2 deletions
diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb
index 9fe02bd1681..d782184da0b 100644
--- a/app/models/preview_card.rb
+++ b/app/models/preview_card.rb
@@ -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
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index c6b600dd7cd..03a8b20015d 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -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)
diff --git a/db/migrate/20240326155335_add_target_status_id_to_preview_cards.rb b/db/migrate/20240326155335_add_target_status_id_to_preview_cards.rb
new file mode 100644
index 00000000000..1ce7eb0b21a
--- /dev/null
+++ b/db/migrate/20240326155335_add_target_status_id_to_preview_cards.rb
@@ -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
diff --git a/db/migrate/20240326160308_add_target_status_foreign_key_to_preview_cards.rb b/db/migrate/20240326160308_add_target_status_foreign_key_to_preview_cards.rb
new file mode 100644
index 00000000000..302bd92a532
--- /dev/null
+++ b/db/migrate/20240326160308_add_target_status_foreign_key_to_preview_cards.rb
@@ -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
diff --git a/db/migrate/20240326160903_validate_target_status_foreign_key_on_preview_cards.rb b/db/migrate/20240326160903_validate_target_status_foreign_key_on_preview_cards.rb
new file mode 100644
index 00000000000..a9369da370d
--- /dev/null
+++ b/db/migrate/20240326160903_validate_target_status_foreign_key_on_preview_cards.rb
@@ -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
diff --git a/db/migrate/20240326161252_add_target_account_id_to_preview_cards.rb b/db/migrate/20240326161252_add_target_account_id_to_preview_cards.rb
new file mode 100644
index 00000000000..e8a2340f3ef
--- /dev/null
+++ b/db/migrate/20240326161252_add_target_account_id_to_preview_cards.rb
@@ -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
diff --git a/db/migrate/20240326161607_add_target_account_foreign_key_to_preview_cards.rb b/db/migrate/20240326161607_add_target_account_foreign_key_to_preview_cards.rb
new file mode 100644
index 00000000000..cf45f3989dc
--- /dev/null
+++ b/db/migrate/20240326161607_add_target_account_foreign_key_to_preview_cards.rb
@@ -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
diff --git a/db/migrate/20240326161740_validate_target_account_foreign_key_on_preview_cards.rb b/db/migrate/20240326161740_validate_target_account_foreign_key_on_preview_cards.rb
new file mode 100644
index 00000000000..a5d7ca75d48
--- /dev/null
+++ b/db/migrate/20240326161740_validate_target_account_foreign_key_on_preview_cards.rb
@@ -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
diff --git a/db/schema.rb b/db/schema.rb
index 27c486487d8..c95401dcf9d 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -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