From 26b48d07363c8a47f073619d7db5038a12b02a4b Mon Sep 17 00:00:00 2001 From: jopejoe1 <34899572+jopejoe1@users.noreply.github.com> Date: Mon, 24 Jan 2022 23:22:15 +1300 Subject: [PATCH] Made Luscious into only one extension (#10563) * Update Luscious.kt * Delete multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious directory * Delete multisrc/overrides/luscious directory * Made in to singel source * Update CHANGELOG.md * Update build.gradle --- .../luscious/luscious/src/LusciousFactory.kt | 37 ----- .../lusciousapi/src/LusciousAPIFactory.kt | 37 ----- .../src/LusciousMembersFactory.kt | 37 ----- .../multisrc/luscious/LusciousGenerator.kt | 26 ---- src/all/AndroidManifest.xml | 4 + src/all/CHANGELOG.md | 132 ++++++++++++++++++ src/all/README.md | 23 +++ src/all/build.gradle | 13 ++ .../all}/res/mipmap-hdpi/ic_launcher.png | Bin .../all}/res/mipmap-mdpi/ic_launcher.png | Bin .../all}/res/mipmap-xhdpi/ic_launcher.png | Bin .../all}/res/mipmap-xxhdpi/ic_launcher.png | Bin .../all}/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../all}/res/web_hi_res_512.png | Bin .../extension/all}/luscious/Luscious.kt | 60 ++++++-- .../extension/all/luscious/LusciousFactory.kt | 36 +++++ 16 files changed, 257 insertions(+), 148 deletions(-) delete mode 100644 multisrc/overrides/luscious/luscious/src/LusciousFactory.kt delete mode 100644 multisrc/overrides/luscious/lusciousapi/src/LusciousAPIFactory.kt delete mode 100644 multisrc/overrides/luscious/lusciousmembers/src/LusciousMembersFactory.kt delete mode 100644 multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/LusciousGenerator.kt create mode 100644 src/all/AndroidManifest.xml create mode 100644 src/all/CHANGELOG.md create mode 100644 src/all/README.md create mode 100644 src/all/build.gradle rename {multisrc/overrides/luscious/default => src/all}/res/mipmap-hdpi/ic_launcher.png (100%) rename {multisrc/overrides/luscious/default => src/all}/res/mipmap-mdpi/ic_launcher.png (100%) rename {multisrc/overrides/luscious/default => src/all}/res/mipmap-xhdpi/ic_launcher.png (100%) rename {multisrc/overrides/luscious/default => src/all}/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {multisrc/overrides/luscious/default => src/all}/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {multisrc/overrides/luscious/default => src/all}/res/web_hi_res_512.png (100%) rename {multisrc/src/main/java/eu/kanade/tachiyomi/multisrc => src/all/src/eu/kanade/tachiyomi/extension/all}/luscious/Luscious.kt (94%) create mode 100644 src/all/src/eu/kanade/tachiyomi/extension/all/luscious/LusciousFactory.kt diff --git a/multisrc/overrides/luscious/luscious/src/LusciousFactory.kt b/multisrc/overrides/luscious/luscious/src/LusciousFactory.kt deleted file mode 100644 index 8355b47df..000000000 --- a/multisrc/overrides/luscious/luscious/src/LusciousFactory.kt +++ /dev/null @@ -1,37 +0,0 @@ -package eu.kanade.tachiyomi.extension.all.luscious - -import eu.kanade.tachiyomi.multisrc.luscious.Luscious -import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.source.SourceFactory - -class LusciousFactory : SourceFactory { - override fun createSources(): List<Source> = listOf( - LusciousEN(), - LusciousJA(), - LusciousES(), - LusciousIT(), - LusciousDE(), - LusciousFR(), - LusciousZH(), - LusciousKO(), - LusciousOTHER(), - LusciousPT(), - LusciousTH(), - LusciousALL(), - ) -} -class LusciousEN : Luscious("Luscious", "https://www.luscious.net", "en") -class LusciousJA : Luscious("Luscious", "https://www.luscious.net", "ja") -class LusciousES : Luscious("Luscious", "https://www.luscious.net", "es") -class LusciousIT : Luscious("Luscious", "https://www.luscious.net", "it") -class LusciousDE : Luscious("Luscious", "https://www.luscious.net", "de") -class LusciousFR : Luscious("Luscious", "https://www.luscious.net", "fr") -class LusciousZH : Luscious("Luscious", "https://www.luscious.net", "zh") -class LusciousKO : Luscious("Luscious", "https://www.luscious.net", "ko") -class LusciousOTHER : Luscious("Luscious", "https://www.luscious.net", "other") -class LusciousPT : Luscious("Luscious", "https://www.luscious.net", "pt-BR") { - // Hardcode the id because the language wasn't specific. - override val id: Long = 5826725746643311801 -} -class LusciousTH : Luscious("Luscious", "https://www.luscious.net", "th") -class LusciousALL : Luscious("Luscious", "https://www.luscious.net", "all") diff --git a/multisrc/overrides/luscious/lusciousapi/src/LusciousAPIFactory.kt b/multisrc/overrides/luscious/lusciousapi/src/LusciousAPIFactory.kt deleted file mode 100644 index d3d6b977f..000000000 --- a/multisrc/overrides/luscious/lusciousapi/src/LusciousAPIFactory.kt +++ /dev/null @@ -1,37 +0,0 @@ -package eu.kanade.tachiyomi.extension.all.lusciousapi - -import eu.kanade.tachiyomi.multisrc.luscious.Luscious -import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.source.SourceFactory - -class LusciousAPIFactory : SourceFactory { - override fun createSources(): List<Source> = listOf( - LusciousAPIEN(), - LusciousAPIJA(), - LusciousAPIES(), - LusciousAPIIT(), - LusciousAPIDE(), - LusciousAPIFR(), - LusciousAPIZH(), - LusciousAPIKO(), - LusciousAPIOTHER(), - LusciousAPIPT(), - LusciousAPITH(), - LusciousAPIALL(), - ) -} -class LusciousAPIEN : Luscious("Luscious (API)", "https://api.luscious.net", "en") -class LusciousAPIJA : Luscious("Luscious (API)", "https://api.luscious.net", "ja") -class LusciousAPIES : Luscious("Luscious (API)", "https://api.luscious.net", "es") -class LusciousAPIIT : Luscious("Luscious (API)", "https://api.luscious.net", "it") -class LusciousAPIDE : Luscious("Luscious (API)", "https://api.luscious.net", "de") -class LusciousAPIFR : Luscious("Luscious (API)", "https://api.luscious.net", "fr") -class LusciousAPIZH : Luscious("Luscious (API)", "https://api.luscious.net", "zh") -class LusciousAPIKO : Luscious("Luscious (API)", "https://api.luscious.net", "ko") -class LusciousAPIOTHER : Luscious("Luscious (API)", "https://api.luscious.net", "other") -class LusciousAPIPT : Luscious("Luscious (API)", "https://api.luscious.net", "pt-BR") { - // Hardcode the id because the language wasn't specific. - override val id: Long = 7982365826055835382 -} -class LusciousAPITH : Luscious("Luscious (API)", "https://api.luscious.net", "th") -class LusciousAPIALL : Luscious("Luscious (API)", "https://api.luscious.net", "all") diff --git a/multisrc/overrides/luscious/lusciousmembers/src/LusciousMembersFactory.kt b/multisrc/overrides/luscious/lusciousmembers/src/LusciousMembersFactory.kt deleted file mode 100644 index 69d3c459e..000000000 --- a/multisrc/overrides/luscious/lusciousmembers/src/LusciousMembersFactory.kt +++ /dev/null @@ -1,37 +0,0 @@ -package eu.kanade.tachiyomi.extension.all.lusciousmembers - -import eu.kanade.tachiyomi.multisrc.luscious.Luscious -import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.source.SourceFactory - -class LusciousMembersFactory : SourceFactory { - override fun createSources(): List<Source> = listOf( - LusciousMembersEN(), - LusciousMembersJA(), - LusciousMembersES(), - LusciousMembersIT(), - LusciousMembersDE(), - LusciousMembersFR(), - LusciousMembersZH(), - LusciousMembersKO(), - LusciousMembersOTHER(), - LusciousMembersPT(), - LusciousMembersTH(), - LusciousMembersALL(), - ) -} -class LusciousMembersEN : Luscious("Luscious (Members)", "https://members.luscious.net", "en") -class LusciousMembersJA : Luscious("Luscious (Members)", "https://members.luscious.net", "ja") -class LusciousMembersES : Luscious("Luscious (Members)", "https://members.luscious.net", "es") -class LusciousMembersIT : Luscious("Luscious (Members)", "https://members.luscious.net", "it") -class LusciousMembersDE : Luscious("Luscious (Members)", "https://members.luscious.net", "de") -class LusciousMembersFR : Luscious("Luscious (Members)", "https://members.luscious.net", "fr") -class LusciousMembersZH : Luscious("Luscious (Members)", "https://members.luscious.net", "zh") -class LusciousMembersKO : Luscious("Luscious (Members)", "https://members.luscious.net", "ko") -class LusciousMembersOTHER : Luscious("Luscious (Members)", "https://members.luscious.net", "other") -class LusciousMembersPT : Luscious("Luscious (Members)", "https://members.luscious.net", "pt-BR") { - // Hardcode the id because the language wasn't specific. - override val id: Long = 6917849530594229844 -} -class LusciousMembersTH : Luscious("Luscious (Members)", "https://members.luscious.net", "th") -class LusciousMembersALL : Luscious("Luscious (Members)", "https://members.luscious.net", "all") 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 deleted file mode 100644 index d821b57c5..000000000 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/LusciousGenerator.kt +++ /dev/null @@ -1,26 +0,0 @@ -package eu.kanade.tachiyomi.multisrc.luscious - -import generator.ThemeSourceData.MultiLang -import generator.ThemeSourceGenerator - -class LusciousGenerator : ThemeSourceGenerator { - - override val themePkg = "luscious" - - override val themeClass = "Luscious" - - override val baseVersionCode: Int = 15 - - override val sources = listOf( - MultiLang("Luscious", "https://www.luscious.net", listOf("en", "ja", "es", "it", "de", "fr", "zh", "ko", "other", "pt-BR", "th", "all"), isNsfw = true, className = "LusciousFactory", overrideVersionCode = 2), - MultiLang("Luscious (Members)", "https://members.luscious.net", listOf("en", "ja", "es", "it", "de", "fr", "zh", "ko", "other", "pt-BR", "th", "all"), isNsfw = true, className = "LusciousMembersFactory", pkgName = "lusciousmembers"), // Requires Account - MultiLang("Luscious (API)", "https://api.luscious.net", listOf("en", "ja", "es", "it", "de", "fr", "zh", "ko", "other", "pt-BR", "th", "all"), isNsfw = true, className = "LusciousAPIFactory", pkgName = "lusciousapi") - ) - - companion object { - @JvmStatic - fun main(args: Array<String>) { - LusciousGenerator().createAll() - } - } -} diff --git a/src/all/AndroidManifest.xml b/src/all/AndroidManifest.xml new file mode 100644 index 000000000..7f8a6d5d3 --- /dev/null +++ b/src/all/AndroidManifest.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" +package="eu.kanade.tachiyomi.extension"> +</manifest> \ No newline at end of file diff --git a/src/all/CHANGELOG.md b/src/all/CHANGELOG.md new file mode 100644 index 000000000..5fccd58c1 --- /dev/null +++ b/src/all/CHANGELOG.md @@ -0,0 +1,132 @@ +## 1.2.18 + +### Features + +* Merged Luscious extensions +* added removed extensions as mirrors + +### Fix + +* webp images downloading as .bin files + +## 1.2.17 + +### Refactor + +* replace Gson with kotlinx.serialization + +## 1.2.16 + +### Fix + +* Gson conversion mistake + +## 1.2.15 + +### Fix + +* Loading of image URLs that are missing `https` at the beginning + +## 1.2.14 + +### Features + +* Chapter Number as prefix +* Missing sort option `Search Score` + +## 1.2.13 + +### Fix + +* Change pr to pt-BR + +## 1.2.12 + +### Features + +* Chapter release date +* Selection filter + +## 1.2.11 + +### Features + +* Uploader Filter +* Favourite filter + +### Fix + +* Api in webview + +## 1.2.10 + +### Fix + +* Latest sort order + +## 1.2.9 + +### Features + +* More genres as filter options + +## 1.2.8 + +### Fix + +* Android 8 Support + +## 1.2.7 + +### Features + +* Unfiltered Language option +* Filter by year is now dynamic +* Page sort preference +* Tag filter is now text input + + +## 1.2.6 + +### Features + +* Merge Chapter preference +* Resolution preference + +## 1.2.5 + +### Features + +* Moved to API +* Every page is now a Chapter +* Album Size Filter +* Restrict Genres Filter +* More sort filter options + +### Fix + +* Details & tags in members mirror + +## 1.2.4 + +### Fix + +* Changed image server + +## 1.2.3 + +### Features + +* added api & members mirror + +## 1.2.2 + +### Fix + +* Page order + +## 1.2.1 + +### Features + +* first version diff --git a/src/all/README.md b/src/all/README.md new file mode 100644 index 000000000..db324677a --- /dev/null +++ b/src/all/README.md @@ -0,0 +1,23 @@ +# Luscious + +Table of Content +- [FAQ](#FAQ) + +[Uncomment this if needed; and replace ( and ) with ( and )]: <> (- [Guides](#Guides)) + +Don't find the question you are look for go check out our general FAQs and Guides over at [Extension FAQ](https://tachiyomi.org/help/faq/#extensions) or [Getting Started](https://tachiyomi.org/help/guides/getting-started/#installation) + +## FAQ +#### Why is each page a Chapter? +New pages can always be added to a Luscious album by the creator of the album. + +#### Why do i get the errors like `Index: 2, Size: 2`? +This happens when the manga is not supporting your current resolution. + +#### Why do features that require login not work even when im logged in? +Features that require login only work when the mirror is changed to the Members mirror. + +#### Where did the other Luscious extensions go? +They are now mirror options in the Luscious extension. + +[Uncomment this if needed]: <> (## Guides) \ No newline at end of file diff --git a/src/all/build.gradle b/src/all/build.gradle new file mode 100644 index 000000000..62c5c2957 --- /dev/null +++ b/src/all/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlinx-serialization' + +ext { + extName = 'Luscious' + pkgNameSuffix = 'all.luscious' + extClass = '.LusciousFactory' + extVersionCode = 18 + isNsfw = true +} + +apply from: "$rootDir/common.gradle" diff --git a/multisrc/overrides/luscious/default/res/mipmap-hdpi/ic_launcher.png b/src/all/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/luscious/default/res/mipmap-hdpi/ic_launcher.png rename to src/all/res/mipmap-hdpi/ic_launcher.png diff --git a/multisrc/overrides/luscious/default/res/mipmap-mdpi/ic_launcher.png b/src/all/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/luscious/default/res/mipmap-mdpi/ic_launcher.png rename to src/all/res/mipmap-mdpi/ic_launcher.png diff --git a/multisrc/overrides/luscious/default/res/mipmap-xhdpi/ic_launcher.png b/src/all/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/luscious/default/res/mipmap-xhdpi/ic_launcher.png rename to src/all/res/mipmap-xhdpi/ic_launcher.png diff --git a/multisrc/overrides/luscious/default/res/mipmap-xxhdpi/ic_launcher.png b/src/all/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/luscious/default/res/mipmap-xxhdpi/ic_launcher.png rename to src/all/res/mipmap-xxhdpi/ic_launcher.png diff --git a/multisrc/overrides/luscious/default/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from multisrc/overrides/luscious/default/res/mipmap-xxxhdpi/ic_launcher.png rename to src/all/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/multisrc/overrides/luscious/default/res/web_hi_res_512.png b/src/all/res/web_hi_res_512.png similarity index 100% rename from multisrc/overrides/luscious/default/res/web_hi_res_512.png rename to src/all/res/web_hi_res_512.png diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/Luscious.kt b/src/all/src/eu/kanade/tachiyomi/extension/all/luscious/Luscious.kt similarity index 94% rename from multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/Luscious.kt rename to src/all/src/eu/kanade/tachiyomi/extension/all/luscious/Luscious.kt index 7724408b3..e8db1c207 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious/Luscious.kt +++ b/src/all/src/eu/kanade/tachiyomi/extension/all/luscious/Luscious.kt @@ -1,4 +1,4 @@ -package eu.kanade.tachiyomi.multisrc.luscious +package eu.kanade.tachiyomi.extension.all.luscious import android.app.Application import android.content.SharedPreferences @@ -30,9 +30,12 @@ import kotlinx.serialization.json.put import kotlinx.serialization.json.putJsonArray import kotlinx.serialization.json.putJsonObject import okhttp3.HttpUrl.Companion.toHttpUrlOrNull +import okhttp3.Interceptor +import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response +import okhttp3.ResponseBody.Companion.toResponseBody import rx.Observable import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -40,21 +43,37 @@ import uy.kohesive.injekt.injectLazy import java.util.Calendar abstract class Luscious( - override val name: String, - override val baseUrl: String, final override val lang: String ) : ConfigurableSource, HttpSource() { - // Based on Luscious single source extension form https://github.com/tachiyomiorg/tachiyomi-extensions/commit/aacf56d0c0ddb173372aac69d798ae998f178377 - // with modification to make it support multisrc - override val supportsLatest: Boolean = true + override val name: String = "Luscious" + + private val preferences: SharedPreferences by lazy { + Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) + } + + override val baseUrl: String = getMirrorPref()!! private val apiBaseUrl: String = "$baseUrl/graphql/nobatch/" private val json: Json by injectLazy() - override val client: OkHttpClient = network.cloudflareClient + override val client: OkHttpClient + get() = network.cloudflareClient.newBuilder() + .addNetworkInterceptor(rewriteOctetStream) + .build() + + private val rewriteOctetStream: Interceptor = Interceptor { chain -> + val originalResponse: Response = chain.proceed(chain.request()) + if (originalResponse.headers("Content-Type").contains("application/octet-stream") && originalResponse.request.url.toString().contains(".webp")) { + val orgBody = originalResponse.body!!.bytes() + val newBody = orgBody.toResponseBody("image/webp".toMediaTypeOrNull()) + originalResponse.newBuilder() + .body(newBody) + .build() + } else originalResponse + } private val lusLang: String = toLusLang(lang) @@ -75,10 +94,6 @@ abstract class Luscious( } } - private val preferences: SharedPreferences by lazy { - Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) - } - // Common private fun buildAlbumListRequestInput(page: Int, filters: FilterList, query: String = ""): JsonObject { @@ -820,6 +835,12 @@ abstract class Luscious( private val SORT_PREF_ENTRIES = arrayOf("Position", "Date", "Rating") private val SORT_PREF_ENTRY_VALUES = arrayOf("position", "date_newest", "rating_all_time") private val SORT_PREF_DEFAULT_VALUE = SORT_PREF_ENTRY_VALUES[0] + + private const val MIRROR_PREF_KEY = "MIRROR" + private const val MIRROR_PREF_TITLE = "Mirror" + private val MIRROR_PREF_ENTRIES = arrayOf("Guest", "API", "Members") + private val MIRROR_PREF_ENTRY_VALUES = arrayOf("https://www.luscious.net", "https://api.luscious.net", "https://members.luscious.net") + private val MIRROR_PREF_DEFAULT_VALUE = MIRROR_PREF_ENTRY_VALUES[0] } override fun setupPreferenceScreen(screen: PreferenceScreen) { @@ -864,12 +885,29 @@ abstract class Luscious( preferences.edit().putBoolean("${MERGE_CHAPTER_PREF_KEY}_$lang", checkValue).commit() } } + val mirrorPref = ListPreference(screen.context).apply { + key = "${MIRROR_PREF_KEY}_$lang" + title = MIRROR_PREF_TITLE + entries = MIRROR_PREF_ENTRIES + entryValues = MIRROR_PREF_ENTRY_VALUES + setDefaultValue(MIRROR_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("${MIRROR_PREF_KEY}_$lang", entry).commit() + } + } screen.addPreference(resolutionPref) screen.addPreference(sortPref) screen.addPreference(mergeChapterPref) + screen.addPreference(mirrorPref) } 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) private fun getSortPref(): String? = preferences.getString("${SORT_PREF_KEY}_$lang", SORT_PREF_DEFAULT_VALUE) + private fun getMirrorPref(): String? = preferences.getString("${MIRROR_PREF_KEY}_$lang", MIRROR_PREF_DEFAULT_VALUE) } diff --git a/src/all/src/eu/kanade/tachiyomi/extension/all/luscious/LusciousFactory.kt b/src/all/src/eu/kanade/tachiyomi/extension/all/luscious/LusciousFactory.kt new file mode 100644 index 000000000..302499157 --- /dev/null +++ b/src/all/src/eu/kanade/tachiyomi/extension/all/luscious/LusciousFactory.kt @@ -0,0 +1,36 @@ +package eu.kanade.tachiyomi.extension.all.luscious + +import eu.kanade.tachiyomi.source.Source +import eu.kanade.tachiyomi.source.SourceFactory + +class LusciousFactory : SourceFactory { + override fun createSources(): List<Source> = listOf( + LusciousEN(), + LusciousJA(), + LusciousES(), + LusciousIT(), + LusciousDE(), + LusciousFR(), + LusciousZH(), + LusciousKO(), + LusciousOTHER(), + LusciousPT(), + LusciousTH(), + LusciousALL(), + ) +} +class LusciousEN : Luscious("en") +class LusciousJA : Luscious("ja") +class LusciousES : Luscious("es") +class LusciousIT : Luscious("it") +class LusciousDE : Luscious("de") +class LusciousFR : Luscious("fr") +class LusciousZH : Luscious("zh") +class LusciousKO : Luscious("ko") +class LusciousOTHER : Luscious("other") +class LusciousPT : Luscious("pt-BR") { + // Hardcode the id because the language wasn't specific. + override val id: Long = 5826725746643311801 +} +class LusciousTH : Luscious("th") +class LusciousALL : Luscious("all")