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, host: nil @attributes = attributes.symbolize_keys @thumbnail = thumbnail @host = host end def run preview = PostImportPreviewer.new.preview_rows( rows: [preview_row], fetch_metadata: false).first if preview[:existing_post_id].present? return { 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'], display_tags: preview[:display_tags] || [], field_warnings: final_field_warnings(preview[:field_warnings] || { }), base_warnings: preview[:base_warnings], existing_post_id: preview[:existing_post_id], existing_post: existing_post_compact(preview[:existing_post_id]) } end if preview[:validation_errors].present? raise ValidationFailed.new(fields: preview[:validation_errors]) end validate_thumbnail_upload! plan = PostCreatePlan.new( attributes: { 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'] }).build! { url: plan[:url], title: plan[:title], thumbnail_base: plan[:thumbnail_base], tags: plan[:tags], parent_post_ids: plan[:parent_post_ids], original_created_from: plan[:original_created_from], original_created_before: plan[:original_created_before], duration: plan[:duration], video_ms: plan[:video_ms], display_tags: plan[:display_tags], direct_tag_specs: plan[:direct_tag_specs], default_tag_specs: plan[:default_tag_specs], snapshot_tag_specs: plan[:snapshot_tag_specs], post_tag_specs: plan[:post_tag_specs], tag_sections: plan[:tag_sections], normalised_parent_post_ids: plan[:normalised_parent_post_ids], field_warnings: final_field_warnings(preview[:field_warnings] || { }), base_warnings: preview[:base_warnings], existing_post_id: preview[:existing_post_id], 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? PostThumbnailUploadValidator.validate!(@thumbnail) rescue PostThumbnailUploadValidator::InvalidUpload => e raise ValidationFailed.new(fields: { thumbnail: [e.message] }) end def existing_post_compact post_id return nil if post_id.blank? post = Post.with_attached_thumbnail.find_by(id: post_id) PostCompactRepr.base(post, host: @host) end def final_field_warnings field_warnings thumbnail_warnings = (field_warnings['thumbnail_base'] || []).reject { _1 == 'サムネールなし' } if @attributes[:thumbnail_base].blank? && @thumbnail.blank? thumbnail_warnings = (thumbnail_warnings + ['サムネールなし']).uniq end next_warnings = field_warnings.except('thumbnail_base') next_warnings['thumbnail_base'] = thumbnail_warnings if thumbnail_warnings.present? next_warnings end end