このコミットが含まれているのは:
@@ -18,14 +18,12 @@ class PreviewController < ApplicationController
|
|||||||
def thumbnail
|
def thumbnail
|
||||||
return render_bad_request('URL は必須です.') if params[:url].blank?
|
return render_bad_request('URL は必須です.') if params[:url].blank?
|
||||||
|
|
||||||
image = MiniMagick::Image.read(Preview::ThumbnailFetcher.fetch(params[:url]))
|
attachment =
|
||||||
image.auto_orient
|
Post.resized_thumbnail_attachment(
|
||||||
image.resize '180x180>'
|
StringIO.new(Preview::ThumbnailFetcher.fetch(params[:url])))
|
||||||
image.format 'png'
|
send_data attachment[:io].read,
|
||||||
width, height = image.dimensions
|
type: attachment[:content_type],
|
||||||
raise Preview::ThumbnailFetcher::GenerationFailed, 'サムネール画像の変換に失敗しました.' if width > 180 || height > 180
|
disposition: 'inline'
|
||||||
|
|
||||||
send_data image.to_blob, type: 'image/png', disposition: 'inline'
|
|
||||||
rescue Preview::UrlSafety::UnsafeUrl => e
|
rescue Preview::UrlSafety::UnsafeUrl => e
|
||||||
render_bad_request(e.message)
|
render_bad_request(e.message)
|
||||||
rescue Preview::HttpFetcher::FetchTimeout => e
|
rescue Preview::HttpFetcher::FetchTimeout => e
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ class Post < ApplicationRecord
|
|||||||
MAX_SVG_DIMENSION = 4_096
|
MAX_SVG_DIMENSION = 4_096
|
||||||
MAX_SVG_PIXELS = 16_777_216
|
MAX_SVG_PIXELS = 16_777_216
|
||||||
THUMBNAIL_PROCESS_TIMEOUT = 5.seconds
|
THUMBNAIL_PROCESS_TIMEOUT = 5.seconds
|
||||||
RASTER_THUMBNAIL_FORMATS = ['jpeg', 'png', 'gif', 'webp'].freeze
|
|
||||||
|
|
||||||
def self.resized_thumbnail_attachment(upload, content_type: nil)
|
def self.resized_thumbnail_attachment(upload, content_type: nil)
|
||||||
upload.rewind
|
upload.rewind
|
||||||
bytes = upload.read
|
bytes = upload.read
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ module Preview
|
|||||||
RASTER_IMAGE_CONTENT_TYPES = [
|
RASTER_IMAGE_CONTENT_TYPES = [
|
||||||
'image/jpeg', 'image/png', 'image/gif', 'image/webp'
|
'image/jpeg', 'image/png', 'image/gif', 'image/webp'
|
||||||
].freeze
|
].freeze
|
||||||
REMOTE_IMAGE_CONTENT_TYPES = [
|
|
||||||
*RASTER_IMAGE_CONTENT_TYPES,
|
|
||||||
'image/svg+xml'
|
|
||||||
].freeze
|
|
||||||
HTML_MAX_BYTES = 1.megabyte
|
HTML_MAX_BYTES = 1.megabyte
|
||||||
NICONICO_XML_MAX_BYTES = 256.kilobytes
|
NICONICO_XML_MAX_BYTES = 256.kilobytes
|
||||||
|
|
||||||
@@ -100,13 +96,7 @@ module Preview
|
|||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.allowed_remote_image_content_type?(content_type)
|
|
||||||
mime_type = content_type.to_s.split(';', 2).first.downcase.strip
|
|
||||||
REMOTE_IMAGE_CONTENT_TYPES.include?(mime_type)
|
|
||||||
end
|
|
||||||
|
|
||||||
private_class_method :fetch_image_or_nil, :fetch_image!,
|
private_class_method :fetch_image_or_nil, :fetch_image!,
|
||||||
:niconico_thumbnail_url,
|
:niconico_thumbnail_url
|
||||||
:allowed_remote_image_content_type?
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ const isRepairRow = (row: PostImportRow): boolean =>
|
|||||||
&& hasErrorMessages (row.validationErrors)))
|
&& hasErrorMessages (row.validationErrors)))
|
||||||
|
|
||||||
const DUPLICATE_URL_MESSAGE = 'URL が重複しています.'
|
const DUPLICATE_URL_MESSAGE = 'URL が重複しています.'
|
||||||
|
const BULK_PROCESSING_FAILED_MESSAGE = '登録中にエラーが発生しました.'
|
||||||
|
|
||||||
const rowMetadataPending = (row: PostImportRow): boolean =>
|
const rowMetadataPending = (row: PostImportRow): boolean =>
|
||||||
row.status === 'pending'
|
row.status === 'pending'
|
||||||
@@ -314,14 +315,28 @@ const indexedBulkResults = (
|
|||||||
}
|
}
|
||||||
if (result?.status === 'skipped')
|
if (result?.status === 'skipped')
|
||||||
{
|
{
|
||||||
|
const existingPostId =
|
||||||
|
result.existingPostId
|
||||||
|
?? result.existingPost?.id
|
||||||
|
?? row.existingPostId
|
||||||
|
if (existingPostId == null)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
sourceRow: row.sourceRow,
|
||||||
|
status: 'failed',
|
||||||
|
fieldWarnings: result.fieldWarnings,
|
||||||
|
baseWarnings: result.baseWarnings,
|
||||||
|
errors: {
|
||||||
|
...(errors ?? { }),
|
||||||
|
base: [...new Set ([...(errors?.base ?? []),
|
||||||
|
BULK_PROCESSING_FAILED_MESSAGE])],
|
||||||
|
},
|
||||||
|
recoverable: false }
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
sourceRow: row.sourceRow,
|
sourceRow: row.sourceRow,
|
||||||
status: 'skipped',
|
status: 'skipped',
|
||||||
existingPostId:
|
existingPostId,
|
||||||
result.existingPostId
|
|
||||||
?? result.existingPost?.id
|
|
||||||
?? row.existingPostId
|
|
||||||
?? row.sourceRow,
|
|
||||||
existingPost: result.existingPost,
|
existingPost: result.existingPost,
|
||||||
fieldWarnings: result.fieldWarnings,
|
fieldWarnings: result.fieldWarnings,
|
||||||
baseWarnings: result.baseWarnings,
|
baseWarnings: result.baseWarnings,
|
||||||
|
|||||||
新しい課題から参照
ユーザをブロックする