feat: ReactionServiceをカスタム絵文字に対応

This commit is contained in:
usbharu 2023-12-22 12:02:28 +09:00
parent 32e60dc6f8
commit a389036827
5 changed files with 91 additions and 3 deletions

View File

@ -0,0 +1,9 @@
package dev.usbharu.hideout.activitypub.service.objects.emoji
import dev.usbharu.hideout.activitypub.domain.model.Emoji
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji
interface EmojiService {
suspend fun fetchEmoji(url: String): Pair<Emoji, CustomEmoji>
suspend fun fetchEmoji(emoji: Emoji): Pair<Emoji, CustomEmoji>
}

View File

@ -0,0 +1,63 @@
package dev.usbharu.hideout.activitypub.service.objects.emoji
import dev.usbharu.hideout.activitypub.domain.model.Emoji
import dev.usbharu.hideout.activitypub.service.common.APResourceResolveServiceImpl
import dev.usbharu.hideout.activitypub.service.common.resolve
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository
import dev.usbharu.hideout.core.service.instance.InstanceService
import dev.usbharu.hideout.core.service.media.MediaService
import dev.usbharu.hideout.core.service.media.RemoteMedia
import org.springframework.stereotype.Service
import java.net.URL
import java.time.Instant
@Service
class EmojiServiceImpl(
private val customEmojiRepository: CustomEmojiRepository,
private val instanceService: InstanceService,
private val mediaService: MediaService,
private val apResourceResolveServiceImpl: APResourceResolveServiceImpl
) : EmojiService {
override suspend fun fetchEmoji(url: String): Pair<Emoji, CustomEmoji> {
val emoji = apResourceResolveServiceImpl.resolve<Emoji>(url, null as Long?)
return fetchEmoji(emoji)
}
override suspend fun fetchEmoji(emoji: Emoji): Pair<Emoji, CustomEmoji> {
return emoji to save(emoji)
}
private suspend fun save(emoji: Emoji): CustomEmoji {
val domain = URL(emoji.id).host
val name = emoji.name.trim(':')
val customEmoji = customEmojiRepository.findByNameAndDomain(name, domain)
if (customEmoji != null) {
return customEmoji
}
val instance = instanceService.fetchInstance(emoji.id)
val media = mediaService.uploadRemoteMedia(
RemoteMedia(
emoji.name,
emoji.icon.url,
emoji.icon.mediaType.orEmpty(),
null
)
)
val customEmoji1 = CustomEmoji(
customEmojiRepository.generateId(),
name,
domain,
instance.id,
media.url,
null,
Instant.now()
)
return customEmojiRepository.save(customEmoji1)
}
}

View File

@ -1,7 +1,9 @@
package dev.usbharu.hideout.core.domain.model.emoji package dev.usbharu.hideout.core.domain.model.emoji
interface CustomEmojiRepository { interface CustomEmojiRepository {
suspend fun generateId(): Long
suspend fun save(customEmoji: CustomEmoji): CustomEmoji suspend fun save(customEmoji: CustomEmoji): CustomEmoji
suspend fun findById(id: Long): CustomEmoji? suspend fun findById(id: Long): CustomEmoji?
suspend fun delete(customEmoji: CustomEmoji) suspend fun delete(customEmoji: CustomEmoji)
suspend fun findByNameAndDomain(name: String, domain: String): CustomEmoji?
} }

View File

@ -1,5 +1,6 @@
package dev.usbharu.hideout.core.infrastructure.exposedrepository package dev.usbharu.hideout.core.infrastructure.exposedrepository
import dev.usbharu.hideout.application.service.id.IdGenerateService
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
@ -8,8 +9,13 @@ import org.jetbrains.exposed.sql.javatime.CurrentTimestamp
import org.jetbrains.exposed.sql.javatime.timestamp import org.jetbrains.exposed.sql.javatime.timestamp
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.stereotype.Repository
@Repository
class CustomEmojiRepositoryImpl(private val idGenerateService: IdGenerateService) : CustomEmojiRepository,
AbstractRepository() {
override suspend fun generateId(): Long = idGenerateService.generateId()
class CustomEmojiRepositoryImpl : CustomEmojiRepository, AbstractRepository() {
override suspend fun save(customEmoji: CustomEmoji): CustomEmoji = query { override suspend fun save(customEmoji: CustomEmoji): CustomEmoji = query {
val singleOrNull = CustomEmojis.select { CustomEmojis.id eq customEmoji.id }.forUpdate().singleOrNull() val singleOrNull = CustomEmojis.select { CustomEmojis.id eq customEmoji.id }.forUpdate().singleOrNull()
if (singleOrNull == null) { if (singleOrNull == null) {
@ -43,6 +49,13 @@ class CustomEmojiRepositoryImpl : CustomEmojiRepository, AbstractRepository() {
CustomEmojis.deleteWhere { CustomEmojis.id eq customEmoji.id } CustomEmojis.deleteWhere { CustomEmojis.id eq customEmoji.id }
} }
override suspend fun findByNameAndDomain(name: String, domain: String): CustomEmoji? = query {
return@query CustomEmojis
.select { CustomEmojis.name eq name and (CustomEmojis.domain eq domain) }
.singleOrNull()
?.toCustomEmoji()
}
override val logger: Logger override val logger: Logger
get() = Companion.logger get() = Companion.logger

View File

@ -1,6 +1,7 @@
package dev.usbharu.hideout.core.service.reaction package dev.usbharu.hideout.core.service.reaction
import dev.usbharu.hideout.activitypub.service.activity.like.APReactionService import dev.usbharu.hideout.activitypub.service.activity.like.APReactionService
import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji
import dev.usbharu.hideout.core.domain.model.reaction.Reaction import dev.usbharu.hideout.core.domain.model.reaction.Reaction
import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository
import org.jetbrains.exposed.exceptions.ExposedSQLException import org.jetbrains.exposed.exceptions.ExposedSQLException
@ -17,7 +18,7 @@ class ReactionServiceImpl(
if (reactionRepository.existByPostIdAndActorIdAndEmojiId(postId, actorId, 0).not()) { if (reactionRepository.existByPostIdAndActorIdAndEmojiId(postId, actorId, 0).not()) {
try { try {
reactionRepository.save( reactionRepository.save(
Reaction(reactionRepository.generateId(), 0, postId, actorId) Reaction(reactionRepository.generateId(), UnicodeEmoji(""), postId, actorId)
) )
} catch (_: ExposedSQLException) { } catch (_: ExposedSQLException) {
} }
@ -42,7 +43,7 @@ class ReactionServiceImpl(
reactionRepository.delete(findByPostIdAndUserIdAndEmojiId) reactionRepository.delete(findByPostIdAndUserIdAndEmojiId)
} }
val reaction = Reaction(reactionRepository.generateId(), 0, postId, actorId) val reaction = Reaction(reactionRepository.generateId(), UnicodeEmoji(""), postId, actorId)
reactionRepository.save(reaction) reactionRepository.save(reaction)
apReactionService.reaction(reaction) apReactionService.reaction(reaction)
} }