mirror of https://github.com/usbharu/Hideout.git
feat: Likeを受け取れるように
This commit is contained in:
parent
f0dbb83c00
commit
9e3a019304
|
@ -0,0 +1,41 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.ap
|
||||||
|
|
||||||
|
open class Emoji : Object {
|
||||||
|
var updated: String? = null
|
||||||
|
var icon: Image? = null
|
||||||
|
|
||||||
|
protected constructor() : super()
|
||||||
|
constructor(type: List<String>,
|
||||||
|
name: String?,
|
||||||
|
actor: String?,
|
||||||
|
id: String?,
|
||||||
|
updated: String?,
|
||||||
|
icon: Image?) : super(
|
||||||
|
type = add(type, "Emoji"),
|
||||||
|
name = name,
|
||||||
|
actor = actor,
|
||||||
|
id = id) {
|
||||||
|
this.updated = updated
|
||||||
|
this.icon = icon
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is Emoji) return false
|
||||||
|
if (!super.equals(other)) return false
|
||||||
|
|
||||||
|
if (updated != other.updated) return false
|
||||||
|
return icon == other.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = super.hashCode()
|
||||||
|
result = 31 * result + (updated?.hashCode() ?: 0)
|
||||||
|
result = 31 * result + (icon?.hashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = "Emoji(updated=$updated, icon=$icon) ${super.toString()}"
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.ap
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
|
||||||
|
|
||||||
|
open class Like : Object {
|
||||||
|
var `object`: String? = null
|
||||||
|
var content: String? = null
|
||||||
|
|
||||||
|
@JsonDeserialize(contentUsing = ObjectDeserializer::class)
|
||||||
|
var tag: List<Object> = emptyList()
|
||||||
|
|
||||||
|
protected constructor() : super()
|
||||||
|
constructor(type: List<String>,
|
||||||
|
name: String?,
|
||||||
|
actor: String?,
|
||||||
|
id: String?,
|
||||||
|
`object`: String?,
|
||||||
|
content: String?,
|
||||||
|
tag: List<Object>
|
||||||
|
) : super(
|
||||||
|
type = add(type, "Like"),
|
||||||
|
name = name,
|
||||||
|
actor = actor,
|
||||||
|
id = id) {
|
||||||
|
this.`object` = `object`
|
||||||
|
this.content = content
|
||||||
|
this.tag = tag
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is Like) return false
|
||||||
|
if (!super.equals(other)) return false
|
||||||
|
|
||||||
|
if (`object` != other.`object`) return false
|
||||||
|
if (content != other.content) return false
|
||||||
|
return tag == other.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = super.hashCode()
|
||||||
|
result = 31 * result + (`object`?.hashCode() ?: 0)
|
||||||
|
result = 31 * result + (content?.hashCode() ?: 0)
|
||||||
|
result = 31 * result + tag.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = "Like(`object`=$`object`, content=$content, tag=$tag) ${super.toString()}"
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -42,7 +42,7 @@ class ObjectDeserializer : JsonDeserializer<Object>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
TODO()
|
TODO("$activityType is not implementation")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package dev.usbharu.hideout.domain.model.hideout.entity
|
||||||
|
|
||||||
|
data class Reaction(val id: Long, val emojiId: Long, val postId: Long, val userId: Long)
|
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Reaction
|
||||||
|
|
||||||
|
interface ReactionRepository {
|
||||||
|
suspend fun generateId(): Long
|
||||||
|
suspend fun save(reaction: Reaction): Reaction
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package dev.usbharu.hideout.repository
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Reaction
|
||||||
|
import dev.usbharu.hideout.service.core.IdGenerateService
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import org.jetbrains.exposed.dao.id.LongIdTable
|
||||||
|
import org.jetbrains.exposed.sql.*
|
||||||
|
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import org.koin.core.annotation.Single
|
||||||
|
|
||||||
|
@Single
|
||||||
|
class ReactionRepositoryImpl(private val database: Database, private val idGenerateService: IdGenerateService) : ReactionRepository {
|
||||||
|
|
||||||
|
init {
|
||||||
|
transaction(database) {
|
||||||
|
SchemaUtils.create(Reactions)
|
||||||
|
SchemaUtils.createMissingTablesAndColumns(Reactions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("InjectDispatcher")
|
||||||
|
suspend fun <T> query(block: suspend () -> T): T =
|
||||||
|
newSuspendedTransaction(Dispatchers.IO) { block() }
|
||||||
|
|
||||||
|
override suspend fun generateId(): Long = idGenerateService.generateId()
|
||||||
|
|
||||||
|
override suspend fun save(reaction: Reaction): Reaction {
|
||||||
|
query {
|
||||||
|
if (Reactions.select { Reactions.id eq reaction.id }.empty()) {
|
||||||
|
Reactions.insert {
|
||||||
|
it[id] = reaction.id
|
||||||
|
it[emojiId] = reaction.emojiId
|
||||||
|
it[postId] = reaction.postId
|
||||||
|
it[userId] = reaction.postId
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Reactions.update({ Reactions.id eq reaction.id }) {
|
||||||
|
it[emojiId] = reaction.emojiId
|
||||||
|
it[postId] = reaction.postId
|
||||||
|
it[userId] = reaction.postId
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reaction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ResultRow.toReaction(): Reaction {
|
||||||
|
return Reaction(
|
||||||
|
this[Reactions.id].value,
|
||||||
|
this[Reactions.emojiId],
|
||||||
|
this[Reactions.postId],
|
||||||
|
this[Reactions.userId]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
object Reactions : LongIdTable("reactions") {
|
||||||
|
val emojiId = long("emoji_id")
|
||||||
|
val postId = long("post_id").references(Posts.id)
|
||||||
|
val userId = long("user_id").references(Users.id)
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.usbharu.hideout.service.activitypub
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.ActivityPubResponse
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Like
|
||||||
|
|
||||||
|
interface ActivityPubLikeService {
|
||||||
|
suspend fun receiveLike(like: Like): ActivityPubResponse
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package dev.usbharu.hideout.service.activitypub
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.ActivityPubResponse
|
||||||
|
import dev.usbharu.hideout.domain.model.ActivityPubStringResponse
|
||||||
|
import dev.usbharu.hideout.domain.model.ap.Like
|
||||||
|
import dev.usbharu.hideout.exception.PostNotFoundException
|
||||||
|
import dev.usbharu.hideout.exception.ap.IllegalActivityPubObjectException
|
||||||
|
import dev.usbharu.hideout.repository.IPostRepository
|
||||||
|
import dev.usbharu.hideout.service.reaction.IReactionService
|
||||||
|
import dev.usbharu.hideout.service.user.IUserService
|
||||||
|
import io.ktor.http.*
|
||||||
|
import org.koin.core.annotation.Single
|
||||||
|
|
||||||
|
|
||||||
|
@Single
|
||||||
|
class ActivityPubLikeServiceImpl(private val reactionService: IReactionService,
|
||||||
|
private val activityPubUserService: ActivityPubUserService,
|
||||||
|
private val userService: IUserService,
|
||||||
|
private val postService: IPostRepository) : ActivityPubLikeService {
|
||||||
|
override suspend fun receiveLike(like: Like): ActivityPubResponse {
|
||||||
|
val actor = like.actor ?: throw IllegalActivityPubObjectException("actor is null")
|
||||||
|
val content = like.content ?: throw IllegalActivityPubObjectException("content is null")
|
||||||
|
like.`object` ?: throw IllegalActivityPubObjectException("object is null")
|
||||||
|
val person = activityPubUserService.fetchPerson(actor)
|
||||||
|
|
||||||
|
val user = userService.findByUrl(person.url
|
||||||
|
?: throw IllegalActivityPubObjectException("actor is not found"))
|
||||||
|
|
||||||
|
val post = postService.findByUrl(like.`object`!!)
|
||||||
|
?: throw PostNotFoundException("${like.`object`} was not found")
|
||||||
|
|
||||||
|
reactionService.receiveReaction(content, actor.substringAfter("://").substringBefore("/"), user.id, post.id)
|
||||||
|
return ActivityPubStringResponse(HttpStatusCode.OK, "")
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,11 +17,12 @@ import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
@Single
|
@Single
|
||||||
class ActivityPubServiceImpl(
|
class ActivityPubServiceImpl(
|
||||||
private val activityPubReceiveFollowService: ActivityPubReceiveFollowService,
|
private val activityPubReceiveFollowService: ActivityPubReceiveFollowService,
|
||||||
private val activityPubNoteService: ActivityPubNoteService,
|
private val activityPubNoteService: ActivityPubNoteService,
|
||||||
private val activityPubUndoService: ActivityPubUndoService,
|
private val activityPubUndoService: ActivityPubUndoService,
|
||||||
private val activityPubAcceptService: ActivityPubAcceptService,
|
private val activityPubAcceptService: ActivityPubAcceptService,
|
||||||
private val activityPubCreateService: ActivityPubCreateService
|
private val activityPubCreateService: ActivityPubCreateService,
|
||||||
|
private val activityPubLikeService: ActivityPubLikeService
|
||||||
) : ActivityPubService {
|
) : ActivityPubService {
|
||||||
|
|
||||||
val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
||||||
|
@ -53,6 +54,7 @@ class ActivityPubServiceImpl(
|
||||||
)
|
)
|
||||||
|
|
||||||
ActivityType.Create -> activityPubCreateService.receiveCreate(configData.objectMapper.readValue(json))
|
ActivityType.Create -> activityPubCreateService.receiveCreate(configData.objectMapper.readValue(json))
|
||||||
|
ActivityType.Like -> activityPubLikeService.receiveLike(configData.objectMapper.readValue(json))
|
||||||
ActivityType.Undo -> activityPubUndoService.receiveUndo(configData.objectMapper.readValue(json))
|
ActivityType.Undo -> activityPubUndoService.receiveUndo(configData.objectMapper.readValue(json))
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package dev.usbharu.hideout.service.reaction
|
||||||
|
|
||||||
|
interface IReactionService {
|
||||||
|
suspend fun receiveReaction(name: String, domain: String, userId: Long, postId: Long)
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package dev.usbharu.hideout.service.reaction
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.domain.model.hideout.entity.Reaction
|
||||||
|
import dev.usbharu.hideout.repository.ReactionRepository
|
||||||
|
import org.koin.core.annotation.Single
|
||||||
|
|
||||||
|
@Single
|
||||||
|
class ReactionServiceImpl(private val reactionRepository: ReactionRepository) : IReactionService {
|
||||||
|
override suspend fun receiveReaction(name: String, domain: String, userId: Long, postId: Long) {
|
||||||
|
reactionRepository.save(
|
||||||
|
Reaction(
|
||||||
|
reactionRepository.generateId(),
|
||||||
|
0,
|
||||||
|
postId, userId
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue