[RU]MultiChan (MangaChan, HenChan, YaoiChan) (#12125)

* [RU]MultiChan (MangaChan, HenChan, YaoiChan)

* id

* simpleDateFormat
This commit is contained in:
Ejan 2022-06-09 23:23:57 +05:00 committed by GitHub
parent 18ae200385
commit 256b11597f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 186 additions and 363 deletions

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -1,47 +1,29 @@
package eu.kanade.tachiyomi.extension.ru.henchan
import android.annotation.SuppressLint
import eu.kanade.tachiyomi.multisrc.multichan.MultiChan
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservable
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
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.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import java.net.URL
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
import java.net.URL
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
class Henchan : ParsedHttpSource() {
class HenChan : MultiChan("HenChan", "https://y.hentaichan.live", "ru"){
override val name = "Henchan"
override val baseUrl = "https://xxxx.hentaichan.live"
override val lang = "ru"
override val supportsLatest = true
override val client: OkHttpClient = network.client.newBuilder()
.rateLimit(2)
.build()
override fun popularMangaRequest(page: Int): Request =
GET("$baseUrl/mostfavorites&sort=manga?offset=${20 * (page - 1)}", headers)
override fun latestUpdatesRequest(page: Int): Request =
GET("$baseUrl/manga/new?offset=${20 * (page - 1)}", headers)
override val id: Long = 5504588601186153612
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
@ -88,10 +70,6 @@ class Henchan : ParsedHttpSource() {
return GET(url, headers)
}
override fun popularMangaSelector() = "div.content_row"
override fun latestUpdatesSelector() = popularMangaSelector()
override fun searchMangaSelector() = ".content_row:not(:has(div.item:containsOwn(Тип)))"
private fun String.getHQThumbnail(): String {
@ -103,33 +81,13 @@ class Henchan : ParsedHttpSource() {
}
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
val manga = super.popularMangaFromElement(element)
manga.thumbnail_url = element.select("img").first().attr("src").getHQThumbnail()
manga.title = element.attr("title")
element.select("h2 > a").first().let {
manga.setUrlWithoutDomain(it.attr("href"))
}
return manga
}
override fun latestUpdatesFromElement(element: Element): SManga =
popularMangaFromElement(element)
override fun searchMangaFromElement(element: Element): SManga =
popularMangaFromElement(element)
override fun popularMangaNextPageSelector() = "#pagination > a:contains(Вперед)"
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaNextPageSelector() = "#nextlink, ${popularMangaNextPageSelector()}"
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
manga.title = document.select("title").text().substringBefore(" »")
manga.author = document.select(".row .item2 h2")[1].text()
manga.genre = document.select(".sidetag > a:eq(2)").joinToString { it.text() }
manga.description = document.select("#description").text().trim()
val manga = super.mangaDetailsParse(document)
manga.thumbnail_url = document.select("img#cover").attr("abs:src").getHQThumbnail()
return manga
}
@ -245,6 +203,7 @@ class Henchan : ParsedHttpSource() {
}
return GET(url, Headers.Builder().add("Accept", "image/webp,image/apng").build())
}
override fun pageListParse(response: Response): List<Page> {
val html = response.body!!.string()
val prefix = "fullimg\": ["
@ -258,12 +217,6 @@ class Henchan : ParsedHttpSource() {
return pageUrls.mapIndexed { i, url -> Page(i, "", url) }
}
override fun pageListParse(document: Document): List<Page> {
throw Exception("Not used")
}
override fun imageUrlParse(document: Document) = ""
private class Genre(val id: String, @SuppressLint("DefaultLocale") name: String = id.replace('_', ' ').capitalize()) : Filter.TriState(name)
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Тэги", genres)
private class OrderBy : UriPartFilter(

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -1,42 +1,15 @@
package eu.kanade.tachiyomi.extension.ru.mangachan
import eu.kanade.tachiyomi.multisrc.multichan.MultiChan
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
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.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
class Mangachan : ParsedHttpSource() {
class MangaChan : MultiChan("MangaChan", "https://manga-chan.me", "ru"){
override val id: Long = 7
override val name = "Mangachan"
override val baseUrl = "https://manga-chan.me"
override val lang = "ru"
override val supportsLatest = true
override val client: OkHttpClient = network.client.newBuilder()
.rateLimit(2)
.build()
override fun popularMangaRequest(page: Int): Request =
GET("$baseUrl/mostfavorites?offset=${20 * (page - 1)}", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
var pageNum = 1
when {
@ -111,126 +84,6 @@ class Mangachan : ParsedHttpSource() {
return GET(url, headers)
}
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/new?offset=${20 * (page - 1)}")
override fun popularMangaSelector() = "div.content_row"
override fun latestUpdatesSelector() = popularMangaSelector()
override fun searchMangaSelector() = popularMangaSelector()
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
manga.thumbnail_url = element.select("div.manga_images img").first().attr("src")
manga.title = element.attr("title")
element.select("h2 > a").first().let {
manga.setUrlWithoutDomain(it.attr("href"))
}
return manga
}
override fun latestUpdatesFromElement(element: Element): SManga {
val manga = SManga.create()
manga.title = element.attr("title")
element.select("a:nth-child(1)").first().let {
manga.setUrlWithoutDomain(it.attr("href"))
}
return manga
}
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
override fun popularMangaNextPageSelector() = "a:contains(Вперед)"
override fun searchMangaNextPageSelector() = "a:contains(Далее)"
private fun searchGenresNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
var hasNextPage = false
val mangas = document.select(searchMangaSelector()).map { element ->
searchMangaFromElement(element)
}
val nextSearchPage = document.select(searchMangaNextPageSelector())
if (nextSearchPage.isNotEmpty()) {
val query = document.select("input#searchinput").first().attr("value")
val pageNum = nextSearchPage.let { selector ->
val onClick = selector.attr("onclick")
onClick?.split("""\\d+""")
}
nextSearchPage.attr("href", "$baseUrl/?do=search&subaction=search&story=$query&search_start=$pageNum")
hasNextPage = true
}
val nextGenresPage = document.select(searchGenresNextPageSelector())
if (nextGenresPage.isNotEmpty()) {
hasNextPage = true
}
return MangasPage(mangas, hasNextPage)
}
override fun mangaDetailsParse(document: Document): SManga {
val infoElement = document.select("table.mangatitle").first()
val descElement = document.select("div#description").first()
val imgElement = document.select("img#cover").first()
val rawCategory = infoElement.select("tr:eq(1) > td:eq(1)").text()
val category = if (rawCategory.isNotEmpty()) {
rawCategory.lowercase()
} else {
"манга"
}
val manga = SManga.create()
manga.title = document.select("title").text().substringBefore(" »")
manga.author = infoElement.select("tr:eq(2) > td:eq(1)").text()
manga.genre = infoElement.select("tr:eq(5) > td:eq(1)").text().split(",").plusElement(category).joinToString { it.trim() }
manga.status = parseStatus(infoElement.select("tr:eq(4) > td:eq(1)").text())
manga.description = descElement.textNodes().first().text().trim()
manga.thumbnail_url = imgElement.attr("src")
return manga
}
private fun parseStatus(element: String): Int = when {
element.contains("перевод завершен") -> SManga.COMPLETED
element.contains("перевод продолжается") -> SManga.ONGOING
else -> SManga.UNKNOWN
}
override fun chapterListSelector() = "table.table_cha tr:gt(1)"
override fun chapterFromElement(element: Element): SChapter {
val urlElement = element.select("a").first()
val chapter = SChapter.create()
chapter.setUrlWithoutDomain(urlElement.attr("href"))
chapter.name = urlElement.text()
chapter.date_upload = element.select("div.date").first()?.text()?.let {
SimpleDateFormat("yyyy-MM-dd", Locale.US).parse(it)?.time ?: 0L
} ?: 0
return chapter
}
override fun pageListParse(response: Response): List<Page> {
val html = response.body!!.string()
val beginIndex = html.indexOf("fullimg\":[") + 10
val endIndex = html.indexOf(",]", beginIndex)
val trimmedHtml = html.substring(beginIndex, endIndex).replace("\"", "")
val pageUrls = trimmedHtml.split(',')
return pageUrls.mapIndexed { i, url -> Page(i, "", url) }
}
override fun pageListParse(document: Document): List<Page> {
throw Exception("Not used")
}
override fun imageUrlParse(document: Document) = ""
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Тэги", genres)
private class Genre(name: String, val id: String = name.replace(' ', '_')) : Filter.TriState(name)
private class Status : Filter.Select<String>("Статус", arrayOf("Все", "Перевод завершен", "Выпуск завершен", "Онгоинг", "Новые главы"))
@ -246,10 +99,6 @@ class Mangachan : ParsedHttpSource() {
GenreList(getGenreList())
)
/* [...document.querySelectorAll("li.sidetag > a:nth-child(1)")]
* .map(el => `Genre("${el.getAttribute('href').substr(6)}")`).join(',\n')
* on https://mangachan.me/
*/
private fun getGenreList() = listOf(
Genre("18_плюс"),
Genre("bdsm"),

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -1,37 +1,14 @@
package eu.kanade.tachiyomi.extension.ru.yaoichan
import eu.kanade.tachiyomi.multisrc.multichan.MultiChan
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
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.source.online.ParsedHttpSource
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
class Yaoichan : ParsedHttpSource() {
class YaoiChan : MultiChan("YaoiChan", "https://yaoi-chan.me", "ru"){
override val name = "Yaoichan"
override val baseUrl = "https://yaoi-chan.me"
override val lang = "ru"
override val supportsLatest = false
override val client: OkHttpClient = network.client.newBuilder()
.rateLimit(2)
.build()
override fun popularMangaRequest(page: Int): Request =
GET("$baseUrl/mostfavorites?offset=${20 * (page - 1)}", headers)
override val id: Long = 2466512768990363955
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = if (query.isNotEmpty()) {
@ -99,87 +76,6 @@ class Yaoichan : ParsedHttpSource() {
return GET(url, headers)
}
override fun popularMangaSelector() = "div.content_row"
override fun searchMangaSelector() = popularMangaSelector()
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
manga.thumbnail_url = element.select("div.manga_images img").first().attr("src")
manga.title = element.attr("title")
element.select("h2 > a").first().let {
manga.setUrlWithoutDomain(it.attr("href"))
}
return manga
}
override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException("Not used")
override fun latestUpdatesSelector() = throw UnsupportedOperationException("Not used")
override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException("Not used")
override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException("Not used")
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun popularMangaNextPageSelector() = "a:contains(Вперед)"
override fun searchMangaNextPageSelector() = "a:contains(Далее), ${popularMangaNextPageSelector()}"
override fun mangaDetailsParse(document: Document): SManga {
val infoElement = document.select("table.mangatitle").first()
val descElement = document.select("div#description").first()
val imgElement = document.select("img#cover").first()
val rawCategory = infoElement.select("tr:eq(1) > td:eq(1)").text()
val category = if (rawCategory.isNotEmpty()) {
rawCategory.lowercase()
} else {
"манга"
}
val manga = SManga.create()
manga.title = document.select("title").text().substringBefore(" »")
manga.author = infoElement.select("tr:eq(2) > td:eq(1)").text()
manga.genre = infoElement.select("tr:eq(5) > td:eq(1)").text().split(",").plusElement(category).joinToString { it.trim() }
manga.status = parseStatus(infoElement.select("tr:eq(4) > td:eq(1)").text())
manga.description = descElement.textNodes().first().text().trim()
manga.thumbnail_url = imgElement.attr("src")
return manga
}
private fun parseStatus(element: String): Int = when {
element.contains("перевод завершен") -> SManga.COMPLETED
element.contains("перевод продолжается") -> SManga.ONGOING
else -> SManga.UNKNOWN
}
override fun chapterListSelector() = "table.table_cha tr:gt(1)"
override fun chapterFromElement(element: Element): SChapter {
val urlElement = element.select("a").first()
val chapter = SChapter.create()
chapter.setUrlWithoutDomain(urlElement.attr("href"))
chapter.name = urlElement.text()
chapter.date_upload = element.select("div.date").first()?.text()?.let {
SimpleDateFormat("yyyy-MM-dd", Locale.US).parse(it)?.time ?: 0L
} ?: 0
return chapter
}
override fun pageListParse(response: Response): List<Page> {
val html = response.body!!.string()
val beginIndex = html.indexOf("fullimg\":[") + 10
val endIndex = html.indexOf(",]", beginIndex)
val trimmedHtml = html.substring(beginIndex, endIndex).replace("\"", "")
val pageUrls = trimmedHtml.split(',')
return pageUrls.mapIndexed { i, url -> Page(i, "", url) }
}
override fun pageListParse(document: Document): List<Page> {
throw Exception("Not used")
}
override fun imageUrlParse(document: Document) = ""
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Тэги", genres)
private class Genre(name: String, val id: String = name.replace(' ', '_')) : Filter.TriState(name)
private class Status : Filter.Select<String>("Статус", arrayOf("Все", "Перевод завершен", "Выпуск завершен", "Онгоинг", "Новые главы"))
@ -195,10 +91,6 @@ class Yaoichan : ParsedHttpSource() {
GenreList(getGenreList())
)
/* [...document.querySelectorAll("li.sidetag > a:nth-child(1)")]
* .map(el => `Genre("${el.getAttribute('href').substr(6)}")`).join(',\n')
* on https://yaoi-chan.me/catalog
*/
private fun getGenreList() = listOf(
Genre("18 плюс"),
Genre("bdsm"),

View File

@ -0,0 +1,26 @@
package eu.kanade.tachiyomi.multisrc.multichan
import generator.ThemeSourceData.SingleLang
import generator.ThemeSourceGenerator
class ChanGenerator: ThemeSourceGenerator {
override val themePkg = "multichan"
override val themeClass = "MultiChan"
override val baseVersionCode: Int = 1
override val sources = listOf(
SingleLang("MangaChan", "https://manga-chan.me", "ru", overrideVersionCode = 14),
SingleLang("HenChan", "https://y.hentaichan.live", "ru",isNsfw = true, overrideVersionCode = 35),
SingleLang("YaoiChan", "https://yaoi-chan.me", "ru",isNsfw = true, overrideVersionCode = 4)
)
companion object {
@JvmStatic
fun main(args: Array<String>) {
ChanGenerator().createAll()
}
}
}

View File

@ -0,0 +1,145 @@
package eu.kanade.tachiyomi.multisrc.multichan
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
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.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
abstract class MultiChan(
override val name: String,
override val baseUrl: String,
final override val lang: String
) : ParsedHttpSource() {
override val supportsLatest = true
override val client: OkHttpClient = network.client.newBuilder()
.rateLimit(2)
.build()
override fun popularMangaRequest(page: Int): Request =
GET("$baseUrl/mostfavorites?offset=${20 * (page - 1)}", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/new?offset=${20 * (page - 1)}")
override fun popularMangaSelector() = "div.content_row"
override fun latestUpdatesSelector() = popularMangaSelector()
override fun searchMangaSelector() = popularMangaSelector()
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
manga.thumbnail_url = element.select("img").first().attr("src")
manga.title = element.attr("title")
element.select("h2 > a").first().let {
manga.setUrlWithoutDomain(it.attr("href"))
}
return manga
}
override fun latestUpdatesFromElement(element: Element): SManga =
popularMangaFromElement(element)
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
override fun popularMangaNextPageSelector() = "a:contains(Вперед)"
override fun searchMangaNextPageSelector() = "a:contains(Далее)"
private fun searchGenresNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
var hasNextPage = false
val mangas = document.select(searchMangaSelector()).map { element ->
searchMangaFromElement(element)
}
val nextSearchPage = document.select(searchMangaNextPageSelector())
if (nextSearchPage.isNotEmpty()) {
val query = document.select("input#searchinput").first().attr("value")
val pageNum = nextSearchPage.let { selector ->
val onClick = selector.attr("onclick")
onClick?.split("""\\d+""")
}
nextSearchPage.attr("href", "$baseUrl/?do=search&subaction=search&story=$query&search_start=$pageNum")
hasNextPage = true
}
val nextGenresPage = document.select(searchGenresNextPageSelector())
if (nextGenresPage.isNotEmpty()) {
hasNextPage = true
}
return MangasPage(mangas, hasNextPage)
}
override fun mangaDetailsParse(document: Document): SManga {
val infoElement = document.select("#info_wrap tr,#info_wrap > div")
val descElement = document.select("div#description").first()
val rawCategory = infoElement.select(":contains(Тип) a").text().lowercase()
val manga = SManga.create()
manga.title = document.select("title").text().substringBefore(" »")
manga.author = infoElement.select(":contains(Автор)").text()
manga.genre = rawCategory + ", " + document.select(".sidetags ul a:last-child").joinToString { it.text() }
manga.status = parseStatus(infoElement.select(":contains(Загружено)").text())
manga.description = descElement.textNodes().first().text().trim()
manga.thumbnail_url = document.select("img#cover").first().attr("src")
return manga
}
private fun parseStatus(element: String): Int = when {
element.contains("перевод завершен") -> SManga.COMPLETED
element.contains("перевод продолжается") -> SManga.ONGOING
else -> SManga.UNKNOWN
}
override fun chapterListSelector() = "table.table_cha tr:gt(1)"
override fun chapterFromElement(element: Element): SChapter {
val urlElement = element.select("a").first()
val chapter = SChapter.create()
chapter.setUrlWithoutDomain(urlElement.attr("href"))
chapter.name = urlElement.text()
chapter.date_upload = simpleDateFormat.parse(element.select("div.date").first().text())?.time ?: 0L
return chapter
}
override fun pageListParse(response: Response): List<Page> {
val html = response.body!!.string()
val beginIndex = html.indexOf("fullimg\":[") + 10
val endIndex = html.indexOf(",]", beginIndex)
val trimmedHtml = html.substring(beginIndex, endIndex).replace("\"", "")
val pageUrls = trimmedHtml.split(',')
return pageUrls.mapIndexed { i, url -> Page(i, "", url) }
}
override fun pageListParse(document: Document): List<Page> {
throw Exception("Not used")
}
override fun imageUrlParse(document: Document) = ""
companion object {
private val simpleDateFormat by lazy { SimpleDateFormat("yyyy-MM-dd", Locale.US) }
}
}

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.extension" />

View File

@ -1,13 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
ext {
extName = 'Henchan'
pkgNameSuffix = 'ru.henchan'
extClass = '.Henchan'
extVersionCode = 35
isNsfw = true
}
apply from: "$rootDir/common.gradle"

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.extension" />

View File

@ -1,11 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'Mangachan'
pkgNameSuffix = 'ru.mangachan'
extClass = '.Mangachan'
extVersionCode = 14
}
apply from: "$rootDir/common.gradle"

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.extension" />

View File

@ -1,12 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'Yaoichan'
pkgNameSuffix = 'ru.yaoichan'
extClass = '.Yaoichan'
extVersionCode = 4
isNsfw = true
}
apply from: "$rootDir/common.gradle"