add transcript support

it could be possible to load closed captions and subtitles from the transcript div via javascript, but I hate javascript so perhaps some other time.
This commit is contained in:
edshot99 2024-11-10 13:58:15 -06:00
parent 9ee8f13d5f
commit 4928747b83
25 changed files with 173 additions and 19 deletions

View File

@ -170,6 +170,7 @@ class PostsController < ApplicationController
source old_source
title old_title
description old_description
transcript old_transcript
rating old_rating
edit_reason
]

View File

@ -72,7 +72,7 @@ class UploadsController < ApplicationController
def upload_params
permitted_params = %i[
file direct_url source tag_string rating parent_id title description description as_pending
file direct_url source tag_string rating parent_id title description description transcript as_pending
]
permitted_params << :locked_tags if CurrentUser.is_admin?

View File

@ -63,6 +63,7 @@ module PostIndex
source: { type: "keyword" },
title: { type: "text" },
description: { type: "text" },
transcript: { type: "text" },
notes: { type: "text" },
del_reason: { type: "keyword" },
@ -276,6 +277,7 @@ module PostIndex
source: source_array,
title: title.present? ? title : nil,
description: description.present? ? description : nil,
transcript: transcript.present? ? transcript : nil,
rating_locked: is_rating_locked,
note_locked: is_note_locked,

View File

@ -21,10 +21,12 @@ module PostVersionIndex
source: { type: "keyword" },
title: { type: "text" },
description: { type: "text" },
transcript: { type: "text" },
reason: { type: "text" },
title_changed: { type: "boolean" },
description_changed: { type: "boolean" },
transcript_changed: { type: "boolean" },
parent_id_changed: { type: "boolean" },
source_changed: { type: "boolean" },
rating_changed: { type: "boolean" },
@ -84,10 +86,12 @@ module PostVersionIndex
source: source,
title: title,
description: description,
transcript: transcript,
reason: reason,
title_changed: title_changed,
description_changed: description_changed,
transcript_changed: transcript_changed,
parent_id_changed: parent_changed,
source_changed: source_changed,
rating_changed: rating_changed,

View File

@ -165,6 +165,14 @@
<%= ApplicationController.new.render_to_string(partial: "dtext_input", locals: { limit: Danbooru.config.post_descr_max_size, textarea: '<textarea class="dtext-formatter-input tag-textarea dtext" id="post_description" rows="10" v-model="description"></textarea>'.html_safe, allow_color: true }) %>
</div>
</div>
<div class="flex-grid border-bottom">
<div class="col">
<label class="section-label" for="post_transcript">Transcript</label>
</div>
<div class="col2">
<textarea spellcheck="true" class="tag-textarea" v-model="transcript" id="post_transcript"></textarea>
</div>
</div>
<div v-if="allowUploadAsPending" class="flex-grid border-bottom">
<div class="col">
<label class="section-label">Upload as Pending</label>
@ -331,6 +339,7 @@
parentID: '',
title: '',
description: '',
transcript: '',
rating: '',
error: '',
duplicateId: 0,
@ -387,6 +396,7 @@
fillField('parentID', 'parent');
fillField('title', 'title');
fillField('description', 'description');
fillField('transcript', 'transcript');
fillTags();
fillRating();
if(params.has('sources')) {
@ -421,6 +431,7 @@
data.append('upload[source]', this.sources.join('\n'));
data.append('upload[title]', this.title);
data.append('upload[description]', this.description);
data.append('upload[transcript]', this.transcript);
data.append('upload[parent_id]', this.parentID);
if (this.allowLockedTags)
data.append('upload[locked_tags]', this.lockedTags);

View File

@ -128,14 +128,25 @@ div#c-post-versions {
@include grid-border(right);
}
.pv-transcript-label {
grid-row: 1;
@include grid-col(9, 10);
}
.pv-transcript {
grid-row: 2;
@include grid-col(9, 10);
@include grid-border(right);
}
.pv-tags-locked-label {
grid-row: 1;
@include grid-col(9, 13);
@include grid-col(10, 13);
}
.pv-tags-locked {
grid-row: 2;
@include grid-col(9, 13);
@include grid-col(10, 13);
@include grid-border(right);
}

View File

@ -110,6 +110,7 @@ class ElasticPostQueryBuilder < ElasticQueryBuilder
add_array_relation(:delreason, :del_reason, action: :wildcard)
add_array_relation(:title, :title, action: :match_phrase_prefix)
add_array_relation(:description, :description, action: :match_phrase_prefix)
add_array_relation(:transcript, :transcript, action: :match_phrase_prefix)
add_array_relation(:note, :notes, action: :match_phrase_prefix)
add_array_relation(:sources, :source, any_none_key: :source, action: :wildcard)
add_array_relation(:deleter, :deleter)
@ -158,6 +159,10 @@ class ElasticPostQueryBuilder < ElasticQueryBuilder
(q[:hasdescription] ? must : must_not).push({exists: {field: :description}})
end
if q.include?(:hastranscript)
(q[:hastranscript] ? must : must_not).push({exists: {field: :transcript}})
end
if q.include?(:ischild)
(q[:ischild] ? must : must_not).push({exists: {field: :parent}})
end

View File

@ -8,11 +8,11 @@ class TagQuery
].freeze
BOOLEAN_METATAGS = %w[
hassource hastitle hasdescription isparent ischild inpool pending_replacements artverified
hassource hastitle hasdescription hastranscript isparent ischild inpool pending_replacements artverified
].freeze
NEGATABLE_METATAGS = %w[
id filetype type rating title description parent user user_id approver flagger deletedby delreason
id filetype type rating title description transcript parent user user_id approver flagger deletedby delreason
source status pool set fav favoritedby note locked upvote votedup downvote voteddown voted
width height mpixels ratio filesize duration score favcount date age change tagcount
commenter comm noter noteupdater
@ -296,6 +296,9 @@ class TagQuery
when "description", "-description", "~description"
add_to_query(type, :description) { g2 }
when "transcript", "-transcript", "~transcript"
add_to_query(type, :transcript) { g2 }
when "note", "-note", "~note"
add_to_query(type, :note) { g2 }

View File

@ -53,6 +53,7 @@ class UploadService
p.is_rating_locked = upload.locked_rating if upload.locked_rating.present?
p.title = upload.title.strip
p.description = upload.description.strip
p.transcript = upload.transcript.strip
p.md5 = upload.md5
p.file_ext = upload.file_ext
p.image_width = upload.image_width

View File

@ -23,6 +23,7 @@ class Post < ApplicationRecord
validates :bg_color, format: { with: /\A[A-Fa-f0-9]{6}\z/ }, allow_nil: true
validates :title, length: { maximum: Danbooru.config.post_title_max_size }, if: :title_changed?
validates :description, length: { maximum: Danbooru.config.post_descr_max_size }, if: :description_changed?
validates :transcript, length: { maximum: Danbooru.config.post_trasc_max_size }, if: :transcript_changed?
validate :added_tags_are_valid, if: :should_process_tags?
validate :removed_tags_are_valid, if: :should_process_tags?
validate :has_artist_tag, if: :should_process_tags?
@ -1174,6 +1175,7 @@ class Post < ApplicationRecord
id: id,
title: title,
description: description,
transcript: transcript,
md5: md5,
tags: tag_string,
height: image_height,
@ -1323,7 +1325,7 @@ class Post < ApplicationRecord
end
def saved_change_to_watched_attributes?
saved_change_to_rating? || saved_change_to_source? || saved_change_to_parent_id? || saved_change_to_tag_string? || saved_change_to_locked_tags? || saved_change_to_title? || saved_change_to_description?
saved_change_to_rating? || saved_change_to_source? || saved_change_to_parent_id? || saved_change_to_tag_string? || saved_change_to_locked_tags? || saved_change_to_title? || saved_change_to_description? || saved_change_to_transcript?
end
def create_new_version
@ -1343,6 +1345,7 @@ class Post < ApplicationRecord
self.parent_id = target.parent_id
self.title = target.title
self.description = target.description
self.transcript = target.transcript
self.edit_reason = "Revert to version #{target.version}"
end

View File

@ -249,6 +249,7 @@ class PostReplacement < ApplicationRecord
parent_id: post.id,
title: post.title,
description: post.description,
transcript: post.transcript,
locked_tags: post.locked_tags,
replacement_id: self.id
}

View File

@ -39,6 +39,7 @@ class PostVersion < ApplicationRecord
locked_tags: post.locked_tags,
title: post.title,
description: post.description,
transcript: post.transcript,
reason: post.edit_reason
})
end
@ -71,6 +72,7 @@ class PostVersion < ApplicationRecord
self.source_changed = prev.nil? || source != prev.try(:source)
self.title_changed = prev.nil? || title != prev.try(:title)
self.description_changed = prev.nil? || description != prev.try(:description)
self.transcript_changed = prev.nil? || transcript != prev.try(:transcript)
end
def tag_array
@ -221,6 +223,10 @@ class PostVersion < ApplicationRecord
post.description = previous.description
end
if transcript_changed
post.transcript = previous.transcript
end
if rating_changed && !post.is_rating_locked?
post.rating = previous.rating
end

View File

@ -150,6 +150,7 @@ class PostPresenter < Presenter
uploader_id: post.uploader_id,
title: post.title,
description: post.description,
transcript: post.transcript,
flags: {
pending: post.is_pending,
flagged: post.is_flagged,

View File

@ -139,5 +139,5 @@ class PostSerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at, :file, :preview, :sample, :score, :tags, :locked_tags, :change_seq, :flags,
:rating, :fav_count, :sources, :pools, :relationships, :approver_id, :uploader_id, :title, :description,
:comment_count, :is_favorited, :has_notes, :duration
:transcript, :comment_count, :is_favorited, :has_notes, :duration
end

View File

@ -21,6 +21,9 @@
<div class="pv-description-label pv-label">
Description
</div>
<div class="pv-transcript-label pv-label">
Transcript
</div>
<div class="pv-tags-locked-label pv-label">
Locked Tags
</div>
@ -70,6 +73,21 @@
<em>Cleared</em>
<% end %>
</div>
<div class="pv-transcript pv-content">
<% if post_version.transcript.present? %>
<div class="desc-show">
<%= post_version.transcript_changed ? "Show Transcript" : "No change" %></div>
<div id='transcript-<%= post_version.id %>' class='desc-popup box-section'>
<h2>Transcript</h2>
<div class="closebutton">X</div>
<div class='desc-popup-inner'>
<p class="dtext-container"><%= format_text(post_version.transcript) %></p>
</div>
</div>
<% elsif post_version.transcript_changed && post_version.version != 1%>
<em>Cleared</em>
<% end %>
</div>
<div class="pv-tags-locked pv-content">
<%= post_version_locked_diff(post_version) %>
</div>

View File

@ -6,6 +6,8 @@
<%= f.input :title_changed, label: "Title Changed", collection: [%w[Yes true], %w[No false]], include_blank: true %>
<%= f.input :description, label: "Description" %>
<%= f.input :description_changed, label: "Description Changed", collection: [%w[Yes true], %w[No false]], include_blank: true %>
<%= f.input :transcript, label: "Transcript" %>
<%= f.input :transcript_changed, label: "Transcript Changed", collection: [%w[Yes true], %w[No false]], include_blank: true %>
<%= f.input :rating_changed, label: "Rating Changed To", collection: rating_collection + [%w[Any any]], include_blank: true %>
<%= f.input :rating, label: "Final Rating", collection: rating_collection, include_blank: true %>
<%= f.input :parent_id, label: "Parent ID" %>

View File

@ -46,6 +46,8 @@
<%= f.input :description, as: :dtext, limit: Danbooru.config.post_descr_max_size, allow_color: true %>
</div>
<%= f.input :transcript, as: :text, label: "Transcript", input_html: { size: "60x5", spellcheck: true } %>
<% if CurrentUser.is_privileged? %>
<div class="input">
<%= f.label :blank, "Lock" %>

View File

@ -194,6 +194,17 @@
</div>
<% end %>
<% if @post.transcript.present? %>
<div id="post-transcript-container" class="styled-dtext">
<details id="transcript">
<summary>Transcript</summary>
<div>
<%= format_text(@post.transcript, max_thumbs: 0) %>
</div>
</details>
</div>
<% end %>
<ul class="menu mobile-only">
<li><a href="#image-and-nav">Image</a></li>
<li><a href="#tag-list">Tags/Info</a></li>

View File

@ -329,6 +329,10 @@ module Danbooru
50_000
end
def post_trasc_max_size
50_000
end
def ticket_max_size
5_000
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddTranscriptToPosts < ActiveRecord::Migration[7.1]
def change
add_column(:posts, :transcript, :text, null: false, default: "")
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddTranscriptToPostVersions < ActiveRecord::Migration[7.1]
def change
add_column :post_versions, :transcript, :text
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddTranscriptChangedToPostVersions < ActiveRecord::Migration[7.1]
def change
add_column(:post_versions, :transcript_changed, :boolean, null: false, default: false)
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddTranscriptToUploads < ActiveRecord::Migration[7.1]
def change
add_column(:uploads, :transcript, :text, null: false, default: "")
end
end

View File

@ -0,0 +1,39 @@
# frozen_string_literal: true
class UpdatePostsTriggerChangeSeqForTranscript < ActiveRecord::Migration[7.1]
def up
execute <<-SQL.squish
CREATE OR REPLACE FUNCTION public.posts_trigger_change_seq() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF NEW.tag_string != OLD.tag_string OR NEW.parent_id != OLD.parent_id OR NEW.source != OLD.source OR NEW.approver_id != OLD.approver_id OR NEW.rating != OLD.rating OR NEW.title != OLD.title OR NEW.description != OLD.description OR NEW.transcript != OLD.transcript OR NEW.md5 != OLD.md5 OR NEW.is_deleted != OLD.is_deleted OR NEW.is_pending != OLD.is_pending OR NEW.is_flagged != OLD.is_flagged OR NEW.is_rating_locked != OLD.is_rating_locked OR NEW.is_status_locked != OLD.is_status_locked OR NEW.is_note_locked != OLD.is_note_locked OR NEW.bit_flags != OLD.bit_flags OR NEW.has_active_children != OLD.has_active_children OR NEW.last_noted_at != OLD.last_noted_at
THEN
NEW.change_seq = nextval('public.posts_change_seq_seq');
END IF;
RETURN NEW;
END;
$$;
SQL
end
def down
execute <<-SQL.squish
CREATE OR REPLACE FUNCTION public.posts_trigger_change_seq() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF NEW.tag_string != OLD.tag_string OR NEW.parent_id != OLD.parent_id OR NEW.source != OLD.source OR NEW.approver_id != OLD.approver_id OR NEW.rating != OLD.rating OR NEW.title != OLD.title OR NEW.description != OLD.description OR NEW.md5 != OLD.md5 OR NEW.is_deleted != OLD.is_deleted OR NEW.is_pending != OLD.is_pending OR NEW.is_flagged != OLD.is_flagged OR NEW.is_rating_locked != OLD.is_rating_locked OR NEW.is_status_locked != OLD.is_status_locked OR NEW.is_note_locked != OLD.is_note_locked OR NEW.bit_flags != OLD.bit_flags OR NEW.has_active_children != OLD.has_active_children OR NEW.last_noted_at != OLD.last_noted_at
THEN
NEW.change_seq = nextval('public.posts_change_seq_seq');
END IF;
RETURN NEW;
END;
$$;
SQL
end
end

View File

@ -29,15 +29,7 @@ COMMENT ON EXTENSION pg_trgm IS 'text similarity measurement and index searching
CREATE FUNCTION public.posts_trigger_change_seq() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF NEW.tag_string != OLD.tag_string OR NEW.parent_id != OLD.parent_id OR NEW.source != OLD.source OR NEW.approver_id != OLD.approver_id OR NEW.rating != OLD.rating OR NEW.title != OLD.title OR NEW.description != OLD.description OR NEW.md5 != OLD.md5 OR NEW.is_deleted != OLD.is_deleted OR NEW.is_pending != OLD.is_pending OR NEW.is_flagged != OLD.is_flagged OR NEW.is_rating_locked != OLD.is_rating_locked OR NEW.is_status_locked != OLD.is_status_locked OR NEW.is_note_locked != OLD.is_note_locked OR NEW.bit_flags != OLD.bit_flags OR NEW.has_active_children != OLD.has_active_children OR NEW.last_noted_at != OLD.last_noted_at
THEN
NEW.change_seq = nextval('public.posts_change_seq_seq');
END IF;
RETURN NEW;
END;
$$;
AS $$ BEGIN IF NEW.tag_string != OLD.tag_string OR NEW.parent_id != OLD.parent_id OR NEW.source != OLD.source OR NEW.approver_id != OLD.approver_id OR NEW.rating != OLD.rating OR NEW.title != OLD.title OR NEW.description != OLD.description OR NEW.transcript != OLD.transcript OR NEW.md5 != OLD.md5 OR NEW.is_deleted != OLD.is_deleted OR NEW.is_pending != OLD.is_pending OR NEW.is_flagged != OLD.is_flagged OR NEW.is_rating_locked != OLD.is_rating_locked OR NEW.is_status_locked != OLD.is_status_locked OR NEW.is_note_locked != OLD.is_note_locked OR NEW.bit_flags != OLD.bit_flags OR NEW.has_active_children != OLD.has_active_children OR NEW.last_noted_at != OLD.last_noted_at THEN NEW.change_seq = nextval('public.posts_change_seq_seq'); END IF; RETURN NEW; END; $$;
SET default_tablespace = '';
@ -1575,7 +1567,9 @@ CREATE TABLE public.post_versions (
description text,
description_changed boolean DEFAULT false NOT NULL,
version integer DEFAULT 1 NOT NULL,
reason character varying
reason character varying,
transcript text,
transcript_changed boolean DEFAULT false NOT NULL
);
@ -1690,7 +1684,8 @@ CREATE TABLE public.posts (
generated_samples character varying[],
duration numeric,
is_comment_disabled boolean DEFAULT false NOT NULL,
is_comment_locked boolean DEFAULT false NOT NULL
is_comment_locked boolean DEFAULT false NOT NULL,
transcript text DEFAULT ''::text NOT NULL
);
@ -2141,7 +2136,8 @@ CREATE TABLE public.uploads (
image_width integer,
image_height integer,
title text DEFAULT ''::text NOT NULL,
description text DEFAULT ''::text NOT NULL
description text DEFAULT ''::text NOT NULL,
transcript text DEFAULT ''::text NOT NULL
);
@ -4682,6 +4678,11 @@ ALTER TABLE ONLY public.avoid_postings
SET search_path TO "$user", public;
INSERT INTO "schema_migrations" (version) VALUES
('20241110171706'),
('20241110171006'),
('20241110170952'),
('20241110170945'),
('20241110170937'),
('20241029202902'),
('20241010174014'),
('20241009155325'),