Fix #4987: Can't populate tag string from upload url anymore.

Usage: https://danbooru.donmai.us/uploads/new?url=...&post[tag_string]=...&post[rating]=...

* Pass the URL parameters from the /uploads/new page to the /uploads/:id page.
* Fix the /uploads/:id page throwing an "unpermitted parameters" error
  when given URL params for the post edit form.
This commit is contained in:
evazion
2022-02-03 18:36:44 -06:00
parent 8173c73aa3
commit 2b1c58c959
8 changed files with 47 additions and 30 deletions

View File

@@ -102,7 +102,14 @@ export default class FileUploadComponent {
}
if (upload.status === "completed") {
window.location.replace(`/uploads/${upload.id}`);
let params = new URLSearchParams(window.location.search);
params.delete("url");
params.delete("ref");
let url = new URL(`/uploads/${upload.id}`, window.location.origin);
url.search = params.toString();
window.location.replace(url);
} else {
this.$dropzone.removeClass("success");
this.$component.find("progress").addClass("hidden");

View File

@@ -64,7 +64,8 @@ class PostsController < ApplicationController
end
def create
@post = authorize Post.new_from_upload(permitted_attributes(Post))
@upload_media_asset = UploadMediaAsset.find(params[:upload_media_asset_id])
@post = authorize Post.new_from_upload(@upload_media_asset.upload, @upload_media_asset.media_asset, **permitted_attributes(Post).to_h.symbolize_keys)
@post.save
if @post.errors.none?
@@ -79,7 +80,8 @@ class PostsController < ApplicationController
flash[:notice] = "Duplicate of post ##{@original_post.id}; merging tags"
redirect_to @original_post
else
@upload = UploadMediaAsset.find(params[:post][:upload_media_asset_id]).upload
@upload = @upload_media_asset.upload
@media_asset = @upload_media_asset.media_asset
flash[:notice] = @post.errors.full_messages.join("; ")
respond_with(@post, render: { template: "uploads/show" })
end

View File

@@ -46,7 +46,10 @@ class UploadsController < ApplicationController
def show
@upload = authorize Upload.find(params[:id])
@post = Post.new(uploader: @upload.uploader, uploader_ip_addr: @upload.uploader_ip_addr, source: @upload.source, rating: nil, **permitted_attributes(Post))
@upload_media_asset = @upload.upload_media_assets.first
@media_asset = @upload_media_asset&.media_asset
@post = Post.new_from_upload(@upload, @media_asset, source: @upload.source, **permitted_attributes(Post).to_h.symbolize_keys)
@post.tag_string = "#{@post.tag_string} #{@upload.source_strategy&.artists.to_a.map(&:tag).map(&:name).join(" ")}".strip
@post.tag_string += " " if @post.tag_string.present?

View File

@@ -75,32 +75,28 @@ class Post < ApplicationRecord
has_many :versions, -> { Rails.env.test? ? order("post_versions.updated_at ASC, post_versions.id ASC") : order("post_versions.updated_at ASC") }, class_name: "PostVersion", dependent: :destroy
end
def self.new_from_upload(params)
upload_media_asset = UploadMediaAsset.find(params[:upload_media_asset_id])
media_asset = upload_media_asset.media_asset
upload = upload_media_asset.upload
def self.new_from_upload(upload, media_asset, tag_string: nil, rating: nil, parent_id: nil, source: nil, artist_commentary_title: nil, artist_commentary_desc: nil, translated_commentary_title: nil, translated_commentary_desc: nil, is_pending: nil)
# XXX depends on CurrentUser
commentary = ArtistCommentary.new(
original_title: params[:artist_commentary_title],
original_description: params[:artist_commentary_desc],
translated_title: params[:translated_commentary_title],
translated_description: params[:translated_commentary_desc],
original_title: artist_commentary_title,
original_description: artist_commentary_desc,
translated_title: translated_commentary_title,
translated_description: translated_commentary_desc,
)
post = Post.new(
uploader: upload.uploader,
uploader_ip_addr: upload.uploader_ip_addr,
md5: media_asset.md5,
file_ext: media_asset.file_ext,
file_size: media_asset.file_size,
image_width: media_asset.image_width,
image_height: media_asset.image_height,
source: params[:source].to_s,
tag_string: params[:tag_string],
rating: params[:rating],
parent_id: params[:parent_id],
is_pending: !upload.uploader.can_upload_free? || params[:is_pending].to_s.truthy?,
md5: media_asset&.md5,
file_ext: media_asset&.file_ext,
file_size: media_asset&.file_size,
image_width: media_asset&.image_width,
image_height: media_asset&.image_height,
source: source.to_s,
tag_string: tag_string,
rating: rating,
parent_id: parent_id,
is_pending: !upload.uploader.can_upload_free? || is_pending.to_s.truthy?,
artist_commentary: (commentary if commentary.any_field_present?),
)
end

View File

@@ -76,6 +76,12 @@ class PostPolicy < ApplicationPolicy
translated_commentary_desc translated_commentary_title]
end
# XXX For UploadsController#show action
def permitted_attributes_for_show
%i[tag_string rating parent_id source is_pending artist_commentary_desc
artist_commentary_title translated_commentary_desc translated_commentary_title]
end
def permitted_attributes_for_update
%i[tag_string old_tag_string parent_id old_parent_id source old_source rating old_rating has_embedded_notes]
end

View File

@@ -29,9 +29,6 @@
<div id="client-errors" class="error-messages ui-state-error ui-corner-all" style="display:none"></div>
<% @upload_media_asset = @upload.upload_media_assets.first %>
<% @media_asset = @upload_media_asset.media_asset %>
<div id="upload-image">
<%= render MediaAssetComponent.new(media_asset: @media_asset) %>
@@ -51,9 +48,7 @@
<% end %>
<%= edit_form_for(@post, html: { id: "form" }) do |f| %>
<%= f.input :upload_id, as: :hidden, input_html: { value: @upload.id } %>
<%= f.input :media_asset_id, as: :hidden, input_html: { value: @media_asset.id } %>
<%= f.input :upload_media_asset_id, as: :hidden, input_html: { value: @upload_media_asset.id } %>
<%= hidden_field_tag :upload_media_asset_id, @upload_media_asset.id %>
<%= f.input :source, as: :string, input_html: { value: @upload.source_strategy&.canonical_url } %>
<%= f.input :rating, collection: [["Explicit", "e"], ["Questionable", "q"], ["Safe", "s"]], as: :radio_buttons, selected: @post.rating %>

View File

@@ -8,7 +8,7 @@ class PostsControllerTest < ActionDispatch::IntegrationTest
def create_post!(user: create(:user), media_asset: build(:media_asset), rating: "q", tag_string: "tagme", **params)
upload = build(:upload, uploader: user)
asset = create(:upload_media_asset, upload: upload, media_asset: media_asset)
post_auth posts_path, user, params: { post: { upload_media_asset_id: asset.id, rating: rating, tag_string: tag_string, **params }}
post_auth posts_path, user, params: { upload_media_asset_id: asset.id, post: { rating: rating, tag_string: tag_string, **params }}
Post.last
end

View File

@@ -138,6 +138,14 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
assert_redirected_to @post
end
should "prefill the upload form with the URL parameters" do
upload = create(:completed_source_upload, uploader: @user)
get_auth upload_path(upload, post: { rating: "s" }), @user
assert_response :success
assert_select "#post_rating_s[checked]"
end
end
context "create action" do