diff --git a/src/en/catmanga/AndroidManifest.xml b/src/en/catmanga/AndroidManifest.xml deleted file mode 100644 index 70b11d5a3..000000000 --- a/src/en/catmanga/AndroidManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/en/catmanga/build.gradle b/src/en/catmanga/build.gradle deleted file mode 100644 index 9297a89ce..000000000 --- a/src/en/catmanga/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlinx-serialization' - -ext { - extName = 'CatManga' - pkgNameSuffix = "en.catmanga" - extClass = '.CatManga' - extVersionCode = 7 -} - -apply from: "$rootDir/common.gradle" diff --git a/src/en/catmanga/res/mipmap-hdpi/ic_launcher.png b/src/en/catmanga/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 4db917a88..000000000 Binary files a/src/en/catmanga/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/catmanga/res/mipmap-mdpi/ic_launcher.png b/src/en/catmanga/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 8637c4583..000000000 Binary files a/src/en/catmanga/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/catmanga/res/mipmap-xhdpi/ic_launcher.png b/src/en/catmanga/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 423723cf7..000000000 Binary files a/src/en/catmanga/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/catmanga/res/mipmap-xxhdpi/ic_launcher.png b/src/en/catmanga/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index f5cf760a0..000000000 Binary files a/src/en/catmanga/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/catmanga/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/catmanga/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 1e7256b0d..000000000 Binary files a/src/en/catmanga/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/catmanga/res/web_hi_res_512.png b/src/en/catmanga/res/web_hi_res_512.png deleted file mode 100644 index 6e46ab8b8..000000000 Binary files a/src/en/catmanga/res/web_hi_res_512.png and /dev/null differ diff --git a/src/en/catmanga/src/eu/kanade/tachiyomi/extension/en/catmanga/CatData.kt b/src/en/catmanga/src/eu/kanade/tachiyomi/extension/en/catmanga/CatData.kt deleted file mode 100644 index 2d6015bd7..000000000 --- a/src/en/catmanga/src/eu/kanade/tachiyomi/extension/en/catmanga/CatData.kt +++ /dev/null @@ -1,57 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.catmanga - -import eu.kanade.tachiyomi.source.model.SManga -import kotlinx.serialization.Serializable - -@Serializable -data class CatSeries( - val alt_titles: List, - val authors: List, - val genres: List, - val chapters: List? = null, - val title: String, - val series_id: String, - val description: String, - val status: String, - val cover_art: CatSeriesCover, - val all_covers: List? = null -) { - fun toSManga() = this.let { series -> - SManga.create().apply { - url = "/series/${series.series_id}" - title = series.title - thumbnail_url = series.cover_art.source - author = series.authors.joinToString(", ") - description = series.description - genre = series.genres.joinToString(", ") - status = when (series.status) { - "ongoing" -> SManga.ONGOING - "completed" -> SManga.COMPLETED - else -> SManga.UNKNOWN - } - - if (alt_titles.isNotEmpty()) { - description += "\n\nAlternative titles:\n" - alt_titles.forEach { - description += "• $it\n" - } - } - } - } -} - -@Serializable -data class CatSeriesChapter( - val title: String? = null, - val groups: List, - val number: Float, - val display_number: String? = null, - val volume: Int? = null -) - -@Serializable -data class CatSeriesCover( - val source: String, - val width: Int, - val height: Int -) diff --git a/src/en/catmanga/src/eu/kanade/tachiyomi/extension/en/catmanga/CatManga.kt b/src/en/catmanga/src/eu/kanade/tachiyomi/extension/en/catmanga/CatManga.kt deleted file mode 100644 index abae4e7c4..000000000 --- a/src/en/catmanga/src/eu/kanade/tachiyomi/extension/en/catmanga/CatManga.kt +++ /dev/null @@ -1,179 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.catmanga - -import android.app.Application -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.network.asObservableSuccess -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.HttpSource -import eu.kanade.tachiyomi.util.asJsoup -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.boolean -import kotlinx.serialization.json.decodeFromJsonElement -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive -import okhttp3.Request -import okhttp3.Response -import org.jsoup.nodes.Document -import rx.Observable -import uy.kohesive.injekt.injectLazy - -@ExperimentalSerializationApi -class CatManga : HttpSource() { - - private val application: Application by injectLazy() - - override val name = "CatManga" - override val baseUrl = "https://catmanga.org" - override val supportsLatest = false - override val lang = "en" - private val json: Json by injectLazy() - - private val allSeriesRequest = GET("$baseUrl/api/series/allSeries") - - override fun popularMangaRequest(page: Int) = allSeriesRequest - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = allSeriesRequest - - override fun chapterListRequest(manga: SManga): Request { - val seriesId = manga.url.substringAfter("/series/") - return GET("$baseUrl/api/series/$seriesId") - } - - override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { - return client.newCall(searchMangaRequest(page, query, filters)) - .asObservableSuccess() - .map { response -> - val manga = json.decodeFromString>(response.body!!.string()) - .filter { - if (query.startsWith(SERIES_ID_SEARCH_PREFIX)) { - return@filter it.series_id.contains(query.removePrefix(SERIES_ID_SEARCH_PREFIX), true) - } - sequence { yieldAll(it.alt_titles); yield(it.title) } - .any { title -> title.contains(query, true) } - } - .map { it.toSManga() } - .toList() - MangasPage(manga, false) - } - } - - override fun fetchMangaDetails(manga: SManga): Observable { - val seriesId = manga.url.substringAfter("/series/") - return client.newCall(allSeriesRequest) - .asObservableSuccess() - .map { response -> - json.decodeFromString>(response.body!!.string()) - .find { it.series_id == seriesId } - ?.toSManga() ?: manga - } - } - - override fun chapterListParse(response: Response): List { - val series = json.decodeFromString(response.body!!.string()) - val seriesPrefs = application.getSharedPreferences("source_${id}_time_found:${series.series_id}", 0) - val seriesPrefsEditor = seriesPrefs.edit() - val chapters = series.chapters!! - .asReversed() - .map { chapter -> - val title = chapter.title ?: "" - val groups = chapter.groups.joinToString(", ") - val numberUrl = chapter.number.chapterNumberToUrlPath() - val displayNumber = chapter.display_number ?: numberUrl - SChapter.create().apply { - url = "/series/${series.series_id}/$numberUrl" - chapter_number = chapter.number - scanlator = groups - - name = if (chapter.volume != null) { - "Vol.${chapter.volume} " - } else { - "" - } - name += "Ch.$displayNumber" - if (title.isNotBlank()) { - name += " - $title" - } - - // Save current time when a chapter is found for the first time, and reuse it on future - // checks to prevent manga entry without any new chapter bumped to the top of - // "Latest chapter" list when the library is updated. - val currentTimeMillis = System.currentTimeMillis() - if (!seriesPrefs.contains(numberUrl)) { - seriesPrefsEditor.putLong(numberUrl, currentTimeMillis) - } - date_upload = seriesPrefs.getLong(numberUrl, currentTimeMillis) - } - } - seriesPrefsEditor.apply() - return chapters - } - - override fun popularMangaParse(response: Response): MangasPage { - val mangas = json.decodeFromString>(response.body!!.string()).map { it.toSManga() } - return MangasPage(mangas, false) - } - - override fun fetchPageList(chapter: SChapter): Observable> { - return client.newCall(pageListRequest(chapter)) - .asObservableSuccess() - .map { - val doc = it.asJsoup().getDataJsonObject() - val pages = if (doc["isFallback"]!!.jsonPrimitive.boolean) { - val buildId = doc["buildId"]!!.jsonPrimitive.content - val directRequest = GET("$baseUrl/_next/data/$buildId/${chapter.url}.json") - val directResponse = client.newCall(directRequest).execute() - json.parseToJsonElement(directResponse.body!!.string()) - } else { - doc["props"]!! - }.jsonObject["pageProps"]!!.jsonObject["pages"]!! - json.decodeFromJsonElement>(pages) - .mapIndexed { index, s -> Page(index, "", s) } - } - } - - /** - * Returns json object of site data - */ - private fun Document.getDataJsonObject() = json.parseToJsonElement(getElementById("__NEXT_DATA__").html()).jsonObject - - /** - * Returns string without decimal when it is not relevant - */ - private fun Float.chapterNumberToUrlPath(): String { - return if (toInt().toFloat() == this) toInt().toString() else toString() - } - - override fun pageListParse(response: Response): List { - throw UnsupportedOperationException("Not used.") - } - - override fun latestUpdatesRequest(page: Int): Request { - throw UnsupportedOperationException("Not used.") - } - - override fun latestUpdatesParse(response: Response): MangasPage { - throw UnsupportedOperationException("Not used.") - } - - override fun mangaDetailsParse(response: Response): SManga { - throw UnsupportedOperationException("Not used.") - } - - override fun searchMangaParse(response: Response): MangasPage { - throw UnsupportedOperationException("Not used.") - } - - override fun imageUrlParse(response: Response): String { - throw UnsupportedOperationException("Not used.") - } - - companion object { - const val SERIES_ID_SEARCH_PREFIX = "series_id:" - } -} diff --git a/src/en/catmanga/src/eu/kanade/tachiyomi/extension/en/catmanga/CatMangaUrlActivity.kt b/src/en/catmanga/src/eu/kanade/tachiyomi/extension/en/catmanga/CatMangaUrlActivity.kt deleted file mode 100644 index fc2a09fe1..000000000 --- a/src/en/catmanga/src/eu/kanade/tachiyomi/extension/en/catmanga/CatMangaUrlActivity.kt +++ /dev/null @@ -1,38 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.catmanga - -import android.app.Activity -import android.content.ActivityNotFoundException -import android.content.Intent -import android.os.Bundle -import android.util.Log -import kotlin.system.exitProcess - -/** - * Springboard that accepts https://catmanga.org/series/xxxxxx intents and redirects them to - * the main Tachiyomi process. - */ -class CatMangaUrlActivity : Activity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - val pathSegments = intent?.data?.pathSegments - if (pathSegments != null && pathSegments.size > 1) { - val id = pathSegments[1] - val mainIntent = Intent().apply { - action = "eu.kanade.tachiyomi.SEARCH" - putExtra("query", "${CatManga.SERIES_ID_SEARCH_PREFIX}$id") - putExtra("filter", packageName) - } - - try { - startActivity(mainIntent) - } catch (e: ActivityNotFoundException) { - Log.e("CatMangaUrlActivity", e.toString()) - } - } else { - Log.e("CatMangaUrlActivity", "could not parse uri from intent $intent") - } - - finish() - exitProcess(0) - } -}