[shabakatycinemana] add staff filter, and more Anime info (#837)

* add shabakaty cinemana extension

* fix kinds default value retrieving from preferences

* fix browse langauge without category

* fix episodes order: reverse

* fix: animePage hasNextPage for popular, search, and latest

* remove debug prints

* bump version to 2

* more Anime info, and add staff title filter

* bump shabakatycinemana version to `3`

* apply PR suggestion on safely handling null values, and remove redundant code
This commit is contained in:
Hasan Pasha 2025-03-24 21:30:02 +03:00 committed by GitHub
parent faf9d63d75
commit 0fb8c32aa6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 33 additions and 10 deletions

View file

@ -1,7 +1,7 @@
ext { ext {
extName = 'ShabakatyCinemana' extName = 'ShabakatyCinemana'
extClass = '.ShabakatyCinemana' extClass = '.ShabakatyCinemana'
extVersionCode = 2 extVersionCode = 3
isNsfw = false isNsfw = false
} }

View file

@ -134,9 +134,17 @@ object SAnimeDeserializer : DeserializationStrategy<SAnime> {
val nb = jsonObject["nb"]?.jsonPrimitive?.content!! val nb = jsonObject["nb"]?.jsonPrimitive?.content!!
val enTitle = jsonObject["en_title"]?.jsonPrimitive?.content ?: "no title" val enTitle = jsonObject["en_title"]?.jsonPrimitive?.content ?: "no title"
val imgObjUrl = jsonObject["imgObjUrl"]?.jsonPrimitive?.content val imgObjUrl = jsonObject["imgObjUrl"]?.jsonPrimitive?.content
val categories = jsonObject["categories"]?.jsonArray?.map { val categories = jsonObject["categories"]?.jsonArray?.mapNotNull {
it.jsonObject["en_title"]?.jsonPrimitive?.content it.jsonObject["en_title"]?.jsonPrimitive?.content
}?.joinToString(", ") }.orEmpty()
val language = jsonObject["videoLanguages"]?.jsonObject?.get("en_title")?.jsonPrimitive?.content
val genreText = (categories + language).mapNotNull { it }.joinToString()
val directors = jsonObject["directorsInfo"]?.jsonArray?.mapNotNull {
it.jsonObject["name"]?.jsonPrimitive?.content
}?.joinToString()
val actors = jsonObject["actorsInfo"]?.jsonArray?.mapNotNull {
it.jsonObject["name"]?.jsonPrimitive?.content
}?.joinToString()
val enContent = jsonObject["en_content"]?.jsonPrimitive?.content val enContent = jsonObject["en_content"]?.jsonPrimitive?.content
val year = jsonObject["year"]?.jsonPrimitive?.content ?: "N/A" val year = jsonObject["year"]?.jsonPrimitive?.content ?: "N/A"
val stars = jsonObject["stars"]?.jsonPrimitive?.content?.parseAs<Float>()?.toInt() ?: 0 val stars = jsonObject["stars"]?.jsonPrimitive?.content?.parseAs<Float>()?.toInt() ?: 0
@ -149,8 +157,13 @@ object SAnimeDeserializer : DeserializationStrategy<SAnime> {
url = nb url = nb
title = enTitle title = enTitle
thumbnail_url = imgObjUrl thumbnail_url = imgObjUrl
genre = categories genre = genreText
description = "$year | $starsText | $likes\uD83D\uDC4D $dislikes\uD83D\uDC4E\n\n$enContent" author = directors
artist = actors
description = listOfNotNull(
"$year | $starsText | $likes\uD83D\uDC4D $dislikes\uD83D\uDC4E",
enContent,
).joinToString("\n\n")
} }
} }
} }
@ -178,7 +191,8 @@ class ShabakatyCinemana : ConfigurableAnimeSource, AnimeHttpSource() {
private const val SUB_CATEGORY_FILTER_NAME = "Sub Category" private const val SUB_CATEGORY_FILTER_NAME = "Sub Category"
private const val LANGUAGE_FILTER_NAME = "Language" private const val LANGUAGE_FILTER_NAME = "Language"
private const val YEAR_FILTER_NAME = "Year" private const val YEAR_FILTER_NAME = "Year"
private const val BROWSE_RESULT_SORT_FILTER = "Browse Sort" private const val BROWSE_RESULT_SORT_FILTER_NAME = "Browse Sort"
private const val STAFF_TITLE_FILTER_NAME = "Staff Title"
private const val POPULAR_ITEMS_PER_PAGE = 30 private const val POPULAR_ITEMS_PER_PAGE = 30
private const val SEARCH_ITEMS_PER_PAGE = 12 private const val SEARCH_ITEMS_PER_PAGE = 12
@ -253,7 +267,8 @@ class ShabakatyCinemana : ConfigurableAnimeSource, AnimeHttpSource() {
val subCategoryFilter = filterList.find { it.name == SUB_CATEGORY_FILTER_NAME } as MultipleSelectFilter val subCategoryFilter = filterList.find { it.name == SUB_CATEGORY_FILTER_NAME } as MultipleSelectFilter
val languageFilter = filterList.find { it.name == LANGUAGE_FILTER_NAME } as SingleSelectFilter val languageFilter = filterList.find { it.name == LANGUAGE_FILTER_NAME } as SingleSelectFilter
val yearFilter = filterList.find { it.name == YEAR_FILTER_NAME } as YearFilter val yearFilter = filterList.find { it.name == YEAR_FILTER_NAME } as YearFilter
val browseResultSortFilter = filterList.find { it.name == BROWSE_RESULT_SORT_FILTER } as BrowseResultSort val staffTitleFilter = filterList.find { it.name == STAFF_TITLE_FILTER_NAME } as StaffTitleFilter
val browseResultSortFilter = filterList.find { it.name == BROWSE_RESULT_SORT_FILTER_NAME } as BrowseResultSort
val isBrowsing = isBrowsingFilter.state val isBrowsing = isBrowsingFilter.state
val kindName = kindFilter.getNameValue() val kindName = kindFilter.getNameValue()
val kindNumber = kindFilter.getNumberValue().toString() val kindNumber = kindFilter.getNumberValue().toString()
@ -263,6 +278,7 @@ class ShabakatyCinemana : ConfigurableAnimeSource, AnimeHttpSource() {
val bothCategory = (selectedMainCategories + selectedSubCategories).joinToString(",") val bothCategory = (selectedMainCategories + selectedSubCategories).joinToString(",")
val language = languageFilter.getNumberValue().toString() val language = languageFilter.getNumberValue().toString()
val year = yearFilter.getFormatted() val year = yearFilter.getFormatted()
val staffTitle = staffTitleFilter.state
val browseResultSort = browseResultSortFilter.getValue() val browseResultSort = browseResultSortFilter.getValue()
var url = apiBaseUrl.toHttpUrl() var url = apiBaseUrl.toHttpUrl()
@ -311,7 +327,12 @@ class ShabakatyCinemana : ConfigurableAnimeSource, AnimeHttpSource() {
if (query.isNotBlank()) { if (query.isNotBlank()) {
url = url.newBuilder() url = url.newBuilder()
.addQueryParameter("videoTitle", query) .addQueryParameter("videoTitle", query)
.addQueryParameter("staffTitle", query) .build()
}
if (staffTitle.isNotBlank()) {
url = url.newBuilder()
.addQueryParameter("staffTitle", staffTitle)
.build() .build()
} }
@ -425,8 +446,10 @@ class ShabakatyCinemana : ConfigurableAnimeSource, AnimeHttpSource() {
} }
} }
private open class StaffTitleFilter(displayName: String) : AnimeFilter.Text(displayName)
override fun getFilterList() = AnimeFilterList( override fun getFilterList() = AnimeFilterList(
AnimeFilter.Header("Filter Search Result"), StaffTitleFilter(STAFF_TITLE_FILTER_NAME),
CheckBoxFilter(IS_BROWSING_FILTER_NAME, false), CheckBoxFilter(IS_BROWSING_FILTER_NAME, false),
SingleSelectFilter( SingleSelectFilter(
KIND_FILTER_NAME, KIND_FILTER_NAME,
@ -550,7 +573,7 @@ class ShabakatyCinemana : ConfigurableAnimeSource, AnimeHttpSource() {
YearTextFilter("end", Calendar.getInstance().get(Calendar.YEAR).toString()), YearTextFilter("end", Calendar.getInstance().get(Calendar.YEAR).toString()),
), ),
BrowseResultSort( BrowseResultSort(
BROWSE_RESULT_SORT_FILTER, BROWSE_RESULT_SORT_FILTER_NAME,
arrayOf( arrayOf(
Pair("Upload", Pair("asc", "desc")), Pair("Upload", Pair("asc", "desc")),
Pair("Release", Pair("r_asc", "r_desc")), Pair("Release", Pair("r_asc", "r_desc")),