Luscious various fixes and updates (#6701)
* Update Luscious.kt * Update LusciousGenerator.kt
This commit is contained in:
parent
7855257372
commit
19c274df1d
multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/luscious
@ -16,48 +16,38 @@ 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.HttpSource
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import rx.Observable
|
||||
import java.text.ParseException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
abstract class Luscious(
|
||||
override val name: String,
|
||||
override val baseUrl: String,
|
||||
override val lang: String ) : HttpSource() {
|
||||
|
||||
//Based on Luscios single source extension form https://github.com/tachiyomiorg/tachiyomi-extensions/commit/aacf56d0c0ddb173372aac69d798ae998f178377
|
||||
//with modifiaction to make it support multisrc
|
||||
//Based on Luscios single source extension form https://github.com/tachiyomiorg/tachiyomi-extensions/commit/aacf56d0c0ddb173372aac69d798ae998f178377
|
||||
//with modifiaction to make it support multisrc
|
||||
|
||||
override val supportsLatest: Boolean = true
|
||||
private val apiBaseUrl: String = "$baseUrl/graphql/nobatch/"
|
||||
private val gson = Gson()
|
||||
override val client: OkHttpClient = network.cloudflareClient
|
||||
private val lusLang: String = lusLang(lang)
|
||||
private fun lusLang(lang: String): String {
|
||||
return when (lang) {
|
||||
"en" -> "1"
|
||||
"ja" -> "2"
|
||||
"es" -> "3"
|
||||
"it" -> "4"
|
||||
"de" -> "5"
|
||||
"fr" -> "6"
|
||||
"zh" -> "8"
|
||||
"ko" -> "9"
|
||||
"pt" -> "100"
|
||||
"th" -> "101"
|
||||
else -> "99"
|
||||
}
|
||||
private val lusLang: String = when (lang) {
|
||||
"en" -> "1"
|
||||
"ja" -> "2"
|
||||
"es" -> "3"
|
||||
"it" -> "4"
|
||||
"de" -> "5"
|
||||
"fr" -> "6"
|
||||
"zh" -> "8"
|
||||
"ko" -> "9"
|
||||
"pt" -> "100"
|
||||
"th" -> "101"
|
||||
else -> "99"
|
||||
}
|
||||
|
||||
|
||||
// Common
|
||||
|
||||
private fun buildAlbumListRequestInput(page: Int, filters: FilterList, query: String = ""): JsonObject {
|
||||
@ -68,6 +58,8 @@ abstract class Luscious(
|
||||
val tagsFilter = filters.findInstance<TagGroupFilter>()!!
|
||||
val genreFilter = filters.findInstance<GenreGroupFilter>()!!
|
||||
val contentTypeFilter = filters.findInstance<ContentTypeSelectFilter>()!!
|
||||
val albumSizeFilter = filters.findInstance<AlbumSizeSelectFilter>()!!
|
||||
val restrictGenresFilter = filters.findInstance<RestrictGenresSelectFilter>()!!
|
||||
|
||||
return JsonObject().apply {
|
||||
add(
|
||||
@ -85,6 +77,12 @@ abstract class Luscious(
|
||||
if (albumTypeFilter.selected != FILTER_VALUE_IGNORE)
|
||||
add(albumTypeFilter.toJsonObject("album_type"))
|
||||
|
||||
if (albumSizeFilter.selected != FILTER_VALUE_IGNORE)
|
||||
add(albumSizeFilter.toJsonObject("picture_count_rank"))
|
||||
|
||||
if (restrictGenresFilter.selected != FILTER_VALUE_IGNORE)
|
||||
add(restrictGenresFilter.toJsonObject("restrict_genres"))
|
||||
|
||||
with(interestsFilter) {
|
||||
if (this.selected.isEmpty()) {
|
||||
throw Exception("Please select an Interest")
|
||||
@ -147,6 +145,22 @@ abstract class Luscious(
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildAlbumInfoRequestInput(id: String): JsonObject {
|
||||
return JsonObject().apply {
|
||||
addProperty("id", id)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildAlbumInfoRequest(id: String): Request {
|
||||
val input = buildAlbumInfoRequestInput(id)
|
||||
val url = HttpUrl.parse(apiBaseUrl)!!.newBuilder()
|
||||
.addQueryParameter("operationName", "AlbumGet")
|
||||
.addQueryParameter("query", albumInfoQuery)
|
||||
.addQueryParameter("variables", input.toString())
|
||||
.toString()
|
||||
return GET(url, headers)
|
||||
}
|
||||
|
||||
// Latest
|
||||
|
||||
override fun latestUpdatesRequest(page: Int): Request = buildAlbumListRequest(page, getSortFilters(LATEST_DEFAULT_SORT_STATE))
|
||||
@ -155,20 +169,47 @@ abstract class Luscious(
|
||||
|
||||
// Chapters
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
val document = response.asJsoup()
|
||||
return listOf(
|
||||
SChapter.create().apply {
|
||||
url = response.request().url().toString()
|
||||
name = "Chapter"
|
||||
date_upload = document.select(".album-info-item:contains(Created:)")?.first()?.ownText()?.trim()?.let {
|
||||
DATE_FORMATS_WITH_ORDINAL_SUFFIXES.mapNotNull { format -> format.parseOrNull(it) }.firstOrNull()?.time
|
||||
} ?: 0L
|
||||
chapter_number = 1f
|
||||
}
|
||||
)
|
||||
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
|
||||
val id = manga.url.substringAfterLast("_").removeSuffix("/")
|
||||
|
||||
return client.newCall(GET(buildAlbumPicturesPageUrl(id, 1, "position")))
|
||||
.asObservableSuccess()
|
||||
.map { parseAlbumPicturesResponse(it, "position") }
|
||||
}
|
||||
|
||||
private fun parseAlbumPicturesResponse(response: Response, sortPagesByOption: String): List<SChapter> {
|
||||
val chapters = mutableListOf<SChapter>()
|
||||
var nextPage = true
|
||||
var page = 2
|
||||
val id = response.request().url().queryParameter("variables").toString()
|
||||
.let { gson.fromJson<JsonObject>(it)["input"]["filters"].asJsonArray }
|
||||
.let { it.first { f -> f["name"].asString == "album_id" } }
|
||||
.let { it["value"].asString }
|
||||
|
||||
var data = gson.fromJson<JsonObject>(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 = it["url_to_original"].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<JsonObject>(newPage.body()!!.string())
|
||||
.let { it["data"]["picture"]["list"].asJsonObject }
|
||||
}
|
||||
page++
|
||||
}
|
||||
return chapters.reversed()
|
||||
}
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> = throw UnsupportedOperationException("Not used")
|
||||
// Pages
|
||||
|
||||
private fun buildAlbumPicturesRequestInput(id: String, page: Int, sortPagesByOption: String): JsonObject {
|
||||
@ -203,43 +244,8 @@ abstract class Luscious(
|
||||
.toString()
|
||||
}
|
||||
|
||||
private fun parseAlbumPicturesResponse(response: Response, sortPagesByOption: String): List<Page> {
|
||||
|
||||
val id = response.request().url().queryParameter("variables").toString()
|
||||
.let { gson.fromJson<JsonObject>(it)["input"]["filters"].asJsonArray }
|
||||
.let { it.first { f -> f["name"].asString == "album_id" } }
|
||||
.let { it["value"].asString }
|
||||
|
||||
val data = gson.fromJson<JsonObject>(response.body()!!.string())
|
||||
.let { it["data"]["picture"]["list"].asJsonObject }
|
||||
|
||||
return data["items"].asJsonArray.mapIndexed { index, it ->
|
||||
Page(index, imageUrl = it["thumbnails"][0]["url"].asString)
|
||||
} + if (data["info"]["total_pages"].asInt > 1) { // get 2nd page onwards
|
||||
(ITEMS_PER_PAGE until data["info"]["total_items"].asInt).chunked(ITEMS_PER_PAGE).mapIndexed { page, indices ->
|
||||
indices.map { Page(it, url = buildAlbumPicturesPageUrl(id, page + 2, sortPagesByOption)) }
|
||||
}.flatten()
|
||||
} else emptyList()
|
||||
}
|
||||
|
||||
private fun getAlbumSortPagesOption(chapter: SChapter): Observable<String> {
|
||||
return client.newCall(GET(chapter.url))
|
||||
.asObservableSuccess()
|
||||
.map {
|
||||
val sortByKey = it.asJsoup().select(".o-input-select:contains(Sorted By) .o-select-value")?.text() ?: ""
|
||||
ALBUM_PICTURES_SORT_OPTIONS.getValue(sortByKey)
|
||||
}
|
||||
}
|
||||
|
||||
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
||||
val id = chapter.url.substringAfterLast("_").removeSuffix("/")
|
||||
|
||||
return getAlbumSortPagesOption(chapter)
|
||||
.concatMap { sortPagesByOption ->
|
||||
client.newCall(GET(buildAlbumPicturesPageUrl(id, 1, sortPagesByOption)))
|
||||
.asObservableSuccess()
|
||||
.map { parseAlbumPicturesResponse(it, sortPagesByOption) }
|
||||
}
|
||||
return Observable.just(listOf(Page(0, chapter.url, chapter.url)))
|
||||
}
|
||||
|
||||
override fun pageListParse(response: Response): List<Page> = throw UnsupportedOperationException("Not used")
|
||||
@ -257,52 +263,47 @@ abstract class Luscious(
|
||||
val data = gson.fromJson<JsonObject>(it.body()!!.string()).let { data ->
|
||||
data["data"]["picture"]["list"].asJsonObject
|
||||
}
|
||||
data["items"].asJsonArray[page.index % 50].asJsonObject["thumbnails"][0]["url"].asString
|
||||
data["items"].asJsonArray[page.index % 50].asJsonObject["url_to_original"].asString
|
||||
}
|
||||
}
|
||||
|
||||
// Details
|
||||
|
||||
private fun parseMangaGenre(document: Document): String {
|
||||
return listOf(
|
||||
document.select(".o-tag--secondary").map { it.text().substringBefore("(").trim() },
|
||||
document.select(".o-tag:not([href *= /tags/artist])").map { it.text() },
|
||||
document.select(".album-info-item:contains(Content:) .o-tag").map { it.text() }
|
||||
).flatten().joinToString()
|
||||
}
|
||||
|
||||
private fun parseMangaDescription(document: Document): String {
|
||||
val pageCount: String? = (
|
||||
document.select(".album-info-item:contains(pictures)").firstOrNull()
|
||||
?: document.select(".album-info-item:contains(gifs)").firstOrNull()
|
||||
)?.text()
|
||||
|
||||
return listOf(
|
||||
Pair("Description", document.select(".album-description:last-of-type")?.text()),
|
||||
Pair("Pages", pageCount)
|
||||
).let {
|
||||
it + listOf("Parody", "Character", "Ethnicity")
|
||||
.map { key -> key to document.select(".o-tag--category:contains($key) .o-tag").joinToString { t -> t.text() } }
|
||||
}.filter { desc -> !desc.second.isNullOrBlank() }
|
||||
.joinToString("\n\n") { "${it.first}:\n${it.second}" }
|
||||
override fun mangaDetailsRequest(manga: SManga): Request {
|
||||
val id = manga.url.substringAfterLast("_").removeSuffix("/")
|
||||
return buildAlbumInfoRequest(id)
|
||||
}
|
||||
|
||||
override fun mangaDetailsParse(response: Response): SManga {
|
||||
val document = response.asJsoup()
|
||||
return SManga.create().apply {
|
||||
|
||||
artist = document.select(".o-tag--category:contains(Artist:) .o-tag")?.joinToString { it.text() }
|
||||
author = artist
|
||||
|
||||
genre = parseMangaGenre(document)
|
||||
|
||||
title = document.select("a[title]").text()
|
||||
status = when {
|
||||
title.contains("ongoing", true) -> SManga.ONGOING
|
||||
else -> SManga.COMPLETED
|
||||
val data = gson.fromJson<JsonObject>(response.body()!!.string())
|
||||
with(data["data"]["album"]["get"]) {
|
||||
val manga = SManga.create()
|
||||
manga.url = this["url"].asString
|
||||
manga.title = this["title"].asString
|
||||
manga.thumbnail_url = this["cover"]["url"].asString
|
||||
manga.status = 0
|
||||
manga.description = "${this["description"].asString}\n\nPictures: ${this["number_of_pictures"].asString}\nAnimated Pictures: ${this["number_of_animated_pictures"].asString}"
|
||||
var genreList = this["language"]["title"].asString
|
||||
for ((i, _) in this["labels"].asJsonArray.withIndex()) {
|
||||
genreList = "$genreList, ${this["labels"][i].asString}"
|
||||
}
|
||||
for ((i, _) in this["genres"].asJsonArray.withIndex()) {
|
||||
genreList = "$genreList, ${this["genres"][i]["title"].asString}"
|
||||
}
|
||||
for ((i, _) in this["audiences"].asJsonArray.withIndex()) {
|
||||
genreList = "$genreList, ${this["audiences"][i]["title"].asString}"
|
||||
}
|
||||
for ((i, _) in this["tags"].asJsonArray.withIndex()) {
|
||||
genreList = "$genreList, ${this["tags"][i]["text"].asString}"
|
||||
if (this["tags"][i]["text"].asString.contains("Artist:")){
|
||||
manga.artist = this["tags"][i]["text"].asString.substringAfter(":").trim()
|
||||
manga.author = manga.artist
|
||||
}
|
||||
}
|
||||
genreList = "$genreList, ${this["content"]["title"].asString}"
|
||||
manga.genre = genreList
|
||||
|
||||
description = parseMangaDescription(document)
|
||||
return manga
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,6 +372,8 @@ abstract class Luscious(
|
||||
class SortBySelectFilter(options: List<SelectFilterOption>, default: Int) : SelectFilter("Sort By", options, default)
|
||||
class AlbumTypeSelectFilter(options: List<SelectFilterOption>) : SelectFilter("Album Type", options)
|
||||
class ContentTypeSelectFilter(options: List<SelectFilterOption>) : SelectFilter("Content Type", options)
|
||||
class RestrictGenresSelectFilter(options: List<SelectFilterOption>) : SelectFilter("Restrict Genres", options)
|
||||
class AlbumSizeSelectFilter(options: List<SelectFilterOption>) : SelectFilter("Album Size", options)
|
||||
|
||||
override fun getFilterList(): FilterList = getSortFilters(POPULAR_DEFAULT_SORT_STATE)
|
||||
|
||||
@ -378,6 +381,8 @@ abstract class Luscious(
|
||||
SortBySelectFilter(getSortFilters(), sortState),
|
||||
AlbumTypeSelectFilter(getAlbumTypeFilters()),
|
||||
ContentTypeSelectFilter(getContentTypeFilters()),
|
||||
AlbumSizeSelectFilter(getAlbumSizeFilters()),
|
||||
RestrictGenresSelectFilter(getRestrictGenresFilters()),
|
||||
InterestGroupFilter(getInterestFilters()),
|
||||
LanguageGroupFilter(getLanguageFilters()),
|
||||
TagGroupFilter(getTagFilters()),
|
||||
@ -391,8 +396,8 @@ abstract class Luscious(
|
||||
SelectFilterOption("Rating - Last 30 Days", "rating_30_days"),
|
||||
SelectFilterOption("Rating - Last 90 Days", "rating_90_days"),
|
||||
SelectFilterOption("Rating - Last Year", "rating_1_year"),
|
||||
SelectFilterOption("Rating - Last Year", "rating_1_year"),
|
||||
SelectFilterOption("Date - Newest First", "date_newest"),
|
||||
SelectFilterOption("Date - 2020", "date_2021"),
|
||||
SelectFilterOption("Date - 2020", "date_2020"),
|
||||
SelectFilterOption("Date - 2019", "date_2019"),
|
||||
SelectFilterOption("Date - 2018", "date_2018"),
|
||||
@ -405,7 +410,39 @@ abstract class Luscious(
|
||||
SelectFilterOption("Date - Upcoming", "date_upcoming"),
|
||||
SelectFilterOption("Date - Trending", "date_trending"),
|
||||
SelectFilterOption("Date - Featured", "date_featured"),
|
||||
SelectFilterOption("Date - Last Viewed", "date_last_interaction")
|
||||
SelectFilterOption("Date - Last Viewed", "date_last_interaction"),
|
||||
SelectFilterOption("First Letter - Any", "alpha_any"),
|
||||
SelectFilterOption("First Letter - A", "alpha_a"),
|
||||
SelectFilterOption("First Letter - B", "alpha_b"),
|
||||
SelectFilterOption("First Letter - C", "alpha_c"),
|
||||
SelectFilterOption("First Letter - D", "alpha_d"),
|
||||
SelectFilterOption("First Letter - Any", "alpha_any"),
|
||||
SelectFilterOption("First Letter - A", "alpha_a"),
|
||||
SelectFilterOption("First Letter - B", "alpha_b"),
|
||||
SelectFilterOption("First Letter - C", "alpha_c"),
|
||||
SelectFilterOption("First Letter - D", "alpha_d"),
|
||||
SelectFilterOption("First Letter - E", "alpha_e"),
|
||||
SelectFilterOption("First Letter - F", "alpha_f"),
|
||||
SelectFilterOption("First Letter - G", "alpha_g"),
|
||||
SelectFilterOption("First Letter - H", "alpha_h"),
|
||||
SelectFilterOption("First Letter - I", "alpha_i"),
|
||||
SelectFilterOption("First Letter - J", "alpha_j"),
|
||||
SelectFilterOption("First Letter - K", "alpha_k"),
|
||||
SelectFilterOption("First Letter - L", "alpha_l"),
|
||||
SelectFilterOption("First Letter - M", "alpha_m"),
|
||||
SelectFilterOption("First Letter - N", "alpha_n"),
|
||||
SelectFilterOption("First Letter - O", "alpha_o"),
|
||||
SelectFilterOption("First Letter - P", "alpha_p"),
|
||||
SelectFilterOption("First Letter - Q", "alpha_q"),
|
||||
SelectFilterOption("First Letter - R", "alpha_r"),
|
||||
SelectFilterOption("First Letter - S", "alpha_s"),
|
||||
SelectFilterOption("First Letter - T", "alpha_t"),
|
||||
SelectFilterOption("First Letter - U", "alpha_u"),
|
||||
SelectFilterOption("First Letter - V", "alpha_v"),
|
||||
SelectFilterOption("First Letter - W", "alpha_w"),
|
||||
SelectFilterOption("First Letter - X", "alpha_x"),
|
||||
SelectFilterOption("First Letter - Y", "alpha_y"),
|
||||
SelectFilterOption("First Letter - Z", "alpha_z"),
|
||||
)
|
||||
|
||||
fun getAlbumTypeFilters() = listOf(
|
||||
@ -414,6 +451,12 @@ abstract class Luscious(
|
||||
SelectFilterOption("Pictures", "pictures")
|
||||
)
|
||||
|
||||
private fun getRestrictGenresFilters() = listOf(
|
||||
SelectFilterOption("None", FILTER_VALUE_IGNORE),
|
||||
SelectFilterOption("Loose", "loose"),
|
||||
SelectFilterOption("Strict", "strict")
|
||||
)
|
||||
|
||||
fun getContentTypeFilters() = listOf(
|
||||
SelectFilterOption("All", FILTER_VALUE_IGNORE),
|
||||
SelectFilterOption("Hentai", "0"),
|
||||
@ -421,6 +464,17 @@ abstract class Luscious(
|
||||
SelectFilterOption("Real People", "6")
|
||||
)
|
||||
|
||||
private fun getAlbumSizeFilters() = listOf(
|
||||
SelectFilterOption("All", FILTER_VALUE_IGNORE),
|
||||
SelectFilterOption("0-25", "0"),
|
||||
SelectFilterOption("0-50", "1"),
|
||||
SelectFilterOption("50-100", "2"),
|
||||
SelectFilterOption("100-200", "3"),
|
||||
SelectFilterOption("200-800", "4"),
|
||||
SelectFilterOption("800-3200", "5"),
|
||||
SelectFilterOption("3200-12800", "6"),
|
||||
)
|
||||
|
||||
fun getInterestFilters() = listOf(
|
||||
CheckboxFilterOption("Straight Sex", "1"),
|
||||
CheckboxFilterOption("Trans x Girl", "10", false),
|
||||
@ -531,28 +585,8 @@ abstract class Luscious(
|
||||
|
||||
private inline fun <reified T> Iterable<*>.findInstance() = find { it is T } as? T
|
||||
|
||||
private fun SimpleDateFormat.parseOrNull(string: String): Date? {
|
||||
return try {
|
||||
parse(string)
|
||||
} catch (e: ParseException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val ALBUM_PICTURES_SORT_OPTIONS = hashMapOf(
|
||||
Pair("Sort By Newest", "date_newest"),
|
||||
Pair("Sort By Rating", "rating_all_time")
|
||||
).withDefault { "position" }
|
||||
|
||||
private const val ITEMS_PER_PAGE = 50
|
||||
|
||||
private val ORDINAL_SUFFIXES = listOf("st", "nd", "rd", "th")
|
||||
private val DATE_FORMATS_WITH_ORDINAL_SUFFIXES = ORDINAL_SUFFIXES.map {
|
||||
SimpleDateFormat("MMMM dd'$it', yyyy", Locale.US)
|
||||
}
|
||||
|
||||
const val ENGLISH_LUS_LANG_VAL = "1"
|
||||
const val JAPANESE_LUS_LANG_VAL = "2"
|
||||
const val SPANISH_LUS_LANG_VAL = "3"
|
||||
@ -594,8 +628,13 @@ abstract class Luscious(
|
||||
total_pages
|
||||
page
|
||||
has_next_page
|
||||
items_per_page
|
||||
}
|
||||
items {
|
||||
created
|
||||
title
|
||||
url_to_original
|
||||
position
|
||||
thumbnails {
|
||||
url
|
||||
}
|
||||
@ -604,5 +643,23 @@ abstract class Luscious(
|
||||
}
|
||||
}
|
||||
""".replace("\n", " ").replace("\\s+".toRegex(), " ")
|
||||
|
||||
val albumInfoQuery = """
|
||||
query AlbumGet(${"$"}id: ID!) {
|
||||
album {
|
||||
get(id: ${"$"}id) {
|
||||
... on Album { ...AlbumStandard }
|
||||
... on MutationError {
|
||||
errors {
|
||||
code message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fragment AlbumStandard on Album {
|
||||
__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()
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class LusciousGenerator : ThemeSourceGenerator {
|
||||
|
||||
override val themeClass = "Luscious"
|
||||
|
||||
override val baseVersionCode: Int = 2
|
||||
override val baseVersionCode: Int = 3
|
||||
|
||||
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),
|
||||
|
Loading…
x
Reference in New Issue
Block a user