From bbf3249c4518089f20ef170961b84a51d3cf55f0 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 4 Oct 2023 18:41:36 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E3=82=A2=E3=83=83=E3=83=97=E3=83=AD=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=81=AE=E5=87=A6=E7=90=86=E3=81=AE=E4=B8=80=E9=83=A8=E3=81=8C?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usbharu/hideout/config/SpringConfig.kt | 14 +++ .../usbharu/hideout/domain/model/MediaSave.kt | 2 +- .../domain/model/hideout/dto/FileType.kt | 8 ++ .../domain/model/hideout/dto/RemoteMedia.kt | 7 ++ .../model/hideout/dto}/SavedMedia.kt | 2 +- .../domain/model/hideout/entity/Media.kt | 4 +- .../exception/media/MediaConvertException.kt | 14 +++ .../exception/media/MediaFileSizeException.kt | 14 +++ .../media/MediaFileSizeIsZeroException.kt | 14 +++ ...loadException.kt => MediaSaveException.kt} | 2 +- .../media/UnsupportedMediaException.kt | 14 +++ .../hideout/repository/MediaRepositoryImpl.kt | 4 +- .../api/mastodon/MediaApiServiceImpl.kt | 5 +- .../media/FileTypeDeterminationService.kt | 8 +- .../media/FileTypeDeterminationServiceImpl.kt | 13 +-- .../hideout/service/media/MediaDataStore.kt | 3 +- .../hideout/service/media/MediaService.kt | 4 +- .../hideout/service/media/MediaServiceImpl.kt | 95 ++++++++++++------- .../service/media/ThumbnailGenerateService.kt | 7 ++ .../service/media/converter/MediaConverter.kt | 9 ++ .../media/converter/MediaConverterRoot.kt | 8 ++ .../media/converter/MediaProcessService.kt | 8 ++ .../converter/MediaProcessServiceImpl.kt | 41 ++++++++ src/main/resources/application.yml | 12 +++ 24 files changed, 258 insertions(+), 54 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/FileType.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/RemoteMedia.kt rename src/main/kotlin/dev/usbharu/hideout/{service/media => domain/model/hideout/dto}/SavedMedia.kt (86%) create mode 100644 src/main/kotlin/dev/usbharu/hideout/exception/media/MediaConvertException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/exception/media/MediaFileSizeException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/exception/media/MediaFileSizeIsZeroException.kt rename src/main/kotlin/dev/usbharu/hideout/exception/media/{MediaUploadException.kt => MediaSaveException.kt} (90%) create mode 100644 src/main/kotlin/dev/usbharu/hideout/exception/media/UnsupportedMediaException.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverter.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRoot.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt index 05d0c019..25ef84ed 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/SpringConfig.kt @@ -10,9 +10,23 @@ class SpringConfig { @Autowired lateinit var config: ApplicationConfig + + @Autowired + lateinit var storageConfig: StorageConfig } @ConfigurationProperties("hideout") data class ApplicationConfig( val url: URL ) + +@ConfigurationProperties("hideout.storage") +data class StorageConfig( + val useS3: Boolean, + val endpoint: String, + val publicUrl: String, + val bucket: String, + val region: String, + val accessKey: String, + val secretKey: String +) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/MediaSave.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/MediaSave.kt index f4086904..cf415fff 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/MediaSave.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/MediaSave.kt @@ -6,5 +6,5 @@ data class MediaSave( val name: String, val prefix: String, val fileInputStream: InputStream, - val thumbnailInputStream: InputStream + val thumbnailInputStream: InputStream? ) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/FileType.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/FileType.kt new file mode 100644 index 00000000..a72ac82a --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/FileType.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.domain.model.hideout.dto + +enum class FileType { + Image, + Video, + Audio, + Unknown +} diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/RemoteMedia.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/RemoteMedia.kt new file mode 100644 index 00000000..d4428ad1 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/RemoteMedia.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.domain.model.hideout.dto + +data class RemoteMedia( + val name: String, + val url: String, + val mediaType: String +) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/SavedMedia.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/SavedMedia.kt similarity index 86% rename from src/main/kotlin/dev/usbharu/hideout/service/media/SavedMedia.kt rename to src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/SavedMedia.kt index ffd94ef8..18dd9e9d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/SavedMedia.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/SavedMedia.kt @@ -1,4 +1,4 @@ -package dev.usbharu.hideout.service.media +package dev.usbharu.hideout.domain.model.hideout.dto sealed class SavedMedia(val success: Boolean) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Media.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Media.kt index 6f5f0e78..042388b7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Media.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/Media.kt @@ -1,6 +1,6 @@ package dev.usbharu.hideout.domain.model.hideout.entity -import dev.usbharu.hideout.service.media.FileTypeDeterminationService +import dev.usbharu.hideout.domain.model.hideout.dto.FileType data class Media( val id: Long, @@ -8,6 +8,6 @@ data class Media( val url: String, val remoteUrl: String?, val thumbnailUrl: String?, - val type: FileTypeDeterminationService.FileType, + val type: FileType, val blurHash: String? ) diff --git a/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaConvertException.kt b/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaConvertException.kt new file mode 100644 index 00000000..1082f080 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaConvertException.kt @@ -0,0 +1,14 @@ +package dev.usbharu.hideout.exception.media + +open class MediaConvertException : MediaException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaFileSizeException.kt b/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaFileSizeException.kt new file mode 100644 index 00000000..f7bd6536 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaFileSizeException.kt @@ -0,0 +1,14 @@ +package dev.usbharu.hideout.exception.media + +open class MediaFileSizeException : MediaException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaFileSizeIsZeroException.kt b/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaFileSizeIsZeroException.kt new file mode 100644 index 00000000..523f94b0 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaFileSizeIsZeroException.kt @@ -0,0 +1,14 @@ +package dev.usbharu.hideout.exception.media + +class MediaFileSizeIsZeroException : MediaFileSizeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaUploadException.kt b/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaSaveException.kt similarity index 90% rename from src/main/kotlin/dev/usbharu/hideout/exception/media/MediaUploadException.kt rename to src/main/kotlin/dev/usbharu/hideout/exception/media/MediaSaveException.kt index 36afc8b7..8887a3fe 100644 --- a/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaUploadException.kt +++ b/src/main/kotlin/dev/usbharu/hideout/exception/media/MediaSaveException.kt @@ -1,6 +1,6 @@ package dev.usbharu.hideout.exception.media -open class MediaUploadException : MediaException { +open class MediaSaveException : MediaException { constructor() : super() constructor(message: String?) : super(message) constructor(message: String?, cause: Throwable?) : super(message, cause) diff --git a/src/main/kotlin/dev/usbharu/hideout/exception/media/UnsupportedMediaException.kt b/src/main/kotlin/dev/usbharu/hideout/exception/media/UnsupportedMediaException.kt new file mode 100644 index 00000000..2fd8fc23 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/exception/media/UnsupportedMediaException.kt @@ -0,0 +1,14 @@ +package dev.usbharu.hideout.exception.media + +class UnsupportedMediaException : MediaException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/MediaRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/MediaRepositoryImpl.kt index ba5724d0..f2ffb720 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/MediaRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/MediaRepositoryImpl.kt @@ -1,9 +1,9 @@ package dev.usbharu.hideout.repository +import dev.usbharu.hideout.domain.model.hideout.dto.FileType import dev.usbharu.hideout.exception.FailedToGetResourcesException import dev.usbharu.hideout.service.core.IdGenerateService -import dev.usbharu.hideout.service.media.FileTypeDeterminationService import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq @@ -63,7 +63,7 @@ class MediaRepositoryImpl(private val idGenerateService: IdGenerateService) : Me this[Media.url], this[Media.remoteUrl], this[Media.thumbnailUrl], - FileTypeDeterminationService.FileType.values().first { it.ordinal == this[Media.type] }, + FileType.values().first { it.ordinal == this[Media.type] }, this[Media.blurhash], ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/mastodon/MediaApiServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/mastodon/MediaApiServiceImpl.kt index 230e749e..1fdb5e60 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/mastodon/MediaApiServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/mastodon/MediaApiServiceImpl.kt @@ -6,6 +6,9 @@ import dev.usbharu.hideout.service.media.MediaService class MediaApiServiceImpl(private val mediaService: MediaService) : MediaApiService { override suspend fun postMedia(media: Media): MediaAttachment { - mediaService.uploadLocalMedia(media) + val uploadLocalMedia = mediaService.uploadLocalMedia(media) + return MediaAttachment( + + ) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/FileTypeDeterminationService.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/FileTypeDeterminationService.kt index c30762de..19a7feb6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/FileTypeDeterminationService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/FileTypeDeterminationService.kt @@ -1,12 +1,8 @@ package dev.usbharu.hideout.service.media +import dev.usbharu.hideout.domain.model.hideout.dto.FileType + interface FileTypeDeterminationService { fun fileType(byteArray: ByteArray, filename: String, contentType: String?): FileType - enum class FileType { - Image, - Video, - Audio, - Unknown - } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/FileTypeDeterminationServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/FileTypeDeterminationServiceImpl.kt index 5ab2df2e..a13ebf66 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/FileTypeDeterminationServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/FileTypeDeterminationServiceImpl.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.service.media +import dev.usbharu.hideout.domain.model.hideout.dto.FileType import org.springframework.stereotype.Component @Component @@ -8,19 +9,19 @@ class FileTypeDeterminationServiceImpl : FileTypeDeterminationService { byteArray: ByteArray, filename: String, contentType: String? - ): FileTypeDeterminationService.FileType { + ): FileType { if (contentType == null) { - return FileTypeDeterminationService.FileType.Unknown + return FileType.Unknown } if (contentType.startsWith("image")) { - return FileTypeDeterminationService.FileType.Image + return FileType.Image } if (contentType.startsWith("video")) { - return FileTypeDeterminationService.FileType.Video + return FileType.Video } if (contentType.startsWith("audio")) { - return FileTypeDeterminationService.FileType.Audio + return FileType.Audio } - return FileTypeDeterminationService.FileType.Unknown + return FileType.Unknown } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/MediaDataStore.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/MediaDataStore.kt index bb452f0d..dd21b519 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/MediaDataStore.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/MediaDataStore.kt @@ -1,8 +1,9 @@ package dev.usbharu.hideout.service.media import dev.usbharu.hideout.domain.model.MediaSave +import dev.usbharu.hideout.domain.model.hideout.dto.SavedMedia interface MediaDataStore { - suspend fun save(dataMediaSave: MediaSave) + suspend fun save(dataMediaSave: MediaSave): SavedMedia suspend fun delete(id: Long) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/MediaService.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/MediaService.kt index 47446a3b..025b22ad 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/MediaService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/MediaService.kt @@ -1,7 +1,9 @@ package dev.usbharu.hideout.service.media +import dev.usbharu.hideout.domain.model.hideout.dto.RemoteMedia import dev.usbharu.hideout.domain.model.hideout.form.Media interface MediaService { - suspend fun uploadLocalMedia(media: Media): SavedMedia + suspend fun uploadLocalMedia(media: Media): dev.usbharu.hideout.domain.model.hideout.entity.Media + suspend fun uploadRemoteMedia(remoteMedia: RemoteMedia) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/MediaServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/MediaServiceImpl.kt index 799e0dc4..041deb57 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/MediaServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/MediaServiceImpl.kt @@ -1,56 +1,87 @@ package dev.usbharu.hideout.service.media import dev.usbharu.hideout.domain.model.MediaSave +import dev.usbharu.hideout.domain.model.hideout.dto.FaildSavedMedia +import dev.usbharu.hideout.domain.model.hideout.dto.FileType +import dev.usbharu.hideout.domain.model.hideout.dto.RemoteMedia +import dev.usbharu.hideout.domain.model.hideout.dto.SuccessSavedMedia import dev.usbharu.hideout.domain.model.hideout.form.Media -import dev.usbharu.hideout.exception.media.MediaException +import dev.usbharu.hideout.exception.media.MediaFileSizeIsZeroException +import dev.usbharu.hideout.exception.media.MediaSaveException +import dev.usbharu.hideout.exception.media.UnsupportedMediaException +import dev.usbharu.hideout.repository.MediaRepository +import dev.usbharu.hideout.service.media.converter.MediaProcessService import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.slf4j.LoggerFactory import org.springframework.stereotype.Service +import java.util.* import javax.imageio.ImageIO +import dev.usbharu.hideout.domain.model.hideout.entity.Media as EntityMedia @Service class MediaServiceImpl( private val mediaDataStore: MediaDataStore, private val fileTypeDeterminationService: FileTypeDeterminationService, - private val mediaBlurhashService: MediaBlurhashService + private val mediaBlurhashService: MediaBlurhashService, + private val mediaRepository: MediaRepository, + private val mediaProcessService: MediaProcessService ) : MediaService { - override suspend fun uploadLocalMedia(media: Media): SavedMedia { + override suspend fun uploadLocalMedia(media: Media): EntityMedia { if (media.file.size == 0L) { - return FaildSavedMedia( - "File size is 0.", - "Cannot upload a file with a file size of 0." - ) + throw MediaFileSizeIsZeroException("Media file size is zero.") } val fileType = fileTypeDeterminationService.fileType(media.file.bytes, media.file.name, media.file.contentType) - if (fileType != FileTypeDeterminationService.FileType.Image) { - return FaildSavedMedia("Unsupported file type.", "FileType: $fileType is not supported.") + if (fileType != FileType.Image) { + throw UnsupportedMediaException("FileType: $fileType is not supported.") } - try { - mediaDataStore.save( - MediaSave( - media.file.name, - "", - media.file.inputStream, - media.thumbnail.inputStream - ) + val process = mediaProcessService.process(fileType, media.file.inputStream, media.thumbnail?.inputStream) + + val dataMediaSave = MediaSave( + UUID.randomUUID().toString(), + "", + process.first, + process.second + ) + val save = try { + mediaDataStore.save(dataMediaSave) + } catch (e: Exception) { + logger.warn("Failed save media", e) + throw MediaSaveException("Failed save media.", e) + } + + if (save.success.not()) { + save as FaildSavedMedia + logger.warn("Failed save media. reason: ${save.reason}") + logger.warn(save.description, save.trace) + throw MediaSaveException("Failed save media.") + } + save as SuccessSavedMedia + + val blurHash = withContext(Dispatchers.IO) { + mediaBlurhashService.generateBlurhash(ImageIO.read(media.file.bytes.inputStream())) + } + + return mediaRepository.save( + EntityMedia( + id = mediaRepository.generateId(), + name = media.file.name, + url = save.url, + remoteUrl = null, + thumbnailUrl = save.thumbnailUrl, + type = fileType, + blurHash = blurHash ) - } catch (e: MediaException) { - return FaildSavedMedia( - "Faild to upload.", - e.localizedMessage, - e - ) - } - - val withContext = withContext(Dispatchers.IO) { - mediaBlurhashService.generateBlurhash(ImageIO.read(media.file.inputStream)) - } - - return SuccessSavedMedia( - media.file.name, "", "", - withContext ) } + + override suspend fun uploadRemoteMedia(remoteMedia: RemoteMedia) { + + } + + companion object { + private val logger = LoggerFactory.getLogger(MediaServiceImpl::class.java) + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateService.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateService.kt new file mode 100644 index 00000000..15db6ee7 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateService.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.service.media + +import java.io.InputStream + +interface ThumbnailGenerateService { + fun generate(bufferedImage: InputStream, width: Int, height: Int): InputStream +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverter.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverter.kt new file mode 100644 index 00000000..6771c73d --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverter.kt @@ -0,0 +1,9 @@ +package dev.usbharu.hideout.service.media.converter + +import dev.usbharu.hideout.domain.model.hideout.dto.FileType +import java.io.InputStream + +interface MediaConverter { + fun isSupport(fileType: FileType): Boolean + fun convert(inputStream: InputStream): InputStream +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRoot.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRoot.kt new file mode 100644 index 00000000..a032a3f1 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRoot.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.service.media.converter + +import dev.usbharu.hideout.domain.model.hideout.dto.FileType +import java.io.InputStream + +interface MediaConverterRoot { + suspend fun convert(fileType: FileType, inputStream: InputStream): InputStream +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessService.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessService.kt new file mode 100644 index 00000000..107647f5 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessService.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.service.media.converter + +import dev.usbharu.hideout.domain.model.hideout.dto.FileType +import java.io.InputStream + +interface MediaProcessService { + suspend fun process(fileType: FileType, file: InputStream, thumbnail: InputStream?): Pair +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessServiceImpl.kt new file mode 100644 index 00000000..b7fc6fd8 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessServiceImpl.kt @@ -0,0 +1,41 @@ +package dev.usbharu.hideout.service.media.converter + +import dev.usbharu.hideout.domain.model.hideout.dto.FileType +import dev.usbharu.hideout.exception.media.MediaConvertException +import dev.usbharu.hideout.service.media.ThumbnailGenerateService +import org.slf4j.LoggerFactory +import java.io.InputStream + +class MediaProcessServiceImpl( + private val mediaConverterRoot: MediaConverterRoot, + private val thumbnailGenerateService: ThumbnailGenerateService +) : MediaProcessService { + override suspend fun process( + fileType: FileType, + file: InputStream, + thumbnail: InputStream? + ): Pair { + + val fileInputStream = try { + mediaConverterRoot.convert(fileType, file) + } catch (e: Exception) { + logger.warn("Failed convert media.", e) + throw MediaConvertException("Failed convert media.", e) + } + val thumbnailInputStream = try { + thumbnail?.let { mediaConverterRoot.convert(fileType, it) } + } catch (e: Exception) { + logger.warn("Failed convert thumbnail media.", e) + null + } + return fileInputStream to (thumbnailInputStream ?: thumbnailGenerateService.generate( + fileInputStream, + 2048, + 2048 + )) + } + + companion object { + private val logger = LoggerFactory.getLogger(MediaProcessServiceImpl::class.java) + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0c4a32a1..9c9975d0 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -7,6 +7,18 @@ hideout: key-id: a private-key: "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7VJTUt9Us8cKjMzEfYyjiWA4R4/M2bS1GB4t7NXp98C3SC6dVMvDuictGeurT8jNbvJZHtCSuYEvuNMoSfm76oqFvAp8Gy0iz5sxjZmSnXyCdPEovGhLa0VzMaQ8s+CLOyS56YyCFGeJZqgtzJ6GR3eqoYSW9b9UMvkBpZODSctWSNGj3P7jRFDO5VoTwCQAWbFnOjDfH5Ulgp2PKSQnSJP3AJLQNFNe7br1XbrhV//eO+t51mIpGSDCUv3E0DDFcWDTH9cXDTTlRZVEiR2BwpZOOkE/Z0/BVnhZYL71oZV34bKfWjQIt6V/isSMahdsAASACp4ZTGtwiVuNd9tybAgMBAAECggEBAKTmjaS6tkK8BlPXClTQ2vpz/N6uxDeS35mXpqasqskVlaAidgg/sWqpjXDbXr93otIMLlWsM+X0CqMDgSXKejLS2jx4GDjI1ZTXg++0AMJ8sJ74pWzVDOfmCEQ/7wXs3+cbnXhKriO8Z036q92Qc1+N87SI38nkGa0ABH9CN83HmQqt4fB7UdHzuIRe/me2PGhIq5ZBzj6h3BpoPGzEP+x3l9YmK8t/1cN0pqI+dQwYdgfGjackLu/2qH80MCF7IyQaseZUOJyKrCLtSD/Iixv/hzDEUPfOCjFDgTpzf3cwta8+oE4wHCo1iI1/4TlPkwmXx4qSXtmw4aQPz7IDQvECgYEA8KNThCO2gsC2I9PQDM/8Cw0O983WCDY+oi+7JPiNAJwv5DYBqEZB1QYdj06YD16XlC/HAZMsMku1na2TN0driwenQQWzoev3g2S7gRDoS/FCJSI3jJ+kjgtaA7Qmzlgk1TxODN+G1H91HW7t0l7VnL27IWyYo2qRRK3jzxqUiPUCgYEAx0oQs2reBQGMVZnApD1jeq7n4MvNLcPvt8b/eU9iUv6Y4Mj0Suo/AU8lYZXm8ubbqAlwz2VSVunD2tOplHyMUrtCtObAfVDUAhCndKaA9gApgfb3xw1IKbuQ1u4IF1FJl3VtumfQn//LiH1B3rXhcdyo3/vIttEk48RakUKClU8CgYEAzV7W3COOlDDcQd935DdtKBFRAPRPAlspQUnzMi5eSHMD/ISLDY5IiQHbIH83D4bvXq0X7qQoSBSNP7Dvv3HYuqMhf0DaegrlBuJllFVVq9qPVRnKxt1Il2HgxOBvbhOT+9in1BzA+YJ99UzC85O0Qz06A+CmtHEy4aZ2kj5hHjECgYEAmNS4+A8Fkss8Js1RieK2LniBxMgmYml3pfVLKGnzmng7H2+cwPLhPIzIuwytXywh2bzbsYEfYx3EoEVgMEpPhoarQnYPukrJO4gwE2o5Te6T5mJSZGlQJQj9q4ZB2Dfzet6INsK0oG8XVGXSpQvQh3RUYekCZQkBBFcpqWpbIEsCgYAnM3DQf3FJoSnXaMhrVBIovic5l0xFkEHskAjFTevO86Fsz1C2aSeRKSqGFoOQ0tmJzBEs1R6KqnHInicDTQrKhArgLXX4v3CddjfTRJkFWDbE/CkvKZNOrcf1nhaGCPspRJj2KUkj1Fhl9Cncdn/RsYEONbwQSjIfMPkvxF+8HQ==" public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmwIDAQAB" + storage: + use-s3: true + endpoint: "" + public-url: "" + bucket: "" + region: "" + access-key: "" + secret-key: "" + + + + spring: jackson: serialization: