Skip to content

Commit

Permalink
Sync upstream of Bangumi Next API, close #1642.
Browse files Browse the repository at this point in the history
  • Loading branch information
StageGuard committed Feb 13, 2025
1 parent ca142ab commit 67d8c9b
Show file tree
Hide file tree
Showing 68 changed files with 4,694 additions and 4,755 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
package me.him188.ani.app.data.models.episode

import me.him188.ani.app.data.models.UserInfo
import me.him188.ani.datasources.bangumi.next.models.BangumiNextGetSubjectEpisodeComments200ResponseInner
import me.him188.ani.datasources.bangumi.next.models.BangumiNextGetEpisodeComments200ResponseInner

data class EpisodeComment(
val commentId: Int,
Expand All @@ -25,9 +25,9 @@ data class EpisodeComment(
val replies: List<EpisodeComment> = listOf()
)

fun BangumiNextGetSubjectEpisodeComments200ResponseInner.toEpisodeComment() = EpisodeComment(
fun BangumiNextGetEpisodeComments200ResponseInner.toEpisodeComment(episodeId: Int) = EpisodeComment(
commentId = id,
episodeId = epID,
episodeId = episodeId,
createdAt = createdAt * 1000L,
content = content,
author = user?.let { u ->
Expand All @@ -41,7 +41,7 @@ fun BangumiNextGetSubjectEpisodeComments200ResponseInner.toEpisodeComment() = Ep
replies = replies.map { r ->
EpisodeComment(
commentId = r.id,
episodeId = r.epID,
episodeId = episodeId,
createdAt = r.createdAt * 1000L,
content = r.content,
author = r.user?.let { u ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ import me.him188.ani.app.data.models.subject.SubjectReview
import me.him188.ani.datasources.api.paging.Paged
import me.him188.ani.datasources.api.paging.processPagedResponse
import me.him188.ani.datasources.bangumi.BangumiClient
import me.him188.ani.datasources.bangumi.next.models.BangumiNextCreateSubjectEpCommentRequest
import me.him188.ani.datasources.bangumi.next.models.BangumiNextGetSubjectEpisodeComments200ResponseInner
import me.him188.ani.datasources.bangumi.next.models.BangumiNextSubjectComment
import me.him188.ani.datasources.bangumi.next.models.BangumiNextCreateEpisodeCommentRequest
import me.him188.ani.datasources.bangumi.next.models.BangumiNextGetEpisodeComments200ResponseInner
import me.him188.ani.datasources.bangumi.next.models.BangumiNextSubjectInterestComment
import me.him188.ani.utils.coroutines.IO_
import kotlin.coroutines.CoroutineContext

sealed interface BangumiCommentService {
/**
* @return `null` if [subjectId] is invalid
*/
suspend fun getSubjectReviews(subjectId: Int, offset: Int, limit: Int): Paged<SubjectReview>?
suspend fun getSubjectComments(subjectId: Int, offset: Int, limit: Int): Paged<SubjectReview>?

/**
* @return `null` if [subjectId] is invalid
* @return `null` if [episodeId] is invalid
*/
suspend fun getSubjectEpisodeComments(subjectId: Int): List<EpisodeComment>?
suspend fun getSubjectEpisodeComments(episodeId: Int): List<EpisodeComment>?

// comment.id 会被忽略
suspend fun postEpisodeComment(
Expand All @@ -51,10 +51,10 @@ class BangumiBangumiCommentServiceImpl(
private val client: BangumiClient,
private val ioDispatcher: CoroutineContext = Dispatchers.IO_,
) : BangumiCommentService {
override suspend fun getSubjectReviews(subjectId: Int, offset: Int, limit: Int): Paged<SubjectReview>? {
override suspend fun getSubjectComments(subjectId: Int, offset: Int, limit: Int): Paged<SubjectReview>? {
return withContext(ioDispatcher) {
val response = try {
client.nextApi {
client.nextSubjectApi {
getSubjectComments(subjectId, null, limit, offset)
.body()
}
Expand All @@ -76,10 +76,10 @@ class BangumiBangumiCommentServiceImpl(
replyToCommentId: Int?
) {
withContext(ioDispatcher) {
client.nextApi {
createSubjectEpComment(
client.nextEpisodeApi {
createEpisodeComment(
episodeId,
BangumiNextCreateSubjectEpCommentRequest(
BangumiNextCreateEpisodeCommentRequest(
cfTurnstileResponse,
content,
replyToCommentId,
Expand All @@ -90,13 +90,13 @@ class BangumiBangumiCommentServiceImpl(
}
}

override suspend fun getSubjectEpisodeComments(subjectId: Int): List<EpisodeComment>? {
override suspend fun getSubjectEpisodeComments(episodeId: Int): List<EpisodeComment>? {
return withContext(ioDispatcher) {
val response = try {
client.nextApi {
getSubjectEpisodeComments(subjectId)
client.nextEpisodeApi {
getEpisodeComments(episodeId)
.body()
.map(BangumiNextGetSubjectEpisodeComments200ResponseInner::toEpisodeComment)
.map { it.toEpisodeComment(episodeId) }
}
} catch (e: ClientRequestException) {
if (e.response.status == HttpStatusCode.NotFound || e.response.status == HttpStatusCode.BadRequest) {
Expand All @@ -109,8 +109,8 @@ class BangumiBangumiCommentServiceImpl(
}
}

private fun BangumiNextSubjectComment.toSubjectReview(subjectId: Int) = SubjectReview(
id = packInts(subjectId, user.id ?: 0),
private fun BangumiNextSubjectInterestComment.toSubjectReview(subjectId: Int) = SubjectReview(
id = packInts(subjectId, user.id),
content = comment,
updatedAt = updatedAt * 1000L,
rating = rate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class BangumiCommentRepository(
}

try {
val subjectReviews = commentService.getSubjectReviews(subjectId, offset, state.config.pageSize)
val subjectReviews = commentService.getSubjectComments(subjectId, offset, state.config.pageSize)
?: return@withContext MediatorResult.Success(endOfPaginationReached = true)

subjectReviewDao.upsert(subjectReviews.page.mapNotNull { it.toEntity(subjectId) })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ object CommentDefaults {
list.forEach {
Reaction(
reaction = it,
modifier = Modifier.padding(vertical = 6.dp),
onClick = { onClickItem(it.id) },
)
}
Expand Down
56 changes: 25 additions & 31 deletions datasource/bangumi/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -130,53 +130,47 @@ val generateApiP1 = tasks.register("generateApiP1", GenerateTask::class) {
)
}

/**
* 我们只需要保留吐槽箱相关的 API
*/
private fun stripP1Api(path: String): File {
val yaml = org.yaml.snakeyaml.Yaml()
val p1ApiObject: Map<String, Any> = File(path).inputStream().use { yaml.load(it) }

// keep subjects only
val paths = p1ApiObject["paths"].cast<Map<String, *>>().toMutableMap()
val subjectPaths = paths.filter { (path, _) -> path.startsWith("/p1/subjects") }
val keepPaths = listOf(
"/p1/episodes/-/comments", // 条目剧集的吐槽箱, 作为剧集评论
"/p1/episodes/{episodeID}", // 条目剧集的吐槽箱, 作为剧集评论
"/p1/subjects/{subjectID}/comments", // 条目吐槽箱, 作为条目评论
)
val subjectPaths = paths.filter { (path, _) -> keepPaths.any { path.startsWith(it) } }
println("The following paths are kept: ${subjectPaths.keys}")

// keep components referred by subjects only
val components = p1ApiObject["components"].cast<Map<String, *>>().toMutableMap()
components.remove("securitySchemes")
val keepSchemaKeys = listOf(
"ErrorResponse",
"Reply",
"UpdateContent",
"Episode",
"Reaction",
"PersonImages",
"BasicReply",
"Subject",
"TopicDetail",
"Group",
"GroupReply",
"BasicReply",
"Topic",
"BaseEpisodeComment",

"SlimSubject",
"SubjectComment",
"SlimUser",
"SubjectCharacter",
"Episode",
"SubjectRec",
"SubjectRelation",
"SubjectStaff",
"SubjectImages",
"CommentBase",
"CreateReply",
"TurnstileToken",

"CollectionType",
"SubjectInterestComment",
"Reaction",
"CollectionType",
"SlimUser",
"Avatar",
"Infobox",
"SubjectAirtime",
"SubjectCollection",
"SubjectImages",
"SubjectPlatform",
"SubjectRating",
"SubjectTag",
"SlimCharacter",
"SlimPerson",
"SubjectRelationType",
"SubjectStaffPosition",
"SimpleUser",

"EpisodeCollectionStatus",
"SlimSubject",
"EpisodeType"
)
val schemas = components["schemas"].cast<Map<String, *>>().toMutableMap()
val keepSchemas = schemas.filter { (component, _) -> component in keepSchemaKeys }
Expand Down
Loading

0 comments on commit 67d8c9b

Please sign in to comment.