105 行
3.4 KiB
Ruby
105 行
3.4 KiB
Ruby
class PostCreatePreflight
|
|
class ValidationFailed < StandardError
|
|
attr_reader :fields, :base_errors
|
|
|
|
def initialize fields: { }, base_errors: []
|
|
super('入力内容を確認してください.')
|
|
@fields = fields
|
|
@base_errors = base_errors
|
|
end
|
|
end
|
|
|
|
def initialize attributes:, thumbnail: nil
|
|
@attributes = attributes.symbolize_keys
|
|
@thumbnail = thumbnail
|
|
end
|
|
|
|
def run
|
|
preview = PostImportPreviewer.new.preview_rows(
|
|
rows: [preview_row],
|
|
fetch_metadata: false).first
|
|
|
|
validate_thumbnail_upload!
|
|
|
|
if preview[:validation_errors].present?
|
|
raise ValidationFailed.new(fields: preview[:validation_errors])
|
|
end
|
|
|
|
{
|
|
url: preview[:url],
|
|
title: preview[:attributes]['title'],
|
|
thumbnail_base: preview[:attributes]['thumbnail_base'],
|
|
tags: preview[:attributes]['tags'],
|
|
parent_post_ids: preview[:attributes]['parent_post_ids'],
|
|
original_created_from: preview[:attributes]['original_created_from'],
|
|
original_created_before: preview[:attributes]['original_created_before'],
|
|
duration: preview[:attributes]['duration'],
|
|
video_ms: preview[:attributes]['video_ms'],
|
|
field_warnings: preview[:field_warnings],
|
|
base_warnings: preview[:base_warnings],
|
|
existing_post: existing_post_compact(preview[:existing_post_id]) }
|
|
end
|
|
|
|
private
|
|
|
|
def preview_row
|
|
{
|
|
source_row: 1,
|
|
url: @attributes[:url].to_s,
|
|
attributes: {
|
|
'title' => @attributes[:title].to_s,
|
|
'thumbnail_base' => @attributes[:thumbnail_base].to_s,
|
|
'original_created_from' => @attributes[:original_created_from].to_s,
|
|
'original_created_before' => @attributes[:original_created_before].to_s,
|
|
'duration' => @attributes[:duration].to_s,
|
|
'video_ms' => @attributes[:video_ms],
|
|
'tags' => @attributes[:tags].to_s,
|
|
'parent_post_ids' => parent_post_ids_text },
|
|
provenance: {
|
|
'url' => 'manual',
|
|
'title' => 'manual',
|
|
'thumbnail_base' => 'manual',
|
|
'original_created_from' => 'manual',
|
|
'original_created_before' => 'manual',
|
|
'duration' => 'manual',
|
|
'video_ms' => 'manual',
|
|
'tags' => 'manual',
|
|
'parent_post_ids' => 'manual' },
|
|
tag_sources: {
|
|
'automatic' => '',
|
|
'manual' => @attributes[:tags].to_s } }
|
|
end
|
|
|
|
def parent_post_ids_text
|
|
Array(@attributes[:parent_post_ids]).flat_map { _1.to_s.split }.join(' ')
|
|
end
|
|
|
|
def validate_thumbnail_upload!
|
|
return if @attributes[:thumbnail_base].present?
|
|
return if @thumbnail.blank?
|
|
|
|
attachment = Post.resized_thumbnail_attachment(@thumbnail)
|
|
attachment[:io].close if attachment[:io].respond_to?(:close)
|
|
rescue MiniMagick::Error
|
|
raise ValidationFailed.new(fields: { thumbnail: ['サムネイル画像の変換に失敗しました.'] })
|
|
end
|
|
|
|
def existing_post_compact post_id
|
|
return nil if post_id.blank?
|
|
|
|
post = Post.with_attached_thumbnail.find_by(id: post_id)
|
|
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
|