tachiyomi-extensions-inspector/inspector/src/main/kotlin/eu/kanade/tachiyomi/source/online/ParsedHttpSource.kt
2023-09-14 22:24:21 -04:00

201 lines
6.4 KiB
Kotlin

package eu.kanade.tachiyomi.source.online
import eu.kanade.tachiyomi.source.model.MangasPage
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.asJsoup
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
/**
* A simple implementation for sources from a website using Jsoup, an HTML parser.
*/
abstract class ParsedHttpSource : HttpSource() {
/**
* Parses the response from the site and returns a [MangasPage] object.
*
* @param response the response from the site.
*/
override fun popularMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
val mangas = document.select(popularMangaSelector()).map { element ->
popularMangaFromElement(element)
}
val hasNextPage = popularMangaNextPageSelector()?.let { selector ->
document.select(selector).first()
} != null
return MangasPage(mangas, hasNextPage)
}
/**
* Returns the Jsoup selector that returns a list of [Element] corresponding to each manga.
*/
protected abstract fun popularMangaSelector(): String
/**
* Returns a manga from the given [element]. Most sites only show the title and the url, it's
* totally fine to fill only those two values.
*
* @param element an element obtained from [popularMangaSelector].
*/
protected abstract fun popularMangaFromElement(element: Element): SManga
/**
* Returns the Jsoup selector that returns the <a> tag linking to the next page, or null if
* there's no next page.
*/
protected abstract fun popularMangaNextPageSelector(): String?
/**
* Parses the response from the site and returns a [MangasPage] object.
*
* @param response the response from the site.
*/
override fun searchMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
val mangas = document.select(searchMangaSelector()).map { element ->
searchMangaFromElement(element)
}
val hasNextPage = searchMangaNextPageSelector()?.let { selector ->
document.select(selector).first()
} != null
return MangasPage(mangas, hasNextPage)
}
/**
* Returns the Jsoup selector that returns a list of [Element] corresponding to each manga.
*/
protected abstract fun searchMangaSelector(): String
/**
* Returns a manga from the given [element]. Most sites only show the title and the url, it's
* totally fine to fill only those two values.
*
* @param element an element obtained from [searchMangaSelector].
*/
protected abstract fun searchMangaFromElement(element: Element): SManga
/**
* Returns the Jsoup selector that returns the <a> tag linking to the next page, or null if
* there's no next page.
*/
protected abstract fun searchMangaNextPageSelector(): String?
/**
* Parses the response from the site and returns a [MangasPage] object.
*
* @param response the response from the site.
*/
override fun latestUpdatesParse(response: Response): MangasPage {
val document = response.asJsoup()
val mangas = document.select(latestUpdatesSelector()).map { element ->
latestUpdatesFromElement(element)
}
val hasNextPage = latestUpdatesNextPageSelector()?.let { selector ->
document.select(selector).first()
} != null
return MangasPage(mangas, hasNextPage)
}
/**
* Returns the Jsoup selector that returns a list of [Element] corresponding to each manga.
*/
protected abstract fun latestUpdatesSelector(): String
/**
* Returns a manga from the given [element]. Most sites only show the title and the url, it's
* totally fine to fill only those two values.
*
* @param element an element obtained from [latestUpdatesSelector].
*/
protected abstract fun latestUpdatesFromElement(element: Element): SManga
/**
* Returns the Jsoup selector that returns the <a> tag linking to the next page, or null if
* there's no next page.
*/
protected abstract fun latestUpdatesNextPageSelector(): String?
/**
* Parses the response from the site and returns the details of a manga.
*
* @param response the response from the site.
*/
override fun mangaDetailsParse(response: Response): SManga {
return mangaDetailsParse(response.asJsoup())
}
/**
* Returns the details of the manga from the given [document].
*
* @param document the parsed document.
*/
protected abstract fun mangaDetailsParse(document: Document): SManga
/**
* Parses the response from the site and returns a list of chapters.
*
* @param response the response from the site.
*/
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
return document.select(chapterListSelector()).map { chapterFromElement(it) }
}
/**
* Returns the Jsoup selector that returns a list of [Element] corresponding to each chapter.
*/
protected abstract fun chapterListSelector(): String
/**
* Returns a chapter from the given element.
*
* @param element an element obtained from [chapterListSelector].
*/
protected abstract fun chapterFromElement(element: Element): SChapter
/**
* Parses the response from the site and returns the page list.
*
* @param response the response from the site.
*/
override fun pageListParse(response: Response): List<Page> {
return pageListParse(response.asJsoup())
}
/**
* Returns a page list from the given document.
*
* @param document the parsed document.
*/
protected abstract fun pageListParse(document: Document): List<Page>
/**
* Parse the response from the site and returns the absolute url to the source image.
*
* @param response the response from the site.
*/
override fun imageUrlParse(response: Response): String {
return imageUrlParse(response.asJsoup())
}
/**
* Returns the absolute url to the source image from the document.
*
* @param document the parsed document.
*/
protected abstract fun imageUrlParse(document: Document): String
}