mirror of https://github.com/usbharu/Hideout.git
refactor: Timeline APIをPagination APIに対応
This commit is contained in:
parent
7141c7bc6a
commit
b63288ff28
|
@ -1,5 +1,8 @@
|
|||
package dev.usbharu.hideout.core.service.timeline
|
||||
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.Page
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.PaginationList
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.pagination
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Timelines
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Status
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.status.StatusQuery
|
||||
|
@ -52,4 +55,40 @@ class ExposedGenerateTimelineService(private val statusQueryService: StatusQuery
|
|||
|
||||
return statusQueryService.findByPostIdsWithMediaIds(statusQueries)
|
||||
}
|
||||
|
||||
override suspend fun getTimeline(
|
||||
forUserId: Long?,
|
||||
localOnly: Boolean,
|
||||
mediaOnly: Boolean,
|
||||
page: Page
|
||||
): PaginationList<Status, Long> {
|
||||
val query = Timelines.selectAll()
|
||||
|
||||
if (forUserId != null) {
|
||||
query.andWhere { Timelines.userId eq forUserId }
|
||||
}
|
||||
if (localOnly) {
|
||||
query.andWhere { Timelines.isLocal eq true }
|
||||
}
|
||||
query.pagination(page, Timelines.id)
|
||||
val result = query
|
||||
.orderBy(Timelines.createdAt, SortOrder.DESC)
|
||||
|
||||
val statusQueries = result.map {
|
||||
StatusQuery(
|
||||
it[Timelines.postId],
|
||||
it[Timelines.replyId],
|
||||
it[Timelines.repostId],
|
||||
it[Timelines.mediaIds].split(",").mapNotNull { s -> s.toLongOrNull() },
|
||||
it[Timelines.emojiIds].split(",").mapNotNull { s -> s.toLongOrNull() }
|
||||
)
|
||||
}
|
||||
|
||||
val findByPostIdsWithMediaIds = statusQueryService.findByPostIdsWithMediaIds(statusQueries)
|
||||
return PaginationList(
|
||||
findByPostIdsWithMediaIds,
|
||||
findByPostIdsWithMediaIds.lastOrNull()?.id?.toLongOrNull(),
|
||||
findByPostIdsWithMediaIds.firstOrNull()?.id?.toLongOrNull()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package dev.usbharu.hideout.core.service.timeline
|
||||
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.Page
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.PaginationList
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Status
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
|
@ -15,4 +17,11 @@ interface GenerateTimelineService {
|
|||
sinceId: Long? = null,
|
||||
limit: Int = 20
|
||||
): List<Status>
|
||||
|
||||
suspend fun getTimeline(
|
||||
forUserId: Long? = null,
|
||||
localOnly: Boolean = false,
|
||||
mediaOnly: Boolean = false,
|
||||
page: Page
|
||||
): PaginationList<Status, Long>
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package dev.usbharu.hideout.core.service.timeline
|
||||
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.Page
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.PaginationList
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.Timeline
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Status
|
||||
import dev.usbharu.hideout.mastodon.interfaces.api.status.StatusQuery
|
||||
|
@ -63,4 +65,54 @@ class MongoGenerateTimelineService(
|
|||
}
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getTimeline(
|
||||
forUserId: Long?,
|
||||
localOnly: Boolean,
|
||||
mediaOnly: Boolean,
|
||||
page: Page
|
||||
): PaginationList<Status, Long> {
|
||||
val query = Query()
|
||||
|
||||
if (forUserId != null) {
|
||||
val criteria = Criteria.where("userId").`is`(forUserId)
|
||||
query.addCriteria(criteria)
|
||||
}
|
||||
if (localOnly) {
|
||||
val criteria = Criteria.where("isLocal").`is`(true)
|
||||
query.addCriteria(criteria)
|
||||
}
|
||||
|
||||
if (page.minId != null) {
|
||||
page.minId?.let { query.addCriteria(Criteria.where("id").gt(it)) }
|
||||
page.maxId?.let { query.addCriteria(Criteria.where("id").lt(it)) }
|
||||
} else {
|
||||
query.with(Sort.by(Sort.Direction.DESC, "createdAt"))
|
||||
page.sinceId?.let { query.addCriteria(Criteria.where("id").gt(it)) }
|
||||
page.maxId?.let { query.addCriteria(Criteria.where("id").lt(it)) }
|
||||
}
|
||||
|
||||
page.limit?.let { query.limit(it) }
|
||||
|
||||
query.with(Sort.by(Sort.Direction.DESC, "createdAt"))
|
||||
|
||||
val timelines = mongoTemplate.find(query, Timeline::class.java)
|
||||
|
||||
val statuses = statusQueryService.findByPostIdsWithMediaIds(
|
||||
timelines.map {
|
||||
StatusQuery(
|
||||
it.postId,
|
||||
it.replyId,
|
||||
it.repostId,
|
||||
it.mediaIds,
|
||||
it.emojiIds
|
||||
)
|
||||
}
|
||||
)
|
||||
return PaginationList(
|
||||
statuses,
|
||||
statuses.lastOrNull()?.id?.toLongOrNull(),
|
||||
statuses.firstOrNull()?.id?.toLongOrNull()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package dev.usbharu.hideout.mastodon.interfaces.api.timeline
|
||||
|
||||
import dev.usbharu.hideout.application.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.Page
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.toHttpHeader
|
||||
import dev.usbharu.hideout.controller.mastodon.generated.TimelineApi
|
||||
import dev.usbharu.hideout.core.infrastructure.springframework.security.LoginUserContextHolder
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Status
|
||||
|
@ -14,7 +17,8 @@ import org.springframework.stereotype.Controller
|
|||
@Controller
|
||||
class MastodonTimelineApiController(
|
||||
private val timelineApiService: TimelineApiService,
|
||||
private val loginUserContextHolder: LoginUserContextHolder
|
||||
private val loginUserContextHolder: LoginUserContextHolder,
|
||||
private val applicationConfig: ApplicationConfig,
|
||||
) : TimelineApi {
|
||||
override fun apiV1TimelinesHomeGet(
|
||||
maxId: String?,
|
||||
|
@ -24,10 +28,12 @@ class MastodonTimelineApiController(
|
|||
): ResponseEntity<Flow<Status>> = runBlocking {
|
||||
val homeTimeline = timelineApiService.homeTimeline(
|
||||
userId = loginUserContextHolder.getLoginUserId(),
|
||||
page = Page.of(
|
||||
maxId = maxId?.toLongOrNull(),
|
||||
minId = minId?.toLongOrNull(),
|
||||
sinceId = sinceId?.toLongOrNull(),
|
||||
limit = limit ?: 20
|
||||
limit = limit?.coerceIn(0, 80) ?: 40
|
||||
)
|
||||
)
|
||||
ResponseEntity(homeTimeline.asFlow(), HttpStatus.OK)
|
||||
}
|
||||
|
@ -45,11 +51,21 @@ class MastodonTimelineApiController(
|
|||
localOnly = local ?: false,
|
||||
remoteOnly = remote ?: false,
|
||||
mediaOnly = onlyMedia ?: false,
|
||||
page = Page.of(
|
||||
maxId = maxId?.toLongOrNull(),
|
||||
minId = minId?.toLongOrNull(),
|
||||
sinceId = sinceId?.toLongOrNull(),
|
||||
limit = limit ?: 20
|
||||
limit = limit?.coerceIn(0, 80) ?: 40
|
||||
)
|
||||
ResponseEntity(publicTimeline.asFlow(), HttpStatus.OK)
|
||||
)
|
||||
|
||||
val httpHeader = publicTimeline.toHttpHeader(
|
||||
{ "${applicationConfig.url}/api/v1/public?max_id=$it" },
|
||||
{ "${applicationConfig.url}/api/v1/public?min_id=$it" }
|
||||
) ?: return@runBlocking ResponseEntity(
|
||||
publicTimeline.asFlow(),
|
||||
HttpStatus.OK
|
||||
)
|
||||
ResponseEntity.ok().header("Link", httpHeader).body(publicTimeline.asFlow())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package dev.usbharu.hideout.mastodon.service.timeline
|
||||
|
||||
import dev.usbharu.hideout.application.external.Transaction
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.Page
|
||||
import dev.usbharu.hideout.application.infrastructure.exposed.PaginationList
|
||||
import dev.usbharu.hideout.core.service.timeline.GenerateTimelineService
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Status
|
||||
import org.springframework.stereotype.Service
|
||||
|
@ -17,6 +19,13 @@ interface TimelineApiService {
|
|||
limit: Int = 20
|
||||
): List<Status>
|
||||
|
||||
suspend fun publicTimeline(
|
||||
localOnly: Boolean = false,
|
||||
remoteOnly: Boolean = false,
|
||||
mediaOnly: Boolean = false,
|
||||
page: Page
|
||||
): PaginationList<Status, Long>
|
||||
|
||||
suspend fun homeTimeline(
|
||||
userId: Long,
|
||||
maxId: Long?,
|
||||
|
@ -24,6 +33,11 @@ interface TimelineApiService {
|
|||
sinceId: Long?,
|
||||
limit: Int = 20
|
||||
): List<Status>
|
||||
|
||||
suspend fun homeTimeline(
|
||||
userId: Long,
|
||||
page: Page
|
||||
): PaginationList<Status, Long>
|
||||
}
|
||||
|
||||
@Service
|
||||
|
@ -51,6 +65,13 @@ class TimelineApiServiceImpl(
|
|||
)
|
||||
}
|
||||
|
||||
override suspend fun publicTimeline(
|
||||
localOnly: Boolean,
|
||||
remoteOnly: Boolean,
|
||||
mediaOnly: Boolean,
|
||||
page: Page
|
||||
): PaginationList<Status, Long> = generateTimelineService.getTimeline(forUserId = 0, localOnly, mediaOnly, page)
|
||||
|
||||
override suspend fun homeTimeline(
|
||||
userId: Long,
|
||||
maxId: Long?,
|
||||
|
@ -66,4 +87,7 @@ class TimelineApiServiceImpl(
|
|||
limit = limit
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun homeTimeline(userId: Long, page: Page): PaginationList<Status, Long> =
|
||||
generateTimelineService.getTimeline(forUserId = userId, page = page)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue