mirror of https://github.com/usbharu/Hideout.git
feat: ブロック等ができるように
This commit is contained in:
parent
54e3af2253
commit
a939dd5f30
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.relationship
|
||||
|
||||
data class Block(val targetActorId: Long)
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.relationship
|
||||
|
||||
data class FollowRequest(val targetActorId: Long)
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.relationship
|
||||
|
||||
data class GetRelationship(val targetActorId: Long)
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.relationship
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInstanceRelationship
|
||||
import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInstanceRelationshipRepository
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class GetRelationshipApplicationService(
|
||||
private val relationshipRepository: RelationshipRepository,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val userDetailRepository: UserDetailRepository,
|
||||
private val actorInstanceRelationshipRepository: ActorInstanceRelationshipRepository,
|
||||
transaction: Transaction,
|
||||
) :
|
||||
AbstractApplicationService<GetRelationship, Relationship>(
|
||||
transaction, logger
|
||||
) {
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(GetRelationshipApplicationService::class.java)
|
||||
}
|
||||
|
||||
override suspend fun internalExecute(command: GetRelationship, executor: CommandExecutor): Relationship {
|
||||
require(executor is UserDetailGettableCommandExecutor)
|
||||
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
|
||||
val actor = actorRepository.findById(userDetail.actorId)!!
|
||||
val targetId = ActorId(command.targetActorId)
|
||||
val target = actorRepository.findById(targetId)!!
|
||||
val relationship = (relationshipRepository.findByActorIdAndTargetId(actor.id, targetId)
|
||||
?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(actor.id, targetId))
|
||||
|
||||
val relationship1 = (relationshipRepository.findByActorIdAndTargetId(targetId, actor.id)
|
||||
?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(targetId, actor.id))
|
||||
|
||||
val actorInstanceRelationship =
|
||||
actorInstanceRelationshipRepository.findByActorIdAndInstanceId(actor.id, target.instance)
|
||||
?: ActorInstanceRelationship.default(
|
||||
actor.id,
|
||||
target.instance
|
||||
)
|
||||
|
||||
return Relationship.of(relationship, relationship1, actorInstanceRelationship)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.relationship
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInstanceRelationship
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
|
||||
|
||||
data class Relationship(
|
||||
val actorId: Long,
|
||||
val targetId: Long,
|
||||
val following: Boolean,
|
||||
val followedBy: Boolean,
|
||||
val blocking: Boolean,
|
||||
val blockedBy: Boolean,
|
||||
val muting: Boolean,
|
||||
val followRequesting: Boolean,
|
||||
val followRequestedBy: Boolean,
|
||||
val domainBlocking: Boolean,
|
||||
val domainMuting: Boolean,
|
||||
val domainDoNotSendPrivate: Boolean,
|
||||
) {
|
||||
companion object {
|
||||
fun of(
|
||||
relationship: Relationship,
|
||||
relationship2: Relationship,
|
||||
actorInstanceRelationship: ActorInstanceRelationship,
|
||||
): dev.usbharu.hideout.core.application.relationship.Relationship {
|
||||
return Relationship(
|
||||
relationship.actorId.id,
|
||||
relationship.targetActorId.id,
|
||||
relationship.following,
|
||||
relationship2.following,
|
||||
relationship.blocking,
|
||||
relationship2.blocking,
|
||||
relationship.muting,
|
||||
relationship.followRequesting,
|
||||
relationship2.followRequesting,
|
||||
actorInstanceRelationship.isBlocking(),
|
||||
actorInstanceRelationship.isMuting(),
|
||||
actorInstanceRelationship.isDoNotSendPrivate()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.relationship
|
||||
|
||||
data class Unblock(val targetActorId: Long)
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.relationship
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
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.RelationshipRepository
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
import dev.usbharu.hideout.core.domain.service.relationship.RelationshipDomainService
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UserBlockApplicationService(
|
||||
private val relationshipRepository: RelationshipRepository,
|
||||
transaction: Transaction,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val userDetailRepository: UserDetailRepository,
|
||||
private val relationshipDomainService: RelationshipDomainService,
|
||||
) :
|
||||
AbstractApplicationService<Block, Unit>(transaction, logger) {
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UserBlockApplicationService::class.java)
|
||||
}
|
||||
|
||||
override suspend fun internalExecute(command: Block, executor: CommandExecutor) {
|
||||
require(executor is UserDetailGettableCommandExecutor)
|
||||
|
||||
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
|
||||
val actor = actorRepository.findById(userDetail.actorId)!!
|
||||
|
||||
val targetId = ActorId(command.targetActorId)
|
||||
val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default(
|
||||
actor.id,
|
||||
targetId
|
||||
)
|
||||
|
||||
val inverseRelationship =
|
||||
relationshipRepository.findByActorIdAndTargetId(targetId, actor.id) ?: Relationship.default(
|
||||
targetId,
|
||||
actor.id
|
||||
)
|
||||
|
||||
relationshipDomainService.block(relationship, inverseRelationship)
|
||||
|
||||
|
||||
relationshipRepository.save(relationship)
|
||||
relationshipRepository.save(inverseRelationship)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.relationship
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
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.RelationshipRepository
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UserFollowRequestApplicationService(
|
||||
private val relationshipRepository: RelationshipRepository,
|
||||
transaction: Transaction,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val userDetailRepository: UserDetailRepository,
|
||||
) : AbstractApplicationService<FollowRequest, Unit>(
|
||||
transaction, logger
|
||||
) {
|
||||
|
||||
override suspend fun internalExecute(command: FollowRequest, executor: CommandExecutor) {
|
||||
require(executor is UserDetailGettableCommandExecutor)
|
||||
|
||||
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
|
||||
val actor = actorRepository.findById(userDetail.actorId)!!
|
||||
|
||||
val targetId = ActorId(command.targetActorId)
|
||||
val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default(
|
||||
actor.id,
|
||||
targetId
|
||||
)
|
||||
|
||||
relationship.followRequest()
|
||||
|
||||
relationshipRepository.save(relationship)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UserFollowRequestApplicationService::class.java)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.application.relationship
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
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.RelationshipRepository
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UserUnblockApplicationService(
|
||||
private val relationshipRepository: RelationshipRepository,
|
||||
transaction: Transaction,
|
||||
private val actorRepository: ActorRepository,
|
||||
private val userDetailRepository: UserDetailRepository,
|
||||
) :
|
||||
AbstractApplicationService<Unblock, Unit>(transaction, logger) {
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UserBlockApplicationService::class.java)
|
||||
}
|
||||
|
||||
override suspend fun internalExecute(command: Unblock, executor: CommandExecutor) {
|
||||
require(executor is UserDetailGettableCommandExecutor)
|
||||
|
||||
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
|
||||
val actor = actorRepository.findById(userDetail.actorId)!!
|
||||
|
||||
val targetId = ActorId(command.targetActorId)
|
||||
val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default(
|
||||
actor.id,
|
||||
targetId
|
||||
)
|
||||
|
||||
relationship.unblock()
|
||||
|
||||
relationshipRepository.save(relationship)
|
||||
}
|
||||
}
|
|
@ -96,5 +96,15 @@ data class ActorInstanceRelationship(
|
|||
")"
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
fun default(actorId: ActorId, instanceId: InstanceId): ActorInstanceRelationship {
|
||||
return ActorInstanceRelationship(
|
||||
actorId = actorId,
|
||||
instanceId = instanceId,
|
||||
blocking = false,
|
||||
muting = false,
|
||||
doNotSendPrivate = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,11 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.model.actorinstancerelationship
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceId
|
||||
|
||||
interface ActorInstanceRelationshipRepository {
|
||||
suspend fun save(actorInstanceRelationship: ActorInstanceRelationship): ActorInstanceRelationship
|
||||
suspend fun delete(actorInstanceRelationship: ActorInstanceRelationship)
|
||||
suspend fun findByActorIdAndInstanceId(actorId: ActorId, instanceId: InstanceId): ActorInstanceRelationship?
|
||||
}
|
||||
|
|
|
@ -102,4 +102,35 @@ class Relationship(
|
|||
fun rejectFollowRequest() {
|
||||
followRequesting = false
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Relationship
|
||||
|
||||
if (actorId != other.actorId) return false
|
||||
if (targetActorId != other.targetActorId) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = actorId.hashCode()
|
||||
result = 31 * result + targetActorId.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
fun default(actorId: ActorId, targetActorId: ActorId): Relationship = Relationship(
|
||||
actorId = actorId,
|
||||
targetActorId = targetActorId,
|
||||
following = false,
|
||||
blocking = false,
|
||||
muting = false,
|
||||
followRequesting = false,
|
||||
mutingFollowRequest = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.model.relationship
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
|
||||
interface RelationshipRepository {
|
||||
suspend fun save(relationship: Relationship): Relationship
|
||||
suspend fun delete(relationship: Relationship)
|
||||
suspend fun findByActorIdAndTargetId(actorId: ActorId, targetId: ActorId): Relationship?
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.domain.service.relationship
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class RelationshipDomainService {
|
||||
fun block(relationship: Relationship, inverseRelationship: Relationship) {
|
||||
require(relationship != inverseRelationship)
|
||||
require(relationship.actorId == inverseRelationship.targetActorId)
|
||||
require(relationship.targetActorId == inverseRelationship.actorId)
|
||||
|
||||
relationship.block()
|
||||
inverseRelationship.unfollow()
|
||||
inverseRelationship.unfollowRequest()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInstanceRelationship
|
||||
import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInstanceRelationshipRepository
|
||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceId
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
|
||||
@Repository
|
||||
class ExposedActorInstanceRelationshipRepository(override val domainEventPublisher: DomainEventPublisher) :
|
||||
ActorInstanceRelationshipRepository, AbstractRepository(),
|
||||
DomainEventPublishableRepository<ActorInstanceRelationship> {
|
||||
override suspend fun save(actorInstanceRelationship: ActorInstanceRelationship): ActorInstanceRelationship {
|
||||
query {
|
||||
ActorInstanceRelationships.upsert {
|
||||
it[actorId] = actorInstanceRelationship.actorId.id
|
||||
it[instanceId] = actorInstanceRelationship.instanceId.instanceId
|
||||
it[blocking] = actorInstanceRelationship.isBlocking()
|
||||
it[muting] = actorInstanceRelationship.isMuting()
|
||||
it[doNotSendPrivate] = actorInstanceRelationship.isDoNotSendPrivate()
|
||||
}
|
||||
}
|
||||
update(actorInstanceRelationship)
|
||||
return actorInstanceRelationship
|
||||
}
|
||||
|
||||
override suspend fun delete(actorInstanceRelationship: ActorInstanceRelationship) {
|
||||
query {
|
||||
ActorInstanceRelationships.deleteWhere {
|
||||
actorId eq actorInstanceRelationship.actorId.id and (instanceId eq actorInstanceRelationship.instanceId.instanceId)
|
||||
}
|
||||
}
|
||||
update(actorInstanceRelationship)
|
||||
}
|
||||
|
||||
override suspend fun findByActorIdAndInstanceId(
|
||||
actorId: ActorId,
|
||||
instanceId: InstanceId,
|
||||
): ActorInstanceRelationship? = query {
|
||||
ActorInstanceRelationships
|
||||
.selectAll()
|
||||
.where {
|
||||
ActorInstanceRelationships.actorId eq actorId.id and (ActorInstanceRelationships.instanceId eq instanceId.instanceId)
|
||||
}
|
||||
.singleOrNull()
|
||||
?.toActorInstanceRelationship()
|
||||
}
|
||||
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedActorInstanceRelationshipRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ResultRow.toActorInstanceRelationship(): ActorInstanceRelationship {
|
||||
return ActorInstanceRelationship(
|
||||
actorId = ActorId(this[ActorInstanceRelationships.actorId]),
|
||||
instanceId = InstanceId(this[ActorInstanceRelationships.instanceId]),
|
||||
blocking = this[ActorInstanceRelationships.blocking],
|
||||
muting = this[ActorInstanceRelationships.muting],
|
||||
doNotSendPrivate = this[ActorInstanceRelationships.doNotSendPrivate],
|
||||
)
|
||||
}
|
||||
|
||||
object ActorInstanceRelationships : Table("actor_instance_relationships") {
|
||||
val actorId = long("actor_id").references(Actors.id)
|
||||
val instanceId = long("instance_id").references(Instance.id)
|
||||
val blocking = bool("blocking")
|
||||
val muting = bool("muting")
|
||||
val doNotSendPrivate = bool("do_not_send_private")
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(actorId, instanceId)
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class ExposedRelationshipRepository(override val domainEventPublisher: DomainEventPublisher) : RelationshipRepository,
|
||||
AbstractRepository(),
|
||||
DomainEventPublishableRepository<Relationship> {
|
||||
override suspend fun save(relationship: Relationship): Relationship {
|
||||
query {
|
||||
Relationships.upsert {
|
||||
it[actorId] = relationship.actorId.id
|
||||
it[targetActorId] = relationship.targetActorId.id
|
||||
it[following] = relationship.following
|
||||
it[blocking] = relationship.blocking
|
||||
it[muting] = relationship.muting
|
||||
it[followRequesting] = relationship.followRequesting
|
||||
it[mutingFollowRequest] = relationship.mutingFollowRequest
|
||||
}
|
||||
}
|
||||
update(relationship)
|
||||
return relationship
|
||||
}
|
||||
|
||||
override suspend fun delete(relationship: Relationship) {
|
||||
query {
|
||||
Relationships.deleteWhere {
|
||||
actorId eq relationship.actorId.id and (targetActorId eq relationship.targetActorId.id)
|
||||
}
|
||||
}
|
||||
update(relationship)
|
||||
}
|
||||
|
||||
override suspend fun findByActorIdAndTargetId(actorId: ActorId, targetId: ActorId): Relationship? = query {
|
||||
Relationships.selectAll().where {
|
||||
Relationships.actorId eq actorId.id and (Relationships.targetActorId eq targetId.id)
|
||||
}.singleOrNull()?.toRelationships()
|
||||
}
|
||||
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedRelationshipRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
fun ResultRow.toRelationships(): Relationship = Relationship(
|
||||
actorId = ActorId(this[Relationships.actorId]),
|
||||
targetActorId = ActorId(this[Relationships.targetActorId]),
|
||||
following = this[Relationships.following],
|
||||
blocking = this[Relationships.blocking],
|
||||
muting = this[Relationships.muting],
|
||||
followRequesting = this[Relationships.followRequesting],
|
||||
mutingFollowRequest = this[Relationships.mutingFollowRequest]
|
||||
)
|
||||
|
||||
object Relationships : Table("relationships") {
|
||||
val actorId = long("actor_id").references(Actors.id)
|
||||
val targetActorId = long("target_actor_id").references(Actors.id)
|
||||
val following = bool("following")
|
||||
val blocking = bool("blocking")
|
||||
val muting = bool("muting")
|
||||
val followRequesting = bool("follow_requesting")
|
||||
val mutingFollowRequest = bool("muting_follow_request")
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(actorId, targetActorId)
|
||||
}
|
|
@ -17,5 +17,7 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.springframework.oauth2
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
|
||||
|
||||
class Oauth2CommandExecutor(override val executor: String, val userDetailId: Long) : CommandExecutor
|
||||
class Oauth2CommandExecutor(override val executor: String, override val userDetailId: Long) : CommandExecutor,
|
||||
UserDetailGettableCommandExecutor
|
|
@ -249,3 +249,15 @@ CREATE TABLE oauth2_authorization
|
|||
device_code_metadata varchar(4000) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
create table if not exists actor_instance_relationships
|
||||
(
|
||||
actor_id bigint not null,
|
||||
instance_id bigint not null,
|
||||
blocking boolean not null,
|
||||
muting boolean not null,
|
||||
do_not_send_private boolean not null,
|
||||
PRIMARY KEY (actor_id, instance_id),
|
||||
constraint fk_actor_instance_relationships_actor_id__id foreign key (actor_id) references actors (id) on delete cascade on update cascade,
|
||||
constraint fk_actor_instance_relationships_instance_id__id foreign key (instance_id) references instance (id) on delete cascade on update cascade
|
||||
);
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.mastodon.application.accounts
|
||||
|
||||
data class GetAccount(val accountId: String)
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.mastodon.application.accounts
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Account
|
||||
import dev.usbharu.hideout.mastodon.query.AccountQueryService
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class GetAccountApplicationService(private val accountQueryService: AccountQueryService, transaction: Transaction) :
|
||||
AbstractApplicationService<GetAccount, Account>(
|
||||
transaction,
|
||||
logger
|
||||
) {
|
||||
override suspend fun internalExecute(command: GetAccount, executor: CommandExecutor): Account {
|
||||
return accountQueryService.findById(command.accountId.toLong()) ?: throw Exception("Account not found")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(GetAccountApplicationService::class.java)
|
||||
}
|
||||
}
|
|
@ -18,9 +18,14 @@ package dev.usbharu.hideout.mastodon.interfaces.api
|
|||
|
||||
import dev.usbharu.hideout.core.application.actor.GetUserDetail
|
||||
import dev.usbharu.hideout.core.application.actor.GetUserDetailApplicationService
|
||||
import dev.usbharu.hideout.core.application.relationship.*
|
||||
import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.Oauth2CommandExecutor
|
||||
import dev.usbharu.hideout.core.infrastructure.springframework.oauth2.Oauth2CommandExecutorFactory
|
||||
import dev.usbharu.hideout.mastodon.application.accounts.GetAccount
|
||||
import dev.usbharu.hideout.mastodon.application.accounts.GetAccountApplicationService
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.AccountApi
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.*
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Relationship
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.stereotype.Controller
|
||||
|
||||
|
@ -28,20 +33,60 @@ import org.springframework.stereotype.Controller
|
|||
class SpringAccountApi(
|
||||
private val oauth2CommandExecutorFactory: Oauth2CommandExecutorFactory,
|
||||
private val getUserDetailApplicationService: GetUserDetailApplicationService,
|
||||
private val getAccountApplicationService: GetAccountApplicationService,
|
||||
private val userFollowRequestApplicationService: UserFollowRequestApplicationService,
|
||||
private val getRelationshipApplicationService: GetRelationshipApplicationService,
|
||||
private val userBlockApplicationService: UserBlockApplicationService,
|
||||
private val userUnblockApplicationService: UserUnblockApplicationService,
|
||||
) : AccountApi {
|
||||
override suspend fun apiV1AccountsIdBlockPost(id: String): ResponseEntity<Relationship> {
|
||||
return super.apiV1AccountsIdBlockPost(id)
|
||||
val executor = oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
userBlockApplicationService.execute(Block(id.toLong()), executor)
|
||||
return fetchRelationship(id, executor)
|
||||
}
|
||||
|
||||
override suspend fun apiV1AccountsIdFollowPost(
|
||||
id: String,
|
||||
followRequestBody: FollowRequestBody?,
|
||||
): ResponseEntity<Relationship> {
|
||||
return super.apiV1AccountsIdFollowPost(id, followRequestBody)
|
||||
val executor = oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
userFollowRequestApplicationService.execute(
|
||||
FollowRequest(id.toLong()), executor
|
||||
)
|
||||
return fetchRelationship(id, executor)
|
||||
}
|
||||
|
||||
private suspend fun fetchRelationship(
|
||||
id: String,
|
||||
executor: Oauth2CommandExecutor,
|
||||
): ResponseEntity<Relationship> {
|
||||
val relationship = getRelationshipApplicationService.execute(GetRelationship(id.toLong()), executor)
|
||||
return ResponseEntity.ok(
|
||||
Relationship(
|
||||
id = relationship.targetId.toString(),
|
||||
following = relationship.following,
|
||||
showingReblogs = true,
|
||||
notifying = false,
|
||||
followedBy = relationship.followedBy,
|
||||
blocking = relationship.blocking,
|
||||
blockedBy = relationship.blockedBy,
|
||||
muting = relationship.muting,
|
||||
mutingNotifications = false,
|
||||
requested = relationship.followRequesting,
|
||||
domainBlocking = relationship.domainBlocking,
|
||||
endorsed = false,
|
||||
note = ""
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun apiV1AccountsIdGet(id: String): ResponseEntity<Account> {
|
||||
return super.apiV1AccountsIdGet(id)
|
||||
return ResponseEntity.ok(
|
||||
getAccountApplicationService.execute(
|
||||
GetAccount(id),
|
||||
oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun apiV1AccountsIdMutePost(id: String): ResponseEntity<Relationship> {
|
||||
|
@ -53,7 +98,11 @@ class SpringAccountApi(
|
|||
}
|
||||
|
||||
override suspend fun apiV1AccountsIdUnblockPost(id: String): ResponseEntity<Relationship> {
|
||||
return super.apiV1AccountsIdUnblockPost(id)
|
||||
val executor = oauth2CommandExecutorFactory.getCommandExecutor()
|
||||
userUnblockApplicationService.execute(
|
||||
Unblock(id.toLong()), executor
|
||||
)
|
||||
return fetchRelationship(id, executor)
|
||||
}
|
||||
|
||||
override suspend fun apiV1AccountsIdUnfollowPost(id: String): ResponseEntity<Relationship> {
|
||||
|
|
Loading…
Reference in New Issue