mirror of https://github.com/usbharu/Hideout.git
refactor: Actorsテーブルにフォロワー数情報とフォロー数情報を追加
This commit is contained in:
parent
e0368ab7c5
commit
77d79e2279
|
@ -22,7 +22,11 @@ data class Actor private constructor(
|
||||||
val followers: String? = null,
|
val followers: String? = null,
|
||||||
val following: String? = null,
|
val following: String? = null,
|
||||||
val instance: Long? = null,
|
val instance: Long? = null,
|
||||||
val locked: Boolean
|
val locked: Boolean,
|
||||||
|
val followersCount: Int = 0,
|
||||||
|
val followingCount: Int = 0,
|
||||||
|
val postsCount: Int = 0,
|
||||||
|
val lastPostDate: Instant? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@ -47,7 +51,11 @@ data class Actor private constructor(
|
||||||
following: String? = null,
|
following: String? = null,
|
||||||
followers: String? = null,
|
followers: String? = null,
|
||||||
instance: Long? = null,
|
instance: Long? = null,
|
||||||
locked: Boolean
|
locked: Boolean,
|
||||||
|
followersCount: Int,
|
||||||
|
followingCount: Int,
|
||||||
|
postsCount: Int,
|
||||||
|
lastPostDate: Instant?
|
||||||
): Actor {
|
): Actor {
|
||||||
// idは0未満ではいけない
|
// idは0未満ではいけない
|
||||||
require(id >= 0) { "id must be greater than or equal to 0." }
|
require(id >= 0) { "id must be greater than or equal to 0." }
|
||||||
|
@ -123,6 +131,18 @@ data class Actor private constructor(
|
||||||
"keyId must contain non-blank characters."
|
"keyId must contain non-blank characters."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require(postsCount >= 0) {
|
||||||
|
"postsCount must be greater than or equal to 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
require(followersCount >= 0) {
|
||||||
|
"followersCount must be greater than or equal to 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
require(followingCount >= 0) {
|
||||||
|
"followingCount must be greater than or equal to 0"
|
||||||
|
}
|
||||||
|
|
||||||
return Actor(
|
return Actor(
|
||||||
id = id,
|
id = id,
|
||||||
name = limitedName,
|
name = limitedName,
|
||||||
|
@ -139,29 +159,47 @@ data class Actor private constructor(
|
||||||
followers = followers,
|
followers = followers,
|
||||||
following = following,
|
following = following,
|
||||||
instance = instance,
|
instance = instance,
|
||||||
locked
|
locked = locked,
|
||||||
|
followersCount = followersCount,
|
||||||
|
followingCount = followingCount,
|
||||||
|
postsCount = postsCount,
|
||||||
|
lastPostDate = lastPostDate
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun incrementFollowing(): Actor = this.copy(followingCount = this.followingCount + 1)
|
||||||
|
|
||||||
|
fun decrementFollowing(): Actor = this.copy(followingCount = this.followingCount - 1)
|
||||||
|
|
||||||
|
fun incrementFollowers(): Actor = this.copy(followersCount = this.followersCount + 1)
|
||||||
|
|
||||||
|
fun decrementFollowers(): Actor = this.copy(followersCount = this.followersCount - 1)
|
||||||
|
|
||||||
|
fun incrementPostsCount(): Actor = this.copy(postsCount = this.postsCount + 1)
|
||||||
|
|
||||||
|
fun decrementPostsCount(): Actor = this.copy(postsCount = this.postsCount - 1)
|
||||||
|
|
||||||
|
fun withLastPostAt(lastPostDate: Instant): Actor = this.copy(lastPostDate = lastPostDate)
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Actor(" +
|
return "Actor(" +
|
||||||
"id=$id, " +
|
"id=$id, " +
|
||||||
"name='$name', " +
|
"name='$name', " +
|
||||||
"domain='$domain', " +
|
"domain='$domain', " +
|
||||||
"screenName='$screenName', " +
|
"screenName='$screenName', " +
|
||||||
"description='$description', " +
|
"description='$description', " +
|
||||||
"inbox='$inbox', " +
|
"inbox='$inbox', " +
|
||||||
"outbox='$outbox', " +
|
"outbox='$outbox', " +
|
||||||
"url='$url', " +
|
"url='$url', " +
|
||||||
"publicKey='$publicKey', " +
|
"publicKey='$publicKey', " +
|
||||||
"privateKey=$privateKey, " +
|
"privateKey=$privateKey, " +
|
||||||
"createdAt=$createdAt, " +
|
"createdAt=$createdAt, " +
|
||||||
"keyId='$keyId', " +
|
"keyId='$keyId', " +
|
||||||
"followers=$followers, " +
|
"followers=$followers, " +
|
||||||
"following=$following, " +
|
"following=$following, " +
|
||||||
"instance=$instance, " +
|
"instance=$instance, " +
|
||||||
"locked=$locked" +
|
"locked=$locked" +
|
||||||
")"
|
")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,11 @@ class UserResultRowMapper(private val actorBuilder: Actor.UserBuilder) : ResultR
|
||||||
followers = resultRow[Actors.followers],
|
followers = resultRow[Actors.followers],
|
||||||
following = resultRow[Actors.following],
|
following = resultRow[Actors.following],
|
||||||
instance = resultRow[Actors.instance],
|
instance = resultRow[Actors.instance],
|
||||||
locked = resultRow[Actors.locked]
|
locked = resultRow[Actors.locked],
|
||||||
|
followingCount = resultRow[Actors.followingCount],
|
||||||
|
followersCount = resultRow[Actors.followersCount],
|
||||||
|
postsCount = resultRow[Actors.postsCount],
|
||||||
|
lastPostDate = resultRow[Actors.lastPostAt],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
|
import org.jetbrains.exposed.sql.javatime.timestamp
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
|
@ -35,6 +36,10 @@ class ActorRepositoryImpl(
|
||||||
it[followers] = actor.followers
|
it[followers] = actor.followers
|
||||||
it[instance] = actor.instance
|
it[instance] = actor.instance
|
||||||
it[locked] = actor.locked
|
it[locked] = actor.locked
|
||||||
|
it[followersCount] = actor.followersCount
|
||||||
|
it[followingCount] = actor.followingCount
|
||||||
|
it[postsCount] = actor.postsCount
|
||||||
|
it[lastPostAt] = actor.lastPostDate
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Actors.update({ Actors.id eq actor.id }) {
|
Actors.update({ Actors.id eq actor.id }) {
|
||||||
|
@ -53,6 +58,10 @@ class ActorRepositoryImpl(
|
||||||
it[followers] = actor.followers
|
it[followers] = actor.followers
|
||||||
it[instance] = actor.instance
|
it[instance] = actor.instance
|
||||||
it[locked] = actor.locked
|
it[locked] = actor.locked
|
||||||
|
it[followersCount] = actor.followersCount
|
||||||
|
it[followingCount] = actor.followingCount
|
||||||
|
it[postsCount] = actor.postsCount
|
||||||
|
it[lastPostAt] = actor.lastPostDate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return actor
|
return actor
|
||||||
|
@ -91,6 +100,10 @@ object Actors : Table("actors") {
|
||||||
val followers = varchar("followers", length = 1000).nullable()
|
val followers = varchar("followers", length = 1000).nullable()
|
||||||
val instance = long("instance").references(Instance.id).nullable()
|
val instance = long("instance").references(Instance.id).nullable()
|
||||||
val locked = bool("locked")
|
val locked = bool("locked")
|
||||||
|
val followingCount = integer("following_count")
|
||||||
|
val followersCount = integer("followers_count")
|
||||||
|
val postsCount = integer("posts_count")
|
||||||
|
val lastPostAt = timestamp("last_post_at").nullable()
|
||||||
|
|
||||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import dev.usbharu.hideout.activitypub.service.activity.undo.APSendUndoService
|
||||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
|
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
|
||||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||||
|
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||||
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
|
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
|
||||||
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
||||||
import dev.usbharu.hideout.core.query.ActorQueryService
|
import dev.usbharu.hideout.core.query.ActorQueryService
|
||||||
|
@ -24,7 +25,8 @@ class RelationshipServiceImpl(
|
||||||
private val apSendBlockService: APSendBlockService,
|
private val apSendBlockService: APSendBlockService,
|
||||||
private val apSendAcceptService: ApSendAcceptService,
|
private val apSendAcceptService: ApSendAcceptService,
|
||||||
private val apSendRejectService: ApSendRejectService,
|
private val apSendRejectService: ApSendRejectService,
|
||||||
private val apSendUndoService: APSendUndoService
|
private val apSendUndoService: APSendUndoService,
|
||||||
|
private val actorRepository: ActorRepository
|
||||||
) : RelationshipService {
|
) : RelationshipService {
|
||||||
override suspend fun followRequest(actorId: Long, targetId: Long) {
|
override suspend fun followRequest(actorId: Long, targetId: Long) {
|
||||||
logger.info("START Follow Request userId: {} targetId: {}", actorId, targetId)
|
logger.info("START Follow Request userId: {} targetId: {}", actorId, targetId)
|
||||||
|
@ -90,6 +92,15 @@ class RelationshipServiceImpl(
|
||||||
|
|
||||||
override suspend fun block(actorId: Long, targetId: Long) {
|
override suspend fun block(actorId: Long, targetId: Long) {
|
||||||
val relationship = relationshipRepository.findByUserIdAndTargetUserId(actorId, targetId)
|
val relationship = relationshipRepository.findByUserIdAndTargetUserId(actorId, targetId)
|
||||||
|
|
||||||
|
val user = actorQueryService.findById(actorId)
|
||||||
|
val targetActor = actorQueryService.findById(targetId)
|
||||||
|
if (relationship?.following == true) {
|
||||||
|
actorRepository.save(user.decrementFollowing())
|
||||||
|
actorRepository.save(targetActor.decrementFollowers())
|
||||||
|
}
|
||||||
|
|
||||||
|
val blockedRelationship = relationship
|
||||||
?.copy(blocking = true, followRequest = false, following = false) ?: Relationship(
|
?.copy(blocking = true, followRequest = false, following = false) ?: Relationship(
|
||||||
actorId = actorId,
|
actorId = actorId,
|
||||||
targetActorId = targetId,
|
targetActorId = targetId,
|
||||||
|
@ -101,17 +112,26 @@ class RelationshipServiceImpl(
|
||||||
)
|
)
|
||||||
|
|
||||||
val inverseRelationship = relationshipRepository.findByUserIdAndTargetUserId(targetId, actorId)
|
val inverseRelationship = relationshipRepository.findByUserIdAndTargetUserId(targetId, actorId)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (inverseRelationship?.following == true) {
|
||||||
|
actorRepository.save(targetActor.decrementFollowing())
|
||||||
|
actorRepository.save(user.decrementFollowers())
|
||||||
|
}
|
||||||
|
|
||||||
|
val blockedInverseRelationship = inverseRelationship
|
||||||
?.copy(followRequest = false, following = false)
|
?.copy(followRequest = false, following = false)
|
||||||
|
|
||||||
relationshipRepository.save(relationship)
|
relationshipRepository.save(blockedRelationship)
|
||||||
if (inverseRelationship != null) {
|
if (blockedInverseRelationship != null) {
|
||||||
relationshipRepository.save(inverseRelationship)
|
relationshipRepository.save(blockedInverseRelationship)
|
||||||
}
|
}
|
||||||
|
|
||||||
val remoteUser = isRemoteUser(targetId)
|
val remoteUser = isRemoteUser(targetId)
|
||||||
|
|
||||||
if (remoteUser != null) {
|
if (remoteUser != null) {
|
||||||
val user = actorQueryService.findById(actorId)
|
|
||||||
apSendBlockService.sendBlock(user, remoteUser)
|
apSendBlockService.sendBlock(user, remoteUser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,13 +177,18 @@ class RelationshipServiceImpl(
|
||||||
|
|
||||||
val copy = relationship.copy(followRequest = false, following = true, blocking = false)
|
val copy = relationship.copy(followRequest = false, following = true, blocking = false)
|
||||||
|
|
||||||
|
val user = actorQueryService.findById(actorId)
|
||||||
|
|
||||||
|
actorRepository.save(user.incrementFollowers())
|
||||||
|
|
||||||
relationshipRepository.save(copy)
|
relationshipRepository.save(copy)
|
||||||
|
|
||||||
val remoteUser = isRemoteUser(targetId)
|
val remoteActor = actorQueryService.findById(targetId)
|
||||||
|
|
||||||
if (remoteUser != null) {
|
actorRepository.save(remoteActor.incrementFollowing())
|
||||||
val user = actorQueryService.findById(actorId)
|
|
||||||
apSendAcceptService.sendAcceptFollow(user, remoteUser)
|
if (isRemoteActor(remoteActor)) {
|
||||||
|
apSendAcceptService.sendAcceptFollow(user, remoteActor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +241,14 @@ class RelationshipServiceImpl(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val user = actorQueryService.findById(actorId)
|
||||||
|
val targetActor = actorQueryService.findById(targetId)
|
||||||
|
|
||||||
|
if (relationship.following) {
|
||||||
|
actorRepository.save(user.decrementFollowing())
|
||||||
|
actorRepository.save(targetActor.decrementFollowers())
|
||||||
|
}
|
||||||
|
|
||||||
if (relationship.following.not()) {
|
if (relationship.following.not()) {
|
||||||
logger.warn("SUCCESS User already unfollow. userId: {} targetId: {}", actorId, targetId)
|
logger.warn("SUCCESS User already unfollow. userId: {} targetId: {}", actorId, targetId)
|
||||||
return
|
return
|
||||||
|
@ -228,7 +261,7 @@ class RelationshipServiceImpl(
|
||||||
val remoteUser = isRemoteUser(targetId)
|
val remoteUser = isRemoteUser(targetId)
|
||||||
|
|
||||||
if (remoteUser != null) {
|
if (remoteUser != null) {
|
||||||
val user = actorQueryService.findById(actorId)
|
|
||||||
apSendUndoService.sendUndoFollow(user, remoteUser)
|
apSendUndoService.sendUndoFollow(user, remoteUser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,6 +315,8 @@ class RelationshipServiceImpl(
|
||||||
relationshipRepository.save(relationship)
|
relationshipRepository.save(relationship)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isRemoteActor(actor: Actor): Boolean = actor.domain != applicationConfig.url.host
|
||||||
|
|
||||||
private suspend fun isRemoteUser(userId: Long): Actor? {
|
private suspend fun isRemoteUser(userId: Long): Actor? {
|
||||||
logger.trace("isRemoteUser({})", userId)
|
logger.trace("isRemoteUser({})", userId)
|
||||||
val user = try {
|
val user = try {
|
||||||
|
|
Loading…
Reference in New Issue