diff --git a/src/en/renascans/build.gradle b/src/en/renascans/build.gradle deleted file mode 100644 index 5e0baabd7..000000000 --- a/src/en/renascans/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - appName = 'Tachiyomi: Renaissance Scans' - pkgNameSuffix = 'en.renascans' - extClass = '.Renascans' - extVersionCode = 3 - libVersion = '1.2' -} - -apply from: "$rootDir/common.gradle" diff --git a/src/en/renascans/res/mipmap-hdpi/ic_launcher.png b/src/en/renascans/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 3d401d1fb..000000000 Binary files a/src/en/renascans/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/renascans/res/mipmap-mdpi/ic_launcher.png b/src/en/renascans/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index ff61fec32..000000000 Binary files a/src/en/renascans/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/renascans/res/mipmap-xhdpi/ic_launcher.png b/src/en/renascans/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 190618787..000000000 Binary files a/src/en/renascans/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/renascans/res/mipmap-xxhdpi/ic_launcher.png b/src/en/renascans/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 050de1cbe..000000000 Binary files a/src/en/renascans/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/renascans/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/renascans/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index be4cef72b..000000000 Binary files a/src/en/renascans/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/renascans/res/web_hi_res_512.png b/src/en/renascans/res/web_hi_res_512.png deleted file mode 100644 index 479ac3edf..000000000 Binary files a/src/en/renascans/res/web_hi_res_512.png and /dev/null differ diff --git a/src/en/renascans/src/eu/kanade/tachiyomi/extension/en/renascans/Renascans.kt b/src/en/renascans/src/eu/kanade/tachiyomi/extension/en/renascans/Renascans.kt deleted file mode 100644 index 2843ead7b..000000000 --- a/src/en/renascans/src/eu/kanade/tachiyomi/extension/en/renascans/Renascans.kt +++ /dev/null @@ -1,154 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.renascans - -import com.github.salomonbrys.kotson.fromJson -import com.github.salomonbrys.kotson.get -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 Renascans : ParsedHttpSource() { - - override val name = "Renascence Scans (Renascans)" - - override val baseUrl = "https://renascans.com" - - override val lang = "en" - - override val supportsLatest = true - - override val client: OkHttpClient = network.cloudflareClient - - override fun popularMangaSelector() = "div.media" - - override fun popularMangaRequest(page: Int): Request { - return GET("$baseUrl/manga-list?page=$page") - } - - override fun latestUpdatesSelector() = "div.events" - - override fun latestUpdatesRequest(page: Int): Request { - return GET("$baseUrl/latest-release?page=$page") - } - - override fun popularMangaFromElement(element: Element): SManga { - val manga = SManga.create() - element.select("a.chart-title").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.text() - } - manga.thumbnail_url = element.select("img").first().attr("src") - return manga - } - - override fun latestUpdatesFromElement(element: Element): SManga { - val manga = SManga.create() - element.select("h3 a").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.text() - } - manga.thumbnail_url = element.select("img").first().attr("src") - return manga - } - - override fun popularMangaNextPageSelector() = "li a:contains(»)" - - override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - return GET("$baseUrl/search?query=$query") - } - - override fun searchMangaParse(response: Response): MangasPage { - val searchMatches = mutableListOf() - - val array = Gson().fromJson(response.body()!!.string())["suggestions"].asJsonArray - for (i in 0 until array.size()) { - val manga = SManga.create() - manga.title = array[i]["value"].asString - manga.url = "/manga/" + array[i]["data"].asString - manga.thumbnail_url = "$baseUrl/uploads/manga/" + array[i]["data"].asString + "/cover/cover_250x350" - searchMatches.add(manga) - } - return MangasPage(searchMatches, false) - } - - override fun searchMangaSelector() = popularMangaSelector() - - override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element) - - override fun searchMangaNextPageSelector() = "None" - - override fun mangaDetailsParse(document: Document): SManga { - val infoElement = document.select("div.row") - - val manga = SManga.create() - manga.title = infoElement.select("h2").first().text() - manga.author = infoElement.select("dt:contains(author) + dd").text() - manga.artist = infoElement.select("dt:contains(artist) + dd").text() - manga.genre = infoElement.select("dt:contains(categories) + dd").text() - val status = infoElement.select("dt:contains(status) + dd").text() - manga.status = parseStatus(status) - manga.description = document.select("h5 + p").text() - manga.thumbnail_url = document.select("img.img-responsive").attr("src") - return manga - } - - private fun parseStatus(status: String?) = when { - status == null -> SManga.UNKNOWN - status.contains("Ongoing") -> SManga.ONGOING - status.contains("Completed") -> SManga.COMPLETED - else -> SManga.UNKNOWN - } - - override fun chapterListSelector() = "li:has([class])" - - override fun chapterFromElement(element: Element): SChapter { - val urlElement = element.select("h3 a").first() - - val chapter = SChapter.create() - chapter.setUrlWithoutDomain(urlElement.attr("href")) - chapter.name = element.select("h3").text() - chapter.date_upload = parseChapterDate(element.select("div.date-chapter-title-rtl").text()) ?: 0 - return chapter - } - - companion object { - val dateFormat by lazy { - SimpleDateFormat("dd MMM. yyyy", Locale.US) - } - } - - private fun parseChapterDate(string: String): Long? { - return dateFormat.parse(string.substringAfter("on ")).time - } - - override fun pageListParse(document: Document): List { - val pages = mutableListOf() - - document.select("div.col-xs-12 img")?.forEach { - val page = it.attr("data-src") - if (page.isNotEmpty()) { - pages.add(Page(pages.size, "", page)) - } - } - - return pages - } - - override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") - - override fun getFilterList() = FilterList() -} diff --git a/src/vi/nettruyen/build.gradle b/src/vi/nettruyen/build.gradle deleted file mode 100644 index f5e00e644..000000000 --- a/src/vi/nettruyen/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - appName = 'Tachiyomi: NetTruyen' - pkgNameSuffix = 'vi.nettruyen' - extClass = '.NetTruyen' - extVersionCode = 5 - libVersion = '1.2' -} - -apply from: "$rootDir/common.gradle" \ No newline at end of file diff --git a/src/vi/nettruyen/res/mipmap-hdpi/ic_launcher.png b/src/vi/nettruyen/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index f71920fa3..000000000 Binary files a/src/vi/nettruyen/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/vi/nettruyen/res/mipmap-mdpi/ic_launcher.png b/src/vi/nettruyen/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 9bb74c829..000000000 Binary files a/src/vi/nettruyen/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/vi/nettruyen/res/mipmap-xhdpi/ic_launcher.png b/src/vi/nettruyen/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 11c615e0e..000000000 Binary files a/src/vi/nettruyen/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/vi/nettruyen/res/mipmap-xxhdpi/ic_launcher.png b/src/vi/nettruyen/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index ee0a1f038..000000000 Binary files a/src/vi/nettruyen/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/vi/nettruyen/res/mipmap-xxxhdpi/ic_launcher.png b/src/vi/nettruyen/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 07c34f651..000000000 Binary files a/src/vi/nettruyen/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/vi/nettruyen/res/web_hi_res_512.png b/src/vi/nettruyen/res/web_hi_res_512.png deleted file mode 100644 index 0c2cbb240..000000000 Binary files a/src/vi/nettruyen/res/web_hi_res_512.png and /dev/null differ diff --git a/src/vi/nettruyen/src/eu/kanade/tachiyomi/extension/vi/nettruyen/NetTruyen.kt b/src/vi/nettruyen/src/eu/kanade/tachiyomi/extension/vi/nettruyen/NetTruyen.kt deleted file mode 100644 index 20e2705f7..000000000 --- a/src/vi/nettruyen/src/eu/kanade/tachiyomi/extension/vi/nettruyen/NetTruyen.kt +++ /dev/null @@ -1,277 +0,0 @@ -package eu.kanade.tachiyomi.extension.vi.nettruyen - -import android.util.Log -import eu.kanade.tachiyomi.network.GET -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 java.util.Calendar -import javax.crypto.Cipher -import javax.crypto.spec.IvParameterSpec -import javax.crypto.spec.SecretKeySpec -import okhttp3.HttpUrl -import okhttp3.Request -import org.json.JSONArray -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element - -class NetTruyen : ParsedHttpSource() { - - override val name = "NetTruyen" - - override val baseUrl = "http://www.nettruyen.com" - - override val lang = "vi" - - override val supportsLatest = true - - override val client = network.cloudflareClient.newBuilder().addInterceptor { - // Intercept any image requests and add a referer to them - // Enables bandwidth stealing feature - val request = - if (it.request().url().host().contains("cloud")) - it.request().newBuilder().addHeader("Referer", baseUrl).build() - else it.request() - it.proceed(request) - }.build()!! - - override fun popularMangaSelector() = "#ctl00_divCenter div.items div.item" - - override fun latestUpdatesSelector() = popularMangaSelector() - - override fun popularMangaRequest(page: Int): Request { - return GET("$baseUrl/tim-truyen?status=-1&sort=11&page=$page", headers) - } - - override fun latestUpdatesRequest(page: Int): Request { - return GET("$baseUrl/tim-truyen?page=$page", headers) - } - - override fun popularMangaFromElement(element: Element): SManga { - val manga = SManga.create() - element.select("a").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.attr("title").replace("Truyện tranh", "").trim() - manga.thumbnail_url = it.select("img").first()?.attr("data-original") - } - return manga - } - - override fun latestUpdatesFromElement(element: Element): SManga { - return popularMangaFromElement(element) - } - - override fun popularMangaNextPageSelector() = "ul a.next-page" - - override fun latestUpdatesNextPageSelector(): String = popularMangaNextPageSelector() - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - var url = HttpUrl.parse("$baseUrl/tim-truyen?")!!.newBuilder() - (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> - when (filter) { - is Genre -> { - url = if (filter.state == 0) url else - HttpUrl.parse(url.toString() - .replace("tim-truyen?", - "tim-truyen/${getGenreList().map { it.first }[filter.state]}?"))!! - .newBuilder() - } - is Status -> { - url.addQueryParameter("status", if (filter.state == 0) "hajau" else filter.state.toString()) - url.addQueryParameter("sort", "0") - } - } - } - url.addQueryParameter("keyword", query) - return GET(url.toString(), headers) - } - - override fun searchMangaSelector() = popularMangaSelector() - - override fun searchMangaFromElement(element: Element): SManga { - return popularMangaFromElement(element) - } - - override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() - - override fun mangaDetailsParse(document: Document): SManga { - val infoElement = document.select("#item-detail").first() - - val manga = SManga.create() - manga.author = infoElement.select(".author a").first()?.text() - manga.genre = infoElement.select(".kind a").joinToString { it.text() } - manga.description = infoElement.select("#item-detail > div.detail-content > p").text() - manga.status = infoElement.select(".status > p.col-xs-8").first()?.text().orEmpty().let { parseStatus(it) } - manga.thumbnail_url = infoElement.select("img").attr("src") - return manga - } - - private fun parseStatus(status: String) = when { - status.contains("Đang tiến hành") -> SManga.ONGOING - status.contains("Hoàn thành") -> SManga.COMPLETED - else -> SManga.UNKNOWN - } - - override fun chapterListSelector() = "#nt_listchapter li:not(.heading)" - - override fun chapterFromElement(element: Element): SChapter { - val urlElement = element.select("a").first() - val chapter = SChapter.create() - chapter.setUrlWithoutDomain(urlElement.attr("href")) - chapter.name = urlElement.text() - chapter.date_upload = element.select(".col-xs-4.text-center").last()?.text()?.let { parseChapterDate(it) } - ?: 0 - return chapter - } - - private fun parseChapterDate(date: String): Long { - val dates: Calendar = Calendar.getInstance() - if (date.contains("/")) { - return if (date.contains(":")) { - // Format eg 17:02 20/04 - val dateDM = date.split(" ")[1].split("/") - dates.set(dates.get(Calendar.YEAR), dateDM[1].toInt() - 1, dateDM[0].toInt()) - dates.timeInMillis - } else { - // Format eg 18/11/17 - val dateDMY = date.split("/") - dates.set(2000 + dateDMY[2].toInt(), dateDMY[1].toInt() - 1, dateDMY[0].toInt()) - dates.timeInMillis - } - } else { - // Format eg 1 ngày trước - val dateWords: List = date.split(" ") - if (dateWords.size == 3) { - val timeAgo = Integer.parseInt(dateWords[0]) - when { - dateWords[1].contains("phút") -> dates.add(Calendar.MINUTE, -timeAgo) - dateWords[1].contains("giờ") -> dates.add(Calendar.HOUR_OF_DAY, -timeAgo) - dateWords[1].contains("ngày") -> dates.add(Calendar.DAY_OF_YEAR, -timeAgo) - dateWords[1].contains("tuần") -> dates.add(Calendar.WEEK_OF_YEAR, -timeAgo) - dateWords[1].contains("tháng") -> dates.add(Calendar.MONTH, -timeAgo) - dateWords[1].contains("năm") -> dates.add(Calendar.YEAR, -timeAgo) - } - return dates.timeInMillis - } - } - return 0L - } - - private fun decrypt(strToDecrypt: String, secret: String): String? { - try { - val k = secret + "x77_x6E_x50_x" - val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") - val keyBytes = k.toByteArray() - val secretKeySpec = SecretKeySpec(keyBytes, "AES") - val ivParameterSpec = IvParameterSpec(keyBytes) - cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec) - return String(cipher.doFinal(android.util.Base64.decode(strToDecrypt, android.util.Base64.DEFAULT))) - } catch (e: Exception) { - Log.e("Decrypt", "Has error $e") - } - return "https://www.upsieutoc.com/images/2019/09/20/1c1b688884689165b.png" - } - - private fun getEncryptedPage(document: Document): List { - val pages = mutableListOf() - val scriptTag = document.select("#ctl00_divCenter > div > .container script").html() - val keyIndex = scriptTag.indexOf("var k=") + 5 - val listIndex = scriptTag.indexOf("var l=") + 5 - val key = scriptTag.substring(keyIndex + 2, scriptTag.indexOf('"', keyIndex + 2)) - val list = scriptTag.substring(listIndex + 1, scriptTag.indexOf(";", listIndex)) - val jsonList = JSONArray(list) - - for (i in 0 until jsonList.length()) { - val imageUrl = decrypt(jsonList.getString(i), key) - val imageUri = if (imageUrl!!.startsWith("//")) "http:$imageUrl" else imageUrl - pages.add(Page(pages.size, "", imageUri)) - } - return pages - } - - override fun pageListParse(document: Document): List { - val pages = mutableListOf() - document.select(".page-chapter img").forEach { - val imageUrl = it.attr("data-original") - if (imageUrl.contains("1c1b688884689165b.png")) { - return getEncryptedPage(document) - } - } - - document.select(".page-chapter img").forEach { - val imageUrl = it.attr("data-original") - pages.add(Page(pages.size, "", if (imageUrl.startsWith("//")) "http:$imageUrl" else imageUrl)) - } - return pages - } - - override fun imageUrlParse(document: Document) = "" - - private fun getStatusList() = arrayOf("Tất cả", "Đang tiến hành", "Đã hoàn thành", "Tạm ngừng") - - private class Status(status: Array) : Filter.Select("Status", status) - private class Genre(genreList: Array) : Filter.Select("Thể loại", genreList) - - override fun getFilterList() = FilterList( - Status(getStatusList()), - Genre(getGenreList().map { it.second }.toTypedArray()) - ) - - private fun getGenreList() = arrayOf( - "tim-truyen" to "Tất cả", - "action" to "Action", - "adult" to "Adult", - "adventure" to "Adventure", - "anime" to "Anime", - "chuyen-sinh" to "Chuyển Sinh", - "comedy" to "Comedy", - "comic" to "Comic", - "cooking" to "Cooking", - "co-dai" to "Cổ Đại", - "doujinshi" to "Doujinshi", - "drama" to "Drama", - "dam-my" to "Đam Mỹ", - "ecchi" to "Ecchi", - "fantasy" to "Fantasy", - "gender-bender" to "Gender Bender", - "harem" to "Harem", - "historical" to "Historical", - "horror" to "Horror", - "josei" to "Josei", - "live-action" to "Live action", - "manga" to "Manga", - "manhua" to "Manhua", - "manhwa" to "Manhwa", - "martial-arts" to "Martial Arts", - "mature" to "Mature", - "mecha" to "Mecha", - "mystery" to "Mystery", - "ngon-tinh" to "Ngôn Tình", - "one-shot" to "One shot", - "psychological" to "Psychological", - "romance" to "Romance", - "school-life" to "School Life", - "sci-fi" to "Sci-fi", - "seinen" to "Seinen", - "shoujo" to "Shoujo", - "shoujo-ai" to "Shoujo Ai", - "shounen" to "Shounen", - "shounen-ai" to "Shounen Ai", - "slice-of-life" to "Slice of Life", - "smut" to "Smut", - "soft-yaoi" to "Soft Yaoi", - "soft-yuri" to "Soft Yuri", - "sports" to "Sports", - "supernatural" to "Supernatural", - "thieu-nhi" to "Thiếu Nhi", - "tragedy" to "Tragedy", - "trinh-tham" to "Trinh Thám", - "truyen-scan" to "Truyện scan", - "truyen-mau" to "Truyện Màu", - "webtoon" to "Webtoon", - "xuyen-khong" to "Xuyên Không" - ) -}