diff --git a/src/all/foolslide/build.gradle b/src/all/foolslide/build.gradle index 91c1f86df..54602ad6b 100644 --- a/src/all/foolslide/build.gradle +++ b/src/all/foolslide/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'FoolSlide (multiple sources)' pkgNameSuffix = 'all.foolslide' extClass = '.FoolSlideFactory' - extVersionCode = 51 + extVersionCode = 52 libVersion = '1.2' containsNsfw = true } diff --git a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt index d666909fb..a63cb3921 100644 --- a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt +++ b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/FoolSlideFactory.kt @@ -56,7 +56,6 @@ class FoolSlideFactory : SourceFactory { HNIScantradEN(), PhoenixScans(), GTO(), - Kangaryu(), FallenWorldOrder(), NIFTeam(), TuttoAnimeManga(), @@ -211,22 +210,6 @@ class PhoenixScans : FoolSlide("The Phoenix Scans", "https://www.phantomreader.c class GTO : FoolSlide("GTO The Great Site", "https://www.gtothegreatsite.net", "it", "/reader") -class Kangaryu : FoolSlide("Kangaryu", "https://kangaryu-team.fr", "fr") { - override fun latestUpdatesRequest(page: Int) = GET(baseUrl, headers).also { latestUpdatesUrls.clear() } - override fun latestUpdatesSelector() = "div.card" - override fun latestUpdatesFromElement(element: Element): SManga { - return SManga.create().apply { - element.select("div.card-text a").let { - title = it.text() - setUrlWithoutDomain(it.attr("href")) - } - thumbnail_url = element.select("img").attr("abs:src") - } - } - override fun latestUpdatesNextPageSelector(): String? = null - override val mangaDetailsInfoSelector = "div.info:not(.comic)" -} - class FallenWorldOrder : FoolSlide("Fall World Reader", "https://faworeader.altervista.org", "it", "/slide") class NIFTeam : FoolSlide("NIFTeam", "http://read-nifteam.info", "it", "/slide") diff --git a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt index b1220f0f7..36d164386 100644 --- a/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt +++ b/src/all/foolslide/src/eu/kanade/tachiyomi/extension/all/foolslide/HentaiCafe.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.extension.all.foolslide +import eu.kanade.tachiyomi.annotations.Nsfw import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.asObservable import eu.kanade.tachiyomi.source.model.Filter @@ -15,6 +16,7 @@ import org.jsoup.nodes.Document import org.jsoup.nodes.Element import rx.Observable +@Nsfw class HentaiCafe : FoolSlide("Hentai Cafe", "https://hentai.cafe", "en", "/manga") { // We have custom latest updates logic so do not dedupe latest updates override val dedupeLatestUpdates = false diff --git a/src/fr/kangaryu/build.gradle b/src/fr/kangaryu/build.gradle new file mode 100644 index 000000000..babda2aa9 --- /dev/null +++ b/src/fr/kangaryu/build.gradle @@ -0,0 +1,12 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +ext { + extName = 'Kangaryu' + pkgNameSuffix = 'fr.kangaryu' + extClass = '.Kangaryu' + extVersionCode = 1 + libVersion = '1.2' +} + +apply from: "$rootDir/common.gradle" diff --git a/src/fr/kangaryu/res/mipmap-hdpi/ic_launcher.png b/src/fr/kangaryu/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..4d40f2e4e Binary files /dev/null and b/src/fr/kangaryu/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/fr/kangaryu/res/mipmap-mdpi/ic_launcher.png b/src/fr/kangaryu/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..7e72a1463 Binary files /dev/null and b/src/fr/kangaryu/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/fr/kangaryu/res/mipmap-xhdpi/ic_launcher.png b/src/fr/kangaryu/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..f143706e0 Binary files /dev/null and b/src/fr/kangaryu/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/fr/kangaryu/res/mipmap-xxhdpi/ic_launcher.png b/src/fr/kangaryu/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..e08bb9f80 Binary files /dev/null and b/src/fr/kangaryu/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/fr/kangaryu/res/mipmap-xxxhdpi/ic_launcher.png b/src/fr/kangaryu/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..f8da38822 Binary files /dev/null and b/src/fr/kangaryu/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/fr/kangaryu/res/web_hi_res_512.png b/src/fr/kangaryu/res/web_hi_res_512.png new file mode 100644 index 000000000..37e5542f8 Binary files /dev/null and b/src/fr/kangaryu/res/web_hi_res_512.png differ diff --git a/src/fr/kangaryu/src/eu/kanade/tachiyomi/extension/fr/kangaryu/Kangaryu.kt b/src/fr/kangaryu/src/eu/kanade/tachiyomi/extension/fr/kangaryu/Kangaryu.kt new file mode 100644 index 000000000..8399ae1ef --- /dev/null +++ b/src/fr/kangaryu/src/eu/kanade/tachiyomi/extension/fr/kangaryu/Kangaryu.kt @@ -0,0 +1,153 @@ +package eu.kanade.tachiyomi.extension.fr.kangaryu + +import com.github.salomonbrys.kotson.array +import com.github.salomonbrys.kotson.fromJson +import com.github.salomonbrys.kotson.get +import com.github.salomonbrys.kotson.string +import com.google.gson.Gson +import com.google.gson.JsonObject +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 java.text.SimpleDateFormat +import java.util.Locale +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element + +class Kangaryu : ParsedHttpSource() { + + override val name = "Kangaryu" + + override val baseUrl = "https://kangaryu-team.fr" + + override val lang = "fr" + + override val supportsLatest = true + + override val client: OkHttpClient = network.cloudflareClient + + // used to be in FoolSlide + override val versionId = 2 + + // Popular + + override fun popularMangaRequest(page: Int): Request { + return GET("$baseUrl/manga-list", headers) + } + + override fun popularMangaSelector() = "div.profile-card-2" + + override fun popularMangaFromElement(element: Element): SManga { + return SManga.create().apply { + element.select("div.profile-name a").let { + setUrlWithoutDomain(it.attr("href")) + title = it.text() + } + thumbnail_url = element.select("img").attr("abs:src") + } + } + + override fun popularMangaNextPageSelector(): String? = null + + // Latest + + override fun latestUpdatesRequest(page: Int): Request { + return GET(baseUrl, headers) + } + + override fun latestUpdatesParse(response: Response): MangasPage { + return MangasPage(super.latestUpdatesParse(response).mangas.distinctBy { it.url }, false) + } + + override fun latestUpdatesSelector() = "div.events" + + override fun latestUpdatesFromElement(element: Element): SManga { + return SManga.create().apply { + element.select("div.manga-chap a").let { + setUrlWithoutDomain(it.attr("href")) + title = it.text() + } + thumbnail_url = element.select("img").attr("abs:src") + } + } + + override fun latestUpdatesNextPageSelector(): String? = null + + // Search + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + return GET("$baseUrl/search?query=$query", headers) + } + + private val gson by lazy { Gson() } + + override fun searchMangaParse(response: Response): MangasPage { + val mangas = gson.fromJson(response.body()!!.string())["suggestions"].array.map { json -> + SManga.create().apply { + url = "/manga/${json["data"].string}" + title = json["value"].string + thumbnail_url = "https://kangaryu-team.fr/uploads/manga/${json["data"].string}/cover/cover_250x350.jpg" + } + } + return MangasPage(mangas, false) + } + + override fun searchMangaSelector() = throw UnsupportedOperationException("Not used") + override fun searchMangaFromElement(element: Element): SManga = throw UnsupportedOperationException("Not used") + override fun searchMangaNextPageSelector() = throw UnsupportedOperationException("Not used") + + // Details + + override fun mangaDetailsParse(document: Document): SManga { + return SManga.create().apply { + thumbnail_url = document.select("div.boxed img").attr("abs:src") + with(document.select("div.col-sm-12 div.col-sm-8")) { + status = select("span.label").text().toStatus() + author = select("dd a[href*=author]").text() + artist = select("dd a[href*=artist]").text() + genre = select("dd a[href*=category]").joinToString { it.text() } + } + } + } + + private fun String.toStatus() = when { + this.contains("Ongoing", ignoreCase = true) -> SManga.ONGOING + this.contains("Completed", ignoreCase = true) -> SManga.COMPLETED + else -> SManga.UNKNOWN + } + + // Chapters + + override fun chapterListSelector() = "ul.chapters li:not([data-volume])" + + override fun chapterFromElement(element: Element): SChapter { + return SChapter.create().apply { + name = element.select("h5").text() + setUrlWithoutDomain(element.select("h5 a").attr("href")) + date_upload = element.select("div.date-chapter-title-rtl").text().toDate() + } + } + + private val dateFormat by lazy { SimpleDateFormat("dd/MM/yy", Locale.getDefault()) } + + private fun String.toDate(): Long { + return dateFormat.parse(this)?.time ?: 0 + } + + // Pages + + override fun pageListParse(document: Document): List { + return document.select("div#all img").mapIndexed { i, img -> + Page(i, "", img.attr("abs:data-src")) + } + } + + override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") +}