diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt index 473c5f66..7b5a5d8e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/MediaQueryServiceImpl.kt @@ -1,17 +1,20 @@ package dev.usbharu.hideout.core.infrastructure.exposedquery -import dev.usbharu.hideout.core.domain.model.media.Media +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.infrastructure.exposedrepository.Media import dev.usbharu.hideout.core.infrastructure.exposedrepository.PostsMedia import dev.usbharu.hideout.core.infrastructure.exposedrepository.toMedia import dev.usbharu.hideout.core.query.MediaQueryService +import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.innerJoin import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Repository +import dev.usbharu.hideout.core.domain.model.media.Media as MediaEntity @Repository class MediaQueryServiceImpl : MediaQueryService { - override suspend fun findByPostId(postId: Long): List { - return dev.usbharu.hideout.core.infrastructure.exposedrepository.Media.innerJoin( + override suspend fun findByPostId(postId: Long): List { + return Media.innerJoin( PostsMedia, onColumn = { id }, otherColumn = { mediaId } @@ -19,4 +22,10 @@ class MediaQueryServiceImpl : MediaQueryService { .select { PostsMedia.postId eq postId } .map { it.toMedia() } } + + override suspend fun findByRemoteUrl(remoteUrl: String): MediaEntity { + return Media.select { Media.remoteUrl eq remoteUrl } + .singleOr { FailedToGetResourcesException("remoteUrl: $remoteUrl is duplicate or not exist.", it) } + .toMedia() + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt index 0206feb9..97b7c527 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/MediaRepositoryImpl.kt @@ -99,9 +99,9 @@ fun ResultRow.toMediaOrNull(): EntityMedia? { object Media : Table("media") { val id = long("id") val name = varchar("name", 255) - val url = varchar("url", 255) - val remoteUrl = varchar("remote_url", 255).nullable() - val thumbnailUrl = varchar("thumbnail_url", 255).nullable() + val url = varchar("url", 255).uniqueIndex() + val remoteUrl = varchar("remote_url", 255).uniqueIndex().nullable() + val thumbnailUrl = varchar("thumbnail_url", 255).uniqueIndex().nullable() val type = integer("type") val blurhash = varchar("blurhash", 255).nullable() val mimeType = varchar("mime_type", 255) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt index fc7fb675..876c2f1e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/MediaQueryService.kt @@ -4,4 +4,5 @@ import dev.usbharu.hideout.core.domain.model.media.Media interface MediaQueryService { suspend fun findByPostId(postId: Long): List + suspend fun findByRemoteUrl(remoteUrl: String): Media } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt index 5337e53a..80d26318 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/media/MediaServiceImpl.kt @@ -1,9 +1,11 @@ package dev.usbharu.hideout.core.service.media +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.exception.media.MediaSaveException import dev.usbharu.hideout.core.domain.exception.media.UnsupportedMediaException import dev.usbharu.hideout.core.domain.model.media.Media import dev.usbharu.hideout.core.domain.model.media.MediaRepository +import dev.usbharu.hideout.core.query.MediaQueryService import dev.usbharu.hideout.core.service.media.converter.MediaProcessService import dev.usbharu.hideout.mastodon.interfaces.api.media.MediaRequest import dev.usbharu.hideout.util.withDelete @@ -22,7 +24,8 @@ class MediaServiceImpl( private val mediaRepository: MediaRepository, private val mediaProcessServices: List, private val remoteMediaDownloadService: RemoteMediaDownloadService, - private val renameService: MediaFileRenameService + private val renameService: MediaFileRenameService, + private val mediaQueryService: MediaQueryService ) : MediaService { @Suppress("LongMethod", "NestedBlockDepth") override suspend fun uploadLocalMedia(mediaRequest: MediaRequest): EntityMedia { @@ -99,6 +102,13 @@ class MediaServiceImpl( override suspend fun uploadRemoteMedia(remoteMedia: RemoteMedia): Media { logger.info("MEDIA Remote media. filename:${remoteMedia.name} url:${remoteMedia.url}") + try { + val findByRemoteUrl = mediaQueryService.findByRemoteUrl(remoteMedia.url) + logger.warn("DUPLICATED Remote media is duplicated. url: {}", remoteMedia.url) + return findByRemoteUrl + } catch (_: FailedToGetResourcesException) { + } + remoteMediaDownloadService.download(remoteMedia.url).withDelete().use { val mimeType = fileTypeDeterminationService.fileType(it.path, remoteMedia.name) diff --git a/src/main/resources/db/migration/V1__Init_DB.sql b/src/main/resources/db/migration/V1__Init_DB.sql index 4ea80255..e0188588 100644 --- a/src/main/resources/db/migration/V1__Init_DB.sql +++ b/src/main/resources/db/migration/V1__Init_DB.sql @@ -46,9 +46,9 @@ create table if not exists media ( id bigint primary key, "name" varchar(255) not null, - url varchar(255) not null, - remote_url varchar(255) null, - thumbnail_url varchar(255) null, + url varchar(255) not null unique, + remote_url varchar(255) null unique, + thumbnail_url varchar(255) null unique, "type" int not null, blurhash varchar(255) null, mime_type varchar(255) not null,