Update extensions lib (#138)

* add comments

* reorganize methods
This commit is contained in:
Tran M. Cuong 2024-07-05 10:36:29 +07:00 committed by GitHub
parent 87306ceef1
commit 799de48b7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 165 additions and 116 deletions

View file

@ -8,10 +8,21 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope
import logcat.LogPriority
import rx.Observable
import tachiyomi.core.common.util.lang.awaitSingle
import tachiyomi.core.common.util.system.logcat
/**
* A basic interface for creating a source. It could be an online source, a local source, etc.
*
* Supposedly, it expects extensions to overwrite get...() methods while leaving those fetch...() alone.
* Hence in extensions-lib, it will leave get...() methods as unimplemented
* and fetch...() as IllegalStateException("Not used").
*
* Prior to extensions-lib 1.5, all extensions still using fetch...(). Because of this,
* in extensions-lib all get...() methods will be implemented as Exception("Stub!") while
* all fetch...() methods will leave unimplemented.
* But if we want to migrate extensions to use get...() then those fetch...()
* should still be implemented as IllegalStateException("Not used").
*/
interface CatalogueSource : Source {
/**
@ -30,10 +41,7 @@ interface CatalogueSource : Source {
* @since extensions-lib 1.5
* @param page the page number to retrieve.
*/
@Suppress("DEPRECATION")
suspend fun getPopularManga(page: Int): MangasPage {
return fetchPopularManga(page).awaitSingle()
}
suspend fun getPopularManga(page: Int): MangasPage
/**
* Get a page with a list of manga.
@ -43,10 +51,7 @@ interface CatalogueSource : Source {
* @param query the search query.
* @param filters the list of filters to apply.
*/
@Suppress("DEPRECATION")
suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage {
return fetchSearchManga(page, query, filters).awaitSingle()
}
suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage
/**
* Get a page with a list of latest manga updates.
@ -54,10 +59,7 @@ interface CatalogueSource : Source {
* @since extensions-lib 1.5
* @param page the page number to retrieve.
*/
@Suppress("DEPRECATION")
suspend fun getLatestUpdates(page: Int): MangasPage {
return fetchLatestUpdates(page).awaitSingle()
}
suspend fun getLatestUpdates(page: Int): MangasPage
/**
* Returns the list of filters for the source.
@ -132,8 +134,7 @@ interface CatalogueSource : Source {
* @return the related mangas for the current manga.
* @throws UnsupportedOperationException if a source doesn't support related mangas.
*/
suspend fun fetchRelatedMangaList(manga: SManga): List<SManga> =
throw IllegalStateException("Not used")
suspend fun fetchRelatedMangaList(manga: SManga): List<SManga> = throw UnsupportedOperationException("Unsupported!")
/**
* Slit & strip manga's title into separate searchable keywords.
@ -195,25 +196,4 @@ interface CatalogueSource : Source {
}
}
// KMK <--
@Deprecated(
"Use the non-RxJava API instead",
ReplaceWith("getPopularManga"),
)
fun fetchPopularManga(page: Int): Observable<MangasPage> =
throw IllegalStateException("Not used")
@Deprecated(
"Use the non-RxJava API instead",
ReplaceWith("getSearchManga"),
)
fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> =
throw IllegalStateException("Not used")
@Deprecated(
"Use the non-RxJava API instead",
ReplaceWith("getLatestUpdates"),
)
fun fetchLatestUpdates(page: Int): Observable<MangasPage> =
throw IllegalStateException("Not used")
}

View file

@ -3,11 +3,19 @@ package eu.kanade.tachiyomi.source
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.awaitSingle
import rx.Observable
/**
* A basic interface for creating a source. It could be an online source, a local source, etc.
* A basic interface for creating a source. It could be an online source, a local source, stub source, etc.
*
* Supposedly, it expects extensions to overwrite get...() methods while leaving those fetch...() alone.
* Hence in extensions-lib, it will leave get...() methods as unimplemented
* and fetch...() as IllegalStateException("Not used").
*
* Prior to extensions-lib 1.5, all extensions still using fetch...(). Because of this,
* in extensions-lib all get...() methods will be implemented as Exception("Stub!") while
* all fetch...() methods will leave unimplemented.
* But if we want to migrate extensions to use get...() then those fetch...()
* should still be implemented as IllegalStateException("Not used").
*/
interface Source {
@ -27,26 +35,30 @@ interface Source {
/**
* Get the updated details for a manga.
*
* @since extensions-lib 1.5
* @since extensions-lib 1.4
* @param manga the manga to update.
* @return the updated manga.
*/
@Suppress("DEPRECATION")
suspend fun getMangaDetails(manga: SManga): SManga {
return fetchMangaDetails(manga).awaitSingle()
}
suspend fun getMangaDetails(manga: SManga): SManga
/**
* Get all the available chapters for a manga.
*
* @since extensions-lib 1.5
* @since extensions-lib 1.4
* @param manga the manga to update.
* @return the chapters for the manga.
*/
@Suppress("DEPRECATION")
suspend fun getChapterList(manga: SManga): List<SChapter> {
return fetchChapterList(manga).awaitSingle()
}
suspend fun getChapterList(manga: SManga): List<SChapter>
/**
* Get the list of pages a chapter has. Pages should be returned
* in the expected order; the index is ignored.
*
* @since komikku/extensions-lib 1.7
* @param chapter the chapter.
* @return the pages for the chapter.
*/
suspend fun getPageList(chapter: SChapter): List<Page>
// KMK -->
/**
@ -60,40 +72,6 @@ interface Source {
manga: SManga,
exceptionHandler: (Throwable) -> Unit,
pushResults: suspend (relatedManga: Pair<String, List<SManga>>, completed: Boolean) -> Unit,
): Unit = throw IllegalStateException("Not used")
)
// KMK <--
/**
* Get the list of pages a chapter has. Pages should be returned
* in the expected order; the index is ignored.
*
* @since extensions-lib 1.5
* @param chapter the chapter.
* @return the pages for the chapter.
*/
@Suppress("DEPRECATION")
suspend fun getPageList(chapter: SChapter): List<Page> {
return fetchPageList(chapter).awaitSingle()
}
@Deprecated(
"Use the non-RxJava API instead",
ReplaceWith("getMangaDetails"),
)
fun fetchMangaDetails(manga: SManga): Observable<SManga> =
throw IllegalStateException("Not used")
@Deprecated(
"Use the non-RxJava API instead",
ReplaceWith("getChapterList"),
)
fun fetchChapterList(manga: SManga): Observable<List<SChapter>> =
throw IllegalStateException("Not used")
@Deprecated(
"Use the non-RxJava API instead",
ReplaceWith("getPageList"),
)
fun fetchPageList(chapter: SChapter): Observable<List<Page>> =
throw IllegalStateException("Not used")
}

View file

@ -32,6 +32,16 @@ import java.security.MessageDigest
/**
* A simple implementation for sources from a website.
*
* Supposedly, it expects extensions to overwrite get...() methods while leaving those fetch...() alone.
* Hence in extensions-lib, it will leave get...() methods as unimplemented
* and fetch...() as IllegalStateException("Not used").
*
* Prior to extensions-lib 1.5, all extensions still using fetch...(). Because of this,
* in extensions-lib all get...() methods will be implemented as Exception("Stub!") while
* all fetch...() methods will leave unimplemented.
* But if we want to migrate extensions to use get...() then those fetch...()
* should still be implemented as IllegalStateException("Not used").
*/
@Suppress("unused")
abstract class HttpSource : CatalogueSource {
@ -132,13 +142,25 @@ abstract class HttpSource : CatalogueSource {
override fun toString() = "$name (${lang.uppercase()})"
/**
* Returns an observable containing a page with a list of manga. Normally it's not needed to
* override this method.
* Get a page with a list of manga.
* Normally it's not needed to override this method.
*
* @since extensions-lib 1.5
* @param page the page number to retrieve.
*/
override suspend fun getPopularManga(page: Int): MangasPage {
@Suppress("DEPRECATION")
return fetchPopularManga(page).awaitSingle()
}
/**
* Returns an observable containing a page with a list of manga.
* Normally it's not needed to override this method.
*
* @param page the page number to retrieve.
*/
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga"))
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPopularManga(page)"))
open fun fetchPopularManga(page: Int): Observable<MangasPage> {
return client.newCall(popularMangaRequest(page))
.asObservableSuccess()
.map { response ->
@ -161,15 +183,29 @@ abstract class HttpSource : CatalogueSource {
protected abstract fun popularMangaParse(response: Response): MangasPage
/**
* Returns an observable containing a page with a list of manga. Normally it's not needed to
* override this method.
* Get a page with a list of manga.
* Normally it's not needed to override this method.
*
* @since extensions-lib 1.5
* @param page the page number to retrieve.
* @param query the search query.
* @param filters the list of filters to apply.
*/
override suspend fun getSearchManga(page: Int, query: String, filters: FilterList): MangasPage {
@Suppress("DEPRECATION")
return fetchSearchManga(page, query, filters).awaitSingle()
}
/**
* Returns an observable containing a page with a list of manga.
* Normally it's not needed to override this method.
*
* @param page the page number to retrieve.
* @param query the search query.
* @param filters the list of filters to apply.
*/
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga"))
override fun fetchSearchManga(
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getSearchManga(page, query, filters)"))
open fun fetchSearchManga(
page: Int,
query: String,
filters: FilterList,
@ -208,13 +244,26 @@ abstract class HttpSource : CatalogueSource {
*/
protected abstract fun searchMangaParse(response: Response): MangasPage
/**
* Get a page with a list of latest manga updates.
* Normally it's not needed to override this method.
*
* @since extensions-lib 1.5
* @param page the page number to retrieve.
*/
override suspend fun getLatestUpdates(page: Int): MangasPage {
@Suppress("DEPRECATION")
return fetchLatestUpdates(page).awaitSingle()
}
/**
* Returns an observable containing a page with a list of latest manga updates.
* Normally it's not needed to override this method.
*
* @param page the page number to retrieve.
*/
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates"))
override fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getLatestUpdates(page)"))
open fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
return client.newCall(latestUpdatesRequest(page))
.asObservableSuccess()
.map { response ->
@ -242,16 +291,23 @@ abstract class HttpSource : CatalogueSource {
* Get the updated details for a manga.
* Normally it's not needed to override this method.
*
* @since extensions-lib 1.4
* @param manga the manga to update.
* @return the updated manga.
*/
@Suppress("DEPRECATION")
override suspend fun getMangaDetails(manga: SManga): SManga {
@Suppress("DEPRECATION")
return fetchMangaDetails(manga).awaitSingle()
}
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getMangaDetails"))
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
/**
* Returns an observable with the updated details for a manga.
* Normally it's not needed to override this method.
*
* @param manga the manga to be updated.
*/
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getMangaDetails(manga)"))
open fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return client.newCall(mangaDetailsRequest(manga))
.asObservableSuccess()
.map { response ->
@ -262,6 +318,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Returns the request for the details of a manga. Override only if it's needed to change the
* url, send different headers or request method like POST.
* Normally it's not needed to override this method.
*
* @param manga the manga to be updated.
*/
@ -279,6 +336,7 @@ abstract class HttpSource : CatalogueSource {
// KMK -->
/**
* Whether parsing related mangas in manga page or extension provide custom related mangas request.
*
* @default true
* @since komikku/extensions-lib 1.6
*/
@ -306,7 +364,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Returns the request for get related manga list. Override only if it's needed to override
* the url, send different headers or request method like POST.
* If using this, must also: 'override val supportsRelatedMangas = true'
* Normally it's not needed to override this method.
*
* @since komikku/extensions-lib 1.6
* @param manga the manga to look for related mangas.
@ -317,7 +375,6 @@ abstract class HttpSource : CatalogueSource {
/**
* Parses the response from the site and returns a list of related mangas.
* If using this, must also: 'override val supportsRelatedMangas = true'
*
* @since komikku/extensions-lib 1.6
* @param response the response from the site.
@ -333,17 +390,23 @@ abstract class HttpSource : CatalogueSource {
* @return the chapters for the manga.
* @throws LicensedMangaChaptersException if a manga is licensed and therefore no chapters are available.
*/
@Suppress("DEPRECATION")
override suspend fun getChapterList(manga: SManga): List<SChapter> {
if (manga.status == SManga.LICENSED) {
throw LicensedMangaChaptersException()
}
@Suppress("DEPRECATION")
return fetchChapterList(manga).awaitSingle()
}
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getChapterList"))
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
/**
* Returns an observable with the updated chapter list for a manga.
* Normally it's not needed to override this method.
*
* @param manga the manga to look for chapters.
*/
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getChapterList(manga)"))
open fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return if (manga.status != SManga.LICENSED) {
client.newCall(chapterListRequest(manga))
.asObservableSuccess()
@ -358,6 +421,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Returns the request for updating the chapter list. Override only if it's needed to override
* the url, send different headers or request method like POST.
* Normally it's not needed to override this method.
*
* @param manga the manga to look for chapters.
*/
@ -377,22 +441,29 @@ abstract class HttpSource : CatalogueSource {
*
* @param response the response from the site.
*/
protected abstract fun chapterPageParse(response: Response): SChapter
protected open fun chapterPageParse(response: Response): SChapter = throw UnsupportedOperationException("Not used!")
/**
* Get the list of pages a chapter has. Pages should be returned
* in the expected order; the index is ignored.
* Normally it's not needed to override this method.
*
* @param chapter the chapter.
* @return the pages for the chapter.
*/
@Suppress("DEPRECATION")
override suspend fun getPageList(chapter: SChapter): List<Page> {
@Suppress("DEPRECATION")
return fetchPageList(chapter).awaitSingle()
}
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPageList"))
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
/**
* Returns an observable with the page list for a chapter.
* Normally it's not needed to override this method.
*
* @param chapter the chapter whose page list has to be fetched.
*/
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getPageList(chapter)"))
open fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
return client.newCall(pageListRequest(chapter))
.asObservableSuccess()
.map { response ->
@ -403,6 +474,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Returns the request for getting the page list. Override only if it's needed to override the
* url, send different headers or request method like POST.
* Normally it's not needed to override this method.
*
* @param chapter the chapter whose page list has to be fetched.
*/
@ -418,8 +490,8 @@ abstract class HttpSource : CatalogueSource {
protected abstract fun pageListParse(response: Response): List<Page>
/**
* Returns an observable with the page containing the source url of the image. If there's any
* error, it will return null instead of throwing an exception.
* Returns the source url of the image.
* Normally it's not needed to override this method.
*
* @since extensions-lib 1.5
* @param page the page whose source image has to be fetched.
@ -429,7 +501,14 @@ abstract class HttpSource : CatalogueSource {
return fetchImageUrl(page).awaitSingle()
}
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl"))
/**
* Returns an observable with the page containing the source url of the image. If there's any
* error, it will return null instead of throwing an exception.
* Normally it's not needed to override this method.
*
* @param page the page whose source image has to be fetched.
*/
@Deprecated("Use the non-RxJava API instead", replaceWith = ReplaceWith("getImageUrl(page)"))
open fun fetchImageUrl(page: Page): Observable<String> {
return client.newCall(imageUrlRequest(page))
.asObservableSuccess()
@ -439,6 +518,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Returns the request for getting the url to the source image. Override only if it's needed to
* override the url, send different headers or request method like POST.
* Normally it's not needed to override this method.
*
* @param page the chapter whose page list has to be fetched
*/
@ -455,7 +535,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Returns the response of the source image.
* Typically does not need to be overridden.
* Normally it's not needed to override this method.
*
* @since extensions-lib 1.5
* @param page the page whose source image has to be downloaded.
@ -468,6 +548,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Returns the request for getting the source image. Override only if it's needed to override
* the url, send different headers or request method like POST.
* Normally it's not needed to override this method.
*
* @param page the chapter whose page list has to be fetched
*/
@ -478,6 +559,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Assigns the url of the chapter without the scheme and domain. It saves some redundancy from
* database and the urls could still work after a domain change.
* Normally it's not needed to override this method.
*
* @param url the full url to the chapter.
*/
@ -488,6 +570,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Assigns the url of the manga without the scheme and domain. It saves some redundancy from
* database and the urls could still work after a domain change.
* Normally it's not needed to override this method.
*
* @param url the full url to the manga.
*/
@ -497,6 +580,7 @@ abstract class HttpSource : CatalogueSource {
/**
* Returns the url of the given string without the scheme and domain.
* Normally it's not needed to override this method.
*
* @param orig the full url.
*/
@ -517,7 +601,8 @@ abstract class HttpSource : CatalogueSource {
}
/**
* Returns the url of the provided manga
* Returns the url of the provided manga.
* Normally it's not needed to override this method.
*
* @since extensions-lib 1.4
* @param manga the manga
@ -528,7 +613,8 @@ abstract class HttpSource : CatalogueSource {
}
/**
* Returns the url of the provided chapter
* Returns the url of the provided chapter.
* Normally it's not needed to override this method.
*
* @since extensions-lib 1.4
* @param chapter the chapter

View file

@ -17,6 +17,7 @@ abstract class ParsedHttpSource : HttpSource() {
/**
* Parses the response from the site and returns a [MangasPage] object.
* Normally it's not needed to override this method.
*
* @param response the response from the site.
*/
@ -55,6 +56,7 @@ abstract class ParsedHttpSource : HttpSource() {
/**
* Parses the response from the site and returns a [MangasPage] object.
* Normally it's not needed to override this method.
*
* @param response the response from the site.
*/
@ -93,6 +95,7 @@ abstract class ParsedHttpSource : HttpSource() {
/**
* Parses the response from the site and returns a [MangasPage] object.
* Normally it's not needed to override this method.
*
* @param response the response from the site.
*/
@ -131,6 +134,7 @@ abstract class ParsedHttpSource : HttpSource() {
/**
* Parses the response from the site and returns the details of a manga.
* Normally it's not needed to override this method.
*
* @param response the response from the site.
*/
@ -148,7 +152,7 @@ abstract class ParsedHttpSource : HttpSource() {
// KMK -->
/**
* Parses the response from the site and returns a list of related mangas.
* If using this, must also: 'override val supportsRelatedMangas = true'
* Normally it's not needed to override this method.
*
* @since komikku/extensions-lib 1.6
* @param response the response from the site.
@ -160,7 +164,6 @@ abstract class ParsedHttpSource : HttpSource() {
/**
* Returns the Jsoup selector that returns a list of [Element] corresponding to each related mangas.
* If using this, must also: 'override val supportsRelatedMangas = true'
*
* @since komikku/extensions-lib 1.6
*/
@ -168,7 +171,6 @@ abstract class ParsedHttpSource : HttpSource() {
/**
* Returns a manga from the given element.
* If using this, must also: 'override val supportsRelatedMangas = true'
*
* @since komikku/extensions-lib 1.6
* @param element an element obtained from [relatedMangaListSelector].
@ -178,6 +180,7 @@ abstract class ParsedHttpSource : HttpSource() {
/**
* Parses the response from the site and returns a list of chapters.
* Normally it's not needed to override this method.
*
* @param response the response from the site.
*/
@ -200,6 +203,7 @@ abstract class ParsedHttpSource : HttpSource() {
/**
* Parses the response from the site and returns the page list.
* Normally it's not needed to override this method.
*
* @param response the response from the site.
*/
@ -216,6 +220,7 @@ abstract class ParsedHttpSource : HttpSource() {
/**
* Parse the response from the site and returns the absolute url to the source image.
* Normally it's not needed to override this method.
*
* @param response the response from the site.
*/