このコミットが含まれているのは:
@@ -1,3 +1,4 @@
|
||||
require 'time'
|
||||
require 'timeout'
|
||||
|
||||
class PostImportPreviewer
|
||||
@@ -86,7 +87,8 @@ class PostImportPreviewer
|
||||
|
||||
if row[:metadata_url].present? && row[:metadata_url] != url_for_metadata
|
||||
clear_automatic_values!(attributes, provenance, tag_sources)
|
||||
clear_fetch_warnings!(field_warnings)
|
||||
field_warnings = { }
|
||||
base_warnings = [ ]
|
||||
end
|
||||
|
||||
if validation_errors.blank? && normal_url.present? && existing_post
|
||||
@@ -248,7 +250,8 @@ class PostImportPreviewer
|
||||
def sanitise_metadata_time value
|
||||
return nil unless value.is_a?(String)
|
||||
|
||||
Time.zone.parse(value)&.iso8601
|
||||
time = Time.iso8601(value)
|
||||
time.nsec.zero? ? time.iso8601 : time.iso8601(9)
|
||||
rescue ArgumentError, TypeError
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -78,8 +78,12 @@ class PostImportRowNormaliser
|
||||
private_class_method :normalise_source_row!
|
||||
|
||||
def self.normalise_url! value
|
||||
raise ArgumentError, 'URL の形式が不正です.' unless value.is_a?(String)
|
||||
raise ArgumentError, 'URL が長すぎます.' if value.bytesize > PostImportUrlListParser::MAX_URL_BYTES
|
||||
unless value.is_a?(String)
|
||||
raise ArgumentError, 'URL の形式が不正です.'
|
||||
end
|
||||
if value.bytesize > PostImportUrlListParser::MAX_URL_BYTES
|
||||
raise ArgumentError, 'URL が長すぎます.'
|
||||
end
|
||||
end
|
||||
private_class_method :normalise_url!
|
||||
|
||||
@@ -112,20 +116,32 @@ class PostImportRowNormaliser
|
||||
private_class_method :normalise_attributes!
|
||||
|
||||
def self.normalise_provenance! provenance
|
||||
raise ArgumentError, 'provenance の形式が不正です.' unless provenance.is_a?(Hash)
|
||||
unless provenance.is_a?(Hash)
|
||||
raise ArgumentError, 'provenance の形式が不正です.'
|
||||
end
|
||||
|
||||
allowed = ATTRIBUTE_FIELDS + ['url']
|
||||
raise ArgumentError, '値の由来が不正です.' unless (provenance.keys - allowed).empty?
|
||||
raise ArgumentError, '値の由来が不正です.' unless provenance.values.all? { ORIGINS.include?(_1) }
|
||||
unless (provenance.keys - allowed).empty?
|
||||
raise ArgumentError, '値の由来が不正です.'
|
||||
end
|
||||
unless provenance.values.all? { ORIGINS.include?(_1) }
|
||||
raise ArgumentError, '値の由来が不正です.'
|
||||
end
|
||||
end
|
||||
private_class_method :normalise_provenance!
|
||||
|
||||
def self.normalise_tag_sources! tag_sources
|
||||
return if tag_sources.nil?
|
||||
|
||||
raise ArgumentError, 'タグ由来の形式が不正です.' unless tag_sources.is_a?(Hash)
|
||||
raise ArgumentError, 'タグ由来の形式が不正です.' unless (tag_sources.keys - ORIGINS).empty?
|
||||
raise ArgumentError, 'タグ由来の形式が不正です.' unless tag_sources.values.all? { _1.is_a?(String) }
|
||||
unless tag_sources.is_a?(Hash)
|
||||
raise ArgumentError, 'タグ由来の形式が不正です.'
|
||||
end
|
||||
unless (tag_sources.keys - ORIGINS).empty?
|
||||
raise ArgumentError, 'タグ由来の形式が不正です.'
|
||||
end
|
||||
unless tag_sources.values.all? { _1.is_a?(String) }
|
||||
raise ArgumentError, 'タグ由来の形式が不正です.'
|
||||
end
|
||||
if tag_sources.values.any? { _1.bytesize > PostImportUrlListParser::MAX_URL_BYTES }
|
||||
raise ArgumentError, 'タグ由来が大きすぎます.'
|
||||
end
|
||||
@@ -143,7 +159,9 @@ class PostImportRowNormaliser
|
||||
raise ArgumentError, '警告の形式が不正です.'
|
||||
end
|
||||
field_warnings&.each do |key, values|
|
||||
raise ArgumentError, '警告の形式が不正です.' unless ATTRIBUTE_FIELDS.include?(key) || key == 'url'
|
||||
unless ATTRIBUTE_FIELDS.include?(key) || key == 'url'
|
||||
raise ArgumentError, '警告の形式が不正です.'
|
||||
end
|
||||
unless values.is_a?(Array) && values.all? { _1.is_a?(String) }
|
||||
raise ArgumentError, '警告の形式が不正です.'
|
||||
end
|
||||
|
||||
@@ -26,7 +26,8 @@ class PostImportRunner
|
||||
attributes = row.fetch('attributes', { }).transform_keys { _1.to_s.underscore }
|
||||
return { source_row: row['source_row'],
|
||||
status: 'failed',
|
||||
errors: preview[:validation_errors] } if preview[:validation_errors].present?
|
||||
errors: preview[:validation_errors],
|
||||
recoverable: true } if preview[:validation_errors].present?
|
||||
if preview[:skip_reason] == 'existing'
|
||||
return { source_row: row['source_row'],
|
||||
status: 'skipped',
|
||||
@@ -45,8 +46,13 @@ class PostImportRunner
|
||||
existing_post_id: existing_post.id }
|
||||
end
|
||||
|
||||
{ source_row: row['source_row'], status: 'failed', errors: e.record.errors.to_hash }
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
{ source_row: row['source_row'],
|
||||
status: 'failed',
|
||||
errors: e.record.errors.to_hash,
|
||||
recoverable: true }
|
||||
rescue ActiveRecord::RecordNotUnique => e
|
||||
raise unless url_record_not_unique?(e)
|
||||
|
||||
existing_post = existing_post_for_race(row)
|
||||
raise unless existing_post
|
||||
|
||||
@@ -56,15 +62,23 @@ class PostImportRunner
|
||||
rescue Tag::NicoTagNormalisationError
|
||||
{ source_row: row['source_row'],
|
||||
status: 'failed',
|
||||
errors: { tags: ['ニコニコ・タグは直接指定できません.'] } }
|
||||
errors: { tags: ['ニコニコ・タグは直接指定できません.'] },
|
||||
recoverable: true }
|
||||
rescue Tag::DeprecatedTagNormalisationError
|
||||
{ source_row: row['source_row'],
|
||||
status: 'failed',
|
||||
errors: { tags: ['廃止済みタグは付与できません.'] } }
|
||||
errors: { tags: ['廃止済みタグは付与できません.'] },
|
||||
recoverable: true }
|
||||
rescue PostCreator::VideoMsParseError
|
||||
{ source_row: row['source_row'],
|
||||
status: 'failed',
|
||||
errors: { duration: ['動画時間の記法が不正です.'] },
|
||||
recoverable: true }
|
||||
rescue ArgumentError
|
||||
{ source_row: row['source_row'],
|
||||
status: 'failed',
|
||||
errors: { base: ['入力値が不正です.'] } }
|
||||
errors: { base: ['入力値が不正です.'] },
|
||||
recoverable: true }
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("post_import_runner_failure #{ { error: e.class.name,
|
||||
message: e.message }.to_json }")
|
||||
@@ -83,4 +97,8 @@ class PostImportRunner
|
||||
|
||||
Post.find_by(url: normal_url)
|
||||
end
|
||||
|
||||
def url_record_not_unique? error
|
||||
error.message.include?('index_posts_on_url')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'time'
|
||||
|
||||
class PostMetadataFetcher
|
||||
TIMESTAMP_PATTERN =
|
||||
Regexp.new(
|
||||
@@ -26,8 +28,8 @@ class PostMetadataFetcher
|
||||
{ title: metadata[:title],
|
||||
thumbnail_base:
|
||||
Preview::KnownSiteExtractor.thumbnail_url(uri) || metadata[:image_url],
|
||||
original_created_from: created_range&.first&.iso8601,
|
||||
original_created_before: created_range&.last&.iso8601,
|
||||
original_created_from: serialise_time(created_range&.first),
|
||||
original_created_before: serialise_time(created_range&.last),
|
||||
duration: duration&.to_f&.then { _1.positive? ? (_1 * 1_000).round : nil },
|
||||
tags: platform_tags.join(' ') }
|
||||
end
|
||||
@@ -114,9 +116,16 @@ class PostMetadataFetcher
|
||||
Rational(value.to_i, 10**value.length)
|
||||
end
|
||||
|
||||
def self.serialise_time value
|
||||
return nil if value.nil?
|
||||
|
||||
value.nsec.zero? ? value.iso8601 : value.iso8601(9)
|
||||
end
|
||||
|
||||
private_class_method :platform_tags,
|
||||
:original_created_range,
|
||||
:parse_timestamp_range,
|
||||
:parse_offset,
|
||||
:fractional_seconds
|
||||
:fractional_seconds,
|
||||
:serialise_time
|
||||
end
|
||||
|
||||
新しい課題から参照
ユーザをブロックする