refactor: 長すぎるメソッドなどを修正

This commit is contained in:
usbharu 2023-11-27 18:28:41 +09:00
parent 8925c321bd
commit 6cf93f0624
28 changed files with 126 additions and 178 deletions

View File

@ -3,9 +3,7 @@ build:
weights:
Indentation: 0
MagicNumber: 0
InjectDispatcher: 0
EnumEntryNameCase: 0
ReplaceSafeCallChainWithRun: 0
VariableNaming: 0
NoNameShadowing: 0
@ -78,7 +76,7 @@ complexity:
active: true
ReplaceSafeCallChainWithRun:
active: true
active: false
StringLiteralDuplication:
active: false
@ -172,3 +170,5 @@ potential-bugs:
coroutines:
RedundantSuspendModifier:
active: false
InjectDispatcher:
active: false

View File

@ -6,6 +6,7 @@ import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectDeserializer
open class Accept : Object {
@JsonDeserialize(using = ObjectDeserializer::class)
@Suppress("VariableNaming")
var `object`: Object? = null
protected constructor()

View File

@ -6,6 +6,7 @@ import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectDeserializer
open class Create : Object {
@JsonDeserialize(using = ObjectDeserializer::class)
@Suppress("VariableNaming")
var `object`: Object? = null
var to: List<String> = emptyList()
var cc: List<String> = emptyList()

View File

@ -6,6 +6,7 @@ import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectDeserializer
open class Delete : Object {
@JsonDeserialize(using = ObjectDeserializer::class)
@Suppress("VariableNaming")
var `object`: Object? = null
var published: String? = null

View File

@ -3,6 +3,7 @@ package dev.usbharu.hideout.activitypub.domain.model
import dev.usbharu.hideout.activitypub.domain.model.objects.Object
open class Follow : Object {
@Suppress("VariableNaming")
var `object`: String? = null
protected constructor() : super()

View File

@ -5,6 +5,7 @@ import dev.usbharu.hideout.activitypub.domain.model.objects.Object
import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectDeserializer
open class Like : Object {
@Suppress("VariableNaming")
var `object`: String? = null
var content: String? = null

View File

@ -8,6 +8,7 @@ import java.time.Instant
open class Undo : Object {
@JsonDeserialize(using = ObjectDeserializer::class)
@Suppress("VariableNaming")
var `object`: Object? = null
var published: String? = null

View File

@ -80,7 +80,7 @@ class NoteQueryServiceImpl(private val postRepository: PostRepository, private v
private suspend fun Query.toNote(): Note {
return this.groupBy { it[Posts.id] }
.map { it.value }
.map { it.first().toNote(it.mapNotNull { it.toMediaOrNull() }) }
.map { it.first().toNote(it.mapNotNull { resultRow -> resultRow.toMediaOrNull() }) }
.singleOr { FailedToGetResourcesException("resource does not exist.") }
}

View File

@ -22,7 +22,7 @@ class APDeleteProcessor(
val post = try {
postQueryService.findByApId(deleteId)
} catch (e: FailedToGetResourcesException) {
logger.warn("FAILED delete id: {} is not found.", deleteId)
logger.warn("FAILED delete id: {} is not found.", deleteId, e)
return
}

View File

@ -134,7 +134,7 @@ class APRequestServiceImpl(
val httpResponse = if (signer?.privateKey == null) {
apPostNotSign(url, date, digest, requestBody)
} else {
apPostSign(date, u, digest, signer, url, requestBody)
apPostSign(date, u, digest, signer, requestBody)
}
val bodyAsText = httpResponse.bodyAsText()
@ -167,7 +167,6 @@ class APRequestServiceImpl(
u: URL,
digest: String,
signer: User,
url: String,
requestBody: String?
): HttpResponse {
val headers = headers {
@ -190,12 +189,11 @@ class APRequestServiceImpl(
signHeaders = listOf("(request-target)", "date", "host", "digest")
)
val httpResponse = httpClient.post(url) {
val httpResponse = httpClient.post(u) {
headers {
appendAll(headers)
append("Signature", sign.signatureHeader)
remove("Host")
}
setBody(requestBody)
contentType(ContentType.Application.Activity)

View File

@ -218,7 +218,6 @@ class APServiceImpl(
}
}
@Suppress("CyclomaticComplexMethod")
override suspend fun processActivity(
json: String,
type: ActivityType,

View File

@ -86,6 +86,7 @@ class InboxJobProcessor(
return verify.success
}
@Suppress("TooGenericExceptionCaught")
private fun parseSignatureHeader(httpHeaders: HttpHeaders): Signature? {
return try {
signatureHeaderParser.parse(httpHeaders)

View File

@ -4,6 +4,7 @@ import dev.usbharu.hideout.activitypub.domain.model.Note
import dev.usbharu.hideout.activitypub.query.NoteQueryService
import dev.usbharu.hideout.application.external.Transaction
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
import dev.usbharu.hideout.core.domain.model.post.Post
import dev.usbharu.hideout.core.domain.model.post.Visibility
import dev.usbharu.hideout.core.query.FollowerQueryService
import org.slf4j.LoggerFactory
@ -28,20 +29,27 @@ class NoteApApiServiceImpl(
}
Visibility.FOLLOWERS -> {
if (userId == null) {
return@transaction null
}
if (followerQueryService.alreadyFollow(findById.second.userId, userId).not()) {
return@transaction null
}
return@transaction findById.first
return@transaction getFollowersNote(userId, findById)
}
Visibility.DIRECT -> return@transaction null
}
}
private suspend fun getFollowersNote(
userId: Long?,
findById: Pair<Note, Post>
): Note? {
if (userId == null) {
return null
}
if (followerQueryService.alreadyFollow(findById.second.userId, userId)) {
return findById.first
}
return null
}
companion object {
private val logger = LoggerFactory.getLogger(NoteApApiServiceImpl::class.java)
}

View File

@ -77,69 +77,18 @@ class APUserServiceImpl(
override suspend fun fetchPerson(url: String, targetActor: String?): Person =
fetchPersonWithEntity(url, targetActor).first
@Suppress("LongMethod")
override suspend fun fetchPersonWithEntity(url: String, targetActor: String?): Pair<Person, User> {
return try {
val userEntity = userQueryService.findByUrl(url)
val id = userEntity.url
return Person(
type = emptyList(),
name = userEntity.name,
id = id,
preferredUsername = userEntity.name,
summary = userEntity.description,
inbox = "$id/inbox",
outbox = "$id/outbox",
url = id,
icon = Image(
type = emptyList(),
name = "$id/icon.png",
mediaType = "image/png",
url = "$id/icon.png"
),
publicKey = Key(
type = emptyList(),
name = "Public Key",
id = userEntity.keyId,
owner = id,
publicKeyPem = userEntity.publicKey
),
endpoints = mapOf("sharedInbox" to "${applicationConfig.url}/inbox"),
followers = userEntity.followers,
following = userEntity.following
) to userEntity
return entityToPerson(userEntity, id) to userEntity
} catch (ignore: FailedToGetResourcesException) {
val person = apResourceResolveService.resolve<Person>(url, null as Long?)
val id = person.id ?: throw IllegalActivityPubObjectException("id is null")
try {
val userEntity = userQueryService.findByUrl(id)
return Person(
type = emptyList(),
name = userEntity.name,
id = id,
preferredUsername = userEntity.name,
summary = userEntity.description,
inbox = "$id/inbox",
outbox = "$id/outbox",
url = id,
icon = Image(
type = emptyList(),
name = "$id/icon.png",
mediaType = "image/png",
url = "$id/icon.png"
),
publicKey = Key(
type = emptyList(),
name = "Public Key",
id = userEntity.keyId,
owner = id,
publicKeyPem = userEntity.publicKey
),
endpoints = mapOf("sharedInbox" to "${applicationConfig.url}/inbox"),
followers = userEntity.followers,
following = userEntity.following
) to userEntity
return entityToPerson(userEntity, id) to userEntity
} catch (_: FailedToGetResourcesException) {
}
person to userService.createRemoteUser(
@ -163,4 +112,34 @@ class APUserServiceImpl(
)
}
}
private fun entityToPerson(
userEntity: User,
id: String
) = Person(
type = emptyList(),
name = userEntity.name,
id = id,
preferredUsername = userEntity.name,
summary = userEntity.description,
inbox = "$id/inbox",
outbox = "$id/outbox",
url = id,
icon = Image(
type = emptyList(),
name = "$id/icon.png",
mediaType = "image/png",
url = "$id/icon.png"
),
publicKey = Key(
type = emptyList(),
name = "Public Key",
id = userEntity.keyId,
owner = id,
publicKeyPem = userEntity.publicKey
),
endpoints = mapOf("sharedInbox" to "${applicationConfig.url}/inbox"),
followers = userEntity.followers,
following = userEntity.following
)
}

View File

@ -200,8 +200,8 @@ class SecurityConfig {
it.ignoringRequestMatchers(builder.pattern("/inbox"))
it.ignoringRequestMatchers(PathRequest.toH2Console())
}.headers {
it.frameOptions {
it.sameOrigin()
it.frameOptions { frameOptionsConfig ->
frameOptionsConfig.sameOrigin()
}
}
return http.build()

View File

@ -2,6 +2,7 @@ package dev.usbharu.hideout.core.domain.model.media
import dev.usbharu.hideout.core.service.media.FileType
import dev.usbharu.hideout.core.service.media.MimeType
import dev.usbharu.hideout.domain.mastodon.model.generated.MediaAttachment
data class Media(
val id: Long,
@ -14,3 +15,19 @@ data class Media(
val blurHash: String?,
val description: String? = null
)
fun Media.toMediaAttachments(): MediaAttachment = MediaAttachment(
id = id.toString(),
type = when (type) {
FileType.Image -> MediaAttachment.Type.image
FileType.Video -> MediaAttachment.Type.video
FileType.Audio -> MediaAttachment.Type.audio
FileType.Unknown -> MediaAttachment.Type.unknown
},
url = url,
previewUrl = thumbnailUrl,
remoteUrl = remoteUrl,
description = description,
blurhash = blurHash,
textUrl = url
)

View File

@ -2,7 +2,6 @@ package dev.usbharu.hideout.core.domain.model.user
import org.springframework.stereotype.Repository
@Suppress("TooManyFunctions")
@Repository
interface UserRepository {
suspend fun save(user: User): User

View File

@ -112,7 +112,9 @@ object DeliverRemoveReactionJob :
val actor: Prop<DeliverRemoveReactionJob, String> = string("actor")
val like: Prop<DeliverRemoveReactionJob, String> = string("like")
override fun convert(value: DeliverRemoveReactionJobParam): ScheduleContext<DeliverRemoveReactionJob>.(DeliverRemoveReactionJob) -> Unit =
override fun convert(
value: DeliverRemoveReactionJobParam
): ScheduleContext<DeliverRemoveReactionJob>.(DeliverRemoveReactionJob) -> Unit =
{
props[id] = value.id
props[inbox] = value.inbox

View File

@ -15,7 +15,7 @@ class PostQueryMapper(private val postResultRowMapper: ResultRowMapper<Post>) :
.map { it.value }
.map {
it.first().let(postResultRowMapper::map)
.copy(mediaIds = it.mapNotNull { it.getOrNull(PostsMedia.mediaId) })
.copy(mediaIds = it.mapNotNull { resultRow -> resultRow.getOrNull(PostsMedia.mediaId) })
}
}
}

View File

@ -13,7 +13,7 @@ import org.springframework.stereotype.Service
@Service
@ConditionalOnProperty(name = ["hideout.use-mongodb"], havingValue = "false", matchIfMissing = true)
class KJobJobQueueParentService() : JobQueueParentService {
class KJobJobQueueParentService : JobQueueParentService {
private val logger = LoggerFactory.getLogger(this::class.java)

View File

@ -9,7 +9,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.stereotype.Repository
@Repository
@Suppress("InjectDispatcher")
@ConditionalOnProperty("hideout.use-mongodb", havingValue = "true", matchIfMissing = false)
class MongoTimelineRepositoryWrapper(
private val mongoTimelineRepository: MongoTimelineRepository,

View File

@ -197,7 +197,7 @@ class ExposedOAuth2AuthorizationService(
}
}
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Suppress("LongMethod", "CyclomaticComplexMethod", "CastToNullableType", "UNCHECKED_CAST")
fun ResultRow.toAuthorization(): OAuth2Authorization {
val registeredClientId = this[Authorization.registeredClientId]
@ -272,7 +272,6 @@ class ExposedOAuth2AuthorizationService(
oidcIdTokenValue,
oidcTokenIssuedAt,
oidcTokenExpiresAt,
@Suppress("CastToNullableType")
oidcTokenMetadata.getValue(OAuth2Authorization.Token.CLAIMS_METADATA_NAME)
as MutableMap<String, Any>?
)

View File

@ -74,11 +74,7 @@ class ImageMediaProcessService(private val imageMediaProcessorConfiguration: Ima
convertType,
it
)
if (write) {
tempThumbnailFile
} else {
null
}
tempThumbnailFile.takeIf { write }
}
} else {
null

View File

@ -45,7 +45,7 @@ class ExposedGenerateTimelineService(private val statusQueryService: StatusQuery
it[Timelines.postId],
it[Timelines.replyId],
it[Timelines.repostId],
it[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() }
it[Timelines.mediaIds].split(",").mapNotNull { s -> s.toLongOrNull() }
)
}

View File

@ -59,6 +59,7 @@ class UserServiceImpl(
}
override suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
@Suppress("TooGenericExceptionCaught")
val instance = try {
instanceService.fetchInstance(user.url, user.sharedInbox)
} catch (e: Exception) {

View File

@ -1,22 +1,19 @@
package dev.usbharu.hideout.mastodon.infrastructure.exposedquery
import dev.usbharu.hideout.core.domain.model.media.toMediaAttachments
import dev.usbharu.hideout.core.infrastructure.exposedrepository.*
import dev.usbharu.hideout.core.service.media.FileType
import dev.usbharu.hideout.domain.mastodon.model.generated.Account
import dev.usbharu.hideout.domain.mastodon.model.generated.MediaAttachment
import dev.usbharu.hideout.domain.mastodon.model.generated.Status
import dev.usbharu.hideout.mastodon.interfaces.api.status.StatusQuery
import dev.usbharu.hideout.mastodon.query.StatusQueryService
import org.jetbrains.exposed.sql.ResultRow
import org.jetbrains.exposed.sql.innerJoin
import org.jetbrains.exposed.sql.select
import org.springframework.stereotype.Repository
import java.time.Instant
@Repository
class StatusQueryServiceImpl : StatusQueryService {
@Suppress("LongMethod")
override suspend fun findByPostIds(ids: List<Long>): List<Status> = findByPostIdsWithMediaAttachments(ids)
override suspend fun findByPostIds(ids: List<Long>): List<Status> = findByPostIdsWithMedia(ids)
override suspend fun findByPostIdsWithMediaIds(statusQueries: List<StatusQuery>): List<Status> {
val postIdSet = mutableSetOf<Long>()
@ -29,23 +26,7 @@ class StatusQueryServiceImpl : StatusQueryService {
.associate { it[Posts.id] to toStatus(it) }
val mediaMap = Media.select { Media.id inList mediaIdSet }
.associate {
it[Media.id] to it.toMedia().let {
MediaAttachment(
id = it.id.toString(),
type = when (it.type) {
FileType.Image -> MediaAttachment.Type.image
FileType.Video -> MediaAttachment.Type.video
FileType.Audio -> MediaAttachment.Type.audio
FileType.Unknown -> MediaAttachment.Type.unknown
},
url = it.url,
previewUrl = it.thumbnailUrl,
remoteUrl = it.remoteUrl,
description = "",
blurhash = it.blurHash,
textUrl = it.url
)
}
it[Media.id] to it.toMedia().toMediaAttachments()
}
return statusQueries.mapNotNull { statusQuery ->
@ -58,18 +39,6 @@ class StatusQueryServiceImpl : StatusQueryService {
}
}
@Suppress("unused")
private suspend fun internalFindByPostIds(ids: List<Long>): List<Status> {
val pairs = Posts
.innerJoin(Users, onColumn = { Posts.userId }, otherColumn = { Users.id })
.select { Posts.id inList ids }
.map {
toStatus(it) to it[Posts.repostId]
}
return resolveReplyAndRepost(pairs)
}
private fun resolveReplyAndRepost(pairs: List<Pair<Status, Long?>>): List<Status> {
val statuses = pairs.map { it.first }
return pairs
@ -89,8 +58,7 @@ class StatusQueryServiceImpl : StatusQueryService {
}
}
@Suppress("FunctionMaxLength")
private suspend fun findByPostIdsWithMediaAttachments(ids: List<Long>): List<Status> {
private suspend fun findByPostIdsWithMedia(ids: List<Long>): List<Status> {
val pairs = Posts
.leftJoin(PostsMedia)
.leftJoin(Users)
@ -100,24 +68,8 @@ class StatusQueryServiceImpl : StatusQueryService {
.map { it.value }
.map {
toStatus(it.first()).copy(
mediaAttachments = it.mapNotNull {
it.toMediaOrNull()?.let {
MediaAttachment(
id = it.id.toString(),
type = when (it.type) {
FileType.Image -> MediaAttachment.Type.image
FileType.Video -> MediaAttachment.Type.video
FileType.Audio -> MediaAttachment.Type.audio
FileType.Unknown -> MediaAttachment.Type.unknown
},
url = it.url,
previewUrl = it.thumbnailUrl,
remoteUrl = it.remoteUrl,
description = "",
blurhash = it.blurHash,
textUrl = it.url
)
}
mediaAttachments = it.mapNotNull { resultRow ->
resultRow.toMediaOrNull()?.toMediaAttachments()
}
) to it.first()[Posts.repostId]
}

View File

@ -1,7 +1,10 @@
package dev.usbharu.hideout.mastodon.interfaces.api.status
import com.fasterxml.jackson.annotation.JsonProperty
import dev.usbharu.hideout.core.domain.model.post.Visibility
import dev.usbharu.hideout.domain.mastodon.model.generated.Status
import dev.usbharu.hideout.domain.mastodon.model.generated.StatusesRequestPoll
import dev.usbharu.hideout.mastodon.interfaces.api.status.StatusesRequest.Visibility.*
@Suppress("VariableNaming", "EnumEntryName")
class StatusesRequest {
@ -67,7 +70,7 @@ class StatusesRequest {
" scheduledAt=$scheduled_at)"
}
@Suppress("EnumNaming")
@Suppress("EnumNaming", "EnumEntryNameCase")
enum class Visibility {
`public`,
unlisted,
@ -75,3 +78,23 @@ class StatusesRequest {
direct
}
}
fun StatusesRequest.Visibility?.toPostVisibility(): Visibility {
return when (this) {
public -> Visibility.PUBLIC
unlisted -> Visibility.UNLISTED
private -> Visibility.FOLLOWERS
direct -> Visibility.DIRECT
null -> Visibility.PUBLIC
}
}
fun StatusesRequest.Visibility?.toStatusVisibility(): Status.Visibility {
return when (this) {
public -> Status.Visibility.public
unlisted -> Status.Visibility.unlisted
private -> Status.Visibility.private
direct -> Status.Visibility.direct
null -> Status.Visibility.public
}
}

View File

@ -3,15 +3,15 @@ package dev.usbharu.hideout.mastodon.service.status
import dev.usbharu.hideout.application.external.Transaction
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException
import dev.usbharu.hideout.core.domain.model.media.MediaRepository
import dev.usbharu.hideout.core.domain.model.post.Visibility
import dev.usbharu.hideout.core.domain.model.media.toMediaAttachments
import dev.usbharu.hideout.core.query.PostQueryService
import dev.usbharu.hideout.core.query.UserQueryService
import dev.usbharu.hideout.core.service.media.FileType
import dev.usbharu.hideout.core.service.post.PostCreateDto
import dev.usbharu.hideout.core.service.post.PostService
import dev.usbharu.hideout.domain.mastodon.model.generated.MediaAttachment
import dev.usbharu.hideout.domain.mastodon.model.generated.Status
import dev.usbharu.hideout.mastodon.interfaces.api.status.StatusesRequest
import dev.usbharu.hideout.mastodon.interfaces.api.status.toPostVisibility
import dev.usbharu.hideout.mastodon.interfaces.api.status.toStatusVisibility
import dev.usbharu.hideout.mastodon.service.account.AccountService
import org.springframework.stereotype.Service
import java.time.Instant
@ -34,24 +34,15 @@ class StatsesApiServiceImpl(
private val transaction: Transaction
) :
StatusesApiService {
@Suppress("LongMethod", "CyclomaticComplexMethod")
override suspend fun postStatus(
statusesRequest: StatusesRequest,
userId: Long
): Status = transaction.transaction {
val visibility = when (statusesRequest.visibility) {
StatusesRequest.Visibility.public -> Visibility.PUBLIC
StatusesRequest.Visibility.unlisted -> Visibility.UNLISTED
StatusesRequest.Visibility.private -> Visibility.FOLLOWERS
StatusesRequest.Visibility.direct -> Visibility.DIRECT
null -> Visibility.PUBLIC
}
val post = postService.createLocal(
PostCreateDto(
text = statusesRequest.status.orEmpty(),
overview = statusesRequest.spoiler_text,
visibility = visibility,
visibility = statusesRequest.visibility.toPostVisibility(),
repolyId = statusesRequest.in_reply_to_id?.toLongOrNull(),
userId = userId,
mediaIds = statusesRequest.media_ids.map { it.toLong() }
@ -59,14 +50,6 @@ class StatsesApiServiceImpl(
)
val account = accountService.findById(userId)
val postVisibility = when (statusesRequest.visibility) {
StatusesRequest.Visibility.public -> Status.Visibility.public
StatusesRequest.Visibility.unlisted -> Status.Visibility.unlisted
StatusesRequest.Visibility.private -> Status.Visibility.private
StatusesRequest.Visibility.direct -> Status.Visibility.direct
null -> Status.Visibility.public
}
val replyUser = if (post.replyId != null) {
try {
userQueryService.findById(postQueryService.findById(post.replyId).userId).id
@ -81,21 +64,7 @@ class StatsesApiServiceImpl(
val mediaAttachment = post.mediaIds.map { mediaId ->
mediaRepository.findById(mediaId)
}.map {
MediaAttachment(
id = it.id.toString(),
type = when (it.type) {
FileType.Image -> MediaAttachment.Type.image
FileType.Video -> MediaAttachment.Type.video
FileType.Audio -> MediaAttachment.Type.audio
FileType.Unknown -> MediaAttachment.Type.unknown
},
url = it.url,
previewUrl = it.thumbnailUrl,
remoteUrl = it.remoteUrl,
description = "",
blurhash = it.blurHash,
textUrl = it.url
)
it.toMediaAttachments()
}
Status(
@ -104,7 +73,7 @@ class StatsesApiServiceImpl(
createdAt = Instant.ofEpochMilli(post.createdAt).toString(),
account = account,
content = post.text,
visibility = postVisibility,
visibility = statusesRequest.visibility.toStatusVisibility(),
sensitive = post.sensitive,
spoilerText = post.overview.orEmpty(),
mediaAttachments = mediaAttachment,