mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-06-30 17:34:39 -05:00
Remove redundant code and add next/prev links (#1263)
This commit is contained in:
@@ -160,29 +160,10 @@ object Opds {
|
|||||||
Pair(sources, totalCount)
|
Pair(sources, totalCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
return serialize(
|
return FeedBuilder(baseUrl, pageNum, "sources", "Sources")
|
||||||
OpdsXmlModels(
|
.apply {
|
||||||
id = "sources",
|
totalResults = totalCount.toLong()
|
||||||
title = "Sources",
|
entries +=
|
||||||
updated = formattedNow,
|
|
||||||
totalResults = totalCount,
|
|
||||||
itemsPerPage = ITEMS_PER_PAGE,
|
|
||||||
startIndex = (pageNum - 1) * ITEMS_PER_PAGE + 1,
|
|
||||||
author = OpdsXmlModels.Author("Suwayomi", "https://suwayomi.org/"),
|
|
||||||
links =
|
|
||||||
listOfNotNull(
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "self",
|
|
||||||
href = "$baseUrl/sources?pageNumber=$pageNum",
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
|
||||||
),
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "start",
|
|
||||||
href = baseUrl,
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
entries =
|
|
||||||
sourceList.map {
|
sourceList.map {
|
||||||
OpdsXmlModels.Entry(
|
OpdsXmlModels.Entry(
|
||||||
updated = formattedNow,
|
updated = formattedNow,
|
||||||
@@ -197,9 +178,9 @@ object Opds {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
),
|
}.build()
|
||||||
)
|
.let(::serialize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCategoriesFeed(
|
fun getCategoriesFeed(
|
||||||
@@ -221,34 +202,16 @@ object Opds {
|
|||||||
Pair(row[CategoryTable.id].value, row[CategoryTable.name])
|
Pair(row[CategoryTable.id].value, row[CategoryTable.name])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val totalCount = categoryList.size
|
val totalCount = categoryList.size
|
||||||
val fromIndex = (pageNum - 1) * ITEMS_PER_PAGE
|
val fromIndex = (pageNum - 1) * ITEMS_PER_PAGE
|
||||||
val toIndex = minOf(fromIndex + ITEMS_PER_PAGE, totalCount)
|
val toIndex = minOf(fromIndex + ITEMS_PER_PAGE, totalCount)
|
||||||
val paginatedCategories = if (fromIndex < totalCount) categoryList.subList(fromIndex, toIndex) else emptyList()
|
val paginatedCategories = if (fromIndex < totalCount) categoryList.subList(fromIndex, toIndex) else emptyList()
|
||||||
|
|
||||||
return serialize(
|
return FeedBuilder(baseUrl, pageNum, "categories", "Categories")
|
||||||
OpdsXmlModels(
|
.apply {
|
||||||
id = "categories",
|
totalResults = totalCount.toLong()
|
||||||
title = "Categories",
|
entries +=
|
||||||
updated = formattedNow,
|
|
||||||
author = OpdsXmlModels.Author("Suwayomi", "https://suwayomi.org/"),
|
|
||||||
totalResults = totalCount.toLong(),
|
|
||||||
itemsPerPage = ITEMS_PER_PAGE,
|
|
||||||
startIndex = fromIndex + 1,
|
|
||||||
links =
|
|
||||||
listOf(
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "self",
|
|
||||||
href = "$baseUrl/categories?pageNumber=$pageNum",
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
|
||||||
),
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "start",
|
|
||||||
href = baseUrl,
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
entries =
|
|
||||||
paginatedCategories.map { (id, name) ->
|
paginatedCategories.map { (id, name) ->
|
||||||
OpdsXmlModels.Entry(
|
OpdsXmlModels.Entry(
|
||||||
id = "category/$id",
|
id = "category/$id",
|
||||||
@@ -263,9 +226,9 @@ object Opds {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
),
|
}.build()
|
||||||
)
|
.let(::serialize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGenresFeed(
|
fun getGenresFeed(
|
||||||
@@ -346,29 +309,10 @@ object Opds {
|
|||||||
val toIndex = minOf(fromIndex + ITEMS_PER_PAGE, totalCount)
|
val toIndex = minOf(fromIndex + ITEMS_PER_PAGE, totalCount)
|
||||||
val paginatedStatuses = if (fromIndex < totalCount) statuses.subList(fromIndex, toIndex) else emptyList()
|
val paginatedStatuses = if (fromIndex < totalCount) statuses.subList(fromIndex, toIndex) else emptyList()
|
||||||
|
|
||||||
return serialize(
|
return FeedBuilder(baseUrl, pageNum, "status", "Status")
|
||||||
OpdsXmlModels(
|
.apply {
|
||||||
id = "status",
|
totalResults = totalCount.toLong()
|
||||||
title = "Status",
|
entries +=
|
||||||
updated = formattedNow,
|
|
||||||
author = OpdsXmlModels.Author("Suwayomi", "https://suwayomi.org/"),
|
|
||||||
totalResults = totalCount.toLong(),
|
|
||||||
itemsPerPage = ITEMS_PER_PAGE,
|
|
||||||
startIndex = fromIndex + 1,
|
|
||||||
links =
|
|
||||||
listOf(
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "self",
|
|
||||||
href = "$baseUrl/status?pageNumber=$pageNum",
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
|
||||||
),
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "start",
|
|
||||||
href = baseUrl,
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
entries =
|
|
||||||
paginatedStatuses.map { status ->
|
paginatedStatuses.map { status ->
|
||||||
OpdsXmlModels.Entry(
|
OpdsXmlModels.Entry(
|
||||||
id = "status/${status.value}",
|
id = "status/${status.value}",
|
||||||
@@ -387,9 +331,46 @@ object Opds {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
),
|
}.build()
|
||||||
)
|
.let(::serialize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLanguagesFeed(baseUrl: String): String {
|
||||||
|
val formattedNow = opdsDateFormatter.format(Instant.now())
|
||||||
|
val languages =
|
||||||
|
transaction {
|
||||||
|
SourceTable
|
||||||
|
.join(MangaTable, JoinType.INNER, onColumn = SourceTable.id, otherColumn = MangaTable.sourceReference)
|
||||||
|
.join(ChapterTable, JoinType.INNER, onColumn = MangaTable.id, otherColumn = ChapterTable.manga)
|
||||||
|
.select(SourceTable.lang)
|
||||||
|
.where { ChapterTable.isDownloaded eq true }
|
||||||
|
.groupBy(SourceTable.lang)
|
||||||
|
.orderBy(SourceTable.lang to SortOrder.ASC)
|
||||||
|
.map { row -> row[SourceTable.lang] }
|
||||||
|
}
|
||||||
|
|
||||||
|
return FeedBuilder(baseUrl, 1, "languages", "Languages")
|
||||||
|
.apply {
|
||||||
|
totalResults = languages.size.toLong()
|
||||||
|
entries +=
|
||||||
|
languages.map { lang ->
|
||||||
|
OpdsXmlModels.Entry(
|
||||||
|
id = "language/$lang",
|
||||||
|
title = lang,
|
||||||
|
updated = formattedNow,
|
||||||
|
link =
|
||||||
|
listOf(
|
||||||
|
OpdsXmlModels.Link(
|
||||||
|
rel = "subsection",
|
||||||
|
href = "$baseUrl/language/$lang",
|
||||||
|
type = "application/atom+xml;profile=opds-catalog;kind=acquisition",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.build()
|
||||||
|
.let(::serialize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMangaFeed(
|
fun getMangaFeed(
|
||||||
@@ -423,111 +404,27 @@ object Opds {
|
|||||||
Triple(mangaData, chaptersData, total)
|
Triple(mangaData, chaptersData, total)
|
||||||
}
|
}
|
||||||
|
|
||||||
return serialize(
|
return FeedBuilder(baseUrl, pageNum, "manga/$mangaId", manga.title)
|
||||||
OpdsXmlModels(
|
.apply {
|
||||||
id = "manga/$mangaId",
|
totalResults = totalCount
|
||||||
title = manga.title,
|
icon = manga.thumbnailUrl
|
||||||
updated = formattedNow,
|
manga.thumbnailUrl?.let { url ->
|
||||||
icon = manga.thumbnailUrl,
|
links +=
|
||||||
author =
|
|
||||||
OpdsXmlModels.Author(
|
|
||||||
name = "Suwayomi",
|
|
||||||
uri = "https://suwayomi.org/",
|
|
||||||
),
|
|
||||||
totalResults = totalCount,
|
|
||||||
itemsPerPage = ITEMS_PER_PAGE,
|
|
||||||
startIndex = (pageNum - 1) * ITEMS_PER_PAGE + 1,
|
|
||||||
links =
|
|
||||||
listOfNotNull(
|
|
||||||
OpdsXmlModels.Link(
|
OpdsXmlModels.Link(
|
||||||
rel = "self",
|
rel = "http://opds-spec.org/image",
|
||||||
href = "$baseUrl/manga/$mangaId?pageNumber=$pageNum",
|
href = url,
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=acquisition",
|
type = "image/jpeg",
|
||||||
),
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "start",
|
|
||||||
href = baseUrl,
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
|
||||||
),
|
|
||||||
manga.thumbnailUrl?.let { url ->
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "http://opds-spec.org/image",
|
|
||||||
href = url,
|
|
||||||
type = "image/jpeg",
|
|
||||||
)
|
|
||||||
},
|
|
||||||
manga.thumbnailUrl?.let { url ->
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "http://opds-spec.org/image/thumbnail",
|
|
||||||
href = url,
|
|
||||||
type = "image/jpeg",
|
|
||||||
)
|
|
||||||
},
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "search",
|
|
||||||
type = "application/opensearchdescription+xml",
|
|
||||||
href = "$baseUrl/search",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
entries =
|
|
||||||
chapters.map { chapter ->
|
|
||||||
createChapterEntry(chapter, manga)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLanguagesFeed(baseUrl: String): String {
|
|
||||||
val formattedNow = opdsDateFormatter.format(Instant.now())
|
|
||||||
val languages =
|
|
||||||
transaction {
|
|
||||||
SourceTable
|
|
||||||
.join(MangaTable, JoinType.INNER, onColumn = SourceTable.id, otherColumn = MangaTable.sourceReference)
|
|
||||||
.join(ChapterTable, JoinType.INNER, onColumn = MangaTable.id, otherColumn = ChapterTable.manga)
|
|
||||||
.select(SourceTable.lang)
|
|
||||||
.where { ChapterTable.isDownloaded eq true }
|
|
||||||
.groupBy(SourceTable.lang)
|
|
||||||
.orderBy(SourceTable.lang to SortOrder.ASC)
|
|
||||||
.map { row -> row[SourceTable.lang] }
|
|
||||||
}
|
|
||||||
|
|
||||||
return serialize(
|
|
||||||
OpdsXmlModels(
|
|
||||||
id = "languages",
|
|
||||||
title = "Languages",
|
|
||||||
updated = formattedNow,
|
|
||||||
author = OpdsXmlModels.Author("Suwayomi", "https://suwayomi.org/"),
|
|
||||||
links =
|
|
||||||
listOf(
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "self",
|
|
||||||
href = "$baseUrl/languages",
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
|
||||||
),
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "start",
|
|
||||||
href = baseUrl,
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
entries =
|
|
||||||
languages.map { lang ->
|
|
||||||
OpdsXmlModels.Entry(
|
|
||||||
id = "language/$lang",
|
|
||||||
title = lang,
|
|
||||||
updated = formattedNow,
|
|
||||||
link =
|
|
||||||
listOf(
|
|
||||||
OpdsXmlModels.Link(
|
|
||||||
rel = "subsection",
|
|
||||||
href = "$baseUrl/language/$lang",
|
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=acquisition",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
links +=
|
||||||
),
|
OpdsXmlModels.Link(
|
||||||
)
|
rel = "http://opds-spec.org/image/thumbnail",
|
||||||
|
href = url,
|
||||||
|
type = "image/jpeg",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
entries += chapters.map { createChapterEntry(it, manga) }
|
||||||
|
}.build()
|
||||||
|
.let(::serialize)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createChapterEntry(
|
private fun createChapterEntry(
|
||||||
@@ -780,16 +677,14 @@ object Opds {
|
|||||||
author = OpdsXmlModels.Author("Suwayomi", "https://suwayomi.org/"),
|
author = OpdsXmlModels.Author("Suwayomi", "https://suwayomi.org/"),
|
||||||
links =
|
links =
|
||||||
links +
|
links +
|
||||||
listOf(
|
listOfNotNull(
|
||||||
OpdsXmlModels.Link(
|
OpdsXmlModels.Link(
|
||||||
rel = "self",
|
rel = "self",
|
||||||
href =
|
href =
|
||||||
if (id == "opds") {
|
when {
|
||||||
baseUrl
|
id == "opds" -> baseUrl
|
||||||
} else if (searchQuery != null) {
|
searchQuery != null -> "$baseUrl/$id?query=$searchQuery"
|
||||||
"$baseUrl/$id?query=$searchQuery"
|
else -> "$baseUrl/$id?pageNumber=$pageNum"
|
||||||
} else {
|
|
||||||
"$baseUrl/$id?pageNumber=$pageNum"
|
|
||||||
},
|
},
|
||||||
type = "application/atom+xml;profile=opds-catalog;kind=acquisition",
|
type = "application/atom+xml;profile=opds-catalog;kind=acquisition",
|
||||||
),
|
),
|
||||||
@@ -803,6 +698,20 @@ object Opds {
|
|||||||
type = "application/opensearchdescription+xml",
|
type = "application/opensearchdescription+xml",
|
||||||
href = "$baseUrl/search",
|
href = "$baseUrl/search",
|
||||||
),
|
),
|
||||||
|
pageNum.takeIf { it > 1 }?.let {
|
||||||
|
OpdsXmlModels.Link(
|
||||||
|
rel = "prev",
|
||||||
|
href = "$baseUrl/$id?pageNumber=${it - 1}",
|
||||||
|
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
(totalResults > pageNum * ITEMS_PER_PAGE).takeIf { it }?.let {
|
||||||
|
OpdsXmlModels.Link(
|
||||||
|
rel = "next",
|
||||||
|
href = "$baseUrl/$id?pageNumber=${pageNum + 1}",
|
||||||
|
type = "application/atom+xml;profile=opds-catalog;kind=navigation",
|
||||||
|
)
|
||||||
|
},
|
||||||
),
|
),
|
||||||
entries = entries,
|
entries = entries,
|
||||||
totalResults = totalResults,
|
totalResults = totalResults,
|
||||||
|
|||||||
Reference in New Issue
Block a user