Add post regenerations

This commit is contained in:
BrokenEagle
2020-11-22 07:08:40 +00:00
committed by evazion
parent e6f2bf1c89
commit 16d6f3bbd5
13 changed files with 234 additions and 12 deletions

View File

@@ -0,0 +1,18 @@
class PostRegenerationsController < ApplicationController
respond_to :html, :xml, :json, :js
def create
@post_regeneration = authorize PostRegeneration.new(creator: CurrentUser.user, **permitted_attributes(PostRegeneration))
@post_regeneration.execute_category_action!
@post_regeneration.save
respond_with(@post_regeneration, location: @post_regeneration.post)
end
def index
@post_regenerations = authorize PostRegeneration.paginated_search(params)
@post_regenerations = @post_regenerations.includes(:creator, :post) if request.format.html?
respond_with(@post_regenerations)
end
end

View File

@@ -32,6 +32,22 @@ class UploadService
[preview_file, crop_file, sample_file]
end
def process_resizes(upload, file, original_post_id, media_file: nil)
media_file ||= upload.media_file
preview_file, crop_file, sample_file = Utils.generate_resizes(media_file)
begin
Utils.distribute_files(file, upload, :original, original_post_id: original_post_id) if file.present?
Utils.distribute_files(sample_file, upload, :large, original_post_id: original_post_id) if sample_file.present?
Utils.distribute_files(preview_file, upload, :preview, original_post_id: original_post_id) if preview_file.present?
Utils.distribute_files(crop_file, upload, :crop, original_post_id: original_post_id) if crop_file.present?
ensure
preview_file.try(:close!)
crop_file.try(:close!)
sample_file.try(:close!)
end
end
def process_file(upload, file, original_post_id: nil)
upload.file = file
media_file = upload.media_file
@@ -45,18 +61,7 @@ class UploadService
upload.validate!(:file)
upload.tag_string = "#{upload.tag_string} #{Utils.automatic_tags(media_file)}"
preview_file, crop_file, sample_file = Utils.generate_resizes(media_file)
begin
Utils.distribute_files(file, upload, :original, original_post_id: original_post_id)
Utils.distribute_files(sample_file, upload, :large, original_post_id: original_post_id) if sample_file.present?
Utils.distribute_files(preview_file, upload, :preview, original_post_id: original_post_id) if preview_file.present?
Utils.distribute_files(crop_file, upload, :crop, original_post_id: original_post_id) if crop_file.present?
ensure
preview_file.try(:close!)
crop_file.try(:close!)
sample_file.try(:close!)
end
process_resizes(upload, file, original_post_id)
end
def automatic_tags(media_file)

View File

@@ -0,0 +1,31 @@
class PostRegeneration < ApplicationRecord
belongs_to :creator, :class_name => "User"
belongs_to :post
validates :category, inclusion: %w[iqdb resizes]
module SearchMethods
def search(params)
q = search_attributes(params, :id, :created_at, :updated_at, :category, :creator, :post)
q.apply_default_order(params)
end
end
extend SearchMethods
def execute_category_action!
if category == "iqdb"
post.update_iqdb_async
elsif category == "resizes"
media_file = MediaFile.open(post.file, frame_data: post.pixiv_ugoira_frame_data)
UploadService::Utils.process_resizes(post, nil, post.id, media_file: media_file)
else
# should never happen
raise Error, "Unknown category: #{category}"
end
end
def self.searchable_includes
[:creator, :post]
end
end

View File

@@ -0,0 +1,9 @@
class PostRegenerationPolicy < ApplicationPolicy
def create?
user.is_moderator?
end
def permitted_attributes_for_create
[:post_id, :category]
end
end

View File

@@ -0,0 +1,5 @@
<% if @post_regeneration.errors.any? %>
Danbooru.error("<%= j @post_regeneration.errors.full_messages.join(',') %>");
<% else %>
Danbooru.notice("Post regenerated");
<% end %>

View File

@@ -0,0 +1,17 @@
<div id="c-post-regenerations">
<div id="a-index">
<h1>Post regenerations</h1>
<%= table_for @post_regenerations, width: "100%" do |t| %>
<% t.column "Post", width: "1%" do |regeneration| %>
<%= PostPresenter.preview(regeneration.post, show_deleted: true) %>
<% end %>
<% t.column :category %>
<% t.column "Creator", width: "10%" do |regeneration| %>
<%= compact_time regeneration.created_at %>
<br> by <%= link_to_user regeneration.creator %>
<% end %>
<% end %>
<%= numbered_paginator(@post_regenerations) %>
</div>
</div>

View File

@@ -86,4 +86,9 @@
<li id="post-option-replace-image"><%= link_to "Replace image", new_post_replacement_path(post_id: post.id), remote: true %></li>
<% end %>
<% end %>
<% if policy(PostRegeneration).create? %>
<li id="post-option-regenerate-iqdb"><%= link_to "Regenerate IQDB", post_regenerations_path(post_regeneration: {post_id: post.id, category: "iqdb"}), remote: true, method: :post %></li>
<li id="post-option-regenerate-preview"><%= link_to "Regenerate image sizes", post_regenerations_path(post_regeneration: {post_id: post.id, category: "resizes"}), remote: true, method: :post %></li>
<% end %>
</ul>

View File

@@ -33,6 +33,7 @@
<li id="post-history-moderation"><%= link_to "Moderation", post_events_path(@post.id) %></li>
<li id="post-history-commentary"><%= link_to "Commentary", artist_commentary_versions_path(search: { post_id: @post.id }) %></li>
<li id="post-history-replacements"><%= link_to "Replacements", post_replacements_path(search: {post_id: @post.id }) %></li>
<li id="post-history-regenerations"><%= link_to "Regenerations", post_regenerations_path(search: {post_id: @post.id }) %></li>
</ul>
</section>
<% end %>

View File

@@ -178,6 +178,7 @@ Rails.application.routes.draw do
get :search
end
end
resources :post_regenerations, :only => [:index, :create]
resources :post_replacements, :only => [:index, :new, :create, :update]
resources :post_votes, only: [:index]

View File

@@ -0,0 +1,13 @@
class CreatePostRegenerations < ActiveRecord::Migration[6.0]
def change
create_table :post_regenerations do |t|
t.timestamps
t.integer :creator_id, null: false
t.integer :post_id, null: false
t.string :category, null: false
t.index :creator_id
t.index :post_id
end
end
end

View File

@@ -2724,6 +2724,39 @@ CREATE SEQUENCE public.post_flags_id_seq
ALTER SEQUENCE public.post_flags_id_seq OWNED BY public.post_flags.id;
--
-- Name: post_regenerations; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.post_regenerations (
id bigint NOT NULL,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL,
creator_id integer NOT NULL,
post_id integer NOT NULL,
category character varying NOT NULL
);
--
-- Name: post_regenerations_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.post_regenerations_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: post_regenerations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.post_regenerations_id_seq OWNED BY public.post_regenerations.id;
--
-- Name: post_replacements; Type: TABLE; Schema: public; Owner: -
--
@@ -4137,6 +4170,13 @@ ALTER TABLE ONLY public.post_disapprovals ALTER COLUMN id SET DEFAULT nextval('p
ALTER TABLE ONLY public.post_flags ALTER COLUMN id SET DEFAULT nextval('public.post_flags_id_seq'::regclass);
--
-- Name: post_regenerations id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.post_regenerations ALTER COLUMN id SET DEFAULT nextval('public.post_regenerations_id_seq'::regclass);
--
-- Name: post_replacements id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -4499,6 +4539,14 @@ ALTER TABLE ONLY public.post_flags
ADD CONSTRAINT post_flags_pkey PRIMARY KEY (id);
--
-- Name: post_regenerations post_regenerations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.post_regenerations
ADD CONSTRAINT post_regenerations_pkey PRIMARY KEY (id);
--
-- Name: post_replacements post_replacements_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@@ -6752,6 +6800,20 @@ CREATE INDEX index_post_flags_on_reason_tsvector ON public.post_flags USING gin
CREATE INDEX index_post_flags_on_status ON public.post_flags USING btree (status);
--
-- Name: index_post_regenerations_on_creator_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_post_regenerations_on_creator_id ON public.post_regenerations USING btree (creator_id);
--
-- Name: index_post_regenerations_on_post_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_post_regenerations_on_post_id ON public.post_regenerations USING btree (post_id);
--
-- Name: index_post_replacements_on_creator_id; Type: INDEX; Schema: public; Owner: -
--
@@ -7520,6 +7582,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200520060951'),
('20200803022359'),
('20200816175151'),
('20201121180345'),
('20201201211748'),
('20201213052805'),
('20201219201007'),

View File

@@ -0,0 +1,5 @@
FactoryBot.define do
factory(:post_regeneration) do
post factory: :post, source: FFaker::Internet.http_url
end
end

View File

@@ -0,0 +1,49 @@
require 'test_helper'
class PostRegenerationsControllerTest < ActionDispatch::IntegrationTest
context "The post regenerations controller" do
setup do
@mod = create(:moderator_user, name: "yukari", created_at: 1.month.ago)
as(@mod) do
@post = create(:post, source: "https://google.com", tag_string: "touhou")
@post_regeneration = create(:post_regeneration, creator: @mod, category: "iqdb")
end
end
context "create action" do
should "render" do
assert_difference("PostRegeneration.count") do
post_auth post_regenerations_path, @mod, params: {format: :json, post_regeneration: {post_id: @post.id, category: "iqdb"}}
assert_response :success
end
end
should "not allow non-mods to regenerate posts" do
assert_difference("PostRegeneration.count", 0) do
post_auth post_regenerations_path, create(:user), params: {format: :json, post_regeneration: {post_id: @post.id, category: "iqdb"}}
assert_response 403
end
end
end
context "index action" do
setup do
@admin = create(:admin_user)
as(@admin) { @admin_regeneration = create(:post_regeneration, post: @post, creator: @admin, category: "resizes") }
end
should "render" do
get post_regenerations_path
assert_response :success
end
should respond_to_search({}).with { [@admin_regeneration, @post_regeneration] }
should respond_to_search(category: "iqdb").with { @post_regeneration }
context "using includes" do
should respond_to_search(post_tags_match: "touhou").with { @admin_regeneration }
should respond_to_search(creator: {level: User::Levels::ADMIN}).with { @admin_regeneration }
end
end
end
end