このコミットが含まれているのは:
@@ -0,0 +1,150 @@
|
||||
class PostBulkCreator
|
||||
def initialize actor:, posts:, thumbnails:
|
||||
@actor = actor
|
||||
@posts = posts
|
||||
@thumbnails = thumbnails
|
||||
end
|
||||
|
||||
def run
|
||||
results = @posts.each_with_index.map { |attributes, index|
|
||||
create_row(attributes, index)
|
||||
}
|
||||
|
||||
{ results: }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_row attributes, index
|
||||
preflight =
|
||||
PostCreatePreflight.new(
|
||||
attributes: attributes,
|
||||
thumbnail: thumbnail_for(index, attributes)).run
|
||||
if preflight[:existing_post].present?
|
||||
return {
|
||||
status: 'skipped',
|
||||
existing_post: preflight[:existing_post] }
|
||||
end
|
||||
|
||||
post = PostCreator.new(
|
||||
actor: @actor,
|
||||
attributes: normalised_attributes(attributes, preflight, index)).create!
|
||||
result = {
|
||||
status: 'created',
|
||||
post: { id: post.id } }
|
||||
result[:field_warnings] = preflight[:field_warnings] if preflight[:field_warnings].present?
|
||||
result[:base_warnings] = preflight[:base_warnings] if preflight[:base_warnings].present?
|
||||
result
|
||||
rescue PostCreatePreflight::ValidationFailed => e
|
||||
{
|
||||
status: 'failed',
|
||||
recoverable: true,
|
||||
errors: e.fields,
|
||||
base_errors: e.base_errors }
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
existing_post = existing_post_for_race(attributes, e.record)
|
||||
if existing_post.present?
|
||||
return {
|
||||
status: 'skipped',
|
||||
existing_post: existing_post }
|
||||
end
|
||||
|
||||
{
|
||||
status: 'failed',
|
||||
recoverable: true,
|
||||
errors: e.record.errors.to_hash,
|
||||
base_errors: e.record.errors[:base] }
|
||||
rescue ActiveRecord::RecordNotUnique => e
|
||||
raise unless e.message.include?('index_posts_on_url')
|
||||
|
||||
existing_post = existing_post_for_race(attributes)
|
||||
raise if existing_post.nil?
|
||||
|
||||
{
|
||||
status: 'skipped',
|
||||
existing_post: existing_post }
|
||||
rescue Tag::NicoTagNormalisationError
|
||||
{
|
||||
status: 'failed',
|
||||
recoverable: true,
|
||||
errors: { tags: ['ニコニコ・タグは直接指定できません.'] },
|
||||
base_errors: [] }
|
||||
rescue Tag::DeprecatedTagNormalisationError
|
||||
{
|
||||
status: 'failed',
|
||||
recoverable: true,
|
||||
errors: { tags: ['廃止済みタグは付与できません.'] },
|
||||
base_errors: [] }
|
||||
rescue PostCreator::VideoMsParseError
|
||||
{
|
||||
status: 'failed',
|
||||
recoverable: true,
|
||||
errors: { video_ms: ['動画時間の記法が不正です.'] },
|
||||
base_errors: [] }
|
||||
rescue Post::RemoteThumbnailFetchFailed
|
||||
{
|
||||
status: 'failed',
|
||||
recoverable: true,
|
||||
errors: { thumbnail_base: ['サムネイル画像の取得に失敗しました.'] },
|
||||
base_errors: [] }
|
||||
rescue ArgumentError => e
|
||||
{
|
||||
status: 'failed',
|
||||
recoverable: true,
|
||||
errors: { base: [e.message] },
|
||||
base_errors: [] }
|
||||
rescue StandardError => e
|
||||
Rails.logger.error(
|
||||
"post_bulk_creator_failure #{ { error: e.class.name,
|
||||
message: e.message }.to_json }")
|
||||
{
|
||||
status: 'failed',
|
||||
recoverable: false,
|
||||
errors: { base: ['登録中にエラーが発生しました.'] },
|
||||
base_errors: [] }
|
||||
end
|
||||
|
||||
def normalised_attributes attributes, preflight, index
|
||||
{
|
||||
url: preflight[:url],
|
||||
title: preflight[:title],
|
||||
thumbnail_base: preflight[:thumbnail_base],
|
||||
thumbnail: thumbnail_for(index, attributes),
|
||||
tags: preflight[:tags],
|
||||
parent_post_ids: preflight[:parent_post_ids],
|
||||
original_created_from: preflight[:original_created_from],
|
||||
original_created_before: preflight[:original_created_before],
|
||||
duration: preflight[:duration],
|
||||
video_ms: preflight[:video_ms] }
|
||||
end
|
||||
|
||||
def thumbnail_for index, attributes
|
||||
return nil if attributes['thumbnail_base'].present? || attributes[:thumbnail_base].present?
|
||||
|
||||
@thumbnails[index]
|
||||
end
|
||||
|
||||
def existing_post_for_race attributes, record = nil
|
||||
return nil if record.present? && !(record.errors.of_kind?(:url, :taken))
|
||||
|
||||
normal_url = PostUrlNormaliser.normalise(attributes['url'] || attributes[:url])
|
||||
return nil if normal_url.blank?
|
||||
|
||||
compact_existing_post(Post.with_attached_thumbnail.find_by(url: normal_url))
|
||||
end
|
||||
|
||||
def compact_existing_post post
|
||||
return nil if post.nil?
|
||||
|
||||
{
|
||||
id: post.id,
|
||||
title: post.title,
|
||||
url: post.url,
|
||||
thumbnail_url:
|
||||
if post.thumbnail.attached?
|
||||
Rails.application.routes.url_helpers.rails_storage_proxy_url(
|
||||
post.thumbnail,
|
||||
only_path: false)
|
||||
end }
|
||||
end
|
||||
end
|
||||
新しい課題から参照
ユーザをブロックする