Merge pull request #561 from usbharu/detekt

Detektをhideout-mastodonにも適用するように
This commit is contained in:
usbharu 2024-08-24 00:32:04 +09:00 committed by GitHub
commit f9c10eeb7a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
64 changed files with 382 additions and 333 deletions

View File

@ -46,7 +46,7 @@ jobs:
gradle-home-cache-cleanup: true gradle-home-cache-cleanup: true
- name: Build - name: Build
run: ./hideout-core/gradlew :hideout-core:classes --no-daemon run: ./gradlew classes --no-daemon
unit-test: unit-test:
name: Unit Test name: Unit Test
@ -115,7 +115,7 @@ jobs:
gradle-home-cache-cleanup: true gradle-home-cache-cleanup: true
- name: Build with Gradle - name: Build with Gradle
run: ./hideout-core/gradlew :hideout-core:detektMain run: ./gradlew :hideout-core:detektMain :hideout-mastodon:detektMain
- name: Auto Commit - name: Auto Commit
if: ${{ always() }} if: ${{ always() }}

View File

@ -0,0 +1,3 @@
package dev.usbharu.hideout.core.application.actor
data class SuspendLocalActor(val actorId: Long)

View File

@ -16,22 +16,29 @@
package dev.usbharu.hideout.core.application.actor package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorId 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.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@Service @Service
class SuspendLocalActorApplicationService( class SuspendLocalActorApplicationService(
private val transaction: Transaction, transaction: Transaction,
private val actorRepository: ActorRepository, private val actorRepository: ActorRepository,
) { ) : LocalUserAbstractApplicationService<SuspendLocalActor, Unit>(transaction, logger) {
suspend fun suspend(actorId: Long, executor: ActorId) {
transaction.transaction {
val id = ActorId(actorId)
val actor = actorRepository.findById(id)!! override suspend fun internalExecute(command: SuspendLocalActor, principal: LocalUser) {
val id = ActorId(command.actorId)
val actor =
actorRepository.findById(id) ?: throw IllegalArgumentException("Actor ${command.actorId} not found.")
actor.suspend = true actor.suspend = true
} actorRepository.save(actor)
}
companion object {
private val logger = LoggerFactory.getLogger(SuspendLocalActorApplicationService::class.java)
} }
} }

View File

@ -0,0 +1,3 @@
package dev.usbharu.hideout.core.application.actor
data class UnsuspendLocalActor(val actorId: Long)

View File

@ -16,21 +16,29 @@
package dev.usbharu.hideout.core.application.actor package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.domain.model.actor.ActorId 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.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@Service @Service
class UnsuspendLocalActorApplicationService( class UnsuspendLocalActorApplicationService(
private val transaction: Transaction, transaction: Transaction,
private val actorRepository: ActorRepository, private val actorRepository: ActorRepository,
) { ) : LocalUserAbstractApplicationService<UnsuspendLocalActor, Unit>(transaction, logger) {
suspend fun unsuspend(actorId: Long, executor: Long) {
transaction.transaction { override suspend fun internalExecute(command: UnsuspendLocalActor, principal: LocalUser) {
val findById = actorRepository.findById(ActorId(actorId))!! val findById = actorRepository.findById(ActorId(command.actorId))
?: throw IllegalArgumentException("Actor ${command.actorId} not found.")
findById.suspend = false findById.suspend = false
} actorRepository.save(findById)
}
companion object {
private val logger = LoggerFactory.getLogger(UnsuspendLocalActorApplicationService::class.java)
} }
} }

View File

@ -20,5 +20,3 @@ class RegisterLocalUserSetHomeTimelineSubscriber(
} }
} }
} }
// todo userdetailにdomain event付けて createのイベントで反応させる タイムラインを新しく一つ作って userdetailのhometimelineに紐づけて自分自身をtimleine relationshipに入れる

View File

@ -5,7 +5,6 @@ import dev.usbharu.hideout.core.application.timeline.TimelineAddPostApplicationS
import dev.usbharu.hideout.core.domain.event.post.PostEvent import dev.usbharu.hideout.core.domain.event.post.PostEvent
import dev.usbharu.hideout.core.domain.event.post.PostEventBody import dev.usbharu.hideout.core.domain.event.post.PostEventBody
import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
@Component @Component
@ -18,8 +17,4 @@ class TimelinePostCreateSubscriber(
timelineAddPostApplicationService.execute(AddPost(it.body.getPostId()), Anonymous) timelineAddPostApplicationService.execute(AddPost(it.body.getPostId()), Anonymous)
} }
} }
companion object {
private val logger = LoggerFactory.getLogger(TimelinePostCreateSubscriber::class.java)
}
} }

View File

@ -1,5 +1,6 @@
package dev.usbharu.hideout.core.application.domainevent.subscribers package dev.usbharu.hideout.core.application.domainevent.subscribers
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.timeline.AddTimelineRelationship import dev.usbharu.hideout.core.application.timeline.AddTimelineRelationship
import dev.usbharu.hideout.core.application.timeline.UserAddTimelineRelationshipApplicationService import dev.usbharu.hideout.core.application.timeline.UserAddTimelineRelationshipApplicationService
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEvent import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEvent
@ -23,11 +24,14 @@ class TimelineRelationshipFollowSubscriber(
init { init {
domainEventSubscriber.subscribe<RelationshipEventBody>(RelationshipEvent.FOLLOW.eventName) { domainEventSubscriber.subscribe<RelationshipEventBody>(RelationshipEvent.FOLLOW.eventName) {
val relationship = it.body.getRelationship() val relationship = it.body.getRelationship()
val userDetail = userDetailRepository.findByActorId(relationship.actorId.id) ?: throw Exception() val userDetail = userDetailRepository.findByActorId(relationship.actorId.id)
?: throw InternalServerException("Userdetail ${relationship.actorId} not found by actorid.")
if (userDetail.homeTimelineId == null) { if (userDetail.homeTimelineId == null) {
logger.warn("Home timeline for ${relationship.actorId} is not found") logger.warn("Home timeline for ${relationship.actorId} is not found")
return@subscribe return@subscribe
} }
@Suppress("UnsafeCallOnNullableType")
userAddTimelineRelationshipApplicationService.execute( userAddTimelineRelationshipApplicationService.execute(
AddTimelineRelationship( AddTimelineRelationship(
TimelineRelationship( TimelineRelationship(

View File

@ -23,6 +23,7 @@ class GetLocalInstanceApplicationService(
override suspend fun internalExecute(command: Unit, principal: Principal): Instance { override suspend fun internalExecute(command: Unit, principal: Principal): Instance {
if (cachedInstance != null) { if (cachedInstance != null) {
@Suppress("UnsafeCallOnNullableType")
return cachedInstance!! return cachedInstance!!
} }
@ -32,6 +33,7 @@ class GetLocalInstanceApplicationService(
) )
cachedInstance = Instance.of(instance) cachedInstance = Instance.of(instance)
@Suppress("UnsafeCallOnNullableType")
return cachedInstance!! return cachedInstance!!
} }

View File

@ -17,14 +17,14 @@ data class ActorDetail(
companion object { companion object {
fun of(actor: Actor, iconMedia: Media?): ActorDetail { fun of(actor: Actor, iconMedia: Media?): ActorDetail {
return ActorDetail( return ActorDetail(
actor.id.id, actorId = actor.id.id,
actor.instance.instanceId, instanceId = actor.instance.instanceId,
actor.name.name, name = actor.name.name,
actor.domain.domain, domain = actor.domain.domain,
actor.screenName.screenName, screenName = actor.screenName.screenName,
actor.url, url = actor.url,
actor.locked, locked = actor.locked,
iconMedia?.url icon = iconMedia?.url
) )
} }
} }

View File

@ -16,6 +16,7 @@
package dev.usbharu.hideout.core.application.post package dev.usbharu.hideout.core.application.post
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.application.exception.PermissionDeniedException import dev.usbharu.hideout.core.application.exception.PermissionDeniedException
import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService
import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.application.shared.Transaction
@ -34,11 +35,13 @@ class DeleteLocalPostApplicationService(
) : LocalUserAbstractApplicationService<DeleteLocalPost, Unit>(transaction, logger) { ) : LocalUserAbstractApplicationService<DeleteLocalPost, Unit>(transaction, logger) {
override suspend fun internalExecute(command: DeleteLocalPost, principal: LocalUser) { override suspend fun internalExecute(command: DeleteLocalPost, principal: LocalUser) {
val findById = postRepository.findById(PostId(command.postId))!! val findById = postRepository.findById(PostId(command.postId))
?: throw IllegalArgumentException("Post ${command.postId} not found.")
if (findById.actorId != principal.actorId) { if (findById.actorId != principal.actorId) {
throw PermissionDeniedException() throw PermissionDeniedException()
} }
val actor = actorRepository.findById(principal.actorId)!! val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.")
findById.delete(actor) findById.delete(actor)
postRepository.save(findById) postRepository.save(findById)
} }

View File

@ -39,13 +39,13 @@ class GetPostDetailApplicationService(
val mediaList = mediaRepository.findByIds(post.mediaIds) val mediaList = mediaRepository.findByIds(post.mediaIds)
return PostDetail.of( return PostDetail.of(
post, post = post,
actor, actor = actor,
iconMedia, iconMedia = iconMedia,
mediaList, mediaList = mediaList,
post.replyId?.let { fetchChild(it, actor, iconMedia, principal) }, reply = post.replyId?.let { fetchChild(it, actor, iconMedia, principal) },
post.repostId?.let { fetchChild(it, actor, iconMedia, principal) }, repost = post.repostId?.let { fetchChild(it, actor, iconMedia, principal) },
post.moveTo?.let { fetchChild(it, actor, iconMedia, principal) }, moveTo = post.moveTo?.let { fetchChild(it, actor, iconMedia, principal) },
) )
} }

View File

@ -26,6 +26,7 @@ data class PostDetail(
val moveTo: PostDetail? val moveTo: PostDetail?
) { ) {
companion object { companion object {
@Suppress("LongParameterList")
fun of( fun of(
post: Post, post: Post,
actor: Actor, actor: Actor,

View File

@ -41,7 +41,7 @@ class UserRejectFollowRequestApplicationService(
val targetId = ActorId(command.sourceActorId) val targetId = ActorId(command.sourceActorId)
val relationship = relationshipRepository.findByActorIdAndTargetId(targetId, actor.id) val relationship = relationshipRepository.findByActorIdAndTargetId(targetId, actor.id)
?: throw Exception("Follow request not found") ?: throw IllegalArgumentException("Follow request not found")
relationship.rejectFollowRequest() relationship.rejectFollowRequest()

View File

@ -35,10 +35,6 @@ class UserUnmuteApplicationService(
private val actorRepository: ActorRepository, private val actorRepository: ActorRepository,
) : ) :
LocalUserAbstractApplicationService<Unmute, Unit>(transaction, logger) { LocalUserAbstractApplicationService<Unmute, Unit>(transaction, logger) {
companion object {
private val logger = LoggerFactory.getLogger(UserBlockApplicationService::class.java)
}
override suspend fun internalExecute(command: Unmute, principal: LocalUser) { override suspend fun internalExecute(command: Unmute, principal: LocalUser) {
val actor = actorRepository.findById(principal.actorId) val actor = actorRepository.findById(principal.actorId)
?: throw InternalServerException("Actor ${principal.actorId} not found.") ?: throw InternalServerException("Actor ${principal.actorId} not found.")
@ -53,4 +49,8 @@ class UserUnmuteApplicationService(
relationshipRepository.save(relationship) relationshipRepository.save(relationship)
} }
companion object {
private val logger = LoggerFactory.getLogger(UserBlockApplicationService::class.java)
}
} }

View File

@ -35,7 +35,7 @@ abstract class AbstractApplicationService<T : Any, R>(
} catch (e: CancellationException) { } catch (e: CancellationException) {
logger.debug("Coroutine canceled", e) logger.debug("Coroutine canceled", e)
throw e throw e
} catch (e: Exception) { } catch (@Suppress("TooGenericExceptionCaught") e: Exception) {
logger.warn("Command execution error", e) logger.warn("Command execution error", e)
throw e throw e
} }

View File

@ -42,6 +42,7 @@ class ReadTimelineApplicationService(
val postDetailList = timeline.map { val postDetailList = timeline.map {
val reply = if (it.replyPost != null) { val reply = if (it.replyPost != null) {
@Suppress("UnsafeCallOnNullableType")
PostDetail.of( PostDetail.of(
it.replyPost, it.replyPost,
it.replyPostActor!!, it.replyPostActor!!,
@ -53,6 +54,7 @@ class ReadTimelineApplicationService(
} }
val repost = if (it.repostPost != null) { val repost = if (it.repostPost != null) {
@Suppress("UnsafeCallOnNullableType")
PostDetail.of( PostDetail.of(
it.repostPost, it.repostPost,
it.repostPostActor!!, it.repostPostActor!!,
@ -64,12 +66,12 @@ class ReadTimelineApplicationService(
} }
PostDetail.of( PostDetail.of(
it.post, post = it.post,
it.postActor, actor = it.postActor,
it.postActorIconMedia, iconMedia = it.postActorIconMedia,
it.postMedias, mediaList = it.postMedias,
reply, reply = reply,
repost repost = repost
) )
} }

View File

@ -34,7 +34,7 @@ class PostDomainEventFactory(private val post: Post, private val actor: Actor? =
class PostEventBody(post: PostId, actor: ActorId?) : DomainEventBody(mapOf("post" to post, "actor" to actor)) { class PostEventBody(post: PostId, actor: ActorId?) : DomainEventBody(mapOf("post" to post, "actor" to actor)) {
fun getPostId(): PostId = toMap()["post"] as PostId fun getPostId(): PostId = toMap()["post"] as PostId
fun getActorId(): ActorId? = toMap()["actor"] as ActorId? fun getActorId(): ActorId? = toMap()["actor"] as? ActorId
} }
enum class PostEvent(val eventName: String) { enum class PostEvent(val eventName: String) {

View File

@ -31,9 +31,7 @@ class RelationshipEventBody(
relationship: Relationship, relationship: Relationship,
override val principal: Principal override val principal: Principal
) : DomainEventBody(mapOf("relationship" to relationship), principal) { ) : DomainEventBody(mapOf("relationship" to relationship), principal) {
fun getRelationship(): Relationship { fun getRelationship(): Relationship = toMap()["relationship"] as Relationship
return toMap()["relationship"] as Relationship
}
} }
enum class RelationshipEvent(val eventName: String) { enum class RelationshipEvent(val eventName: String) {

View File

@ -11,9 +11,7 @@ class TimelineEventFactory(private val timeline: Timeline) {
} }
class TimelineEventBody(timelineId: TimelineId) : DomainEventBody(mapOf("timeline" to timelineId)) { class TimelineEventBody(timelineId: TimelineId) : DomainEventBody(mapOf("timeline" to timelineId)) {
fun getTimelineId(): TimelineId { fun getTimelineId(): TimelineId = toMap()["timeline"] as TimelineId
return toMap()["timeline"] as TimelineId
}
} }
enum class TimelineEvent(val eventName: String) { enum class TimelineEvent(val eventName: String) {

View File

@ -19,9 +19,7 @@ class UserDetailEventBody(userDetail: UserDetailId) : DomainEventBody(
"userDetail" to userDetail "userDetail" to userDetail
) )
) { ) {
fun getUserDetail(): UserDetailId { fun getUserDetail(): UserDetailId = toMap()["userDetail"] as UserDetailId
return toMap()["userDetail"] as UserDetailId
}
} }
enum class UserDetailEvent(val eventName: String) { enum class UserDetailEvent(val eventName: String) {

View File

@ -65,9 +65,7 @@ class Filter(
return id == other.id return id == other.id
} }
override fun hashCode(): Int { override fun hashCode(): Int = id.hashCode()
return id.hashCode()
}
companion object { companion object {
fun isAllow(user: UserDetail, action: Action, resource: Filter): Boolean { fun isAllow(user: UserDetail, action: Action, resource: Filter): Boolean {

View File

@ -19,6 +19,7 @@ package dev.usbharu.hideout.core.domain.model.media
import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.actor.ActorId
import java.net.URI import java.net.URI
@Suppress("LongParameterList")
class Media( class Media(
val id: MediaId, val id: MediaId,
val name: MediaName, val name: MediaName,
@ -47,9 +48,7 @@ class Media(
return id == other.id return id == other.id
} }
override fun hashCode(): Int { override fun hashCode(): Int = id.hashCode()
return id.hashCode()
}
override fun toString(): String { override fun toString(): String {
return "Media(" + return "Media(" +

View File

@ -201,7 +201,7 @@ class Post(
var moveTo = moveTo var moveTo = moveTo
private set private set
fun moveTo(moveTo: PostId, actor: Actor) { fun moveTo(moveTo: PostId) {
require(this.moveTo == null) require(this.moveTo == null)
this.moveTo = moveTo this.moveTo = moveTo
} }

View File

@ -27,6 +27,8 @@ interface PostRepository {
suspend fun findAllById(ids: List<PostId>): List<Post> suspend fun findAllById(ids: List<PostId>): List<Post>
suspend fun findByActorId(id: ActorId, page: Page? = null): PaginationList<Post, PostId> suspend fun findByActorId(id: ActorId, page: Page? = null): PaginationList<Post, PostId>
suspend fun delete(post: Post) suspend fun delete(post: Post)
@Suppress("FunctionMaxLength")
suspend fun findByActorIdAndVisibilityInList( suspend fun findByActorIdAndVisibilityInList(
actorId: ActorId, actorId: ActorId,
visibilityList: List<Visibility>, visibilityList: List<Visibility>,

View File

@ -18,6 +18,7 @@ package dev.usbharu.hideout.core.domain.model.relationship
import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.actor.ActorId
@Suppress("FunctionMaxLength")
interface RelationshipRepository { interface RelationshipRepository {
suspend fun save(relationship: Relationship): Relationship suspend fun save(relationship: Relationship): Relationship
suspend fun delete(relationship: Relationship) suspend fun delete(relationship: Relationship)

View File

@ -4,7 +4,5 @@ data class Acct(
val userpart: String, val userpart: String,
val host: String val host: String
) { ) {
override fun toString(): String { override fun toString(): String = "acct:$userpart@$host"
return "acct:$userpart@$host"
}
} }

View File

@ -32,6 +32,7 @@ data class TimelineObjectDetail(
val warnFilter: List<TimelineObjectWarnFilter> val warnFilter: List<TimelineObjectWarnFilter>
) { ) {
companion object { companion object {
@Suppress("LongParameterList")
fun of( fun of(
timelineObject: TimelineObject, timelineObject: TimelineObject,
timelineUserDetail: UserDetail, timelineUserDetail: UserDetail,

View File

@ -16,6 +16,9 @@ class Timeline(
var visibility = visibility var visibility = visibility
private set private set
var name = name
private set
fun setVisibility(visibility: TimelineVisibility, userDetail: UserDetail) { fun setVisibility(visibility: TimelineVisibility, userDetail: UserDetail) {
check(isSystem.not()) check(isSystem.not())
require(userDetailId == userDetail.id) require(userDetailId == userDetail.id)
@ -23,9 +26,6 @@ class Timeline(
addDomainEvent(TimelineEventFactory(this).createEvent(TimelineEvent.CHANGE_VISIBILITY)) addDomainEvent(TimelineEventFactory(this).createEvent(TimelineEvent.CHANGE_VISIBILITY))
} }
var name = name
private set
companion object { companion object {
fun create( fun create(
id: TimelineId, id: TimelineId,

View File

@ -13,6 +13,7 @@ import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
import java.time.Instant import java.time.Instant
@Suppress("LongParameterList")
class TimelineObject( class TimelineObject(
val id: TimelineObjectId, val id: TimelineObjectId,
val userDetailId: UserDetailId, val userDetailId: UserDetailId,
@ -59,7 +60,10 @@ class TimelineObject(
emojiIds = post.emojiIds.toList() emojiIds = post.emojiIds.toList()
lastUpdatedAt = Instant.now() lastUpdatedAt = Instant.now()
isPureRepost = isPureRepost =
post.repostId != null && post.replyId == null && post.text.isEmpty() && post.overview?.overview.isNullOrEmpty() post.repostId != null &&
post.replyId == null &&
post.text.isEmpty() &&
post.overview?.overview.isNullOrEmpty()
warnFilters = filterResults.map { TimelineObjectWarnFilter(it.filter.id, it.matchedKeyword) } warnFilters = filterResults.map { TimelineObjectWarnFilter(it.filter.id, it.matchedKeyword) }
} }
@ -102,6 +106,7 @@ class TimelineObject(
) )
} }
@Suppress("LongParameterList")
fun create( fun create(
timelineObjectId: TimelineObjectId, timelineObjectId: TimelineObjectId,
timeline: Timeline, timeline: Timeline,

View File

@ -44,6 +44,7 @@ class UserDetail(
override fun hashCode(): Int = id.hashCode() override fun hashCode(): Int = id.hashCode()
companion object { companion object {
@Suppress("LongParameterList")
fun create( fun create(
id: UserDetailId, id: UserDetailId,
actorId: ActorId, actorId: ActorId,

View File

@ -14,6 +14,9 @@ import org.springframework.stereotype.Repository
@Repository @Repository
class ExposedPrincipalQueryService : PrincipalQueryService, AbstractRepository() { class ExposedPrincipalQueryService : PrincipalQueryService, AbstractRepository() {
override val logger: Logger
get() = Companion.logger
override suspend fun findByUserDetailId(userDetailId: UserDetailId): PrincipalDTO { override suspend fun findByUserDetailId(userDetailId: UserDetailId): PrincipalDTO {
return query { return query {
UserDetails.leftJoin(Actors).selectAll().where { UserDetails.id eq userDetailId.id }.single() UserDetails.leftJoin(Actors).selectAll().where { UserDetails.id eq userDetailId.id }.single()
@ -28,9 +31,6 @@ class ExposedPrincipalQueryService : PrincipalQueryService, AbstractRepository()
} }
} }
override val logger: Logger
get() = Companion.logger
companion object { companion object {
private val logger: Logger = LoggerFactory.getLogger(ExposedPrincipalQueryService::class.java) private val logger: Logger = LoggerFactory.getLogger(ExposedPrincipalQueryService::class.java)
} }

View File

@ -152,8 +152,8 @@ class ExposedPostRepository(
this[PostsVisibleActors.actorId] = it.second this[PostsVisibleActors.actorId] = it.second
} }
onComplete { onComplete {
posts.forEach { posts.forEach { post: Post ->
update(it) update(post)
} }
} }
} }

View File

@ -15,6 +15,9 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu
TimelineRepository, TimelineRepository,
AbstractRepository(), AbstractRepository(),
DomainEventPublishableRepository<Timeline> { DomainEventPublishableRepository<Timeline> {
override val logger: Logger
get() = Companion.logger
override suspend fun save(timeline: Timeline): Timeline { override suspend fun save(timeline: Timeline): Timeline {
query { query {
Timelines.insert { Timelines.insert {
@ -58,9 +61,6 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu
companion object { companion object {
private val logger = LoggerFactory.getLogger(ExposedTimelineRepository::class.java.name) private val logger = LoggerFactory.getLogger(ExposedTimelineRepository::class.java.name)
} }
override val logger: Logger
get() = Companion.logger
} }
fun ResultRow.toTimeline(): Timeline { fun ResultRow.toTimeline(): Timeline {

View File

@ -109,12 +109,12 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub
} }
private fun userDetail(it: ResultRow) = UserDetail( private fun userDetail(it: ResultRow) = UserDetail(
UserDetailId(it[UserDetails.id]), id = UserDetailId(it[UserDetails.id]),
ActorId(it[UserDetails.actorId]), actorId = ActorId(it[UserDetails.actorId]),
UserDetailHashedPassword(it[UserDetails.password]), password = UserDetailHashedPassword(it[UserDetails.password]),
it[UserDetails.autoAcceptFolloweeFollowRequest], autoAcceptFolloweeFollowRequest = it[UserDetails.autoAcceptFolloweeFollowRequest],
it[UserDetails.lastMigration], lastMigration = it[UserDetails.lastMigration],
it[UserDetails.homeTimelineId]?.let { it1 -> TimelineId(it1) } homeTimelineId = it[UserDetails.homeTimelineId]?.let { it1 -> TimelineId(it1) }
) )
companion object { companion object {

View File

@ -1,5 +1,6 @@
package dev.usbharu.hideout.core.infrastructure.media.image package dev.usbharu.hideout.core.infrastructure.media.image
import dev.usbharu.hideout.core.application.exception.InternalServerException
import dev.usbharu.hideout.core.config.ImageIOImageConfig import dev.usbharu.hideout.core.config.ImageIOImageConfig
import dev.usbharu.hideout.core.domain.model.media.FileType import dev.usbharu.hideout.core.domain.model.media.FileType
import dev.usbharu.hideout.core.domain.model.media.MimeType import dev.usbharu.hideout.core.domain.model.media.MimeType
@ -59,7 +60,7 @@ class ImageIOImageProcessor(
tempFile.outputStream().use { tempFile.outputStream().use {
if (ImageIO.write(bufferedImage, imageIOImageConfig.format, it).not()) { if (ImageIO.write(bufferedImage, imageIOImageConfig.format, it).not()) {
logger.warn("Failed to save a temporary file. type: {} ,path: {}", imageIOImageConfig.format, tempFile) logger.warn("Failed to save a temporary file. type: {} ,path: {}", imageIOImageConfig.format, tempFile)
throw Exception("Failed to save a temporary file.") throw InternalServerException("Failed to save a temporary file.")
} }
} }

View File

@ -46,9 +46,8 @@ class MongoInternalTimelineObjectRepository(
return timelineObjectList return timelineObjectList
} }
override suspend fun findByPostId(postId: PostId): List<TimelineObject> { override suspend fun findByPostId(postId: PostId): List<TimelineObject> =
return springDataMongoTimelineObjectRepository.findByPostId(postId.id).map { it.toTimelineObject() }.toList() springDataMongoTimelineObjectRepository.findByPostId(postId.id).map { it.toTimelineObject() }.toList()
}
override suspend fun deleteByPostId(postId: PostId) { override suspend fun deleteByPostId(postId: PostId) {
springDataMongoTimelineObjectRepository.deleteByPostId(postId.id) springDataMongoTimelineObjectRepository.deleteByPostId(postId.id)
@ -139,48 +138,48 @@ data class SpringDataMongoTimelineObject(
fun toTimelineObject(): TimelineObject { fun toTimelineObject(): TimelineObject {
return TimelineObject( return TimelineObject(
TimelineObjectId(id), id = TimelineObjectId(id),
UserDetailId(userDetailId), userDetailId = UserDetailId(userDetailId),
TimelineId(timelineId), timelineId = TimelineId(timelineId),
PostId(postId), postId = PostId(postId),
ActorId(postActorId), postActorId = ActorId(postActorId),
Instant.ofEpochSecond(postCreatedAt), postCreatedAt = Instant.ofEpochSecond(postCreatedAt),
replyId?.let { PostId(it) }, replyId = replyId?.let { PostId(it) },
replyActorId?.let { ActorId(it) }, replyActorId = replyActorId?.let { ActorId(it) },
repostId?.let { PostId(it) }, repostId = repostId?.let { PostId(it) },
repostActorId?.let { ActorId(it) }, repostActorId = repostActorId?.let { ActorId(it) },
visibility, visibility = visibility,
isPureRepost, isPureRepost = isPureRepost,
mediaIds.map { MediaId(it) }, mediaIds = mediaIds.map { MediaId(it) },
emojiIds.map { EmojiId(it) }, emojiIds = emojiIds.map { EmojiId(it) },
visibleActors.map { ActorId(it) }, visibleActors = visibleActors.map { ActorId(it) },
hasMediaInRepost, hasMediaInRepost = hasMediaInRepost,
Instant.ofEpochSecond(lastUpdatedAt), lastUpdatedAt = Instant.ofEpochSecond(lastUpdatedAt),
warnFilters.map { it.toTimelineObjectWarnFilter() } warnFilters = warnFilters.map { it.toTimelineObjectWarnFilter() }
) )
} }
companion object { companion object {
fun of(timelineObject: TimelineObject): SpringDataMongoTimelineObject { fun of(timelineObject: TimelineObject): SpringDataMongoTimelineObject {
return SpringDataMongoTimelineObject( return SpringDataMongoTimelineObject(
timelineObject.id.value, id = timelineObject.id.value,
timelineObject.userDetailId.id, userDetailId = timelineObject.userDetailId.id,
timelineObject.timelineId.value, timelineId = timelineObject.timelineId.value,
timelineObject.postId.id, postId = timelineObject.postId.id,
timelineObject.postActorId.id, postActorId = timelineObject.postActorId.id,
timelineObject.postCreatedAt.epochSecond, postCreatedAt = timelineObject.postCreatedAt.epochSecond,
timelineObject.replyId?.id, replyId = timelineObject.replyId?.id,
timelineObject.replyActorId?.id, replyActorId = timelineObject.replyActorId?.id,
timelineObject.repostId?.id, repostId = timelineObject.repostId?.id,
timelineObject.repostActorId?.id, repostActorId = timelineObject.repostActorId?.id,
timelineObject.visibility, visibility = timelineObject.visibility,
timelineObject.isPureRepost, isPureRepost = timelineObject.isPureRepost,
timelineObject.mediaIds.map { it.id }, mediaIds = timelineObject.mediaIds.map { it.id },
timelineObject.emojiIds.map { it.emojiId }, emojiIds = timelineObject.emojiIds.map { it.emojiId },
timelineObject.visibleActors.map { it.id }, visibleActors = timelineObject.visibleActors.map { it.id },
timelineObject.hasMediaInRepost, hasMediaInRepost = timelineObject.hasMediaInRepost,
timelineObject.lastUpdatedAt.epochSecond, lastUpdatedAt = timelineObject.lastUpdatedAt.epochSecond,
timelineObject.warnFilters.map { SpringDataMongoTimelineObjectWarnFilter.of(it) } warnFilters = timelineObject.warnFilters.map { SpringDataMongoTimelineObjectWarnFilter.of(it) }
) )
} }
} }
@ -208,6 +207,7 @@ data class SpringDataMongoTimelineObjectWarnFilter(
} }
} }
@Suppress("FunctionMaxLength")
interface SpringDataMongoTimelineObjectRepository : CoroutineCrudRepository<SpringDataMongoTimelineObject, Long> { interface SpringDataMongoTimelineObjectRepository : CoroutineCrudRepository<SpringDataMongoTimelineObject, Long> {
fun findByPostId(postId: Long): Flow<SpringDataMongoTimelineObject> fun findByPostId(postId: Long): Flow<SpringDataMongoTimelineObject>
@ -217,8 +217,6 @@ interface SpringDataMongoTimelineObjectRepository : CoroutineCrudRepository<Spri
suspend fun deleteByTimelineId(timelineId: Long) suspend fun deleteByTimelineId(timelineId: Long)
suspend fun findByTimelineId(timelineId: TimelineId): Flow<SpringDataMongoTimelineObject>
suspend fun findFirstByTimelineIdAndPostIdGreaterThanOrderByIdAsc( suspend fun findFirstByTimelineIdAndPostIdGreaterThanOrderByIdAsc(
timelineId: Long, timelineId: Long,
postId: Long postId: Long

View File

@ -23,7 +23,7 @@ class SpringFrameworkDomainEventSubscriber : DomainEventSubscriber {
map[domainEvent.name]?.forEach { map[domainEvent.name]?.forEach {
try { try {
it.invoke(domainEvent) it.invoke(domainEvent)
} catch (e: Exception) { } catch (@Suppress("TooGenericExceptionCaught") e: Exception) {
logger.error("", e) logger.error("", e)
} }
} }

View File

@ -58,7 +58,9 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
if (timeline.visibility == TimelineVisibility.PUBLIC && post.visibility != Visibility.PUBLIC) { if (timeline.visibility == TimelineVisibility.PUBLIC && post.visibility != Visibility.PUBLIC) {
return null return null
} }
if (timeline.visibility == TimelineVisibility.UNLISTED && (post.visibility != Visibility.PUBLIC || post.visibility != Visibility.UNLISTED)) { if (timeline.visibility == TimelineVisibility.UNLISTED &&
(post.visibility != Visibility.PUBLIC || post.visibility != Visibility.UNLISTED)
) {
return null return null
} }
@ -68,21 +70,21 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
if (repost != null) { if (repost != null) {
return TimelineObject.create( return TimelineObject.create(
TimelineObjectId(idGenerateService.generateId()), timelineObjectId = TimelineObjectId(idGenerateService.generateId()),
timeline, timeline = timeline,
post, post = post,
replyActorId, replyActorId = replyActorId,
repost, repost = repost,
applyFilters.filterResults filterResults = applyFilters.filterResults
) )
} }
return TimelineObject.create( return TimelineObject.create(
TimelineObjectId(idGenerateService.generateId()), timelineObjectId = TimelineObjectId(idGenerateService.generateId()),
timeline, timeline = timeline,
post, post = post,
replyActorId, replyActorId = replyActorId,
applyFilters.filterResults filterResults = applyFilters.filterResults
) )
} }
@ -106,7 +108,10 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
protected abstract suspend fun removeTimelineObject(timelineId: TimelineId) protected abstract suspend fun removeTimelineObject(timelineId: TimelineId)
protected abstract suspend fun getPostsByTimelineRelationshipList(timelineRelationshipList: List<TimelineRelationship>): List<Post> @Suppress("FunctionMaxLength")
protected abstract suspend fun getPostsByTimelineRelationshipList(
timelineRelationshipList: List<TimelineRelationship>
): List<Post>
protected abstract suspend fun getPostsByPostId(postIds: List<PostId>, principal: Principal): List<Post> protected abstract suspend fun getPostsByPostId(postIds: List<PostId>, principal: Principal): List<Post>
@ -116,6 +121,7 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
page: Page? page: Page?
): PaginationList<TimelineObject, PostId> ): PaginationList<TimelineObject, PostId>
@Suppress("RedundantHigherOrderMapUsage") // if式に対応していないため
override suspend fun updatePost(post: Post) { override suspend fun updatePost(post: Post) {
val timelineObjectByPostId = getTimelineObjectByPostId(post.id) val timelineObjectByPostId = getTimelineObjectByPostId(post.id)
@ -236,16 +242,19 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
val actors = val actors =
getActors( getActors(
timelineObjectList.map { timelineObjectList.map { it.postActorId } +
it.postActorId timelineObjectList.mapNotNull { it.repostActorId } +
} + timelineObjectList.mapNotNull { it.repostActorId } + timelineObjectList.mapNotNull { it.replyActorId } timelineObjectList.mapNotNull { it.replyActorId }
) )
val postMap = posts.associate { post -> val postMap = posts.associate { post ->
post.id to applyFilters(post, newerFilters) post.id to applyFilters(post, newerFilters)
} }
val mediaMap = getMedias(posts.flatMap { it.mediaIds } + actors.mapNotNull { it.value.icon }) val mediaMap = getMedias(
posts.flatMap { it.mediaIds } +
actors.mapNotNull { it.value.icon }
)
return PaginationList( return PaginationList(
timelineObjectList.mapNotNull<TimelineObject, TimelineObjectDetail> { timelineObjectList.mapNotNull<TimelineObject, TimelineObjectDetail> {
@ -274,10 +283,10 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe
repostPostMedias = repostMedias, repostPostMedias = repostMedias,
repostPostActor = repostActor, repostPostActor = repostActor,
repostPostActorIconMedia = mediaMap[repostActor?.icon], repostPostActorIconMedia = mediaMap[repostActor?.icon],
warnFilter = it.warnFilters + post.filterResults.map { warnFilter = it.warnFilters + post.filterResults.map { filterResult ->
TimelineObjectWarnFilter( TimelineObjectWarnFilter(
it.filter.id, filterResult.filter.id,
it.matchedKeyword filterResult.matchedKeyword
) )
} }
) )

View File

@ -36,6 +36,7 @@ import org.springframework.stereotype.Component
import java.time.Instant import java.time.Instant
@Component @Component
@Suppress("LongParameterList")
open class DefaultTimelineStore( open class DefaultTimelineStore(
private val timelineRepository: TimelineRepository, private val timelineRepository: TimelineRepository,
private val timelineRelationshipRepository: TimelineRelationshipRepository, private val timelineRelationshipRepository: TimelineRelationshipRepository,
@ -59,25 +60,18 @@ open class DefaultTimelineStore(
) )
} }
override suspend fun getTimeline(timelineId: TimelineId): Timeline? { override suspend fun getTimeline(timelineId: TimelineId): Timeline? = timelineRepository.findById(timelineId)
return timelineRepository.findById(timelineId)
}
override suspend fun getFilters(userDetailId: UserDetailId): List<Filter> { override suspend fun getFilters(userDetailId: UserDetailId): List<Filter> =
return filterRepository.findByUserDetailId(userDetailId) filterRepository.findByUserDetailId(userDetailId)
}
override suspend fun getNewerFilters(userDetailId: UserDetailId, lastUpdateAt: Instant): List<Filter> { override suspend fun getNewerFilters(userDetailId: UserDetailId, lastUpdateAt: Instant): List<Filter> =
return filterRepository.findByUserDetailId(userDetailId) filterRepository.findByUserDetailId(userDetailId)
}
override suspend fun applyFilters(post: Post, filters: List<Filter>): FilteredPost { override suspend fun applyFilters(post: Post, filters: List<Filter>): FilteredPost =
return filterDomainService.apply(post, FilterContext.HOME, filters) filterDomainService.apply(post, FilterContext.HOME, filters)
}
override suspend fun getPost(postId: PostId): Post? { override suspend fun getPost(postId: PostId): Post? = postRepository.findById(postId)
return postRepository.findById(postId)
}
override suspend fun insertTimelineObject(timelineObjectList: List<TimelineObject>) { override suspend fun insertTimelineObject(timelineObjectList: List<TimelineObject>) {
internalTimelineObjectRepository.saveAll(timelineObjectList) internalTimelineObjectRepository.saveAll(timelineObjectList)
@ -87,9 +81,8 @@ open class DefaultTimelineStore(
internalTimelineObjectRepository.saveAll(timelineObjectList) internalTimelineObjectRepository.saveAll(timelineObjectList)
} }
override suspend fun getTimelineObjectByPostId(postId: PostId): List<TimelineObject> { override suspend fun getTimelineObjectByPostId(postId: PostId): List<TimelineObject> =
return internalTimelineObjectRepository.findByPostId(postId) internalTimelineObjectRepository.findByPostId(postId)
}
override suspend fun removeTimelineObject(postId: PostId) { override suspend fun removeTimelineObject(postId: PostId) {
internalTimelineObjectRepository.deleteByPostId(postId) internalTimelineObjectRepository.deleteByPostId(postId)
@ -103,9 +96,8 @@ open class DefaultTimelineStore(
internalTimelineObjectRepository.deleteByTimelineId(timelineId) internalTimelineObjectRepository.deleteByTimelineId(timelineId)
} }
override suspend fun getPostsByTimelineRelationshipList(timelineRelationshipList: List<TimelineRelationship>): List<Post> { override suspend fun getPostsByTimelineRelationshipList(timelineRelationshipList: List<TimelineRelationship>): List<Post> =
return timelineRelationshipList.flatMap { getActorPost(it.actorId, visibilities(it)) } timelineRelationshipList.flatMap { getActorPost(it.actorId, visibilities(it)) }
}
override suspend fun getPostsByPostId(postIds: List<PostId>, principal: Principal): List<Post> { override suspend fun getPostsByPostId(postIds: List<PostId>, principal: Principal): List<Post> {
val findAllById = postRepository.findAllById(postIds) val findAllById = postRepository.findAllById(postIds)
@ -136,6 +128,7 @@ open class DefaultTimelineStore(
) )
} }
@Suppress("UnsafeCallOnNullableType")
override suspend fun getNextPaging( override suspend fun getNextPaging(
timelineId: TimelineId, timelineId: TimelineId,
page: Page? page: Page?
@ -158,15 +151,12 @@ open class DefaultTimelineStore(
return PaginationList(emptyList(), page?.maxId?.let { PostId(it) }, page?.minId?.let { PostId(it) }) return PaginationList(emptyList(), page?.maxId?.let { PostId(it) }, page?.minId?.let { PostId(it) })
} }
override suspend fun getActors(actorIds: List<ActorId>): Map<ActorId, Actor> { override suspend fun getActors(actorIds: List<ActorId>): Map<ActorId, Actor> =
return actorRepository.findAllById(actorIds).associateBy { it.id } actorRepository.findAllById(actorIds).associateBy { it.id }
}
override suspend fun getMedias(mediaIds: List<MediaId>): Map<MediaId, Media> { override suspend fun getMedias(mediaIds: List<MediaId>): Map<MediaId, Media> =
return mediaRepository.findByIds(mediaIds).associateBy { it.id } mediaRepository.findByIds(mediaIds).associateBy { it.id }
}
override suspend fun getUserDetails(userDetailIdList: List<UserDetailId>): Map<UserDetailId, UserDetail> { override suspend fun getUserDetails(userDetailIdList: List<UserDetailId>): Map<UserDetailId, UserDetail> =
return userDetailRepository.findAllById(userDetailIdList).associateBy { it.id } userDetailRepository.findAllById(userDetailIdList).associateBy { it.id }
}
} }

View File

@ -30,6 +30,8 @@ class PublishController(
} }
val instance = getLocalInstanceApplicationService.execute(Unit, principal) val instance = getLocalInstanceApplicationService.execute(Unit, principal)
@Suppress("UnsafeCallOnNullableType")
val userDetail = getUserDetailApplicationService.execute(GetUserDetail(principal.userDetailId!!.id), principal) val userDetail = getUserDetailApplicationService.execute(GetUserDetail(principal.userDetailId!!.id), principal)
model.addAttribute("instance", instance) model.addAttribute("instance", instance)
model.addAttribute("user", userDetail) model.addAttribute("user", userDetail)

View File

@ -32,7 +32,8 @@ class TimelineController(
?: throw InternalServerException("UserDetail not found.") ?: throw InternalServerException("UserDetail not found.")
} }
val homeTimelineId = userDetail.homeTimelineId!! val homeTimelineId =
userDetail.homeTimelineId ?: throw InternalServerException("HomeTimeline ${userDetail.id} is null.")
val execute = readTimelineApplicationService.execute( val execute = readTimelineApplicationService.execute(
ReadTimeline( ReadTimeline(
timelineId = homeTimelineId.value, timelineId = homeTimelineId.value,

View File

@ -677,7 +677,7 @@ class PostTest {
val actor = TestActorFactory.create(post.actorId.id) val actor = TestActorFactory.create(post.actorId.id)
assertThrows<IllegalArgumentException> { assertThrows<IllegalArgumentException> {
post.moveTo(PostId(2), actor) post.moveTo(PostId(2))
} }
} }
@ -687,7 +687,7 @@ class PostTest {
val actor = TestActorFactory.create(post.actorId.id) val actor = TestActorFactory.create(post.actorId.id)
assertDoesNotThrow { assertDoesNotThrow {
post.moveTo(PostId(2), actor) post.moveTo(PostId(2))
} }
assertEquals(PostId(2), post.moveTo) assertEquals(PostId(2), post.moveTo)

View File

@ -5,6 +5,7 @@ plugins {
alias(libs.plugins.openapi.generator) alias(libs.plugins.openapi.generator)
alias(libs.plugins.spring.boot) alias(libs.plugins.spring.boot)
alias(libs.plugins.kotlin.spring) alias(libs.plugins.kotlin.spring)
alias(libs.plugins.detekt)
} }
@ -48,6 +49,7 @@ configurations {
} }
dependencies { dependencies {
detektPlugins(libs.detekt.formatting)
implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-security") implementation("org.springframework.boot:spring-boot-starter-security")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
@ -115,3 +117,35 @@ sourceSets.main {
) )
} }
detekt {
parallel = true
config.setFrom(files("../detekt.yml"))
buildUponDefaultConfig = true
basePath = "${rootDir.absolutePath}/src/main/kotlin"
autoCorrect = true
}
configurations.matching { it.name == "detekt" }.all {
resolutionStrategy.eachDependency {
if (requested.group == "org.jetbrains.kotlin") {
useVersion(io.gitlab.arturbosch.detekt.getSupportedKotlinVersion())
}
}
}
tasks.withType<io.gitlab.arturbosch.detekt.Detekt> {
exclude("**/generated/**")
doFirst {
}
setSource("src/main/kotlin")
exclude("build/")
}
tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
exclude("**/org/koin/ksp/generated/**", "**/generated/**")
}
tasks.withType<io.gitlab.arturbosch.detekt.DetektCreateBaselineTask>().configureEach {
exclude("**/org/koin/ksp/generated/**", "**/generated/**")
}

View File

@ -31,7 +31,8 @@ class GetAccountApplicationService(private val accountQueryService: AccountQuery
logger logger
) { ) {
override suspend fun internalExecute(command: GetAccount, principal: LocalUser): Account { override suspend fun internalExecute(command: GetAccount, principal: LocalUser): Account {
return accountQueryService.findById(command.accountId.toLong()) ?: throw Exception("Account not found") return accountQueryService.findById(command.accountId.toLong())
?: throw IllegalArgumentException("Account ${command.accountId} not found")
} }
companion object { companion object {

View File

@ -28,7 +28,8 @@ import org.springframework.stereotype.Service
@Service @Service
class DeleteFilterV1ApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) : class DeleteFilterV1ApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) :
LocalUserAbstractApplicationService<DeleteFilterV1, Unit>( LocalUserAbstractApplicationService<DeleteFilterV1, Unit>(
transaction, logger transaction,
logger
) { ) {
override suspend fun internalExecute(command: DeleteFilterV1, principal: LocalUser) { override suspend fun internalExecute(command: DeleteFilterV1, principal: LocalUser) {
val filter = filterRepository.findByFilterKeywordId(FilterKeywordId(command.filterKeywordId)) val filter = filterRepository.findByFilterKeywordId(FilterKeywordId(command.filterKeywordId))

View File

@ -31,7 +31,8 @@ import org.springframework.stereotype.Repository
@Repository @Repository
class GetFilterV1ApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) : class GetFilterV1ApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) :
AbstractApplicationService<GetFilterV1, V1Filter>( AbstractApplicationService<GetFilterV1, V1Filter>(
transaction, logger transaction,
logger
) { ) {
override suspend fun internalExecute(command: GetFilterV1, principal: Principal): V1Filter { override suspend fun internalExecute(command: GetFilterV1, principal: Principal): V1Filter {
val filter = filterRepository.findByFilterKeywordId(FilterKeywordId(command.filterKeywordId)) val filter = filterRepository.findByFilterKeywordId(FilterKeywordId(command.filterKeywordId))

View File

@ -32,13 +32,12 @@ class GetStatusApplicationService(
transaction, transaction,
logger logger
) { ) {
companion object {
val logger = LoggerFactory.getLogger(GetStatusApplicationService::class.java)!!
}
override suspend fun internalExecute(command: GetStatus, principal: Principal): Status { override suspend fun internalExecute(command: GetStatus, principal: Principal): Status {
return statusQueryService.findByPostId(command.id.toLong(), principal) return statusQueryService.findByPostId(command.id.toLong(), principal)
?: throw IllegalArgumentException("Post ${command.id} not found.") ?: throw IllegalArgumentException("Post ${command.id} not found.")
}
companion object {
val logger = LoggerFactory.getLogger(GetStatusApplicationService::class.java)!!
} }
} }

View File

@ -25,7 +25,7 @@ import org.jetbrains.exposed.sql.selectAll
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
@Repository @Repository
class AccountQueryServiceImpl(private val applicationConfig: ApplicationConfig) : AccountQueryService { class ExposedAccountQueryServiceImpl(private val applicationConfig: ApplicationConfig) : AccountQueryService {
override suspend fun findById(accountId: Long): Account? { override suspend fun findById(accountId: Long): Account? {
val query = Actors.selectAll().where { Actors.id eq accountId } val query = Actors.selectAll().where { Actors.id eq accountId }

View File

@ -56,7 +56,8 @@ class StatusQueryServiceImpl : StatusQueryService {
.leftJoin( .leftJoin(
relationshipsAlias, relationshipsAlias,
onColumn = { Posts.actorId }, onColumn = { Posts.actorId },
otherColumn = { relationshipsAlias[Relationships.targetActorId] }) otherColumn = { relationshipsAlias[Relationships.targetActorId] }
)
.select(Posts.columns) .select(Posts.columns)
.where { .where {
Posts.visibility eq Visibility.PUBLIC.name or Posts.visibility eq Visibility.PUBLIC.name or

View File

@ -48,6 +48,7 @@ import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Controller import org.springframework.stereotype.Controller
@Controller @Controller
@Suppress("LongParameterList")
class SpringAccountApi( class SpringAccountApi(
private val getUserDetailApplicationService: GetUserDetailApplicationService, private val getUserDetailApplicationService: GetUserDetailApplicationService,
private val getAccountApplicationService: GetAccountApplicationService, private val getAccountApplicationService: GetAccountApplicationService,
@ -64,7 +65,6 @@ class SpringAccountApi(
private val principalContextHolder: SpringSecurityOauth2PrincipalContextHolder private val principalContextHolder: SpringSecurityOauth2PrincipalContextHolder
) : AccountApi { ) : AccountApi {
override suspend fun apiV1AccountsIdBlockPost(id: String): ResponseEntity<Relationship> { override suspend fun apiV1AccountsIdBlockPost(id: String): ResponseEntity<Relationship> {
userBlockApplicationService.execute(Block(id.toLong()), principalContextHolder.getPrincipal()) userBlockApplicationService.execute(Block(id.toLong()), principalContextHolder.getPrincipal())
return fetchRelationship(id) return fetchRelationship(id)
@ -74,9 +74,9 @@ class SpringAccountApi(
id: String, id: String,
followRequestBody: FollowRequestBody?, followRequestBody: FollowRequestBody?,
): ResponseEntity<Relationship> { ): ResponseEntity<Relationship> {
userFollowRequestApplicationService.execute( userFollowRequestApplicationService.execute(
FollowRequest(id.toLong()), principalContextHolder.getPrincipal() FollowRequest(id.toLong()),
principalContextHolder.getPrincipal()
) )
return fetchRelationship(id) return fetchRelationship(id)
} }
@ -110,53 +110,57 @@ class SpringAccountApi(
override suspend fun apiV1AccountsIdGet(id: String): ResponseEntity<Account> { override suspend fun apiV1AccountsIdGet(id: String): ResponseEntity<Account> {
return ResponseEntity.ok( return ResponseEntity.ok(
getAccountApplicationService.execute( getAccountApplicationService.execute(
GetAccount(id), principalContextHolder.getPrincipal() GetAccount(id),
principalContextHolder.getPrincipal()
) )
) )
} }
override suspend fun apiV1AccountsIdMutePost(id: String): ResponseEntity<Relationship> { override suspend fun apiV1AccountsIdMutePost(id: String): ResponseEntity<Relationship> {
userMuteApplicationService.execute( userMuteApplicationService.execute(
Mute(id.toLong()), principalContextHolder.getPrincipal() Mute(id.toLong()),
principalContextHolder.getPrincipal()
) )
return fetchRelationship(id) return fetchRelationship(id)
} }
override suspend fun apiV1AccountsIdRemoveFromFollowersPost(id: String): ResponseEntity<Relationship> { override suspend fun apiV1AccountsIdRemoveFromFollowersPost(id: String): ResponseEntity<Relationship> {
userRemoveFromFollowersApplicationService.execute( userRemoveFromFollowersApplicationService.execute(
RemoveFromFollowers(id.toLong()), principalContextHolder.getPrincipal() RemoveFromFollowers(id.toLong()),
principalContextHolder.getPrincipal()
) )
return fetchRelationship(id) return fetchRelationship(id)
} }
override suspend fun apiV1AccountsIdUnblockPost(id: String): ResponseEntity<Relationship> { override suspend fun apiV1AccountsIdUnblockPost(id: String): ResponseEntity<Relationship> {
userUnblockApplicationService.execute( userUnblockApplicationService.execute(
Unblock(id.toLong()), principalContextHolder.getPrincipal() Unblock(id.toLong()),
principalContextHolder.getPrincipal()
) )
return fetchRelationship(id) return fetchRelationship(id)
} }
override suspend fun apiV1AccountsIdUnfollowPost(id: String): ResponseEntity<Relationship> { override suspend fun apiV1AccountsIdUnfollowPost(id: String): ResponseEntity<Relationship> {
userUnfollowApplicationService.execute( userUnfollowApplicationService.execute(
Unfollow(id.toLong()), principalContextHolder.getPrincipal() Unfollow(id.toLong()),
principalContextHolder.getPrincipal()
) )
return fetchRelationship(id) return fetchRelationship(id)
} }
override suspend fun apiV1AccountsIdUnmutePost(id: String): ResponseEntity<Relationship> { override suspend fun apiV1AccountsIdUnmutePost(id: String): ResponseEntity<Relationship> {
userUnmuteApplicationService.execute( userUnmuteApplicationService.execute(
Unmute(id.toLong()), principalContextHolder.getPrincipal() Unmute(id.toLong()),
principalContextHolder.getPrincipal()
) )
return fetchRelationship(id) return fetchRelationship(id)
} }
override suspend fun apiV1AccountsPost(accountsCreateRequest: AccountsCreateRequest): ResponseEntity<Unit> { override suspend fun apiV1AccountsPost(accountsCreateRequest: AccountsCreateRequest): ResponseEntity<Unit> =
return super.apiV1AccountsPost(accountsCreateRequest) super.apiV1AccountsPost(accountsCreateRequest)
}
override suspend fun apiV1AccountsUpdateCredentialsPatch(updateCredentials: UpdateCredentials?): ResponseEntity<Account> { override suspend fun apiV1AccountsUpdateCredentialsPatch(updateCredentials: UpdateCredentials?): ResponseEntity<Account> =
return super.apiV1AccountsUpdateCredentialsPatch(updateCredentials) super.apiV1AccountsUpdateCredentialsPatch(updateCredentials)
}
override suspend fun apiV1AccountsVerifyCredentialsGet(): ResponseEntity<CredentialAccount> { override suspend fun apiV1AccountsVerifyCredentialsGet(): ResponseEntity<CredentialAccount> {
val principal = principalContextHolder.getPrincipal() val principal = principalContextHolder.getPrincipal()
@ -164,7 +168,8 @@ class SpringAccountApi(
getUserDetailApplicationService.execute( getUserDetailApplicationService.execute(
GetUserDetail( GetUserDetail(
principal.userDetailId?.id ?: throw PermissionDeniedException() principal.userDetailId?.id ?: throw PermissionDeniedException()
), principal ),
principal
) )
return ResponseEntity.ok( return ResponseEntity.ok(
@ -215,19 +220,18 @@ class SpringAccountApi(
} }
override suspend fun apiV1FollowRequestsAccountIdAuthorizePost(accountId: String): ResponseEntity<Relationship> { override suspend fun apiV1FollowRequestsAccountIdAuthorizePost(accountId: String): ResponseEntity<Relationship> {
userAcceptFollowRequestApplicationService.execute( userAcceptFollowRequestApplicationService.execute(
AcceptFollowRequest(accountId.toLong()), principalContextHolder.getPrincipal() AcceptFollowRequest(accountId.toLong()),
principalContextHolder.getPrincipal()
) )
return fetchRelationship(accountId) return fetchRelationship(accountId)
} }
override suspend fun apiV1FollowRequestsAccountIdRejectPost(accountId: String): ResponseEntity<Relationship> { override suspend fun apiV1FollowRequestsAccountIdRejectPost(accountId: String): ResponseEntity<Relationship> {
userRejectFollowRequestApplicationService.execute( userRejectFollowRequestApplicationService.execute(
RejectFollowRequest(accountId.toLong()), principalContextHolder.getPrincipal() RejectFollowRequest(accountId.toLong()),
principalContextHolder.getPrincipal()
) )
return fetchRelationship(accountId) return fetchRelationship(accountId)
} }
} }

View File

@ -29,7 +29,6 @@ import java.net.URI
@Controller @Controller
class SpringAppApi(private val registerApplicationApplicationService: RegisterApplicationApplicationService) : AppApi { class SpringAppApi(private val registerApplicationApplicationService: RegisterApplicationApplicationService) : AppApi {
override suspend fun apiV1AppsPost(appsRequest: AppsRequest): ResponseEntity<Application> { override suspend fun apiV1AppsPost(appsRequest: AppsRequest): ResponseEntity<Application> {
val registerApplication = RegisterApplication( val registerApplication = RegisterApplication(
appsRequest.clientName, appsRequest.clientName,
setOf(URI.create(appsRequest.redirectUris)), setOf(URI.create(appsRequest.redirectUris)),
@ -39,12 +38,12 @@ class SpringAppApi(private val registerApplicationApplicationService: RegisterAp
val registeredApplication = registerApplicationApplicationService.execute(registerApplication, Anonymous) val registeredApplication = registerApplicationApplicationService.execute(registerApplication, Anonymous)
return ResponseEntity.ok( return ResponseEntity.ok(
Application( Application(
registeredApplication.name, name = registeredApplication.name,
"invalid-vapid-key", vapidKey = "invalid-vapid-key",
null, website = null,
registeredApplication.clientId, clientId = registeredApplication.clientId,
registeredApplication.clientSecret, clientSecret = registeredApplication.clientSecret,
appsRequest.redirectUris redirectUri = appsRequest.redirectUris
) )
) )
} }

View File

@ -47,7 +47,8 @@ class SpringFilterApi(
override suspend fun apiV1FiltersIdDelete(id: String): ResponseEntity<Any> { override suspend fun apiV1FiltersIdDelete(id: String): ResponseEntity<Any> {
return ResponseEntity.ok( return ResponseEntity.ok(
deleteFilterV1ApplicationService.execute( deleteFilterV1ApplicationService.execute(
DeleteFilterV1(id.toLong()), principalContextHolder.getPrincipal() DeleteFilterV1(id.toLong()),
principalContextHolder.getPrincipal()
) )
) )
} }
@ -55,7 +56,8 @@ class SpringFilterApi(
override suspend fun apiV1FiltersIdGet(id: String): ResponseEntity<V1Filter> { override suspend fun apiV1FiltersIdGet(id: String): ResponseEntity<V1Filter> {
return ResponseEntity.ok( return ResponseEntity.ok(
getFilterV1ApplicationService.execute( getFilterV1ApplicationService.execute(
GetFilterV1(id.toLong()), principalContextHolder.getPrincipal() GetFilterV1(id.toLong()),
principalContextHolder.getPrincipal()
) )
) )
} }
@ -67,12 +69,9 @@ class SpringFilterApi(
irreversible: Boolean?, irreversible: Boolean?,
wholeWord: Boolean?, wholeWord: Boolean?,
expiresIn: Int?, expiresIn: Int?,
): ResponseEntity<V1Filter> { ): ResponseEntity<V1Filter> = super.apiV1FiltersIdPut(id, phrase, context, irreversible, wholeWord, expiresIn)
return super.apiV1FiltersIdPut(id, phrase, context, irreversible, wholeWord, expiresIn)
}
override suspend fun apiV1FiltersPost(v1FilterPostRequest: V1FilterPostRequest): ResponseEntity<V1Filter> { override suspend fun apiV1FiltersPost(v1FilterPostRequest: V1FilterPostRequest): ResponseEntity<V1Filter> {
val filterMode = if (v1FilterPostRequest.wholeWord == true) { val filterMode = if (v1FilterPostRequest.wholeWord == true) {
FilterMode.WHOLE_WORD FilterMode.WHOLE_WORD
} else { } else {
@ -89,13 +88,17 @@ class SpringFilterApi(
}.toSet() }.toSet()
val filter = userRegisterFilterApplicationService.execute( val filter = userRegisterFilterApplicationService.execute(
RegisterFilter( RegisterFilter(
v1FilterPostRequest.phrase, filterContext, FilterAction.WARN, v1FilterPostRequest.phrase,
filterContext,
FilterAction.WARN,
setOf(RegisterFilterKeyword(v1FilterPostRequest.phrase, filterMode)) setOf(RegisterFilterKeyword(v1FilterPostRequest.phrase, filterMode))
), principalContextHolder.getPrincipal() ),
principalContextHolder.getPrincipal()
) )
return ResponseEntity.ok( return ResponseEntity.ok(
getFilterV1ApplicationService.execute( getFilterV1ApplicationService.execute(
GetFilterV1(filter.filterKeywords.first().id), principalContextHolder.getPrincipal() GetFilterV1(filter.filterKeywords.first().id),
principalContextHolder.getPrincipal()
) )
) )
} }
@ -103,27 +106,25 @@ class SpringFilterApi(
override suspend fun apiV2FiltersFilterIdKeywordsPost( override suspend fun apiV2FiltersFilterIdKeywordsPost(
filterId: String, filterId: String,
filterKeywordsPostRequest: FilterKeywordsPostRequest, filterKeywordsPostRequest: FilterKeywordsPostRequest,
): ResponseEntity<FilterKeyword> { ): ResponseEntity<FilterKeyword> = super.apiV2FiltersFilterIdKeywordsPost(filterId, filterKeywordsPostRequest)
return super.apiV2FiltersFilterIdKeywordsPost(filterId, filterKeywordsPostRequest)
}
override suspend fun apiV2FiltersFilterIdStatusesPost( override suspend fun apiV2FiltersFilterIdStatusesPost(
filterId: String, filterId: String,
filterStatusRequest: FilterStatusRequest, filterStatusRequest: FilterStatusRequest,
): ResponseEntity<FilterStatus> { ): ResponseEntity<FilterStatus> = super.apiV2FiltersFilterIdStatusesPost(filterId, filterStatusRequest)
return super.apiV2FiltersFilterIdStatusesPost(filterId, filterStatusRequest)
}
override suspend fun apiV2FiltersIdDelete(id: String): ResponseEntity<Any> { override suspend fun apiV2FiltersIdDelete(id: String): ResponseEntity<Any> {
userDeleteFilterApplicationService.execute( userDeleteFilterApplicationService.execute(
DeleteFilter(id.toLong()), principalContextHolder.getPrincipal() DeleteFilter(id.toLong()),
principalContextHolder.getPrincipal()
) )
return ResponseEntity.ok(Unit) return ResponseEntity.ok(Unit)
} }
override suspend fun apiV2FiltersIdGet(id: String): ResponseEntity<Filter> { override suspend fun apiV2FiltersIdGet(id: String): ResponseEntity<Filter> {
val filter = userGetFilterApplicationService.execute( val filter = userGetFilterApplicationService.execute(
GetFilter(id.toLong()), principalContextHolder.getPrincipal() GetFilter(id.toLong()),
principalContextHolder.getPrincipal()
) )
return ResponseEntity.ok( return ResponseEntity.ok(
filter(filter) filter(filter)
@ -146,7 +147,6 @@ class SpringFilterApi(
filterAction = when (filter.filterAction) { filterAction = when (filter.filterAction) {
FilterAction.WARN -> Filter.FilterAction.warn FilterAction.WARN -> Filter.FilterAction.warn
FilterAction.HIDE -> Filter.FilterAction.hide FilterAction.HIDE -> Filter.FilterAction.hide
}, },
keywords = filter.filterKeywords.map { keywords = filter.filterKeywords.map {
FilterKeyword( FilterKeyword(
@ -154,7 +154,8 @@ class SpringFilterApi(
it.keyword, it.keyword,
it.filterMode == FilterMode.WHOLE_WORD it.filterMode == FilterMode.WHOLE_WORD
) )
}, statuses = null },
statuses = null
) )
override suspend fun apiV2FiltersIdPut( override suspend fun apiV2FiltersIdPut(
@ -164,29 +165,23 @@ class SpringFilterApi(
filterAction: String?, filterAction: String?,
expiresIn: Int?, expiresIn: Int?,
keywordsAttributes: List<FilterPubRequestKeyword>?, keywordsAttributes: List<FilterPubRequestKeyword>?,
): ResponseEntity<Filter> { ): ResponseEntity<Filter> =
return super.apiV2FiltersIdPut(id, title, context, filterAction, expiresIn, keywordsAttributes) super.apiV2FiltersIdPut(id, title, context, filterAction, expiresIn, keywordsAttributes)
}
override suspend fun apiV2FiltersKeywordsIdDelete(id: String): ResponseEntity<Any> { override suspend fun apiV2FiltersKeywordsIdDelete(id: String): ResponseEntity<Any> =
return super.apiV2FiltersKeywordsIdDelete(id) super.apiV2FiltersKeywordsIdDelete(id)
}
override suspend fun apiV2FiltersKeywordsIdGet(id: String): ResponseEntity<FilterKeyword> { override suspend fun apiV2FiltersKeywordsIdGet(id: String): ResponseEntity<FilterKeyword> =
return super.apiV2FiltersKeywordsIdGet(id) super.apiV2FiltersKeywordsIdGet(id)
}
override suspend fun apiV2FiltersKeywordsIdPut( override suspend fun apiV2FiltersKeywordsIdPut(
id: String, id: String,
keyword: String?, keyword: String?,
wholeWord: Boolean?, wholeWord: Boolean?,
regex: Boolean?, regex: Boolean?,
): ResponseEntity<FilterKeyword> { ): ResponseEntity<FilterKeyword> = super.apiV2FiltersKeywordsIdPut(id, keyword, wholeWord, regex)
return super.apiV2FiltersKeywordsIdPut(id, keyword, wholeWord, regex)
}
override suspend fun apiV2FiltersPost(filterPostRequest: FilterPostRequest): ResponseEntity<Filter> { override suspend fun apiV2FiltersPost(filterPostRequest: FilterPostRequest): ResponseEntity<Filter> {
val filter = userRegisterFilterApplicationService.execute( val filter = userRegisterFilterApplicationService.execute(
RegisterFilter( RegisterFilter(
filterName = filterPostRequest.title, filterName = filterPostRequest.title,
@ -216,16 +211,15 @@ class SpringFilterApi(
} }
) )
}.toSet() }.toSet()
), principalContextHolder.getPrincipal() ),
principalContextHolder.getPrincipal()
) )
return ResponseEntity.ok(filter(filter)) return ResponseEntity.ok(filter(filter))
} }
override suspend fun apiV2FiltersStatusesIdDelete(id: String): ResponseEntity<Any> { override suspend fun apiV2FiltersStatusesIdDelete(id: String): ResponseEntity<Any> =
return ResponseEntity.notFound().build() ResponseEntity.notFound().build()
}
override suspend fun apiV2FiltersStatusesIdGet(id: String): ResponseEntity<FilterStatus> { override suspend fun apiV2FiltersStatusesIdGet(id: String): ResponseEntity<FilterStatus> =
return ResponseEntity.notFound().build() ResponseEntity.notFound().build()
}
} }

View File

@ -17,23 +17,19 @@
package dev.usbharu.hideout.mastodon.interfaces.api package dev.usbharu.hideout.mastodon.interfaces.api
import dev.usbharu.hideout.mastodon.interfaces.api.generated.InstanceApi import dev.usbharu.hideout.mastodon.interfaces.api.generated.InstanceApi
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.* import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.ExtendedDescription
import kotlinx.coroutines.flow.Flow import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Instance
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.V1Instance
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Controller import org.springframework.stereotype.Controller
@Controller @Controller
class SpringInstanceApi : InstanceApi { class SpringInstanceApi : InstanceApi {
override suspend fun apiV1InstanceExtendedDescriptionGet(): ResponseEntity<ExtendedDescription> { override suspend fun apiV1InstanceExtendedDescriptionGet(): ResponseEntity<ExtendedDescription> =
return super.apiV1InstanceExtendedDescriptionGet() super.apiV1InstanceExtendedDescriptionGet()
}
override suspend fun apiV1InstanceGet(): ResponseEntity<V1Instance> { override suspend fun apiV1InstanceGet(): ResponseEntity<V1Instance> = super.apiV1InstanceGet()
return super.apiV1InstanceGet()
}
override suspend fun apiV2InstanceGet(): ResponseEntity<Instance> { override suspend fun apiV2InstanceGet(): ResponseEntity<Instance> = super.apiV2InstanceGet()
return super.apiV2InstanceGet()
}
} }

View File

@ -52,24 +52,25 @@ class SpringMediaApi(
file.originalFilename ?: file.name, file.originalFilename ?: file.name,
null, null,
description description
), principalContextHolder.getPrincipal() ),
principalContextHolder.getPrincipal()
) )
return ResponseEntity.ok( return ResponseEntity.ok(
MediaAttachment( MediaAttachment(
media.id.toString(), id = media.id.toString(),
when (media.type) { type = when (media.type) {
Image -> MediaAttachment.Type.image Image -> MediaAttachment.Type.image
Video -> MediaAttachment.Type.video Video -> MediaAttachment.Type.video
Audio -> MediaAttachment.Type.audio Audio -> MediaAttachment.Type.audio
Unknown -> MediaAttachment.Type.unknown Unknown -> MediaAttachment.Type.unknown
}, },
media.url.toString(), url = media.url.toString(),
media.thumbprintURI?.toString(), previewUrl = media.thumbprintURI?.toString(),
media.remoteURL?.toString(), remoteUrl = media.remoteURL?.toString(),
media.description, description = media.description,
media.blurHash, blurhash = media.blurHash,
media.url.toASCIIString() textUrl = media.url.toASCIIString()
) )
) )
} }

View File

@ -18,21 +18,16 @@ package dev.usbharu.hideout.mastodon.interfaces.api
import dev.usbharu.hideout.mastodon.interfaces.api.generated.NotificationsApi import dev.usbharu.hideout.mastodon.interfaces.api.generated.NotificationsApi
import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Notification import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Notification
import kotlinx.coroutines.flow.Flow
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Controller import org.springframework.stereotype.Controller
@Controller @Controller
class SpringNotificationApi : NotificationsApi { class SpringNotificationApi : NotificationsApi {
override suspend fun apiV1NotificationsClearPost(): ResponseEntity<Any> { override suspend fun apiV1NotificationsClearPost(): ResponseEntity<Any> = super.apiV1NotificationsClearPost()
return super.apiV1NotificationsClearPost()
}
override suspend fun apiV1NotificationsIdDismissPost(id: String): ResponseEntity<Any> { override suspend fun apiV1NotificationsIdDismissPost(id: String): ResponseEntity<Any> =
return super.apiV1NotificationsIdDismissPost(id) super.apiV1NotificationsIdDismissPost(id)
}
override suspend fun apiV1NotificationsIdGet(id: String): ResponseEntity<Notification> { override suspend fun apiV1NotificationsIdGet(id: String): ResponseEntity<Notification> =
return super.apiV1NotificationsIdGet(id) super.apiV1NotificationsIdGet(id)
}
} }

View File

@ -34,25 +34,22 @@ class SpringStatusApi(
private val getStatusApplicationService: GetStatusApplicationService, private val getStatusApplicationService: GetStatusApplicationService,
private val principalContextHolder: SpringSecurityOauth2PrincipalContextHolder private val principalContextHolder: SpringSecurityOauth2PrincipalContextHolder
) : StatusApi { ) : StatusApi {
override suspend fun apiV1StatusesIdEmojiReactionsEmojiDelete(id: String, emoji: String): ResponseEntity<Status> { override suspend fun apiV1StatusesIdEmojiReactionsEmojiDelete(id: String, emoji: String): ResponseEntity<Status> =
return super.apiV1StatusesIdEmojiReactionsEmojiDelete(id, emoji) super.apiV1StatusesIdEmojiReactionsEmojiDelete(id, emoji)
}
override suspend fun apiV1StatusesIdEmojiReactionsEmojiPut(id: String, emoji: String): ResponseEntity<Status> { override suspend fun apiV1StatusesIdEmojiReactionsEmojiPut(id: String, emoji: String): ResponseEntity<Status> =
return super.apiV1StatusesIdEmojiReactionsEmojiPut(id, emoji) super.apiV1StatusesIdEmojiReactionsEmojiPut(id, emoji)
}
override suspend fun apiV1StatusesIdGet(id: String): ResponseEntity<Status> { override suspend fun apiV1StatusesIdGet(id: String): ResponseEntity<Status> {
return ResponseEntity.ok( return ResponseEntity.ok(
getStatusApplicationService.execute( getStatusApplicationService.execute(
GetStatus(id), principalContextHolder.getPrincipal() GetStatus(id),
principalContextHolder.getPrincipal()
) )
) )
} }
override suspend fun apiV1StatusesPost(statusesRequest: dev.usbharu.hideout.mastodon.interfaces.api.StatusesRequest): ResponseEntity<Status> { override suspend fun apiV1StatusesPost(statusesRequest: StatusesRequest): ResponseEntity<Status> {
val principal = principalContextHolder.getPrincipal() val principal = principalContextHolder.getPrincipal()
val execute = registerLocalPostApplicationService.execute( val execute = registerLocalPostApplicationService.execute(
RegisterLocalPost( RegisterLocalPost(
@ -69,10 +66,10 @@ class SpringStatusApi(
replyId = statusesRequest.in_reply_to_id?.toLong(), replyId = statusesRequest.in_reply_to_id?.toLong(),
sensitive = statusesRequest.sensitive == true, sensitive = statusesRequest.sensitive == true,
mediaIds = statusesRequest.media_ids.map { it.toLong() } mediaIds = statusesRequest.media_ids.map { it.toLong() }
), principal ),
principal
) )
val status = val status =
getStatusApplicationService.execute(GetStatus(execute.toString()), principal) getStatusApplicationService.execute(GetStatus(execute.toString()), principal)
return ResponseEntity.ok( return ResponseEntity.ok(