mirror of
https://github.com/keiyoushi/extensions-source.git
synced 2024-11-25 03:33:24 +01:00
Add Ưng Tỷ Comics (#1286)
This commit is contained in:
parent
6399255e78
commit
fcd38a3ed6
8
src/vi/ungtycomics/build.gradle
Normal file
8
src/vi/ungtycomics/build.gradle
Normal file
@ -0,0 +1,8 @@
|
||||
ext {
|
||||
extName = "Ung Ty Comics"
|
||||
extClass = ".UngTyComics"
|
||||
extVersionCode = 1
|
||||
isNsfw = true
|
||||
}
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
BIN
src/vi/ungtycomics/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
src/vi/ungtycomics/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
BIN
src/vi/ungtycomics/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
src/vi/ungtycomics/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
src/vi/ungtycomics/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
src/vi/ungtycomics/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
src/vi/ungtycomics/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
src/vi/ungtycomics/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
BIN
src/vi/ungtycomics/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
BIN
src/vi/ungtycomics/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
@ -0,0 +1,239 @@
|
||||
package eu.kanade.tachiyomi.extension.vi.ungtycomics
|
||||
|
||||
import android.app.Application
|
||||
import android.widget.Toast
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
|
||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||
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 okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class UngTyComics : ParsedHttpSource(), ConfigurableSource {
|
||||
|
||||
override val name = "Ưng Tỷ Comics"
|
||||
|
||||
override val baseUrl by lazy {
|
||||
when {
|
||||
System.getenv("CI") == "true" -> MIRRORS.joinToString("#, ")
|
||||
else -> preferences.getString(PREF_BASE_URL, MIRRORS[0])!!
|
||||
}
|
||||
}
|
||||
|
||||
override val lang = "vi"
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
private val preferences by lazy {
|
||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||
}
|
||||
|
||||
override val client = network.cloudflareClient.newBuilder()
|
||||
.rateLimitHost(baseUrl.toHttpUrl(), 2)
|
||||
.build()
|
||||
|
||||
override fun headersBuilder() = super.headersBuilder()
|
||||
.add("Referer", "$baseUrl/")
|
||||
|
||||
override fun popularMangaRequest(page: Int) = GET("$baseUrl/truyen-hot?page=$page", headers)
|
||||
|
||||
override fun popularMangaSelector() = "div.item-comics"
|
||||
|
||||
override fun popularMangaFromElement(element: Element) = SManga.create().apply {
|
||||
element.selectFirst(".content-title a")!!.let {
|
||||
setUrlWithoutDomain(it.attr("href"))
|
||||
title = it.text()
|
||||
}
|
||||
thumbnail_url = element.selectFirst(".content-image img")?.absUrl("data-src")
|
||||
}
|
||||
|
||||
override fun popularMangaNextPageSelector() = "ul.pagination li:has(.fa-angle-double-right):not(.disabled)"
|
||||
|
||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/truyen-tranh?page=$page", headers)
|
||||
|
||||
override fun latestUpdatesSelector() = popularMangaSelector()
|
||||
|
||||
override fun latestUpdatesFromElement(element: Element) = popularMangaFromElement(element)
|
||||
|
||||
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
|
||||
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val genreFilter = filters.ifEmpty { getFilterList() }
|
||||
.filterIsInstance<GenreFilter>()
|
||||
.firstOrNull()
|
||||
val url = baseUrl.toHttpUrl().newBuilder().apply {
|
||||
if (query.isNotEmpty()) {
|
||||
addPathSegment("search")
|
||||
addQueryParameter("query_string", query)
|
||||
} else if (genreFilter != null) {
|
||||
addPathSegments(genreFilter.genres[genreFilter.state].path)
|
||||
} else {
|
||||
addPathSegment("truyen-tranh")
|
||||
}
|
||||
|
||||
if (page > 1) {
|
||||
addQueryParameter("page", page.toString())
|
||||
}
|
||||
}.build()
|
||||
|
||||
return GET(url, headers)
|
||||
}
|
||||
|
||||
override fun searchMangaSelector() = popularMangaSelector()
|
||||
|
||||
override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element)
|
||||
|
||||
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
|
||||
|
||||
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
||||
val statusText = document.selectFirst(".comics-info .meta_label:contains(Trạng thái) + .meta_info")?.text()
|
||||
|
||||
title = document.selectFirst(".title-heading")!!.text()
|
||||
author = document.selectFirst(".comics-info .meta_label:contains(Tác giả) + .meta_info")?.text()
|
||||
genre = document.selectFirst(".comics-info .meta_label:contains(Thể loại) + .meta_info")?.text()
|
||||
status = when (statusText) {
|
||||
"Đang tiến hành" -> SManga.ONGOING
|
||||
"Đã đủ bộ" -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
thumbnail_url = document.selectFirst(".comics-thumbnail img")?.absUrl("src")
|
||||
}
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
var document = response.asJsoup()
|
||||
var page = 2
|
||||
|
||||
return buildList {
|
||||
document.select(chapterListSelector())
|
||||
.forEach { add(chapterFromElement(it)) }
|
||||
|
||||
while (document.selectFirst(chapterNextPageSelector()) != null) {
|
||||
val url = response.request.url.newBuilder()
|
||||
.addQueryParameter("page", page.toString())
|
||||
.build()
|
||||
|
||||
document = client.newCall(GET(url, headers)).execute().asJsoup()
|
||||
document.select(chapterListSelector())
|
||||
.forEach { add(chapterFromElement(it)) }
|
||||
page++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun chapterListSelector() = ".list-comics-chapter .item-chapter"
|
||||
|
||||
override fun chapterFromElement(element: Element) = SChapter.create().apply {
|
||||
element.selectFirst(".episode-title a")!!.let {
|
||||
setUrlWithoutDomain(it.attr("href"))
|
||||
name = it.text()
|
||||
}
|
||||
date_upload = try {
|
||||
val date = element.selectFirst(".episode-date span")!!.text()
|
||||
|
||||
DATE_FORMAT.parse(date)!!.time
|
||||
} catch (_: Exception) {
|
||||
0L
|
||||
}
|
||||
}
|
||||
|
||||
private fun chapterNextPageSelector() = popularMangaNextPageSelector()
|
||||
|
||||
override fun pageListParse(document: Document) =
|
||||
document.select("img.chapter-img").mapIndexed { i, it ->
|
||||
Page(i, imageUrl = it.absUrl("data-src"))
|
||||
}
|
||||
|
||||
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException()
|
||||
|
||||
override fun getFilterList() = FilterList(
|
||||
Filter.Header("Không dùng được khi tìm kiếm bằng chữ"),
|
||||
GenreFilter(getGenreList()),
|
||||
)
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
ListPreference(screen.context).apply {
|
||||
key = PREF_BASE_URL
|
||||
title = "Tên miền"
|
||||
summary = "%s"
|
||||
entries = MIRRORS
|
||||
entryValues = MIRRORS
|
||||
setDefaultValue(MIRRORS[0])
|
||||
|
||||
setOnPreferenceChangeListener { _, _ ->
|
||||
Toast.makeText(screen.context, "Khởi động lại ứng dụng để áp dụng cài đặt mới.", Toast.LENGTH_LONG)
|
||||
.show()
|
||||
true
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
}
|
||||
}
|
||||
|
||||
private const val PREF_BASE_URL = "baseUrl"
|
||||
private val MIRRORS = arrayOf("https://ungtycomicsvip.com", "https://topdammy.com")
|
||||
private val DATE_FORMAT = SimpleDateFormat("dd-MM-yyyy", Locale.ROOT)
|
||||
|
||||
private class GenreFilter(val genres: List<Genre>) : Filter.Select<String>(
|
||||
"Thể loại",
|
||||
genres.map { it.name }.toTypedArray(),
|
||||
)
|
||||
|
||||
private class Genre(val name: String, val path: String)
|
||||
|
||||
// https://ungtycomicsvip.com/truyen-tranh
|
||||
// copy([...document.querySelectorAll(".item-category a")].map((e) => `Genre("${e.textContent.trim()}", "${new URL(e.href).pathname.replace("/", "")}"),`).join("\n"))
|
||||
// removed the Truyện Chữ genre since this is not a light novel reader. there's nothing in that genre
|
||||
// anyways.
|
||||
private fun getGenreList() = listOf(
|
||||
Genre("Tất cả", "truyen-tranh"),
|
||||
Genre("Truyện hot", "truyen-hot"),
|
||||
Genre("Giới giải trí", "gioi-giai-tri.html"),
|
||||
Genre("Ngôn Tình", "ngon-tinh.html"),
|
||||
Genre("Cổ Trang", "co-trang.html"),
|
||||
Genre("Lãng Mạn", "lang-man.html"),
|
||||
Genre("Đam Mỹ", "dam-my.html"),
|
||||
Genre("Boys Love", "boys-love.html"),
|
||||
Genre("Manhua", "manhua.html"),
|
||||
Genre("Romance", "romance.html"),
|
||||
Genre("Ngược", "nguoc.html"),
|
||||
Genre("Sủng", "sung.html"),
|
||||
Genre("Cung Đấu", "cung-dau.html"),
|
||||
Genre("Drama", "drama.html"),
|
||||
Genre("Trinh Thám", "trinh-tham.html"),
|
||||
Genre("Học Đường", "hoc-duong.html"),
|
||||
Genre("Xuyên Không", "xuyen-khong.html"),
|
||||
Genre("Trọng Sinh", "trong-sinh.html"),
|
||||
Genre("School Life", "school-life.html"),
|
||||
Genre("Hiện Đại", "hien-dai.html"),
|
||||
Genre("Võng Du", "vong-du.html"),
|
||||
Genre("Báo Thù", "bao-thu.html"),
|
||||
Genre("Tổng Tài", "tong-tai.html"),
|
||||
Genre("ABO", "abo.html"),
|
||||
Genre("Hài Hước", "hai-huoc.html"),
|
||||
Genre("Niên Hạ", "nien-ha.html"),
|
||||
Genre("Hiện Thực", "hien-thuc.html"),
|
||||
Genre("Xuyên Nhanh", "xuyen-nhanh.html"),
|
||||
Genre("Sư Đồ Luyến", "su-do-luyen.html"),
|
||||
Genre("Hệ Thống", "he-thong.html"),
|
||||
Genre("Huyết Tộc", "huyet-toc.html"),
|
||||
Genre("Hắc Bang", "hac-bang.html"),
|
||||
Genre("Full Trọn Bộ", "full-tron-bo.html"),
|
||||
Genre("Phá Án", "pha-an.html"),
|
||||
Genre("Linh Dị", "linh-di.html"),
|
||||
Genre("Tu Tiên", "tu-tien.html"),
|
||||
Genre("eSports", "esports.html"),
|
||||
)
|
Loading…
Reference in New Issue
Block a user