ColorlibAnime ()

* ColorlibAnime

* remove adaptive icons

* lint

* lint

* Optimize icons with `oxipng -omax --strip all`

---------

Co-authored-by: stevenyomi <95685115+stevenyomi@users.noreply.github.com>
This commit is contained in:
Mike 2024-02-02 17:26:40 -05:00 committed by Draff
parent cc9a0d2b41
commit dd60a193e7
26 changed files with 193 additions and 115 deletions
multisrc
overrides
colorlibanime
default/res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
komikzoid/res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
neumanga
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src
sektekomik/res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
zmanga
neumanga/src
sektekomik/src
src/main/java/eu/kanade/tachiyomi/multisrc

Binary file not shown.

After

(image error) Size: 2.0 KiB

Binary file not shown.

After

(image error) Size: 1.4 KiB

Binary file not shown.

After

(image error) Size: 2.7 KiB

Binary file not shown.

After

(image error) Size: 3.9 KiB

Binary file not shown.

After

(image error) Size: 5.4 KiB

Binary file not shown.

After

(image error) Size: 2.4 KiB

Binary file not shown.

After

(image error) Size: 1.5 KiB

Binary file not shown.

After

(image error) Size: 3.6 KiB

Binary file not shown.

After

(image error) Size: 6.3 KiB

Binary file not shown.

After

(image error) Size: 9.1 KiB

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.id.neumanga
import eu.kanade.tachiyomi.multisrc.colorlibanime.ColorlibAnime
class Neumanga : ColorlibAnime("Neumanga", "https://neumanga.xyz", "id") {
override val versionId = 2
}

@ -1,12 +0,0 @@
package eu.kanade.tachiyomi.extension.id.neumanga
import eu.kanade.tachiyomi.multisrc.zmanga.ZManga
import okhttp3.Headers
import java.text.SimpleDateFormat
import java.util.Locale
class Neumanga : ZManga("Neumanga", "https://neumanga.net", "id", SimpleDateFormat("MMMM dd, yyyy", Locale("id"))) {
override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
}

@ -1,101 +0,0 @@
package eu.kanade.tachiyomi.extension.id.sektekomik
import eu.kanade.tachiyomi.multisrc.zmanga.ZManga
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.SManga
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import org.jsoup.nodes.Element
import java.util.concurrent.TimeUnit
class SekteKomik : ZManga("Sekte Komik", "https://sektekomik.com", "id") {
// Formerly "Sekte Komik (WP Manga Stream)"
override val id = 7866629035053218469
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.rateLimit(3)
.build()
// popular
override fun popularMangaRequest(page: Int): Request {
return GET("$baseUrl")
}
override fun popularMangaSelector() = "div.flexbox-item"
override fun popularMangaFromElement(element: Element): SManga {
return SManga.create().apply {
setUrlWithoutDomain(element.select("a").attr("href"))
title = element.select("a").attr("title")
thumbnail_url = element.select("img").attr("abs:src")
}
}
override fun popularMangaNextPageSelector() = "Not used"
// latest
override fun latestUpdatesRequest(page: Int): Request {
return GET("$baseUrl/page/$page")
}
override fun latestUpdatesSelector() = "div.flexbox4-item"
override fun latestUpdatesFromElement(element: Element): SManga {
return SManga.create().apply {
setUrlWithoutDomain(element.select("div.flexbox4-content a").attr("href"))
title = element.select("div.flexbox4-side .title").first()!!.text()
thumbnail_url = element.select("img").attr("abs:src")
}
}
override fun latestUpdatesNextPageSelector() = "div.pagination .next"
// search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
var url = "$baseUrl/${pagePathSegment(page)}".toHttpUrl().newBuilder()
url.addQueryParameter("s", query)
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
when (filter) {
// if site has project page, default value "hasProjectPage" = false
is ProjectFilter -> {
if (filter.toUriPart() == "project-filter-on") {
url = "$baseUrl$projectPageString/${pagePathSegment(page)}".toHttpUrl().newBuilder()
}
}
else -> {}
}
}
return GET(url.build(), headers)
}
override fun searchMangaSelector() = "div.flexbox2-item"
override fun searchMangaFromElement(element: Element): SManga {
return SManga.create().apply {
setUrlWithoutDomain(element.select("div.flexbox2-content a").attr("href"))
title = element.select("div.flexbox2-title > span").first()!!.text()
thumbnail_url = element.select("img").attr("abs:src")
}
}
override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector()
// filter
override val hasProjectPage = true
override fun getFilterList(): FilterList {
val filters = mutableListOf<Filter<*>>(
Filter.Separator(),
Filter.Header("NOTE: cant be used with search!"),
Filter.Header("$name Project List page"),
ProjectFilter(),
)
return FilterList(filters)
}
}

@ -0,0 +1,160 @@
package eu.kanade.tachiyomi.multisrc.colorlibanime
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 eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
abstract class ColorlibAnime(
override val name: String,
override val baseUrl: String,
override val lang: String,
) : ParsedHttpSource() {
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.rateLimit(3)
.build()
private fun Element.toThumbnail(): String {
return this.select(".set-bg").attr("abs:data-setbg").substringBeforeLast("?")
}
// Search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = baseUrl.toHttpUrl().newBuilder().apply {
addPathSegment("manga")
addQueryParameter("page", page.toString())
addQueryParameter("sort", filters.findInstance<OrderFilter>()!!.toUriPart())
addQueryParameter("search", query)
}
return GET(url.build(), headers)
}
override fun searchMangaSelector(): String = ".product__page__content > [style]:has(.col-6) .product__item"
override fun searchMangaFromElement(element: Element): SManga {
return SManga.create().apply {
setUrlWithoutDomain(element.select("a.img-link").attr("abs:href"))
title = element.select("h5").text()
thumbnail_url = element.toThumbnail()
}
}
override fun searchMangaNextPageSelector(): String? = ".fa-angle-right"
// Popular
override fun popularMangaRequest(page: Int): Request {
return searchMangaRequest(page, "", FilterList(OrderFilter(0)))
}
override fun popularMangaSelector(): String = searchMangaSelector()
override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
override fun popularMangaNextPageSelector(): String? = searchMangaNextPageSelector()
// Latest
override fun latestUpdatesRequest(page: Int): Request {
return searchMangaRequest(page, "", FilterList(OrderFilter(1)))
}
override fun latestUpdatesSelector(): String = searchMangaSelector()
override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
override fun latestUpdatesNextPageSelector(): String? = searchMangaNextPageSelector()
// Details
override fun mangaDetailsParse(document: Document): SManga {
document.select(".anime__details__content").let { element ->
return SManga.create().apply {
title = element.select("h3").text()
author = element.select("h3 + span").text()
description = element.select("p").text()
thumbnail_url = element.first()?.toThumbnail()
status = when (element.select("li:contains(status)").text().substringAfter(" ")) {
"Ongoing" -> SManga.ONGOING
"Complete" -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
}
}
}
// Chapters
private val timeRegex = Regex("""Date\((\d+)\)""")
override fun chapterListParse(response: Response): List<SChapter> {
val doc = response.asJsoup()
val time = timeRegex.find(doc.select("script:containsData(lastUpdated)").html())
?.let { it.groupValues[1].toLong() } ?: 0
return doc.select(chapterListSelector())
.map { chapterFromElement(it) }
.apply { this.first().date_upload = time }
}
override fun chapterListSelector(): String = ".anime__details__episodes a"
override fun chapterFromElement(element: Element): SChapter {
return SChapter.create().apply {
setUrlWithoutDomain(element.attr("abs:href"))
name = element.text()
date_upload = 0L
}
}
// Pages
override fun pageListParse(document: Document): List<Page> {
return document.select(".container .read-img > img").mapIndexed { i, element ->
Page(i, "", element.attr("abs:src"))
}
}
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException()
// Filters
override fun getFilterList() = FilterList(
OrderFilter(),
)
class OrderFilter(state: Int = 0) : UriPartFilter(
"Order By",
arrayOf(
Pair("Views", "view"),
Pair("Updated", "updated"),
),
state,
)
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 inline fun <reified T> Iterable<*>.findInstance() = find { it is T } as? T
}

@ -0,0 +1,26 @@
package eu.kanade.tachiyomi.multisrc.colorlibanime
import generator.ThemeSourceData.SingleLang
import generator.ThemeSourceGenerator
class ColorlibAnimeGenerator : ThemeSourceGenerator {
override val themePkg = "colorlibanime"
override val themeClass = "ColorlibAnime"
override val baseVersionCode: Int = 1
override val sources = listOf(
SingleLang("Sekte Komik", "https://sektekomik.xyz", "id", overrideVersionCode = 26),
SingleLang("Komikzoid", "https://komikzoid.id", "id"),
SingleLang("Neumanga", "https://neumanga.xyz", "id", overrideVersionCode = 1),
)
companion object {
@JvmStatic
fun main(args: Array<String>) {
ColorlibAnimeGenerator().createAll()
}
}
}

@ -17,9 +17,7 @@ class ZMangaGenerator : ThemeSourceGenerator {
SingleLang("KomikIndo.info", "http://komikindo.info", "id", isNsfw = true, className = "KomikIndoInfo"),
SingleLang("KomikPlay", "https://komikplay.com", "id", overrideVersionCode = 1),
SingleLang("Maid - Manga", "https://www.maid.my.id", "id", overrideVersionCode = 10, className = "MaidManga"),
SingleLang("Neumanga", "https://neumanga.net", "id"),
SingleLang("ShiroDoujin", "https://shirodoujin.com", "id", isNsfw = true, overrideVersionCode = 1, className = "Shirodoujin"),
SingleLang("Sekte Komik", "https://sektekomik.com", "id", overrideVersionCode = 25),
)
companion object {