From 2b1c58c959948d163f39c2ac5f87a21a6b22a4ba Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 3 Feb 2022 18:36:44 -0600 Subject: [PATCH] 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. --- .../file_upload_component.js | 9 ++++- app/controllers/posts_controller.rb | 6 ++-- app/controllers/uploads_controller.rb | 5 ++- app/models/post.rb | 34 ++++++++----------- app/policies/post_policy.rb | 6 ++++ app/views/uploads/show.html.erb | 7 +--- test/functional/posts_controller_test.rb | 2 +- test/functional/uploads_controller_test.rb | 8 +++++ 8 files changed, 47 insertions(+), 30 deletions(-) diff --git a/app/components/file_upload_component/file_upload_component.js b/app/components/file_upload_component/file_upload_component.js index c6f2901ab..0a83aeccb 100644 --- a/app/components/file_upload_component/file_upload_component.js +++ b/app/components/file_upload_component/file_upload_component.js @@ -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"); diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index a8617669a..82c6e1457 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -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 diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index c2e18d52c..a5b06fad4 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -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? diff --git a/app/models/post.rb b/app/models/post.rb index 3ffec42a1..007dd42c2 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -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 diff --git a/app/policies/post_policy.rb b/app/policies/post_policy.rb index aa498d77c..4e49dfbed 100644 --- a/app/policies/post_policy.rb +++ b/app/policies/post_policy.rb @@ -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 diff --git a/app/views/uploads/show.html.erb b/app/views/uploads/show.html.erb index feefe6522..26bd1f013 100644 --- a/app/views/uploads/show.html.erb +++ b/app/views/uploads/show.html.erb @@ -29,9 +29,6 @@ - <% @upload_media_asset = @upload.upload_media_assets.first %> - <% @media_asset = @upload_media_asset.media_asset %> -
<%= 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 %> diff --git a/test/functional/posts_controller_test.rb b/test/functional/posts_controller_test.rb index 4fa3c6aff..92658e3a8 100644 --- a/test/functional/posts_controller_test.rb +++ b/test/functional/posts_controller_test.rb @@ -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 diff --git a/test/functional/uploads_controller_test.rb b/test/functional/uploads_controller_test.rb index a1d0fdd7c..bbf43c610 100644 --- a/test/functional/uploads_controller_test.rb +++ b/test/functional/uploads_controller_test.rb @@ -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