refactor: MediaServiceImplをリファクタリング

This commit is contained in:
usbharu 2023-11-14 22:47:00 +09:00
parent cdf0f23332
commit 3a2286e8fe
2 changed files with 92 additions and 56 deletions

View File

@ -6,6 +6,7 @@ import dev.usbharu.hideout.core.domain.model.media.Media
import dev.usbharu.hideout.core.domain.model.media.MediaRepository import dev.usbharu.hideout.core.domain.model.media.MediaRepository
import dev.usbharu.hideout.core.service.media.converter.MediaProcessService import dev.usbharu.hideout.core.service.media.converter.MediaProcessService
import dev.usbharu.hideout.mastodon.interfaces.api.media.MediaRequest import dev.usbharu.hideout.mastodon.interfaces.api.media.MediaRequest
import dev.usbharu.hideout.util.withDelete
import io.ktor.client.* import io.ktor.client.*
import io.ktor.client.request.* import io.ktor.client.request.*
import io.ktor.client.statement.* import io.ktor.client.statement.*
@ -38,78 +39,60 @@ class MediaServiceImpl(
) )
val tempFile = Files.createTempFile("hideout-tmp-file", ".tmp") val tempFile = Files.createTempFile("hideout-tmp-file", ".tmp")
AutoCloseable { println(tempFile);Files.delete(tempFile) }.use {
tempFile.withDelete().use {
Files.newOutputStream(tempFile).use { outputStream -> Files.newOutputStream(tempFile).use { outputStream ->
mediaRequest.file.inputStream.use { mediaRequest.file.inputStream.use {
it.transferTo(outputStream) it.transferTo(outputStream)
} }
} }
val mimeType = fileTypeDeterminationService.fileType( val mimeType = fileTypeDeterminationService.fileType(tempFile, fileName)
tempFile,
val process = findMediaProcessor(mimeType).process(
mimeType,
fileName, fileName,
tempFile,
null
) )
val process = try {
mediaProcessServices.first { it.isSupport(mimeType) }.process(
mimeType,
fileName,
tempFile,
null
)
} catch (e: NoSuchElementException) {
throw UnsupportedMediaException("MediaType: $mimeType isn't supported.")
}
val dataMediaSave = MediaSaveRequest( val dataMediaSave = MediaSaveRequest(
process.filePath.fileName.toString(), process.filePath.fileName.toString(),
"", "",
process.filePath, process.filePath,
process.thumbnailPath process.thumbnailPath
) )
val save = try { dataMediaSave.filePath.withDelete().use {
mediaDataStore.save(dataMediaSave) dataMediaSave.thumbnailPath.withDelete().use {
} catch (e: Exception) { val save = try {
logger.warn("Failed to save the media", e) mediaDataStore.save(dataMediaSave)
throw MediaSaveException("Failed to save the media.", e) } catch (e: Exception) {
} logger.warn("Failed to save the media", e)
if (save.success.not()) { throw MediaSaveException("Failed to save the media.", e)
save as FaildSavedMedia
logger.warn("Failed to save the media. reason: ${save.reason}")
logger.warn(save.description, save.trace)
throw MediaSaveException("Failed to save the media.")
}
save as SuccessSavedMedia
val blurHash = withContext(Dispatchers.IO) {
if (process.thumbnailPath != null && process.thumbnailMimeType != null) {
val iterator =
ImageIO.getImageReadersByMIMEType(process.thumbnailMimeType.type + "/" + process.thumbnailMimeType.subtype)
for (imageReader in iterator) {
try {
ImageIO.createImageInputStream(process.thumbnailPath.toFile()).use {
imageReader.input = it
val read = imageReader.read(0)
return@withContext mediaBlurhashService.generateBlurhash(read)
}
} catch (e: Exception) {
logger.warn("Failed to read thumbnail", e)
}
} }
"" if (save.success.not()) {
} else { save as FaildSavedMedia
"" logger.warn("Failed to save the media. reason: ${save.reason}")
logger.warn(save.description, save.trace)
throw MediaSaveException("Failed to save the media.")
}
save as SuccessSavedMedia
val blurHash = generateBlurhash(process)
return mediaRepository.save(
EntityMedia(
id = mediaRepository.generateId(),
name = fileName,
url = save.url,
remoteUrl = null,
thumbnailUrl = save.thumbnailUrl,
type = process.fileMimeType.fileType,
mimeType = process.fileMimeType,
blurHash = blurHash
)
)
} }
} }
return mediaRepository.save(
EntityMedia(
id = mediaRepository.generateId(),
name = fileName,
url = save.url,
remoteUrl = null,
thumbnailUrl = save.thumbnailUrl,
type = process.fileMimeType.fileType,
mimeType = process.fileMimeType,
blurHash = blurHash
)
)
} }
@ -178,6 +161,47 @@ class MediaServiceImpl(
) )
} }
protected fun findMediaProcessor(mimeType: MimeType): MediaProcessService {
try {
return mediaProcessServices.first {
try {
it.isSupport(mimeType)
} catch (e: Exception) {
false
}
}
} catch (e: NoSuchElementException) {
throw UnsupportedMediaException("MediaType: $mimeType isn't supported.")
}
}
protected fun generateBlurhash(process: ProcessedMediaPath): String {
val path = if (process.thumbnailPath != null && process.thumbnailMimeType != null) {
process.thumbnailPath
} else {
process.filePath
}
val mimeType = if (process.thumbnailPath != null && process.thumbnailMimeType != null) {
process.thumbnailMimeType
} else {
process.fileMimeType
}
val imageReadersByMIMEType = ImageIO.getImageReadersByMIMEType(mimeType.type + "/" + mimeType.subtype)
for (imageReader in imageReadersByMIMEType) {
try {
val bufferedImage = ImageIO.createImageInputStream(path.toFile()).use {
imageReader.input = it
imageReader.read(0)
}
return mediaBlurhashService.generateBlurhash(bufferedImage)
} catch (e: Exception) {
logger.warn("Failed to read thumbnail", e)
}
}
return ""
}
companion object { companion object {
private val logger = LoggerFactory.getLogger(MediaServiceImpl::class.java) private val logger = LoggerFactory.getLogger(MediaServiceImpl::class.java)
} }

View File

@ -0,0 +1,12 @@
package dev.usbharu.hideout.util
import java.nio.file.Files
import java.nio.file.Path
fun Path?.withDelete(): TempFile = TempFile(this)
class TempFile(val path: Path?) : AutoCloseable {
override fun close() {
path?.let { Files.deleteIfExists(it) }
}
}