Initial commit
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 30 KiB |
BIN
multisrc/overrides/mmrcms/amascans/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 243 KiB |
29
multisrc/overrides/mmrcms/amascans/src/AmaScans.kt
Normal file
@@ -0,0 +1,29 @@
|
||||
package eu.kanade.tachiyomi.extension.pt.amascans
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mmrcms.MMRCMS
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class AmaScans : MMRCMS("Ama Scans", "https://amascan.com", "pt-BR") {
|
||||
|
||||
override val client: OkHttpClient = super.client.newBuilder()
|
||||
.rateLimit(1, 2, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
||||
override fun imageRequest(page: Page): Request {
|
||||
val newHeaders = headersBuilder()
|
||||
.add("Accept", ACCEPT_IMAGE)
|
||||
.add("Referer", page.url)
|
||||
.build()
|
||||
|
||||
return GET(page.imageUrl!!, newHeaders)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ACCEPT_IMAGE = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 53 KiB |
BIN
multisrc/overrides/mmrcms/animaregia/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 472 KiB |
115
multisrc/overrides/mmrcms/animaregia/src/AnimaRegia.kt
Normal file
@@ -0,0 +1,115 @@
|
||||
package eu.kanade.tachiyomi.extension.pt.animaregia
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mmrcms.MMRCMS
|
||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Element
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class AnimaRegia : MMRCMS("AnimaRegia", "https://animaregia.net", "pt-BR") {
|
||||
|
||||
override val id: Long = 4378659695320121364
|
||||
|
||||
override val client: OkHttpClient = super.client.newBuilder()
|
||||
.rateLimit(1, 2, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
||||
// Remove the language tag from the title name.
|
||||
override fun internalMangaParse(response: Response): MangasPage {
|
||||
return super.internalMangaParse(response).let {
|
||||
it.copy(
|
||||
mangas = it.mangas.map { manga ->
|
||||
manga.apply { title = title.removeSuffix(LANGUAGE_SUFFIX) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun latestUpdatesFromElement(element: Element, urlSelector: String): SManga? {
|
||||
return super.latestUpdatesFromElement(element, urlSelector)
|
||||
?.apply { title = title.removeSuffix(LANGUAGE_SUFFIX) }
|
||||
}
|
||||
|
||||
override fun gridLatestUpdatesFromElement(element: Element): SManga {
|
||||
return super.gridLatestUpdatesFromElement(element)
|
||||
.apply { title = title.removeSuffix(LANGUAGE_SUFFIX) }
|
||||
}
|
||||
|
||||
// Override searchMangaParse with same body from internalMangaParse since
|
||||
// it can use the other endpoint instead.
|
||||
override fun searchMangaParse(response: Response): MangasPage {
|
||||
return super.searchMangaParse(response).let {
|
||||
it.copy(
|
||||
mangas = it.mangas.map { manga ->
|
||||
manga.apply { title = title.removeSuffix(LANGUAGE_SUFFIX) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// The website modified the information panel.
|
||||
override fun mangaDetailsParse(response: Response): SManga = SManga.create().apply {
|
||||
val document = response.asJsoup()
|
||||
|
||||
title = document.selectFirst("h1.widget-title")!!.text()
|
||||
thumbnail_url = coverGuess(
|
||||
document.select("div.col-sm-5 img.img-thumbnail").firstOrNull()?.attr("abs:src"),
|
||||
document.location(),
|
||||
)
|
||||
description = document.select("div.row div.well p")!!.text().trim()
|
||||
|
||||
for (element in document.select("div.col-sm-5 ul.list-group li.list-group-item")) {
|
||||
when (element.text().trim().lowercase(BRAZILIAN_LOCALE).substringBefore(":")) {
|
||||
"autor(es)" -> author = element.select("a")
|
||||
.joinToString(", ") { it.text().trim() }
|
||||
"artist(s)" -> artist = element.select("a")
|
||||
.joinToString(", ") { it.text().trim() }
|
||||
"categorias" -> genre = element.select("a")
|
||||
.joinToString(", ") { it.text().trim() }
|
||||
"status" -> status = when (element.select("span.label").text()) {
|
||||
"Completo", "Concluído" -> SManga.COMPLETED
|
||||
"Ativo" -> SManga.ONGOING
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun chapterListSelector(): String = "div.row ul.chapters > li"
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
return response.asJsoup()
|
||||
.select(chapterListSelector())
|
||||
.map { el ->
|
||||
SChapter.create().apply {
|
||||
name = el.select("h5.chapter-title-rtl").text()
|
||||
scanlator = el.select("div.col-md-3 ul li")
|
||||
.joinToString(" & ") { it.text().trim() }
|
||||
date_upload = el.select("div.col-md-4").firstOrNull()
|
||||
?.text()?.removeSuffix("Download")?.toDate() ?: 0L
|
||||
setUrlWithoutDomain(el.select("h5.chapter-title-rtl a").first()!!.attr("href"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.toDate(): Long {
|
||||
return runCatching { DATE_FORMAT.parse(trim())?.time }
|
||||
.getOrNull() ?: 0L
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val LANGUAGE_SUFFIX = " (pt-br)"
|
||||
private val BRAZILIAN_LOCALE = Locale("pt", "BR")
|
||||
|
||||
private val DATE_FORMAT by lazy {
|
||||
SimpleDateFormat("dd MMM. yyyy", Locale.ENGLISH)
|
||||
}
|
||||
}
|
||||
}
|
||||
60
multisrc/overrides/mmrcms/bentoscan/src/Bentoscan.kt
Normal file
@@ -0,0 +1,60 @@
|
||||
package eu.kanade.tachiyomi.extension.fr.bentoscan
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mmrcms.MMRCMS
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import okhttp3.Request
|
||||
import org.jsoup.nodes.Element
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class Bentoscan : MMRCMS("Bentoscan", "https://bentoscan.com", "fr") {
|
||||
override fun imageRequest(page: Page): Request {
|
||||
val newHeaders = headersBuilder()
|
||||
.set("Referer", IMG_URL)
|
||||
.set("Accept", "image/avif,image/webp,*/*")
|
||||
.build()
|
||||
|
||||
return GET(page.imageUrl!!, newHeaders)
|
||||
}
|
||||
|
||||
override fun nullableChapterFromElement(element: Element): SChapter? {
|
||||
val chapter = SChapter.create()
|
||||
|
||||
val titleWrapper = element.select("[class^=chapter-title-rtl]").first()!!
|
||||
val chapterElement = titleWrapper.getElementsByTag("a")!!
|
||||
val url = chapterElement.attr("href")
|
||||
|
||||
chapter.url = getUrlWithoutBaseUrl(url)
|
||||
|
||||
// Construct chapter names
|
||||
// Before -> Scan <manga_name> <chapter_number> VF: <chapter_number>
|
||||
// Now -> Chapitre <chapter_number> : <chapter_title> OR Chapitre <chapter_number>
|
||||
val chapterText = chapterElement.text()
|
||||
val numberRegex = Regex("""[1-9]\d*(\.\d+)*""")
|
||||
val chapterNumber = numberRegex.find(chapterText)?.value.orEmpty()
|
||||
val chapterTitle = titleWrapper.getElementsByTag("em")!!.text()
|
||||
if (chapterTitle.toIntOrNull() != null) {
|
||||
chapter.name = "Chapitre $chapterNumber"
|
||||
} else {
|
||||
chapter.name = "Chapitre $chapterNumber : $chapterTitle"
|
||||
}
|
||||
|
||||
// Parse date
|
||||
val dateText = element.getElementsByClass("date-chapter-title-rtl").text().trim()
|
||||
|
||||
chapter.date_upload = runCatching {
|
||||
dateFormat.parse(dateText)?.time
|
||||
}.getOrNull() ?: 0L
|
||||
|
||||
return chapter
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val IMG_URL = "https://scansmangas.me"
|
||||
val dateFormat by lazy {
|
||||
SimpleDateFormat("d MMM. yyyy", Locale.US)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
BIN
multisrc/overrides/mmrcms/default/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 15 KiB |
BIN
multisrc/overrides/mmrcms/fallenangels/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
41
multisrc/overrides/mmrcms/fallenangels/src/FallenAngels.kt
Normal file
@@ -0,0 +1,41 @@
|
||||
package eu.kanade.tachiyomi.extension.en.fallenangels
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mmrcms.MMRCMS
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import org.jsoup.nodes.Element
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class FallenAngels : MMRCMS("Fallen Angels", "https://manga.fascans.com", "en") {
|
||||
|
||||
/**
|
||||
* Returns a chapter from the given element.
|
||||
*
|
||||
* @param element an element obtained from [chapterListSelector].
|
||||
*/
|
||||
override fun nullableChapterFromElement(element: Element): SChapter? {
|
||||
val chapter = SChapter.create()
|
||||
|
||||
val titleWrapper = element.select("[class^=chapter-title-rtl]").first()!!
|
||||
val chapterElement = titleWrapper.getElementsByTag("a")!!
|
||||
val url = chapterElement.attr("href")
|
||||
|
||||
chapter.url = getUrlWithoutBaseUrl(url)
|
||||
|
||||
// Construct chapter names
|
||||
// before -> <mangaName> <chapterNumber> : <chapterTitle>
|
||||
// after -> Chapter <chapterNumber> : <chapterTitle>
|
||||
val chapterText = chapterElement.text()
|
||||
val numberRegex = Regex("""[1-9]\d*(\.\d+)*""")
|
||||
val chapterNumber = numberRegex.find(chapterText)?.value.orEmpty()
|
||||
val chapterTitle = titleWrapper.getElementsByTag("em")!!.text()
|
||||
chapter.name = "Chapter $chapterNumber : $chapterTitle"
|
||||
|
||||
// Parse date
|
||||
val dateText = element.getElementsByClass("date-chapter-title-rtl").text().trim()
|
||||
val dateFormat = SimpleDateFormat("d MMM. yyyy", Locale.US)
|
||||
chapter.date_upload = dateFormat.parse(dateText)?.time ?: 0L
|
||||
|
||||
return chapter
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 18 KiB |
BIN
multisrc/overrides/mmrcms/hentaishark/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
BIN
multisrc/overrides/mmrcms/mangadoor/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
55
multisrc/overrides/mmrcms/mangafr/src/MangaFR.kt
Normal file
@@ -0,0 +1,55 @@
|
||||
package eu.kanade.tachiyomi.extension.fr.mangafr
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mmrcms.MMRCMS
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Element
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class MangaFR : MMRCMS("Manga-FR", "https://manga-fr.cc", "fr") {
|
||||
override fun mangaDetailsParse(response: Response): SManga {
|
||||
return super.mangaDetailsParse(response).apply {
|
||||
title = title.replace("Chapitres ", "")
|
||||
}
|
||||
}
|
||||
|
||||
override fun nullableChapterFromElement(element: Element): SChapter? {
|
||||
val chapter = SChapter.create()
|
||||
|
||||
val titleWrapper = element.select("[class^=chapter-title-rtl]").first()!!
|
||||
val chapterElement = titleWrapper.getElementsByTag("a")!!
|
||||
val url = chapterElement.attr("href")
|
||||
|
||||
chapter.url = getUrlWithoutBaseUrl(url)
|
||||
|
||||
// Construct chapter names
|
||||
// Before -> Scan <manga_name> <chapter_number> VF: <chapter_number>
|
||||
// Now -> Chapitre <chapter_number> : <chapter_title> OR Chapitre <chapter_number>
|
||||
val chapterText = chapterElement.text()
|
||||
val numberRegex = Regex("""[1-9]\d*(\.\d+)*""")
|
||||
val chapterNumber = numberRegex.find(chapterText)?.value.orEmpty()
|
||||
val chapterTitle = titleWrapper.getElementsByTag("em")!!.text()
|
||||
if (chapterTitle.toIntOrNull() != null) {
|
||||
chapter.name = "Chapitre $chapterNumber"
|
||||
} else {
|
||||
chapter.name = "Chapitre $chapterNumber : $chapterTitle"
|
||||
}
|
||||
|
||||
// Parse date
|
||||
val dateText = element.getElementsByClass("date-chapter-title-rtl").text().trim()
|
||||
|
||||
chapter.date_upload = runCatching {
|
||||
dateFormat.parse(dateText)?.time
|
||||
}.getOrNull() ?: 0L
|
||||
|
||||
return chapter
|
||||
}
|
||||
|
||||
companion object {
|
||||
val dateFormat by lazy {
|
||||
SimpleDateFormat("d MMM. yyyy", Locale.US)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 26 KiB |
BIN
multisrc/overrides/mmrcms/mangaid/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 188 KiB |
17
multisrc/overrides/mmrcms/mangascan/src/MangaScan.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
package eu.kanade.tachiyomi.extension.fr.mangascan
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mmrcms.MMRCMS
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import okhttp3.Request
|
||||
|
||||
class MangaScan : MMRCMS("Manga-Scan", "https://mangascan.cc", "fr") {
|
||||
override fun imageRequest(page: Page): Request {
|
||||
val newHeaders = headersBuilder()
|
||||
.set("Referer", baseUrl)
|
||||
.set("Accept", "image/avif,image/webp,*/*")
|
||||
.build()
|
||||
|
||||
return GET(page.imageUrl!!, newHeaders)
|
||||
}
|
||||
}
|
||||
BIN
multisrc/overrides/mmrcms/onma/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
multisrc/overrides/mmrcms/onma/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
multisrc/overrides/mmrcms/onma/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
multisrc/overrides/mmrcms/onma/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 10 KiB |
BIN
multisrc/overrides/mmrcms/onma/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 59 KiB |
BIN
multisrc/overrides/mmrcms/phoenixscans/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 478 KiB |
BIN
multisrc/overrides/mmrcms/scanfr/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
multisrc/overrides/mmrcms/scanfr/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 69 KiB |
BIN
multisrc/overrides/mmrcms/scanfr/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 691 KiB |
BIN
multisrc/overrides/mmrcms/scanvf/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
multisrc/overrides/mmrcms/scanvf/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 50 KiB |
BIN
multisrc/overrides/mmrcms/scanvf/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 315 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 30 KiB |
BIN
multisrc/overrides/mmrcms/utsukushii/res/web_hi_res_512.png
Normal file
|
After Width: | Height: | Size: 156 KiB |
11
multisrc/overrides/mmrcms/utsukushii/src/Utsukushii.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
package eu.kanade.tachiyomi.extension.bg.utsukushii
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mmrcms.MMRCMS
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import okhttp3.Request
|
||||
|
||||
class Utsukushii : MMRCMS("Utsukushii", "https://manga.utsukushii-bg.com", "bg") {
|
||||
override fun popularMangaRequest(page: Int): Request {
|
||||
return GET("$baseUrl/manga-list", headers)
|
||||
}
|
||||
}
|
||||