Remove several (#17962)

* Remove Aln Scans

* Remove Trap Scans

* Remove Komik Lab (ID)

* Remove ManhwaTime

* Remove مانجا عرب تيم Manga Arab Team

* Remove Truyện Tranh 8

* Remove LKDTT

* Remove MeDocTruyenTranh

* Remove 好漫6

* Remove 好漫6 (g-lens)
This commit is contained in:
Vetle Ledaal 2023-09-15 19:23:43 +00:00 committed by GitHub
parent d7ddac2e3c
commit be446da874
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 1 additions and 892 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

View File

@ -1,14 +0,0 @@
package eu.kanade.tachiyomi.extension.ar.mangaarabteam
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Page
import okhttp3.Request
import java.text.SimpleDateFormat
import java.util.Locale
class MangaArabTeam : Madara("مانجا عرب تيم Manga Arab Team", "https://mangaarbteam.com", "ar", SimpleDateFormat("dd MMM، yyyy", Locale.forLanguageTag("ar"))) {
override fun imageRequest(page: Page): Request {
return GET(page.imageUrl!!.replace("http:", "https:"))
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

View File

@ -1,8 +0,0 @@
package eu.kanade.tachiyomi.extension.en.trapscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
class TrapScans : Madara("Trap Scans", "https://trapscans.com", "en") {
override val mangaDetailsSelectorDescription = ".description-summary p"
}

View File

@ -1,19 +0,0 @@
package eu.kanade.tachiyomi.extension.all.komiklab
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import eu.kanade.tachiyomi.source.SourceFactory
class KomikLabFactory : SourceFactory {
override fun createSources() = listOf(
KomikLabEn(),
KomikLabId(),
)
}
class KomikLabEn : MangaThemesia("KomikLab Scans", "https://komiklab.com", "en")
class KomikLabId : MangaThemesia("Komik Lab", "https://komiklab.net", "id") {
override val hasProjectPage = true
override val seriesDetailsSelector = ".seriestucon"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,18 +0,0 @@
package eu.kanade.tachiyomi.extension.zh.haoman6
import eu.kanade.tachiyomi.multisrc.mccms.MCCMSWeb
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
class Haoman6 : MCCMSWeb("好漫6", "https://www.haoman6.com") {
override fun SManga.cleanup() = apply {
description = description?.substringBefore(title)
title = title.removeSuffix("(最新在线)").removeSuffix("-")
}
override fun pageListRequest(chapter: SChapter) =
GET(baseUrl + chapter.url, headers)
override val lazyLoadImageAttr = "mob-ec"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,12 +0,0 @@
package eu.kanade.tachiyomi.extension.zh.haoman6glens
import eu.kanade.tachiyomi.multisrc.mccms.MCCMSWeb
import eu.kanade.tachiyomi.source.model.SManga
class Haoman6glens : MCCMSWeb("好漫6 (g-lens)", "https://www.g-lens.com") {
override fun SManga.cleanup() = apply {
title = title.removeSuffix("_").removeSuffix("-").removeSuffix("漫画")
}
override val lazyLoadImageAttr = "pc-ec"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

View File

@ -1,121 +0,0 @@
package eu.kanade.tachiyomi.extension.vi.lkdtt
import eu.kanade.tachiyomi.multisrc.mymangacms.MyMangaCMS
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.TimeZone
class LKDTT : MyMangaCMS("LKDTT", "https://lkdttee.com", "vi") {
override val dateFormatter = SimpleDateFormat("dd/MM/yy", Locale.US).apply {
timeZone = TimeZone.getTimeZone(super.timeZone)
}
override fun dateUpdatedParser(date: String): Long =
runCatching { super.dateUpdatedParser(date.split(" - ")[1]) }.getOrNull() ?: 0L
override fun getGenreList() = listOf(
Genre("Học đường", 1),
Genre("Hài hước", 2),
Genre("Cổ Đại", 3),
Genre("Hiện đại", 4),
Genre("Kinh dị", 5),
Genre("Tổng tài", 6),
Genre("Xuyên không", 7),
Genre("Manhua", 8),
Genre("Manhwa", 9),
Genre("Mystery", 10),
Genre("One shot", 11),
Genre("Smut", 12),
Genre("Webtoon", 13),
Genre("Yaoi", 14),
Genre("Yuri", 15),
Genre("Trinh Thám", 16),
Genre("Tình Cảm", 17),
Genre("Drama", 18),
Genre("Comedy", 19),
Genre("Fantasy", 20),
Genre("Novel", 21),
Genre("Action", 22),
Genre("Manga", 23),
Genre("Đam Mỹ", 24),
Genre("Trọng Sinh", 25),
Genre("Ngôn Tình", 26),
Genre("Phiêu Lưu", 27),
Genre("Boy Love", 28),
Genre("giới giải trí", 29),
Genre("đô thị", 30),
Genre("Romance", 31),
Genre("Đô Thị", 32),
Genre("Shoujo", 33),
Genre("Historical", 34),
Genre("Slice of life", 35),
Genre("Mature", 36),
Genre("GL", 37),
Genre("Adult", 38),
Genre("Huyền huyễn", 39),
Genre("Baby", 40),
Genre("Tragedy", 41),
Genre("Truyện Màu", 42),
Genre("School Life", 43),
Genre("Josei", 44),
Genre("Oneshot", 45),
Genre("Gender Bender", 46),
Genre("Nữ cường", 47),
Genre("Harem", 48),
Genre("Reverse Harem", 49),
Genre("Isekai", 50),
Genre("Adventure", 51),
Genre("Chuyển Sinh", 52),
Genre("Đại Nữ Chủ", 53),
Genre("Shounen", 54),
Genre("Sports", 55),
Genre("Sủng Ngọt", 56),
Genre("Truyện 18+", 57),
Genre("Trung Cổ", 58),
Genre("Ma Thuật", 59),
Genre("Webtoons", 60),
Genre("Xuyên", 61),
Genre("Ngôn", 62),
Genre("Tiểu Bạch Thỏ", 63),
Genre("Sủng", 65),
Genre("Trùng Sinh", 66),
Genre("Ma Cà Rồng", 67),
Genre("Tái Sinh", 68),
Genre("Quân Nhân", 69),
Genre("Showbiz", 70),
Genre("Comic", 71),
Genre("Phép Thuật", 72),
Genre("Psychological", 73),
Genre("Supernatural", 74),
Genre("Lãng Mạn", 75),
Genre("Gender", 76),
Genre("Bender", 77),
Genre("Vườn Trường", 78),
Genre("Magic", 79),
Genre("Nhân Thú", 80),
Genre("Soft Yaoi", 81),
Genre("Hôn Nhân Hợp Đồng", 82),
Genre("Cưới Trước Yêu Sau", 83),
Genre("Bi Kịch", 84),
Genre("Horror", 85),
Genre("Reincarnation", 86),
Genre("Hồi Sinh", 87),
Genre("Hoàng Gia", 88),
Genre("Giả Tưởng", 89),
Genre("Xuyên Sách", 90),
Genre("Hài", 91),
Genre("Ngọt", 92),
Genre("Nam Cường", 93),
Genre("Chủ Nam", 94),
Genre("Minh Tinh", 95),
Genre("Cổ Trang", 96),
Genre("Xuyên Game", 97),
Genre("Villainess", 98),
Genre("Cung Đấu", 99),
Genre("Hành Động", 100),
Genre("Truyện Tranh", 101),
Genre("Adaptation", 102),
Genre("Magi", 103),
Genre("Âu Cổ", 104),
)
}

View File

@ -31,7 +31,6 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("AkuManga", "https://akumanga.com", "ar", overrideVersionCode = 1),
SingleLang("Akuzenai Arts", "https://akuzenaiarts.org", "en"),
SingleLang("AllPornComic", "https://allporncomic.com", "en", isNsfw = true),
SingleLang("Aln Scans", "https://alnscans.com", "en"),
SingleLang("Amuy", "https://apenasmaisumyaoi.com", "pt-BR", isNsfw = true, overrideVersionCode = 1),
SingleLang("Anikiga", "https://anikiga.com", "tr"),
SingleLang("Anisa Manga", "https://anisamanga.com", "tr"),
@ -348,7 +347,6 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("ManhwaManhua", "https://manhwamanhua.com", "en", isNsfw = true),
SingleLang("ManhwaNew", "https://manhwanew.com", "en", isNsfw = true),
SingleLang("Manhwas Men", "https://manhwas.men", "en", className = "ManhwasMen", isNsfw = true),
SingleLang("ManhwaTime", "https://manhwatime.com", "ar"),
SingleLang("Manhwatop", "https://manhwatop.com", "en", overrideVersionCode = 2),
SingleLang("ManhwaWorld", "https://manhwaworld.com", "en"),
SingleLang("Manhwua.fans", "https://manhwua.fans", "en", isNsfw = true, className = "Manhwuafans"),
@ -477,7 +475,6 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Top Manhua", "https://topmanhua.com", "en", overrideVersionCode = 2),
SingleLang("Tortuga Ceviri", "https://tortuga-ceviri.com", "tr"),
SingleLang("Traducciones Moonlight", "https://traduccionesmoonlight.com", "es"),
SingleLang("Trap Scans", "https://trapscans.com", "en"),
SingleLang("TreeManga", "https://treemanga.com", "en", overrideVersionCode = 1),
SingleLang("TritiniaScans", "https://tritinia.org", "en", overrideVersionCode = 4),
SingleLang("Tumangaonline.site", "https://tumangaonline.site", "es", isNsfw = true, className = "TumangaonlineSite", pkgName = "tumangaonlinesite"),
@ -525,7 +522,6 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("شبكة كونان العربية", "https://manga.detectiveconanar.com", "ar", className = "DetectiveConanAr", overrideVersionCode = 2),
SingleLang("عرب تونز", "https://arabtoons.net", "ar", isNsfw = true, className = "ArabToons"),
SingleLang("مانجا العاشق", "https://3asq.org", "ar", className = "Manga3asq", overrideVersionCode = 2),
SingleLang("مانجا عرب تيم Manga Arab Team", "https://mangaarbteam.com", "ar", className = "MangaArabTeam", overrideVersionCode = 1),
SingleLang("مانجا ليك", "https://mangalek.com", "ar", className = "Mangalek", overrideVersionCode = 2),
SingleLang("مانجا ليكس", "https://mangaleks.com", "ar", className = "MangaLeks"),
SingleLang("مانجا لينك", "https://mangalink.io", "ar", className = "MangaLinkio", overrideVersionCode = 3),

View File

@ -16,7 +16,6 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
override val sources = listOf(
MultiLang("Asura Scans", "https://asuracomics.com", listOf("en", "tr"), className = "AsuraScansFactory", pkgName = "asurascans", overrideVersionCode = 26),
MultiLang("Flame Scans", "https://flamescans.org", listOf("en"), className = "FlameScansFactory", pkgName = "flamescans", overrideVersionCode = 4),
MultiLang("Komik Lab", "https://komiklab.com", listOf("en", "id"), className = "KomikLabFactory", pkgName = "komiklab", overrideVersionCode = 2),
MultiLang("Miau Scan", "https://miauscans.com", listOf("es", "pt-BR"), overrideVersionCode = 1),
SingleLang("Animated Glitched Scans", "https://anigliscans.com", "en"),
SingleLang("Arena Scans", "https://arenascans.net", "en", overrideVersionCode = 1),
@ -53,6 +52,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("KomikDewasa", "https://komikdewasa.org", "id", isNsfw = true),
SingleLang("Komik Station", "https://komikstation.co", "id", overrideVersionCode = 3),
SingleLang("KomikIndo.co", "https://komikindo.co", "id", className = "KomikindoCo", overrideVersionCode = 3),
SingleLang("Komik Lab", "https://komiklab.com", "en", overrideVersionCode = 3),
SingleLang("KomikMama", "https://komikmama.co", "id", overrideVersionCode = 1),
SingleLang("KomikManhwa", "https://komikmanhwa.me", "id", isNsfw = true),
SingleLang("KumaPoi", "https://kumapoi.club", "id", isNsfw = true, overrideVersionCode = 2),

View File

@ -8,22 +8,6 @@ class MCCMSGenerator : ThemeSourceGenerator {
override val themePkg = "mccms"
override val baseVersionCode = 6
override val sources = listOf(
SingleLang(
name = "Haoman6",
baseUrl = "https://www.haoman6.com",
lang = "zh",
className = "Haoman6",
sourceName = "好漫6",
overrideVersionCode = 3,
),
SingleLang( // same as: www.haoman6.cc
name = "Haoman6 (g-lens)",
baseUrl = "https://www.g-lens.com",
lang = "zh",
className = "Haoman6glens",
sourceName = "好漫6 (g-lens)",
overrideVersionCode = 0,
),
SingleLang(
name = "Kuaikuai Manhua 3",
baseUrl = "https://mobile3.manhuaorg.com",

View File

@ -18,7 +18,6 @@ class MyMangaCMSGenerator : ThemeSourceGenerator {
"vi",
overrideVersionCode = 9,
),
SingleLang("LKDTT", "https://lkdttee.com", "vi", true, overrideVersionCode = 4),
)
companion object {

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />

View File

@ -1,12 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
ext {
extName = 'MeDocTruyenTranh'
pkgNameSuffix = 'vi.medoctruyentranh'
extClass = '.MeDocTruyenTranh'
extVersionCode = 6
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

View File

@ -1,189 +0,0 @@
package eu.kanade.tachiyomi.extension.vi.medoctruyentranh
import eu.kanade.tachiyomi.network.GET
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 kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import uy.kohesive.injekt.injectLazy
import java.text.SimpleDateFormat
import java.util.Locale
class MeDocTruyenTranh : ParsedHttpSource() {
override val name = "MeDocTruyenTranh"
override val baseUrl = "https://www.medoctruyentranh.net"
override val lang = "vi"
override val supportsLatest = false
override val client = network.cloudflareClient
private val json: Json by injectLazy()
override fun popularMangaSelector() = "div.classifyList a"
override fun searchMangaSelector() = ".listCon a"
override fun popularMangaRequest(page: Int): Request {
return GET("$baseUrl/tim-truyen/toan-bo" + if (page > 1) "/$page" else "", headers)
}
override fun popularMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
// trying to build URLs from this JSONObject could cause issues but we need it to get thumbnails
val nextData = document.select("script#__NEXT_DATA__").first()!!
.let { json.parseToJsonElement(it.data()).jsonObject }
val titleCoverMap = nextData["props"]!!
.jsonObject["pageProps"]!!
.jsonObject["initialState"]!!
.jsonObject["classify"]!!
.jsonObject["comics"]!!
.jsonArray.associate {
Pair(
it.jsonObject["title"]!!.jsonPrimitive.content,
it.jsonObject["coverimg"]!!.jsonPrimitive.content,
)
}
val mangas = document.select(popularMangaSelector()).map {
popularMangaFromElement(it).apply {
thumbnail_url = titleCoverMap[this.title]
}
}
return MangasPage(mangas, document.select(popularMangaNextPageSelector()) != null)
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return GET("$baseUrl/search/$query", headers)
}
override fun popularMangaFromElement(element: Element): SManga {
return SManga.create().apply {
title = element.select("div.storytitle").text()
setUrlWithoutDomain(element.attr("href"))
}
}
override fun popularMangaNextPageSelector() = "div.page_floor a.focus + a + a"
override fun searchMangaFromElement(element: Element): SManga {
val manga = SManga.create()
val jsonData = element.ownerDocument()!!.select("#__NEXT_DATA__").first()!!.data()
manga.setUrlWithoutDomain(element.attr("href"))
manga.title = element.select("div.storytitle").text()
val indexOfManga = jsonData.indexOf(manga.title)
val startIndex = jsonData.indexOf("coverimg", indexOfManga) + 11
val endIndex = jsonData.indexOf("}", startIndex) - 1
manga.thumbnail_url = jsonData.substring(startIndex, endIndex)
return manga
}
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply {
val nextData = document.select("script#__NEXT_DATA__").first()!!
.let { json.parseToJsonElement(it.data()).jsonObject }
val mangaDetail = nextData["props"]!!
.jsonObject["pageProps"]!!
.jsonObject["initialState"]!!
.jsonObject["detail"]!!
.jsonObject["story_item"]!!
.jsonObject
title = mangaDetail["title"]!!.jsonPrimitive.content
author = mangaDetail["author_list"]!!.jsonArray.joinToString { it.jsonPrimitive.content }
genre = mangaDetail["category_list"]!!.jsonArray.joinToString { it.jsonPrimitive.content }
description = mangaDetail["summary"]!!.jsonPrimitive.content
status = parseStatus(mangaDetail["is_updating"]!!.jsonPrimitive.content)
thumbnail_url = mangaDetail["coverimg"]!!.jsonPrimitive.content
}
private fun parseStatus(status: String) = when {
status.contains("1") -> SManga.ONGOING
status.contains("0") -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
override fun chapterListSelector() = "div.chapters a"
override fun chapterListParse(response: Response): List<SChapter> {
val nextData = response.asJsoup().select("script#__NEXT_DATA__").first()!!
.let { json.parseToJsonElement(it.data()).jsonObject }
return nextData["props"]!!
.jsonObject["pageProps"]!!
.jsonObject["initialState"]!!
.jsonObject["detail"]!!
.jsonObject["story_chapters"]!!
.jsonArray
.flatMap { it.jsonArray }
.map {
val chapterObj = it.jsonObject
SChapter.create().apply {
name = chapterObj["title"]!!.jsonPrimitive.content
date_upload = parseChapterDate(chapterObj["time"]!!.jsonPrimitive.content)
setUrlWithoutDomain("${response.request.url}/${chapterObj["chapter_index"]!!.jsonPrimitive.content}")
}
}
.reversed()
}
private fun parseChapterDate(date: String): Long {
// 2019-05-09T07:09:58
val dateFormat = SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss",
Locale.US,
)
return dateFormat.parse(date)?.time ?: 0L
}
override fun pageListParse(document: Document): List<Page> {
val nextData = document.select("script#__NEXT_DATA__").firstOrNull()
?.let { json.parseToJsonElement(it.data()).jsonObject }
?: return emptyList()
return nextData["props"]!!
.jsonObject["pageProps"]!!
.jsonObject["initialState"]!!
.jsonObject["read"]!!
.jsonObject["detail_item"]!!
.jsonObject["elements"]!!
.jsonArray
.mapIndexed { i, jsonEl ->
Page(i, "", jsonEl.jsonObject["content"]!!.jsonPrimitive.content)
}
}
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("This method should not be called!")
override fun latestUpdatesSelector() = throw UnsupportedOperationException("This method should not be called!")
override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException("This method should not be called!")
override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException("This method should not be called!")
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException("This method should not be called!")
override fun chapterFromElement(element: Element): SChapter = throw UnsupportedOperationException("This method should not be called!")
}

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name=".vi.truyentranh8.TruyenTranh8UrlActivity"
android:excludeFromRecents="true"
android:exported="true"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="truyentranh86.com"
android:pathPattern="/truyen-tranh/..*"
android:scheme="http" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -1,12 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'Truyện Tranh 8'
pkgNameSuffix = 'vi.truyentranh8'
extClass = '.TruyenTranh8'
extVersionCode = 1
isNsfw = true
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

View File

@ -1,404 +0,0 @@
package eu.kanade.tachiyomi.extension.vi.truyentranh8
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 okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.select.Evaluator
import rx.Observable
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.TimeZone
import java.util.concurrent.TimeUnit
class TruyenTranh8 : ParsedHttpSource() {
override val name = "Truyện Tranh 8"
override val baseUrl = "http://truyentranh86.com"
override val lang = "vi"
override val supportsLatest = true
override val client = network.cloudflareClient.newBuilder()
.rateLimit(1, 2, TimeUnit.SECONDS)
.build()
override fun headersBuilder() = Headers.Builder()
.add("Referer", "$baseUrl/")
.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0")
private val dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).apply {
timeZone = TimeZone.getTimeZone("Asia/Ho_Chi_Minh")
}
private val floatingNumberRegex = Regex("""([+-]?(?:[0-9]*[.])?[0-9]+)""")
override fun popularMangaRequest(page: Int) = GET(
baseUrl.toHttpUrl().newBuilder().apply {
addPathSegment("search.php")
addQueryParameter("act", "search")
addQueryParameter("sort", "xem")
addQueryParameter("view", "thumb")
addQueryParameter("page", page.toString())
}.build().toString(),
headers,
)
override fun popularMangaNextPageSelector(): String = "div#tblChap p.page a:contains(Cuối)"
override fun popularMangaSelector(): String = "div#tblChap figure.col"
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
setUrlWithoutDomain(element.select("figcaption h3 a").first()!!.attr("href"))
title = element.select("figcaption h3 a").first()!!.text().replace("[TT8] ", "")
thumbnail_url = element.select("img").first()!!.attr("abs:src")
}
override fun latestUpdatesRequest(page: Int) = GET(
baseUrl.toHttpUrl().newBuilder().apply {
addPathSegment("search.php")
addQueryParameter("act", "search")
addQueryParameter("sort", "chap")
addQueryParameter("view", "thumb")
addQueryParameter("page", page.toString())
}.build().toString(),
headers,
)
override fun latestUpdatesNextPageSelector(): String = popularMangaNextPageSelector()
override fun latestUpdatesSelector(): String = popularMangaSelector()
override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return when {
query.startsWith(PREFIX_ID_SEARCH) -> {
val id = query.removePrefix(PREFIX_ID_SEARCH).trim()
if (id.isEmpty()) {
throw Exception("ID tìm kiếm không hợp lệ.")
}
fetchMangaDetails(SManga.create().apply { url = "/truyen-tranh/$id/" })
.map { MangasPage(listOf(it), false) }
}
else -> super.fetchSearchManga(page, query, filters)
}
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET(
baseUrl.toHttpUrl().newBuilder().apply {
addPathSegment("search.php")
addQueryParameter("act", "timnangcao")
addQueryParameter("view", "thumb")
addQueryParameter("page", page.toString())
if (query.isNotEmpty()) {
addQueryParameter("q", query)
}
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
when (filter) {
is SortByFilter -> addQueryParameter("sort", filter.toUriPart())
is SearchTypeFilter -> addQueryParameter("andor", filter.toUriPart())
is ForFilter -> if (filter.state != 0) {
addQueryParameter("danhcho", filter.toUriPart())
}
is AgeFilter -> if (filter.state != 0) {
addQueryParameter("DoTuoi", filter.toUriPart())
}
is StatusFilter -> if (filter.state != 0) {
addQueryParameter("TinhTrang", filter.toUriPart())
}
is OriginFilter -> if (filter.state != 0) {
addQueryParameter("quocgia", filter.toUriPart())
}
is ReadingModeFilter -> if (filter.state != 0) {
addQueryParameter("KieuDoc", filter.toUriPart())
}
is YearFilter -> if (filter.state.isNotEmpty()) {
addQueryParameter("NamPhaHanh", filter.state)
}
is UserFilter -> if (filter.state.isNotEmpty()) {
addQueryParameter("u", filter.state)
}
is AuthorFilter -> if (filter.state.isNotEmpty()) {
addQueryParameter("TacGia", filter.state)
}
is SourceFilter -> if (filter.state.isNotEmpty()) {
addQueryParameter("Nguon", filter.state)
}
is GenreList -> {
addQueryParameter(
"baogom",
filter.state
.filter { it.state == Filter.TriState.STATE_INCLUDE }
.joinToString(",") { it.id },
)
addQueryParameter(
"khonggom",
filter.state
.filter { it.state == Filter.TriState.STATE_EXCLUDE }
.joinToString(",") { it.id },
)
}
else -> {}
}
}
}.build().toString(),
headers,
)
override fun searchMangaNextPageSelector(): String = popularMangaNextPageSelector()
override fun searchMangaSelector(): String = popularMangaSelector()
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
title = document.select("h1.fs-5").first()!!.text().replace("Truyện Tranh ", "")
author = document.select("span[itemprop=author]").toList()
.filter { it.text().isNotEmpty() }
.joinToString(", ") { it.text() }
thumbnail_url = document.select("img.thumbnail").first()!!.attr("abs:src")
genre = document.select("a[itemprop=genre]").toList()
.filter { it.text().isNotEmpty() }
.joinToString(", ") { it.text() }
status = when (document.select("ul.mangainfo b:contains(Tình Trạng) + a").first()!!.text().trim()) {
"Đang tiến hành" -> SManga.ONGOING
"Đã hoàn thành" -> SManga.COMPLETED
"Tạm ngưng" -> SManga.ON_HIATUS
else -> SManga.UNKNOWN
}
val descnode = document.select("div.card-body.border-start.border-info.border-3").first()!!
descnode.select(Evaluator.Tag("br")).prepend("\\n")
description = if (descnode.select("p").any()) {
descnode.select("p").joinToString("\n") {
it.text().replace("\\n", "\n").replace("\n ", "\n")
}.trim()
} else {
descnode.text().replace("\\n", "\n").replace("\n ", "\n").trim()
}
}
override fun chapterListSelector() = "ul#ChapList li"
override fun chapterFromElement(element: Element) = SChapter.create().apply {
setUrlWithoutDomain(element.select("a").first()!!.attr("abs:href"))
name = element.text().replace(element.select("time").first()!!.text(), "")
date_upload = runCatching {
dateFormatter.parse(element.select("time").first()!!.attr("datetime"))?.time
}.getOrNull() ?: 0L
val match = floatingNumberRegex.find(name)
chapter_number = if (name.lowercase().startsWith("vol")) {
match?.groups?.get(2)
} else {
match?.groups?.get(1)
}?.value?.toFloat() ?: -1f
}
override fun pageListParse(document: Document) = document.select("div.page-chapter")
.mapIndexed { i, elem ->
Page(i, "", elem.select("img").first()!!.attr("abs:src"))
}
override fun imageUrlParse(document: Document): String = throw Exception("Not used")
open class UriPartFilter(displayName: String, private val vals: Array<Pair<String, String>>, state: Int = 0) :
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray(), state) {
fun toUriPart() = vals[state].second
}
private class YearFilter : Filter.Text("Năm phát hành")
private class UserFilter : Filter.Text("Đăng bởi thành viên")
private class AuthorFilter : Filter.Text("Tên tác giả")
private class SourceFilter : Filter.Text("Nguồn/Nhóm dịch")
private class SearchTypeFilter : UriPartFilter(
"Kiểu tìm",
arrayOf(
Pair("AND/và", "and"),
Pair("OR/hoặc", "or"),
),
)
private class ForFilter : UriPartFilter(
"Dành cho",
arrayOf(
Pair("Bất kì", ""),
Pair("Con gái", "gai"),
Pair("Con trai", "trai"),
Pair("Con nít", "nit"),
),
)
private class AgeFilter : UriPartFilter(
"Bất kỳ",
arrayOf(
Pair("Bất kì", ""),
Pair("= 13", "13"),
Pair("= 14", "14"),
Pair("= 15", "15"),
Pair("= 16", "16"),
Pair("= 17", "17"),
Pair("= 18", "18"),
),
)
private class StatusFilter : UriPartFilter(
"Tình trạng",
arrayOf(
Pair("Bất kì", ""),
Pair("Đang dịch", "Ongoing"),
Pair("Hoàn thành", "Complete"),
Pair("Tạm ngưng", "Drop"),
),
)
private class OriginFilter : UriPartFilter(
"Quốc gia",
arrayOf(
Pair("Bất kì", ""),
Pair("Nhật Bản", "nhat"),
Pair("Trung Quốc", "trung"),
Pair("Hàn Quốc", "han"),
Pair("Việt Nam", "vietnam"),
),
)
private class ReadingModeFilter : UriPartFilter(
"Kiểu đọc",
arrayOf(
Pair("Bất kì", ""),
Pair("Chưa xác định", "chưa xác định"),
Pair("Phải qua trái", "xem từ phải qua trái"),
Pair("Trái qua phải", "xem từ trái qua phải"),
),
)
private class SortByFilter : UriPartFilter(
"Sắp xếp theo",
arrayOf(
Pair("Chap mới", "chap"),
Pair("Truyện mới", "truyen"),
Pair("Xem nhiều", "xem"),
Pair("Theo ABC", "ten"),
Pair("Số Chương", "sochap"),
),
2,
)
open class Genre(name: String, val id: String) : Filter.TriState(name)
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Thể loại", genres)
override fun getFilterList() = FilterList(
GenreList(getGenreList()),
SortByFilter(),
SearchTypeFilter(),
ForFilter(),
AgeFilter(),
StatusFilter(),
OriginFilter(),
ReadingModeFilter(),
YearFilter(),
UserFilter(),
AuthorFilter(),
SourceFilter(),
)
private fun getGenreList() = listOf(
Genre("Phát Hành Tại TT8", "106"),
Genre("Truyện Màu", "113"),
Genre("Webtoons", "112"),
Genre("Manga - Truyện Nhật", "141"),
Genre("Action - Hành động", "52"),
Genre("Adult - Người lớn", "53"),
Genre("Adventure - Phiêu lưu", "65"),
Genre("Anime", "107"),
Genre("Biseinen", "123"),
Genre("Bishounen", "122"),
Genre("Comedy - Hài hước", "50"),
Genre("Doujinshi", "72"),
Genre("Drama", "73"),
Genre("Ecchi", "74"),
Genre("Fantasy", "75"),
Genre("Gender Bender - Đổi giới tính", "76"),
Genre("Harem", "77"),
Genre("Historical - Lịch sử", "78"),
Genre("Horror - Kinh dị", "79"),
Genre("Isekai - Xuyên không", "139"),
Genre("Josei", "80"),
Genre("Live-action - Live Action", "81"),
Genre("Macgic", "138"),
Genre("Magic - Phép thuật", "116"),
Genre("Martial Arts - Martial-Arts", "84"),
Genre("Mature - Trưởng thành", "85"),
Genre("Mecha - Robot", "86"),
Genre("Mystery - Bí ẩn", "87"),
Genre("One-shot", "88"),
Genre("Psychological - Tâm lý", "89"),
Genre("Romance - Tình cảm", "90"),
Genre("School Life - Học đường", "91"),
Genre("Sci fi - Khoa học viễn tưởng", "92"),
Genre("Seinen", "93"),
Genre("Shoujo", "94"),
Genre("Shoujo Ai", "66"),
Genre("Shounen", "96"),
Genre("Shounen Ai", "97"),
Genre("Slash", "121"),
Genre("Slice-of-Life - Đời sống", "98"),
Genre("Smut", "99"),
Genre("Soft Yaoi - Soft-Yaoi", "100"),
Genre("Sports - Thể thao", "101"),
Genre("Supernatural - Siêu nhiên", "102"),
Genre("Tạp chí truyện tranh", "103"),
Genre("Tragedy - Bi kịch", "104"),
Genre("Trap - Crossdressing", "115"),
Genre("Yaoi", "114"),
Genre("Yaoi Hardcore", "120"),
Genre("Yuri", "111"),
Genre("Manhua - Truyện Trung", "82"),
Genre("Bách Hợp", "128"),
Genre("Chuyển sinh", "134"),
Genre("Cổ đại", "135"),
Genre("Cung đình", "144"),
Genre("Giới giải trí", "146"),
Genre("Hậu cung", "145"),
Genre("Huyền Huyễn", "132"),
Genre("Khoa Huyễn", "130"),
Genre("Lịch Sử", "131"),
Genre("Ngôn tình", "127"),
Genre("Ngọt sủng", "148"),
Genre("Ngược", "143"),
Genre("Người đóng góp", "147"),
Genre("Nữ Cường", "136"),
Genre("Tổng tài", "137"),
Genre("Trọng Sinh", "126"),
Genre("Trường học", "142"),
Genre("Tu chân - tu tiên", "140"),
Genre("Võng Du", "125"),
Genre("Xuyên không", "124"),
Genre("Đam Mỹ", "108"),
Genre("Đô thị", "129"),
Genre("Manhwa - Truyện Hàn", "83"),
Genre("Boy love", "133"),
Genre("Thriller - Giết người, sát nhân, máu me", "149"),
Genre("Truyện Tranh Việt", "51"),
Genre("Cướp bồ - NTR, Netorare", "118"),
Genre("Hướng dẫn vẽ!", "109"),
Genre("Truyện scan", "105"),
Genre("Comic - truyện Âu Mĩ", "71"),
)
companion object {
const val PREFIX_ID_SEARCH = "id:"
}
}

View File

@ -1,36 +0,0 @@
package eu.kanade.tachiyomi.extension.vi.truyentranh8
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.util.Log
import kotlin.system.exitProcess
class TruyenTranh8UrlActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val pathSegments = intent?.data?.pathSegments
if (pathSegments != null && pathSegments.size > 1) {
val id = pathSegments[1]
try {
startActivity(
Intent().apply {
action = "eu.kanade.tachiyomi.SEARCH"
putExtra("query", "${TruyenTranh8.PREFIX_ID_SEARCH}$id")
putExtra("filter", packageName)
},
)
} catch (e: ActivityNotFoundException) {
Log.e("TruyenTranh8UrlActivity", e.toString())
}
} else {
Log.e("TruyenTranh8UrlActivity", "Could not parse URL from intent $intent")
}
finish()
exitProcess(0)
}
}