96 行
3.0 KiB
Ruby
96 行
3.0 KiB
Ruby
class PostCreatePlan
|
|
def initialize attributes:
|
|
@attributes = attributes.symbolize_keys
|
|
end
|
|
|
|
def build!
|
|
Tag.normalise_tags!(tag_names, with_tagme: false, deny_deprecated: true,
|
|
with_sections: true) =>
|
|
{ tags:, sections: }
|
|
|
|
tags = Tag.expand_parent_tags(tags).reject(&:deprecated?)
|
|
video_ms = normalise_video_ms(tags)
|
|
validate_video_sections!(video_ms, sections)
|
|
parent_post_ids = normalise_parent_post_ids
|
|
validate_parent_post_ids!(parent_post_ids)
|
|
|
|
{
|
|
url: @attributes[:url],
|
|
title: @attributes[:title].to_s,
|
|
thumbnail_base: @attributes[:thumbnail_base].presence,
|
|
original_created_from: @attributes[:original_created_from].presence,
|
|
original_created_before: @attributes[:original_created_before].presence,
|
|
tags: serialised_tags(tags, sections),
|
|
duration: @attributes[:duration].to_s,
|
|
video_ms: video_ms,
|
|
parent_post_ids: parent_post_ids.join(' '),
|
|
normalised_tags: tags,
|
|
tag_sections: sections,
|
|
normalised_parent_post_ids: parent_post_ids }
|
|
end
|
|
|
|
private
|
|
|
|
def tag_names = @attributes[:tags].to_s.split
|
|
|
|
def normalise_parent_post_ids
|
|
Array(@attributes[:parent_post_ids]).flat_map { _1.to_s.split }.map { |token|
|
|
id = Integer(token, exception: false)
|
|
raise ArgumentError, "親投稿 Id. が不正です: #{ token }" if id.nil? || id <= 0
|
|
|
|
id
|
|
}.uniq.sort
|
|
end
|
|
|
|
def validate_parent_post_ids! ids
|
|
missing = ids - Post.where(id: ids).pluck(:id)
|
|
raise ArgumentError, "存在しない親投稿 Id. があります: #{ missing.join(' ') }" if missing.present?
|
|
end
|
|
|
|
def serialised_tags tags, sections
|
|
tags.uniq(&:id).map { |tag|
|
|
"#{ tag.name }#{ sections[tag.id].to_a.map { Post.section_literal(_1) }.join }"
|
|
}.sort.join(' ')
|
|
end
|
|
|
|
def normalise_video_ms tags
|
|
return nil unless tags.any? { _1.id == Tag.video.id }
|
|
|
|
video_ms = @attributes[:video_ms]
|
|
if video_ms.present?
|
|
value = Integer(video_ms, exception: false)
|
|
raise PostCreator::VideoMsParseError unless value&.positive?
|
|
|
|
return value
|
|
end
|
|
|
|
duration = @attributes[:duration]
|
|
return nil if duration.blank?
|
|
|
|
value = Tag.time_to_ms!(duration.to_s, tag_name: '動画時間')
|
|
raise PostCreator::VideoMsParseError unless value.positive?
|
|
|
|
value
|
|
rescue Tag::SectionLiteralParseError
|
|
raise PostCreator::VideoMsParseError
|
|
end
|
|
|
|
def validate_video_sections! video_ms, sections
|
|
return unless video_ms
|
|
|
|
sections.each_value do |ranges|
|
|
ranges.each do |begin_ms, end_ms|
|
|
post = Post.new
|
|
if begin_ms >= video_ms
|
|
post.errors.add :video_ms, 'タグ区間の開始が動画時間以上です.'
|
|
raise ActiveRecord::RecordInvalid, post
|
|
end
|
|
if end_ms && end_ms > video_ms
|
|
post.errors.add :video_ms, 'タグ区間の終端が動画時間を超えてゐます.'
|
|
raise ActiveRecord::RecordInvalid, post
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|