diff --git a/src/all/madara/build.gradle b/src/all/madara/build.gradle index 024f56a4f..a01fadc4c 100644 --- a/src/all/madara/build.gradle +++ b/src/all/madara/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: Madara' pkgNameSuffix = "all.madara" extClass = '.MadaraFactory' - extVersionCode = 1 + extVersionCode = 2 libVersion = '1.2' } diff --git a/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/MadaraFactory.kt b/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/MadaraFactory.kt index f082018a2..74fc026dc 100644 --- a/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/MadaraFactory.kt +++ b/src/all/madara/src/eu/kanade/tachiyomi/extension/all/madara/MadaraFactory.kt @@ -13,8 +13,6 @@ import java.util.* class MadaraFactory : SourceFactory { override fun createSources(): List<Source> = listOf( - LeviatanScans("en"), - LeviatanScans("es"), Mangasushi(), NinjaScans(), ReadManhua(), @@ -22,11 +20,6 @@ class MadaraFactory : SourceFactory { ) } -class LeviatanScans(lang: String) : LoadMadara("LeviatanScans", "https://leviatanscans.com", lang, dateFormat = SimpleDateFormat("MMMM dd, yy", Locale("es", "ES"))) { - override fun popularMangaSelector() = if(lang == "en") "div.page-item-detail:not(:contains(Capitulo))" else "div.page-item-detail:contains(Capitulo)" - override fun latestUpdatesSelector() = if(lang == "en") "div.item__wrap:not(:contains(Capitulo))" else "div.item__wrap:contains(Capitulo)" - override fun searchMangaSelector() = if(lang == "en") "div.c-tabs-item__content:not(:contains(Capitulo))" else "div.c-tabs-item__content:contains(Capitulo)" -} class Mangasushi : LoadMadara("Mangasushi", "https://mangasushi.net", "en") { override fun latestUpdatesSelector() = "div.page-item-detail" } @@ -88,4 +81,4 @@ open class PageMadara( override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = GET("$baseUrl/page/$page/?s=$query&post_type=wp-manga", headers) -} \ No newline at end of file +} diff --git a/src/en/mangafox/build.gradle b/src/en/mangafox/build.gradle deleted file mode 100644 index acfd095ee..000000000 --- a/src/en/mangafox/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - appName = 'Tachiyomi: Mangafox' - pkgNameSuffix = 'en.mangafox' - extClass = '.Mangafox' - extVersionCode = 3 - libVersion = '1.2' -} - -apply from: "$rootDir/common.gradle" diff --git a/src/en/mangafox/res/mipmap-hdpi/ic_launcher.png b/src/en/mangafox/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index f2b26e65b..000000000 Binary files a/src/en/mangafox/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/mangafox/res/mipmap-mdpi/ic_launcher.png b/src/en/mangafox/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index ec97ff9ff..000000000 Binary files a/src/en/mangafox/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/mangafox/res/mipmap-xhdpi/ic_launcher.png b/src/en/mangafox/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 629ac98da..000000000 Binary files a/src/en/mangafox/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/mangafox/res/mipmap-xxhdpi/ic_launcher.png b/src/en/mangafox/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 73b1eb472..000000000 Binary files a/src/en/mangafox/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/mangafox/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/mangafox/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 5ea69c7ba..000000000 Binary files a/src/en/mangafox/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/mangafox/res/web_hi_res_512.png b/src/en/mangafox/res/web_hi_res_512.png deleted file mode 100644 index ee61fab76..000000000 Binary files a/src/en/mangafox/res/web_hi_res_512.png and /dev/null differ diff --git a/src/en/mangafox/src/eu/kanade/tachiyomi/extension/en/mangafox/Mangafox.kt b/src/en/mangafox/src/eu/kanade/tachiyomi/extension/en/mangafox/Mangafox.kt deleted file mode 100644 index ee69054a5..000000000 --- a/src/en/mangafox/src/eu/kanade/tachiyomi/extension/en/mangafox/Mangafox.kt +++ /dev/null @@ -1,230 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.mangafox -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.source.model.* -import eu.kanade.tachiyomi.source.online.ParsedHttpSource -import okhttp3.HttpUrl -import okhttp3.Request -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import java.text.ParseException -import java.text.SimpleDateFormat -import java.util.* - -class Mangafox : ParsedHttpSource() { - - override val id: Long = 3 - - override val name = "Mangafox" - - override val baseUrl = "http://fanfox.net" - - override val lang = "en" - - override val supportsLatest = true - - override fun popularMangaSelector() = "div#mangalist > ul.list > li" - - override fun popularMangaRequest(page: Int): Request { - val pageStr = if (page != 1) "$page.htm" else "" - return GET("$baseUrl/directory/$pageStr", headers) - } - - override fun latestUpdatesSelector() = "div#mangalist > ul.list > li" - - override fun latestUpdatesRequest(page: Int): Request { - val pageStr = if (page != 1) "$page.htm" else "" - return GET("$baseUrl/directory/$pageStr?latest") - } - - override fun popularMangaFromElement(element: Element): SManga { - val manga = SManga.create() - element.select("a.title").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.text() - } - return manga - } - - override fun latestUpdatesFromElement(element: Element): SManga { - return popularMangaFromElement(element) - } - - override fun popularMangaNextPageSelector() = "a:has(span.next)" - - override fun latestUpdatesNextPageSelector() = "a:has(span.next)" - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val url = HttpUrl.parse("$baseUrl/search.php?name_method=cw&author_method=cw&artist_method=cw&advopts=1")!!.newBuilder().addQueryParameter("name", query) - (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> - when (filter) { - is Status -> url.addQueryParameter(filter.id, filter.state.toString()) - is GenreList -> filter.state.forEach { genre -> url.addQueryParameter(genre.id, genre.state.toString()) } - is TextField -> url.addQueryParameter(filter.key, filter.state) - is Type -> url.addQueryParameter("type", if (filter.state == 0) "" else filter.state.toString()) - is OrderBy -> { - url.addQueryParameter("sort", arrayOf("name", "rating", "views", "total_chapters", "last_chapter_time")[filter.state!!.index]) - url.addQueryParameter("order", if (filter.state?.ascending == true) "az" else "za") - } - } - } - url.addQueryParameter("page", page.toString()) - return GET(url.toString(), headers) - } - - override fun searchMangaSelector() = "div#mangalist > ul.list > li" - - override fun searchMangaFromElement(element: Element): SManga { - val manga = SManga.create() - element.select("a.title").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.text() - } - return manga - } - - override fun searchMangaNextPageSelector() = "a:has(span.next)" - - override fun mangaDetailsParse(document: Document): SManga { - val infoElement = document.select("div#title").first() - val rowElement = infoElement.select("table > tbody > tr:eq(1)").first() - val sideInfoElement = document.select("#series_info").first() - val licensedElement = document.select("div.warning").first() - - val manga = SManga.create() - manga.author = rowElement.select("td:eq(1)").first()?.text() - manga.artist = rowElement.select("td:eq(2)").first()?.text() - manga.genre = rowElement.select("td:eq(3)").first()?.text() - manga.description = infoElement.select("p.summary").first()?.text() - val isLicensed = licensedElement?.text()?.contains("licensed") - if (isLicensed == true) { - manga.status = SManga.LICENSED - } else { - manga.status = sideInfoElement.select(".data").first()?.text().orEmpty().let { parseStatus(it) } - } - - manga.thumbnail_url = sideInfoElement.select("div.cover > img").first()?.attr("src") - return manga - } - - private fun parseStatus(status: String) = when { - status.contains("Ongoing") -> SManga.ONGOING - status.contains("Completed") -> SManga.COMPLETED - else -> SManga.UNKNOWN - } - - override fun chapterListSelector() = "div#chapters li div" - - override fun chapterFromElement(element: Element): SChapter { - val urlElement = element.select("a.tips").first() - - val chapter = SChapter.create() - chapter.setUrlWithoutDomain(urlElement.attr("href")) - chapter.name = element.select("span.title.nowrap").first()?.text()?.let { urlElement.text() + " - " + it } ?: urlElement.text() - chapter.date_upload = element.select("span.date").first()?.text()?.let { parseChapterDate(it) } ?: 0 - return chapter - } - - private fun parseChapterDate(date: String): Long { - return if ("Today" in date || " ago" in date) { - Calendar.getInstance().apply { - set(Calendar.HOUR_OF_DAY, 0) - set(Calendar.MINUTE, 0) - set(Calendar.SECOND, 0) - set(Calendar.MILLISECOND, 0) - }.timeInMillis - } else if ("Yesterday" in date) { - Calendar.getInstance().apply { - add(Calendar.DATE, -1) - set(Calendar.HOUR_OF_DAY, 0) - set(Calendar.MINUTE, 0) - set(Calendar.SECOND, 0) - set(Calendar.MILLISECOND, 0) - }.timeInMillis - } else { - try { - SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH).parse(date).time - } catch (e: ParseException) { - 0L - } - } - } - - override fun pageListParse(document: Document): List<Page> { - val url = document.baseUri().substringBeforeLast('/') - - val pages = mutableListOf<Page>() - document.select("select.m").first()?.select("option:not([value=0])")?.forEach { - pages.add(Page(pages.size, "$url/${it.attr("value")}.html")) - } - return pages - } - - override fun imageUrlParse(document: Document): String { - val url = document.getElementById("image").attr("src") - return if ("compressed?token=" !in url) { - url - } else { - "http://mangafox.me/media/logo.png" - } - } - - private class Status(val id: String = "is_completed") : Filter.TriState("Completed") - private class Genre(name: String, val id: String = "genres[$name]") : Filter.TriState(name) - private class TextField(name: String, val key: String) : Filter.Text(name) - private class Type : Filter.Select<String>("Type", arrayOf("Any", "Japanese Manga", "Korean Manhwa", "Chinese Manhua")) - private class OrderBy : Filter.Sort("Order by", - arrayOf("Series name", "Rating", "Views", "Total chapters", "Last chapter"), - Filter.Sort.Selection(2, false)) - - private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres) - - override fun getFilterList() = FilterList( - TextField("Author", "author"), - TextField("Artist", "artist"), - Type(), - Status(), - OrderBy(), - GenreList(getGenreList()) - ) - - // $('select.genres').map((i,el)=>`Genre("${$(el).next().text().trim()}", "${$(el).attr('name')}")`).get().join(',\n') - // on http://mangafox.me/search.php - private fun getGenreList() = listOf( - Genre("Action"), - Genre("Adult"), - Genre("Adventure"), - Genre("Comedy"), - Genre("Doujinshi"), - Genre("Drama"), - Genre("Ecchi"), - Genre("Fantasy"), - Genre("Gender Bender"), - Genre("Harem"), - Genre("Historical"), - Genre("Horror"), - Genre("Josei"), - Genre("Martial Arts"), - Genre("Mature"), - Genre("Mecha"), - Genre("Mystery"), - Genre("One Shot"), - Genre("Psychological"), - Genre("Romance"), - Genre("School Life"), - Genre("Sci-fi"), - Genre("Seinen"), - Genre("Shoujo"), - Genre("Shoujo Ai"), - Genre("Shounen"), - Genre("Shounen Ai"), - Genre("Slice of Life"), - Genre("Smut"), - Genre("Sports"), - Genre("Supernatural"), - Genre("Tragedy"), - Genre("Webtoons"), - Genre("Yaoi"), - Genre("Yuri") - ) - -} diff --git a/src/en/psychoplay/build.gradle b/src/en/psychoplay/build.gradle deleted file mode 100644 index 835d10da9..000000000 --- a/src/en/psychoplay/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - appName = 'Tachiyomi: PsychoPlay' - pkgNameSuffix = 'en.psychoplay' - extClass = '.PsychoPlay' - extVersionCode = 3 - libVersion = '1.2' -} - -apply from: "$rootDir/common.gradle" diff --git a/src/en/psychoplay/res/mipmap-hdpi/ic_launcher.png b/src/en/psychoplay/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 0e96b2f4b..000000000 Binary files a/src/en/psychoplay/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/psychoplay/res/mipmap-mdpi/ic_launcher.png b/src/en/psychoplay/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index bd606fbf7..000000000 Binary files a/src/en/psychoplay/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/psychoplay/res/mipmap-xhdpi/ic_launcher.png b/src/en/psychoplay/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 4e8a42a32..000000000 Binary files a/src/en/psychoplay/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/psychoplay/res/mipmap-xxhdpi/ic_launcher.png b/src/en/psychoplay/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 86436c74d..000000000 Binary files a/src/en/psychoplay/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/psychoplay/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/psychoplay/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index b5ec911b5..000000000 Binary files a/src/en/psychoplay/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/psychoplay/res/web_hi_res_512.png b/src/en/psychoplay/res/web_hi_res_512.png deleted file mode 100644 index 1bf4994d8..000000000 Binary files a/src/en/psychoplay/res/web_hi_res_512.png and /dev/null differ diff --git a/src/en/psychoplay/src/eu/kanade/tachiyomi/extension/en/psychoplay/PsychoPlay.kt b/src/en/psychoplay/src/eu/kanade/tachiyomi/extension/en/psychoplay/PsychoPlay.kt deleted file mode 100644 index 5c3ba9099..000000000 --- a/src/en/psychoplay/src/eu/kanade/tachiyomi/extension/en/psychoplay/PsychoPlay.kt +++ /dev/null @@ -1,192 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.psychoplay - -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.source.model.* -import eu.kanade.tachiyomi.source.online.ParsedHttpSource -import eu.kanade.tachiyomi.util.asJsoup -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.Response -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import org.jsoup.select.Elements -import java.text.SimpleDateFormat -import java.util.* - -class PsychoPlay : ParsedHttpSource() { - - override val name = "PsychoPlay" - - override val baseUrl = "https://psychoplay.co" - - override val lang = "en" - - override val supportsLatest = true - - override val client: OkHttpClient = network.cloudflareClient - - override fun popularMangaSelector() = "div.list-item" - - private val popularMangaUrl = "$baseUrl/comics?page=" - override fun popularMangaRequest(page: Int): Request { - return GET("$popularMangaUrl$page") - } - - override fun latestUpdatesSelector() = popularMangaSelector() - - override fun latestUpdatesRequest(page: Int): Request { - return GET("$baseUrl/latest?page=$page") - } - - override fun popularMangaFromElement(element: Element): SManga { - val manga = SManga.create() - element.select("a.list-title").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.text() - } - manga.thumbnail_url = element.select("a.media-content").first().attr("style").substringAfter("(").substringBefore(")") - return manga - } - - override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element) - - override fun popularMangaNextPageSelector() = "[rel=next]" - - override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() - - // Didn't see a search function on PsychoPlay's website when I updated this extension; so searching locally - private var searchQuery = "" - private var searchPage = 1 - private var nextPageSelectorElement = Elements() - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - if (page == 1) searchPage = 1 - searchQuery = query.toLowerCase() - return GET("$popularMangaUrl$page") - } - - override fun searchMangaParse(response: Response): MangasPage { - val searchMatches = mutableListOf<SManga>() - val document = response.asJsoup() - searchMatches.addAll(getMatchesFrom(document)) - - /* call another function if there's more pages to search - not doing it this way can lead to a false "no results found" - if no matches are found on the first page but there are matches - on subsequent pages */ - nextPageSelectorElement = document.select(searchMangaNextPageSelector()) - while (nextPageSelectorElement.hasText()) { - searchMatches.addAll(searchMorePages()) - } - - return MangasPage(searchMatches, false) - } - - // search the given document for matches - private fun getMatchesFrom(document: Document): MutableList<SManga> { - val searchMatches = mutableListOf<SManga>() - document.select(searchMangaSelector()).forEach { - if (it.text().toLowerCase().contains(searchQuery)) { - searchMatches.add(searchMangaFromElement(it)) - } - } - return searchMatches - } - - // search additional pages if called - private fun searchMorePages(): MutableList<SManga> { - searchPage++ - val nextPage = client.newCall(GET("$popularMangaUrl$searchPage", headers)).execute().asJsoup() - val searchMatches = mutableListOf<SManga>() - searchMatches.addAll(getMatchesFrom(nextPage)) - nextPageSelectorElement = nextPage.select(searchMangaNextPageSelector()) - - return searchMatches - } - - override fun searchMangaSelector() = popularMangaSelector() - - override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element) - - override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() - - override fun mangaDetailsParse(document: Document): SManga { - val infoElement = document.select("div#content").first() - - val manga = SManga.create() - manga.title = infoElement.select("h5").first().text() - - manga.description = document.select("div.col-lg-9").text().substringAfter("Description ").substringBefore(" Volume") - manga.thumbnail_url = document.select("div.media a").first().attr("style").substringAfter("(").substringBefore(")") - return manga - } - - override fun chapterListSelector() = "div.col-lg-9 div.flex" - - override fun chapterFromElement(element: Element): SChapter { - val urlElement = element.select("a.item-author") - - val chapNum = urlElement.attr("href").split("/").last() - val chapter = SChapter.create() - chapter.setUrlWithoutDomain(urlElement.attr("href")) - if (urlElement.text().contains("Chapter $chapNum")) { - chapter.name = urlElement.text() - } else { - chapter.name = "Ch. " + chapNum + ": " + urlElement.text() - } - chapter.date_upload = parseChapterDate(element.select("a.item-company").first().text()) ?: 0 - return chapter - } - - companion object { - val dateFormat by lazy { - SimpleDateFormat("MMM d, yyyy", Locale.US) - } - } - - // If the date string contains the word "ago" send it off for relative date parsing otherwise use dateFormat - private fun parseChapterDate(string: String): Long? { - if ("ago" in string) { - return parseRelativeDate(string) ?: 0 - } else { - return dateFormat.parse(string).time - } - } - - // Subtract relative date (e.g. posted 3 days ago) - private fun parseRelativeDate(date: String): Long? { - val trimmedDate = date.substringBefore(" ago").split(" ") - - val calendar = Calendar.getInstance() - when (trimmedDate[1]){ - "month", "months" -> calendar.apply{add(Calendar.MONTH, -trimmedDate[0].toInt())} - "week", "weeks" -> calendar.apply{add(Calendar.WEEK_OF_MONTH, -trimmedDate[0].toInt())} - "day", "days" -> calendar.apply{add(Calendar.DAY_OF_MONTH, -trimmedDate[0].toInt())} - "hour", "hours" -> calendar.apply{add(Calendar.HOUR_OF_DAY, -trimmedDate[0].toInt())} - "minute", "minutes" -> calendar.apply{add(Calendar.MONTH, -trimmedDate[0].toInt())} - "second", "seconds" -> calendar.apply{add(Calendar.SECOND, 0)} - } - - return calendar.timeInMillis - } - - override fun pageListParse(document: Document): List<Page> { - val pages = mutableListOf<Page>() - - val allImages = document.select("script").first().data() - .substringAfter("[").substringBefore("];") - .replace(Regex("""["\\]"""), "") - .split(",") - - for (i in 0 until allImages.size) { - pages.add(Page(i, "", allImages[i])) - } - - return pages - } - - override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") - - override fun getFilterList() = FilterList() - -}