このコミットが含まれているのは:
2026-07-14 18:39:24 +09:00
コミット d035da99ad
14個のファイルの変更188行の追加232行の削除
+4 -4
ファイルの表示
@@ -6,11 +6,11 @@ class PostImportsController < ApplicationController
rows: PostImportUrlListParser.parse(params[:source]))
render json: { rows: }
rescue ArgumentError => e
render_bad_request(e.message)
render_bad_request e.message
end
def validate
rows = normalised_import_rows(allow_warning_fields: true)
rows = normalised_import_rows allow_warning_fields: true
changed_row = Integer(params[:changed_row], exception: false)
result =
PostImportPreviewer.new.preview_rows(rows:,
@@ -18,7 +18,7 @@ class PostImportsController < ApplicationController
metadata_cache: { })
render json: { rows: result }
rescue ArgumentError => e
render_bad_request(e.message)
render_bad_request e.message
end
def create
@@ -26,7 +26,7 @@ class PostImportsController < ApplicationController
rows: normalised_import_rows).run
render json: result, status: result[:created].positive? ? :created : :ok
rescue ArgumentError => e
render_bad_request(e.message)
render_bad_request e.message
end
private
-9
ファイルの表示
@@ -174,14 +174,5 @@ class Post < ApplicationRecord
return if url.blank?
self.url = PostUrlNormaliser.normalise(url) || url.strip
u = URI.parse(url)
return unless u in URI::HTTP
u.host = u.host.downcase if u.host
u.path = u.path.sub(/\/\Z/, '') if u.path.present?
self.url = PostUrlSanitisationRule.sanitise(u.to_s)
rescue URI::InvalidURIError
;
end
end
+11 -3
ファイルの表示
@@ -38,7 +38,7 @@ class PostImportPreviewer
provenance['url'] = 'manual'
normal_url = normalised_url(url)
url_for_metadata = normal_url || url
existing_post = normal_url.present? && Post.exists?(url: normal_url)
existing_post = normal_url.present? ? Post.find_by(url: normal_url) : nil
validation_errors = {}
validation_errors[:url] = ['URL が不正です.'] if normal_url.blank?
@@ -61,6 +61,8 @@ class PostImportPreviewer
provenance:,
tag_sources:,
metadata_url: url_for_metadata,
skip_reason: 'existing',
existing_post_id: existing_post.id,
field_warnings:,
base_warnings:,
validation_errors:,
@@ -93,6 +95,8 @@ class PostImportPreviewer
provenance:,
tag_sources:,
metadata_url: url_for_metadata,
skip_reason: nil,
existing_post_id: nil,
field_warnings:,
base_warnings:,
validation_errors:,
@@ -129,7 +133,9 @@ class PostImportPreviewer
end
def initial_field_warnings row
(row[:field_warnings] || { }).stringify_keys.transform_values { |value| Array(value).map(&:to_s) }
(row[:field_warnings] || { })
.stringify_keys
.transform_values { |value| Array(value).map(&:to_s) }
end
def initial_base_warnings row
@@ -161,7 +167,9 @@ class PostImportPreviewer
data = PostMetadataFetcher.fetch(url).stringify_keys.compact
warnings = { }
add_field_warning!(warnings, 'title', TITLE_FETCH_WARNING) if data['title'].blank?
add_field_warning!(warnings, 'thumbnail_base', THUMBNAIL_FETCH_WARNING) if data['thumbnail_base'].blank?
if data['thumbnail_base'].blank?
add_field_warning!(warnings, 'thumbnail_base', THUMBNAIL_FETCH_WARNING)
end
{ data:, warnings: }
rescue Preview::UrlSafety::UnsafeUrl,
Preview::HttpFetcher::FetchFailed,
+3 -1
ファイルの表示
@@ -161,7 +161,9 @@ class PostImportRowNormaliser
unless base_warnings.is_a?(Array) && base_warnings.all? { _1.is_a?(String) }
raise ArgumentError, '警告の形式が不正です.'
end
raise ArgumentError, '警告が大きすぎます.' if base_warnings.any? { _1.bytesize > PostImportUrlListParser::MAX_URL_BYTES }
if base_warnings.any? { _1.bytesize > PostImportUrlListParser::MAX_URL_BYTES }
raise ArgumentError, '警告が大きすぎます.'
end
end
private_class_method :normalise_warning_values!
+28 -32
ファイルの表示
@@ -6,40 +6,29 @@ class PostImportRunner
def run
normalised_rows = PostImportRowNormaliser.normalise!(@rows)
previews = PostImportPreviewer.new.preview_rows(rows: normalised_rows,
fetch_metadata: false)
preview_map = previews.index_by { _1[:source_row] }
results = normalised_rows.map { |row| run_row(row) }
{
created: results.count { _1[:status] == 'created' },
results = normalised_rows.map do |row|
run_row(row, preview_map.fetch(row['source_row']))
end
{ created: results.count { _1[:status] == 'created' },
skipped: results.count { _1[:status] == 'skipped' },
failed: results.count { _1[:status] == 'failed' },
rows: results,
}
rows: results }
end
private
def run_row row
def run_row row, preview
attributes = row.fetch('attributes', { }).transform_keys { _1.to_s.underscore }
preview = PostImportPreviewer.new.preview_rows(
rows: [{
source_row: row['source_row'],
url: row['url'],
attributes:,
provenance: row['provenance'],
tag_sources: row['tag_sources'],
}],
fetch_metadata: false).first
if Array(preview.dig(:field_warnings, 'url')).include?(PostImportPreviewer::EXISTING_SKIP_WARNING)
return row.slice('source_row').merge(status: 'skipped')
end
return row.slice('source_row').merge(status: 'skipped') if preview[:skip_reason] == 'existing'
if preview[:validation_errors].present?
return {
source_row: row['source_row'],
status: 'failed',
errors: preview[:validation_errors],
}
end
return { source_row: row['source_row'],
status: 'failed',
errors: preview[:validation_errors] } if preview[:validation_errors].present?
attributes['tags'] = preview[:attributes]['tags']
attributes['url'] = row['url']
@@ -48,15 +37,22 @@ class PostImportRunner
rescue ActiveRecord::RecordInvalid => e
{ source_row: row['source_row'], status: 'failed', errors: e.record.errors.to_hash }
rescue Tag::NicoTagNormalisationError
{ source_row: row['source_row'], status: 'failed', errors: { tags: ['ニコニコ・タグは直接指定できません.'] } }
{ source_row: row['source_row'],
status: 'failed',
errors: { tags: ['ニコニコ・タグは直接指定できません.'] } }
rescue Tag::DeprecatedTagNormalisationError
{ source_row: row['source_row'], status: 'failed', errors: { tags: ['廃止済みタグは付与できません.'] } }
{ source_row: row['source_row'],
status: 'failed',
errors: { tags: ['廃止済みタグは付与できません.'] } }
rescue ArgumentError, PostCreator::VideoMsParseError
{ source_row: row['source_row'], status: 'failed', errors: { base: ['入力値が不正です.'] } }
{ source_row: row['source_row'],
status: 'failed',
errors: { base: ['入力値が不正です.'] } }
rescue StandardError => e
Rails.logger.error(
"post_import_runner_failure #{ { error: e.class.name, message: e.message }.to_json }",
)
{ source_row: row['source_row'], status: 'failed', errors: { base: ['登録中にエラーが発生しました.'] } }
Rails.logger.error("post_import_runner_failure #{ { error: e.class.name,
message: e.message }.to_json }")
{ source_row: row['source_row'],
status: 'failed',
errors: { base: ['登録中にエラーが発生しました.'] } }
end
end