Manga Park - chapter list preferences v2 (#2324)

Manga Park - chapter list preferences v2
This commit is contained in:
happywillow0 2020-03-01 23:18:32 -05:00 committed by GitHub
parent c53c69a95c
commit 506619d153
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 129 additions and 16 deletions

View File

@ -9,4 +9,9 @@ ext {
libVersion = '1.2' libVersion = '1.2'
} }
dependencies {
compileOnly project(':preference-stub')
compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440'
}
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -1,22 +1,34 @@
package eu.kanade.tachiyomi.extension.en.mangapark package eu.kanade.tachiyomi.extension.en.mangapark
import android.annotation.SuppressLint
import android.app.Application
import android.content.SharedPreferences
import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen
import android.net.Uri import android.net.Uri
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Request import okhttp3.Request
import okhttp3.Response
import org.json.JSONArray import org.json.JSONArray
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Locale import java.util.Locale
import kotlin.math.absoluteValue
class MangaPark : ParsedHttpSource() {
class MangaPark : ConfigurableSource, ParsedHttpSource() {
override val lang = "en" override val lang = "en"
@ -75,9 +87,10 @@ class MangaPark : ParsedHttpSource() {
val coverElement = element.getElementsByClass("cover").first() val coverElement = element.getElementsByClass("cover").first()
url = coverElement.attr("href") url = coverElement.attr("href")
title = coverElement.attr("title") title = coverElement.attr("title")
thumbnail_url = coverElement.select("img").attr("abs:src")
} }
@SuppressLint("DefaultLocale")
override fun mangaDetailsParse(document: Document) = SManga.create().apply { override fun mangaDetailsParse(document: Document) = SManga.create().apply {
val coverElement = document.select(".cover > img").first() val coverElement = document.select(".cover > img").first()
@ -86,8 +99,7 @@ class MangaPark : ParsedHttpSource() {
thumbnail_url = cleanUrl(coverElement.attr("src")) thumbnail_url = cleanUrl(coverElement.attr("src"))
document.select(".attr > tbody > tr").forEach { document.select(".attr > tbody > tr").forEach {
val type = it.getElementsByTag("th").first().text().trim().toLowerCase() when (it.getElementsByTag("th").first().text().trim().toLowerCase()) {
when (type) {
"author(s)" -> { "author(s)" -> {
author = it.getElementsByTag("a").joinToString(transform = Element::text) author = it.getElementsByTag("a").joinToString(transform = Element::text)
} }
@ -109,20 +121,58 @@ class MangaPark : ParsedHttpSource() {
description = document.getElementsByClass("summary").text().trim() description = document.getElementsByClass("summary").text().trim()
} }
override fun chapterListParse(response: Response): List<SChapter> {
fun List<SChapter>.getMissingChapters(allChapters: List<SChapter>): List<SChapter> {
val chapterNums = this.map { it.chapter_number }
return allChapters.filter { it.chapter_number !in chapterNums }.distinctBy { it.chapter_number }
}
//TODO MangaPark has "versioning" fun List<SChapter>.filterOrAll(source: String): List<SChapter>{
//TODO Previously we just use the version that is expanded by default however this caused an issue when a manga didnt have an expanded version val chapters = this.filter { it.scanlator!!.contains(source) }
//TODO if we just choose one to expand it will cause potential missing chapters return if (chapters.isNotEmpty()) {
//TODO right now all versions are combined so no chapters are missed (chapters + chapters.getMissingChapters(this)).sortedByDescending { it.chapter_number }
//TODO Maybe make it possible for users to view the other versions as well? } else {
override fun chapterListSelector() = ".stream .volume .chapter li" this
}
}
override fun chapterFromElement(element: Element) = SChapter.create().apply { val mangaBySource = response.asJsoup().select("div[id^=stream]").map { sourceElement ->
url = element.select(".tit > a").first().attr("href").replaceAfterLast("/", "") sourceElement.select(chapterListSelector()).map { chapterFromElement(it, sourceElement.select("i + span").text()) }
name = element.select(".tit > a").first().text() }
date_upload = parseDate(element.select(".time").first().text().trim()) return when (getSourcePref()) {
// source with most chapters along with chapters that source doesn't have
"most" -> {
val chapters = mangaBySource.maxBy { it.count() }!!
(chapters + chapters.getMissingChapters(mangaBySource.flatten())).sortedByDescending { it.chapter_number }
}
// "smart list" - try not to miss a chapter and avoid dupes
"smart" -> mangaBySource.flatten().distinctBy { it.chapter_number }.sortedByDescending { it.chapter_number }
// use a specific source + any missing chapters, display all if none available from that source
"rock" -> mangaBySource.flatten().filterOrAll("Rock")
"duck" -> mangaBySource.flatten().filterOrAll("Duck")
"mini" -> mangaBySource.flatten().filterOrAll("Mini")
"fox" -> mangaBySource.flatten().filterOrAll("Fox")
"panda" -> mangaBySource.flatten().filterOrAll("Panda")
// all sources, all chapters
else -> mangaBySource.flatten()
}
} }
override fun chapterListSelector() = ".volume .chapter li"
private fun chapterFromElement(element: Element, source: String) = SChapter.create().apply {
url = element.select(".tit > a").first().attr("href").replaceAfterLast("/", "")
name = element.select(".tit > a").first().text()
// Get the chapter number or create a unique one if it's not available
chapter_number = Regex("""\b\d+\.?\d?\b""").find(name)?.value?.toFloatOrNull() ?: ".${name.hashCode().absoluteValue}".toFloat()
date_upload = parseDate(element.select(".time").first().text().trim())
scanlator = source
}
override fun chapterFromElement(element: Element): SChapter = throw UnsupportedOperationException("Not used")
@SuppressLint("DefaultLocale")
private fun parseDate(date: String): Long { private fun parseDate(date: String): Long {
val lcDate = date.toLowerCase() val lcDate = date.toLowerCase()
if (lcDate.endsWith("ago")) return parseRelativeDate(lcDate) if (lcDate.endsWith("ago")) return parseRelativeDate(lcDate)
@ -331,8 +381,8 @@ class MangaPark : ParsedHttpSource() {
GenreFilter("zombies", "Zombies") GenreFilter("zombies", "Zombies")
)), UriFilter { )), UriFilter {
override fun addToUri(uri: Uri.Builder) { override fun addToUri(uri: Uri.Builder) {
uri.appendQueryParameter("genres", state.filter { it.isIncluded() }.map { it.uriParam }.joinToString(",")) uri.appendQueryParameter("genres", state.filter { it.isIncluded() }.joinToString(",") { it.uriParam })
uri.appendQueryParameter("genres-exclude", state.filter { it.isExcluded() }.map { it.uriParam }.joinToString(",")) uri.appendQueryParameter("genres-exclude", state.filter { it.isExcluded() }.joinToString(",") { it.uriParam })
} }
} }
@ -419,4 +469,62 @@ class MangaPark : ParsedHttpSource() {
fun addToUri(uri: Uri.Builder) fun addToUri(uri: Uri.Builder)
} }
// Preferences
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
val myPref = androidx.preference.ListPreference(screen.context).apply {
key = SOURCE_PREF_TITLE
title = SOURCE_PREF_TITLE
entries = sourceArray.map { it.first }.toTypedArray()
entryValues = sourceArray.map { it.second }.toTypedArray()
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = this.findIndexOfValue(selected)
val entry = entryValues.get(index) as String
preferences.edit().putString(SOURCE_PREF, entry).commit()
}
}
screen.addPreference(myPref)
}
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val myPref = ListPreference(screen.context).apply {
key = SOURCE_PREF_TITLE
title = SOURCE_PREF_TITLE
entries = sourceArray.map { it.first }.toTypedArray()
entryValues = sourceArray.map { it.second }.toTypedArray()
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = this.findIndexOfValue(selected)
val entry = entryValues.get(index) as String
preferences.edit().putString(SOURCE_PREF, entry).commit()
}
}
screen.addPreference(myPref)
}
private fun getSourcePref(): String? = preferences.getString(SOURCE_PREF, "all")
companion object {
private const val SOURCE_PREF_TITLE = "Chapter List Source"
private const val SOURCE_PREF = "Manga_Park_Source"
private val sourceArray = arrayOf(
Pair("All sources, all chapters","all"),
Pair("Source with most chapters","most"),
Pair("Smart list","smart"),
Pair("Prioritize source: Rock","rock"),
Pair("Prioritize source: Duck","duck"),
Pair("Prioritize source: Mini","mini"),
Pair("Prioritize source: Fox","fox"),
Pair("Prioritize source: Panda","panda")
)
}
} }