diff --git a/src/en/rizzcomic/build.gradle b/src/en/rizzcomic/build.gradle index db8636788..391cfeaa0 100644 --- a/src/en/rizzcomic/build.gradle +++ b/src/en/rizzcomic/build.gradle @@ -1,9 +1,9 @@ ext { - extName = 'Realm Oasis' - extClass = '.RealmOasis' + extName = 'Rizz Comic' + extClass = '.RizzComic' themePkg = 'mangathemesia' - baseUrl = 'https://realmoasis.com' - overrideVersionCode = 8 + baseUrl = 'https://rizzfables.com' + overrideVersionCode = 9 } apply from: "$rootDir/common.gradle" diff --git a/src/en/rizzcomic/src/eu/kanade/tachiyomi/extension/en/rizzcomic/RealmOasis.kt b/src/en/rizzcomic/src/eu/kanade/tachiyomi/extension/en/rizzcomic/RizzComic.kt similarity index 61% rename from src/en/rizzcomic/src/eu/kanade/tachiyomi/extension/en/rizzcomic/RealmOasis.kt rename to src/en/rizzcomic/src/eu/kanade/tachiyomi/extension/en/rizzcomic/RizzComic.kt index c9b498e93..1caae477d 100644 --- a/src/en/rizzcomic/src/eu/kanade/tachiyomi/extension/en/rizzcomic/RealmOasis.kt +++ b/src/en/rizzcomic/src/eu/kanade/tachiyomi/extension/en/rizzcomic/RizzComic.kt @@ -1,7 +1,7 @@ package eu.kanade.tachiyomi.extension.en.rizzcomic -import android.app.Application -import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia +import androidx.preference.PreferenceScreen +import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesiaAlt import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.asObservableSuccess @@ -10,28 +10,22 @@ 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.util.asJsoup import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import okhttp3.FormBody -import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Request import okhttp3.Response -import org.jsoup.nodes.Element import rx.Observable -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get import java.text.SimpleDateFormat import java.util.Locale -class RealmOasis : MangaThemesia( - "Realm Oasis", - "https://realmoasis.com", +class RizzComic : MangaThemesiaAlt( + "Rizz Comic", + "https://rizzfables.com", "en", - mangaUrlDirectory = "/comics", + mangaUrlDirectory = "/series", dateFormat = SimpleDateFormat("dd MMM yyyy", Locale.ENGLISH), ) { @@ -55,26 +49,18 @@ class RealmOasis : MangaThemesia( headersBuilder() .set("X-Requested-With", "XMLHttpRequest") .set("X-API-Request", "1") - .set("Referer", "$baseUrl$mangaUrlDirectory") .build() } - override val versionId = 3 + override val versionId = 4 - private val preferences = - Injekt.get().getSharedPreferences("source_$id", 0x0000) + override val slugRegex = Regex("""^(r\d+-)""") - private val mangaPath by lazy { - client.newCall(GET(baseUrl, headers)) - .execute().asJsoup() - .selectFirst(".listupd a")!! - .absUrl("href") - .toHttpUrl() - .pathSegments[0] - .also { - mangaPathCache = it - } - } + // don't allow disabling random part setting + override fun setupPreferenceScreen(screen: PreferenceScreen) = Unit + + override val listUrl = mangaUrlDirectory + override val listSelector = "div.bsx a" override fun popularMangaRequest(page: Int) = searchMangaRequest(page, "", SortFilter.POPULAR) override fun popularMangaParse(response: Response) = searchMangaParse(response) @@ -88,7 +74,7 @@ class RealmOasis : MangaThemesia( .add("search_value", query.trim()) .build() - return POST("$baseUrl/search", apiHeaders, form) + return POST("$baseUrl/Index/live_search", apiHeaders, form) } val form = FormBody.Builder().apply { @@ -112,8 +98,8 @@ class RealmOasis : MangaThemesia( @Serializable class Comic( - val id: String, val title: String, + val id: String, @SerialName("image_url") val cover: String? = null, @SerialName("long_description") val synopsis: String? = null, val status: String? = null, @@ -123,7 +109,16 @@ class RealmOasis : MangaThemesia( val serialization: String? = null, @SerialName("genre_id") val genres: String? = null, ) { + val slug get() = title.trim().lowercase() + .replace(slugRegex, "-") + .replace("-s-", "s-") + .replace("-ll-", "ll-") + val genreIds get() = genres?.split(",")?.map(String::trim) + + companion object { + private val slugRegex = Regex("""[^a-z0-9]+""") + } } override fun searchMangaParse(response: Response): MangasPage { @@ -131,7 +126,7 @@ class RealmOasis : MangaThemesia( val entries = result.map { comic -> SManga.create().apply { - url = comic.id + url = "$mangaUrlDirectory/${comic.slug}/#${comic.id}" title = comic.title description = comic.synopsis author = listOfNotNull(comic.author, comic.serialization).joinToString() @@ -151,75 +146,12 @@ class RealmOasis : MangaThemesia( return MangasPage(entries, false) } - override fun mangaDetailsRequest(manga: SManga): Request { - val url = baseUrl.toHttpUrl().newBuilder() - .addPathSegment(mangaPath) - .addPathSegment( - UrlUtils.generateSeriesLink(manga.url.toInt()), - ).build() - - return GET(url, headers) - } - - override fun getMangaUrl(manga: SManga): String { - return buildString { - append(baseUrl) - append("/") - append(mangaPathCache) - append("/") - append( - UrlUtils.generateSeriesLink(manga.url.toInt()), - ) - } - } - override fun fetchMangaDetails(manga: SManga): Observable { return client.newCall(mangaDetailsRequest(manga)) .asObservableSuccess() .map { mangaDetailsParse(it).apply { description = manga.description } } } - override fun chapterListRequest(manga: SManga): Request { - return mangaDetailsRequest(manga) - } - - override fun chapterFromElement(element: Element): SChapter { - return super.chapterFromElement(element).apply { - val chapUrl = element.selectFirst("a")!!.absUrl("href") - - val (seriesId, chapterId) = UrlUtils.extractChapterIds(chapUrl) - ?: throw Exception("unable find chapter id from url") - - url = "$seriesId/$chapterId" - } - } - - override fun pageListRequest(chapter: SChapter): Request { - val (seriesId, chapterId) = chapter.url.split("/").take(2).map(String::toInt) - - val url = baseUrl.toHttpUrl().newBuilder() - .addPathSegment(mangaPath) - .addPathSegment( - UrlUtils.generateChapterLink(seriesId, chapterId), - ).build() - - return GET(url, headers) - } - - override fun getChapterUrl(chapter: SChapter): String { - val (seriesId, chapterId) = chapter.url.split("/").take(2).map(String::toInt) - - return buildString { - append(baseUrl) - append("/") - append(mangaPathCache) - append("/") - append( - UrlUtils.generateChapterLink(seriesId, chapterId), - ) - } - } - override fun imageRequest(page: Page): Request { val newHeaders = headersBuilder() .set("Accept", "image/avif,image/webp,image/png,image/jpeg,*/*") @@ -244,19 +176,4 @@ class RealmOasis : MangaThemesia( val charPool = ('a'..'z') + ('A'..'Z') return List(length) { charPool.random() }.joinToString("") } - - private var mangaPathCache: String = "" - get() { - if (field.isBlank()) { - field = preferences.getString(mangaPathPrefCache, "comics")!! - } - - return field - } - set(newVal) { - preferences.edit().putString(mangaPathPrefCache, newVal).apply() - field = newVal - } } - -private const val mangaPathPrefCache = "manga_path" diff --git a/src/en/rizzcomic/src/eu/kanade/tachiyomi/extension/en/rizzcomic/UrlUtils.kt b/src/en/rizzcomic/src/eu/kanade/tachiyomi/extension/en/rizzcomic/UrlUtils.kt deleted file mode 100644 index 9a7288e61..000000000 --- a/src/en/rizzcomic/src/eu/kanade/tachiyomi/extension/en/rizzcomic/UrlUtils.kt +++ /dev/null @@ -1,56 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.rizzcomic - -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull - -object UrlUtils { - private fun randomString(length: Int): String { - val charPool = ('a'..'z') + ('0'..'9') - return List(length) { charPool.random() }.joinToString("") - } - - fun generateSeriesLink(seriesId: Int): String { - return buildString { - append(randomString(4)) - append("s") - append(randomString(4)) - append(seriesId.toString().padStart(5, '0')) - append(randomString(12)) - } - } - - fun generateChapterLink(seriesId: Int, chapterId: Int): String { - return buildString { - append(randomString(4)) - append("c") - append(randomString(4)) - append(seriesId.toString().padStart(5, '0')) - append(randomString(4)) - append(chapterId.toString().padStart(6, '0')) - append(randomString(4)) - } - } - - // private val seriesRegex = """^[a-z0-9]{4}s[a-z0-9]{4}([0-9]{5})[a-z0-9]+$""".toRegex() - // - // fun extractSeriesId(url: String): Int? { - // val path = url.toHttpUrlOrNull()?.pathSegments?.lastOrNull() - // ?: return null - // return seriesRegex.find(path)?.groupValues?.get(1)?.toIntOrNull() - // } - - private val ChaptersRegex = """^[a-z0-9]{4}c[a-z0-9]{4}([0-9]{5})[a-z0-9]{4}([0-9]{6})[a-z0-9]+$""".toRegex() - - fun extractChapterIds(url: String): Pair? { - val path = url.toHttpUrlOrNull()?.pathSegments?.lastOrNull() - ?: return null - return ChaptersRegex.find(path)?.let { matchResult -> - val seriesId = matchResult.groupValues[1].toIntOrNull() - val chapterId = matchResult.groupValues[2].toIntOrNull() - if (seriesId != null && chapterId != null) { - seriesId to chapterId - } else { - null - } - } - } -}