From 4b9e845bbab481b83db2af4112717dc2ef8a3ce9 Mon Sep 17 00:00:00 2001 From: Johannes Joens <34899572+jopejoe1@users.noreply.github.com> Date: Mon, 26 Apr 2021 11:57:16 +1200 Subject: [PATCH] Added Preferences Screen to Luscious (#6707) * Update Luscious.kt * Update LusciousGenerator.kt --- .../tachiyomi/multisrc/luscious/Luscious.kt | 211 +++++++++++++++--- .../multisrc/luscious/LusciousGenerator.kt | 2 +- 2 files changed, 187 insertions(+), 26 deletions(-) diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/Luscious.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/Luscious.kt index 82fc4325b..a651f7eea 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/Luscious.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/Luscious.kt @@ -21,11 +21,23 @@ import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response import rx.Observable +import android.app.Application +import android.content.SharedPreferences +import android.net.Uri +import androidx.preference.CheckBoxPreference +import androidx.preference.PreferenceScreen +import androidx.preference.ListPreference +import eu.kanade.tachiyomi.source.ConfigurableSource +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get +import android.support.v7.preference.CheckBoxPreference as LegacyCheckBoxPreference +import android.support.v7.preference.PreferenceScreen as LegacyPreferenceScreen +import android.support.v7.preference.ListPreference as LegacyListPreference abstract class Luscious( override val name: String, override val baseUrl: String, - override val lang: String ) : HttpSource() { + override val lang: String ) : ConfigurableSource, HttpSource() { //Based on Luscios single source extension form https://github.com/tachiyomiorg/tachiyomi-extensions/commit/aacf56d0c0ddb173372aac69d798ae998f178377 //with modifiaction to make it support multisrc @@ -48,6 +60,11 @@ abstract class Luscious( else -> "99" } + private val preferences: SharedPreferences by lazy { + Injekt.get().getSharedPreferences("source_$id", 0x0000) + } + + // Common private fun buildAlbumListRequestInput(page: Int, filters: FilterList, query: String = ""): JsonObject { @@ -174,42 +191,60 @@ abstract class Luscious( return client.newCall(GET(buildAlbumPicturesPageUrl(id, 1, "position"))) .asObservableSuccess() - .map { parseAlbumPicturesResponse(it, "position") } + .map { parseAlbumPicturesResponse(it, "position", manga.url) } } - private fun parseAlbumPicturesResponse(response: Response, sortPagesByOption: String): List { + private fun parseAlbumPicturesResponse(response: Response, sortPagesByOption: String, mangaUrl: String): List { val chapters = mutableListOf() - var nextPage = true - var page = 2 - val id = response.request().url().queryParameter("variables").toString() - .let { gson.fromJson(it)["input"]["filters"].asJsonArray } - .let { it.first { f -> f["name"].asString == "album_id" } } - .let { it["value"].asString } - - var data = gson.fromJson(response.body()!!.string()) - .let { it["data"]["picture"]["list"].asJsonObject } - - while (nextPage) { - nextPage = data["info"]["has_next_page"].asBoolean - data["items"].asJsonArray.map { + when (getMergeChapterPref()){ + true -> { val chapter = SChapter.create() - chapter.url = it["url_to_original"].asString - chapter.name = it["title"].asString + chapter.url = mangaUrl + chapter.name = "Merged Chapter" //chapter.date_upload = it["created"].asLong // not parsing correctly for some reason - chapter.chapter_number = it["position"].asInt.toFloat() + chapter.chapter_number = 1F chapters.add(chapter) } - if (nextPage) { - val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page, sortPagesByOption))).execute() - data = gson.fromJson(newPage.body()!!.string()) + false -> { + var nextPage = true + var page = 2 + val id = response.request().url().queryParameter("variables").toString() + .let { gson.fromJson(it)["input"]["filters"].asJsonArray } + .let { it.first { f -> f["name"].asString == "album_id" } } + .let { it["value"].asString } + + var data = gson.fromJson(response.body()!!.string()) .let { it["data"]["picture"]["list"].asJsonObject } + + while (nextPage) { + nextPage = data["info"]["has_next_page"].asBoolean + data["items"].asJsonArray.map { + val chapter = SChapter.create() + chapter.url = when (getResolutionPref()){ + "-1" -> it["url_to_original"].asString + else -> it["thumbnails"][getResolutionPref()?.toInt()!!]["url"].asString + } + chapter.name = it["title"].asString + //chapter.date_upload = it["created"].asLong // not parsing correctly for some reason + chapter.chapter_number = it["position"].asInt.toFloat() + chapters.add(chapter) + } + if (nextPage) { + val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page, sortPagesByOption))).execute() + data = gson.fromJson(newPage.body()!!.string()) + .let { it["data"]["picture"]["list"].asJsonObject } + } + page++ + } } - page++ + } + return chapters.reversed() } override fun chapterListParse(response: Response): List = throw UnsupportedOperationException("Not used") + // Pages private fun buildAlbumPicturesRequestInput(id: String, page: Int, sortPagesByOption: String): JsonObject { @@ -244,8 +279,54 @@ abstract class Luscious( .toString() } + private fun parseAlbumPicturesResponseMergeChapter(response: Response, sortPagesByOption: String): List { + val pages = mutableListOf() + var nextPage = true + var page = 2 + val id = response.request().url().queryParameter("variables").toString() + .let { gson.fromJson(it)["input"]["filters"].asJsonArray } + .let { it.first { f -> f["name"].asString == "album_id" } } + .let { it["value"].asString } + + var data = gson.fromJson(response.body()!!.string()) + .let { it["data"]["picture"]["list"].asJsonObject } + + while (nextPage) { + nextPage = data["info"]["has_next_page"].asBoolean + data["items"].asJsonArray.map { + val index = it["position"].asInt + val url = when (getResolutionPref()){ + "-1" -> it["url_to_original"].asString + else -> it["thumbnails"][getResolutionPref()?.toInt()!!]["url"].asString + } + + + pages.add(Page(index, url, url)) + } + if (nextPage) { + val newPage = client.newCall(GET(buildAlbumPicturesPageUrl(id, page, sortPagesByOption))).execute() + data = gson.fromJson(newPage.body()!!.string()) + .let { it["data"]["picture"]["list"].asJsonObject } + } + page++ + } + return pages + } + override fun fetchPageList(chapter: SChapter): Observable> { - return Observable.just(listOf(Page(0, chapter.url, chapter.url))) + return when (getMergeChapterPref()) { + true -> { + val id = chapter.url.substringAfterLast("_").removeSuffix("/") + + client.newCall(GET(buildAlbumPicturesPageUrl(id, 1, "position"))) + .asObservableSuccess() + .map { parseAlbumPicturesResponseMergeChapter(it, "position") } + } + false -> { + Observable.just(listOf(Page(0, chapter.url, chapter.url))) + } + } + } override fun pageListParse(response: Response): List = throw UnsupportedOperationException("Not used") @@ -263,7 +344,11 @@ abstract class Luscious( val data = gson.fromJson(it.body()!!.string()).let { data -> data["data"]["picture"]["list"].asJsonObject } - data["items"].asJsonArray[page.index % 50].asJsonObject["url_to_original"].asString + when (getResolutionPref()){ + "-1" -> data["items"].asJsonArray[page.index % 50].asJsonObject["url_to_original"].asString + else -> data["items"].asJsonArray[page.index % 50].asJsonObject["thumbnails"][getResolutionPref()?.toInt()!!]["url"].asString + } + } } @@ -661,5 +746,81 @@ abstract class Luscious( __typename id title labels description created modified like_status number_of_favorites number_of_dislikes rating moderation_status marked_for_deletion marked_for_processing number_of_pictures number_of_animated_pictures number_of_duplicates slug is_manga url download_url permissions cover { width height size url } created_by { id url name display_name user_title avatar { url size } } content { id title url } language { id title url } tags { category text url count } genres { id title slug url } audiences { id title url url } last_viewed_picture { id position url } is_featured featured_date featured_by { id url name display_name user_title avatar { url size } } } """.trimIndent() + + private const val MERGE_CHAPTER_PREF_KEY = "MERGE_CHAPTER" + private const val MERGE_CHAPTER_PREF_TITLE = "Merge Chapter" + private const val MERGE_CHAPTER_PREF_SUMMARY = "If checked, merges all content of one Album into one Chapter" + private const val MERGE_CHAPTER_PREF_DEFAULT_VALUE = false + + private const val RESOLUTION_PREF_KEY = "RESOLUTION" + private const val RESOLUTION_PREF_TITLE = "Image resolution" + private val RESOLUTION_PREF_ENTRIES = arrayOf("Low", "Medium", "High", "Original") + private val RESOLUTION_PREF_ENTRY_VALUES = arrayOf("2", "1", "0", "-1") + private val RESOLUTION_PREF_DEFAULT_VALUE = RESOLUTION_PREF_ENTRY_VALUES[3] } + + override fun setupPreferenceScreen(screen: PreferenceScreen) { + val resolutionPref = ListPreference(screen.context).apply { + key = "${RESOLUTION_PREF_KEY}_$lang" + title = RESOLUTION_PREF_TITLE + entries = RESOLUTION_PREF_ENTRIES + entryValues = RESOLUTION_PREF_ENTRY_VALUES + setDefaultValue(RESOLUTION_PREF_DEFAULT_VALUE) + summary = "%s" + + setOnPreferenceChangeListener { _, newValue -> + val selected = newValue as String + val index = findIndexOfValue(selected) + val entry = entryValues[index] as String + preferences.edit().putString("${RESOLUTION_PREF_KEY}_$lang", entry).commit() + } + } + val mergeChapterPref = CheckBoxPreference(screen.context).apply { + key = "${MERGE_CHAPTER_PREF_KEY}_$lang" + title = MERGE_CHAPTER_PREF_TITLE + summary = MERGE_CHAPTER_PREF_SUMMARY + setDefaultValue(MERGE_CHAPTER_PREF_DEFAULT_VALUE) + + setOnPreferenceChangeListener { _, newValue -> + val checkValue = newValue as Boolean + preferences.edit().putBoolean("${MERGE_CHAPTER_PREF_KEY}_$lang", checkValue).commit() + } + } + screen.addPreference(resolutionPref) + screen.addPreference(mergeChapterPref) + } + + override fun setupPreferenceScreen(screen: LegacyPreferenceScreen) { + val resolutionPref = LegacyListPreference(screen.context).apply { + key = "${RESOLUTION_PREF_KEY}_$lang" + title = RESOLUTION_PREF_TITLE + entries = RESOLUTION_PREF_ENTRIES + entryValues = RESOLUTION_PREF_ENTRY_VALUES + setDefaultValue(RESOLUTION_PREF_DEFAULT_VALUE) + summary = "%s" + + setOnPreferenceChangeListener { _, newValue -> + val selected = newValue as String + val index = findIndexOfValue(selected) + val entry = entryValues[index] as String + preferences.edit().putString("${RESOLUTION_PREF_KEY}_$lang", entry).commit() + } + } + val mergeChapterPref = LegacyCheckBoxPreference(screen.context).apply { + key = "${MERGE_CHAPTER_PREF_KEY}_$lang" + title = MERGE_CHAPTER_PREF_TITLE + summary = MERGE_CHAPTER_PREF_SUMMARY + setDefaultValue(MERGE_CHAPTER_PREF_DEFAULT_VALUE) + + setOnPreferenceChangeListener { _, newValue -> + val checkValue = newValue as Boolean + preferences.edit().putBoolean("${MERGE_CHAPTER_PREF_KEY}_$lang", checkValue).commit() + } + } + screen.addPreference(resolutionPref) + screen.addPreference(mergeChapterPref) + } + + private fun getMergeChapterPref(): Boolean = preferences.getBoolean("${MERGE_CHAPTER_PREF_KEY}_$lang", MERGE_CHAPTER_PREF_DEFAULT_VALUE) + private fun getResolutionPref(): String? = preferences.getString("${RESOLUTION_PREF_KEY}_$lang", RESOLUTION_PREF_DEFAULT_VALUE) } diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/LusciousGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/LusciousGenerator.kt index 02a957c03..a023b927d 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/LusciousGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/LusciousGenerator.kt @@ -10,7 +10,7 @@ class LusciousGenerator : ThemeSourceGenerator { override val themeClass = "Luscious" - override val baseVersionCode: Int = 3 + override val baseVersionCode: Int = 4 override val sources = listOf( MultiLang("Luscious", "https://www.luscious.net", listOf("en","ja", "es", "it", "de", "fr", "zh", "ko", "other", "pt", "th"), isNsfw = true, className = "LusciousFactory", overrideVersionCode = 2),