Minor fix

This commit is contained in:
tom5079
2020-11-27 20:44:41 +09:00
parent aa6cc80172
commit 24aedfc400
23 changed files with 426 additions and 640 deletions

View File

@@ -18,20 +18,39 @@
package xyz.quaver.pupil.sources
import com.google.android.gms.vision.L
import kotlinx.coroutines.channels.Channel
import xyz.quaver.pupil.R
import kotlin.reflect.KClass
interface SearchResult {
val id: String
val title: String
val thumbnail: String
val artists: List<String>
data class SearchResult(
val id: String,
val title: String,
val thumbnail: String,
val artists: String,
val extra: Map<ExtraType, suspend () -> String>,
val tags: List<String>
) {
enum class ExtraType {
GROUP,
CHARACTER,
SERIES,
TYPE,
LANGUAGE,
PAGECOUNT
}
companion object {
val extraTypeMap = mapOf(
ExtraType.SERIES to R.string.galleryblock_series,
ExtraType.TYPE to R.string.galleryblock_type,
ExtraType.LANGUAGE to R.string.galleryblock_language,
ExtraType.PAGECOUNT to R.string.galleryblock_pagecount
)
}
}
// Might be better to use channel on Query_Result
interface Source<Query_SortMode: Enum<*>, Query_Result: SearchResult> {
val querySortModeClass: KClass<Query_SortMode>
val queryResultClass: KClass<Query_Result>
interface Source<Query_SortMode: Enum<*>> {
val querySortModeClass: KClass<Query_SortMode>?
suspend fun query(query: String, range: IntRange, sortMode: Query_SortMode? = null) : Pair<List<Query_Result>, Int>
suspend fun query(query: String, range: IntRange, sortMode: Query_SortMode? = null) : Pair<Channel<SearchResult>, Int>
}

View File

@@ -18,35 +18,31 @@
package xyz.quaver.pupil.sources.hitomi
import kotlinx.coroutines.yield
import xyz.quaver.hitomi.doSearch
import xyz.quaver.hitomi.getGalleryBlock
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import xyz.quaver.hitomi.*
import xyz.quaver.pupil.sources.SearchResult
import xyz.quaver.pupil.sources.SearchResult.ExtraType
import xyz.quaver.pupil.sources.Source
import kotlin.math.min
import xyz.quaver.pupil.util.wordCapitalize
import kotlin.math.max
import kotlin.math.min
class Hitomi : Source<Hitomi.SortMode, Hitomi.SearchResult> {
class Hitomi : Source<Hitomi.SortMode> {
override val querySortModeClass = SortMode::class
override val queryResultClass = SearchResult::class
enum class SortMode {
NEWEST,
POPULAR
}
data class SearchResult(
override val id: String,
override val title: String,
override val thumbnail: String,
override val artists: List<String>,
) : xyz.quaver.pupil.sources.SearchResult
var cachedQuery: String? = null
var cachedSortMode: SortMode? = null
val cache = mutableListOf<Int>()
override suspend fun query(query: String, range: IntRange, sortMode: SortMode?): Pair<List<SearchResult>, Int> {
if (cachedQuery != query) {
override suspend fun query(query: String, range: IntRange, sortMode: SortMode?): Pair<Channel<SearchResult>, Int> {
if (cachedQuery != query || cachedSortMode != sortMode || cache.isEmpty()) {
cachedQuery = null
cache.clear()
yield()
@@ -57,17 +53,85 @@ class Hitomi : Source<Hitomi.SortMode, Hitomi.SearchResult> {
cachedQuery = query
}
val channel = Channel<SearchResult>()
val sanitizedRange = max(0, range.first) .. min(range.last, cache.size-1)
return Pair(cache.slice(sanitizedRange).map {
getGalleryBlock(it).let { gallery ->
SearchResult(
gallery.id.toString(),
gallery.title,
gallery.thumbnails.first(),
gallery.artists
)
CoroutineScope(Dispatchers.IO).launch {
cache.slice(sanitizedRange).map {
async {
getGalleryBlock(it)
}
}.forEach {
kotlin.runCatching {
yield()
channel.send(transform(it.await()))
}.onFailure {
channel.close()
}
}
}, cache.size)
channel.close()
}
return Pair(channel, cache.size)
}
companion object {
val languageMap = mapOf(
"indonesian" to "Bahasa Indonesia",
"catalan" to "català",
"cebuano" to "Cebuano",
"czech" to "Čeština",
"danish" to "Dansk",
"german" to "Deutsch",
"estonian" to "eesti",
"english" to "English",
"spanish" to "Español",
"esperanto" to "Esperanto",
"french" to "Français",
"italian" to "Italiano",
"latin" to "Latina",
"hungarian" to "magyar",
"dutch" to "Nederlands",
"norwegian" to "norsk",
"polish" to "polski",
"portuguese" to "Português",
"romanian" to "română",
"albanian" to "shqip",
"slovak" to "Slovenčina",
"finnish" to "Suomi",
"swedish" to "Svenska",
"tagalog" to "Tagalog",
"vietnamese" to "tiếng việt",
"turkish" to "Türkçe",
"greek" to "Ελληνικά",
"mongolian" to "Монгол",
"russian" to "Русский",
"ukrainian" to "Українська",
"hebrew" to "עברית",
"arabic" to "العربية",
"persian" to "فارسی",
"thai" to "ไทย",
"korean" to "한국어",
"chinese" to "中文",
"japanese" to "日本語"
)
fun transform(galleryBlock: GalleryBlock): SearchResult =
SearchResult(
galleryBlock.id.toString(),
galleryBlock.title,
galleryBlock.thumbnails.first(),
galleryBlock.artists.joinToString { it.wordCapitalize() },
mapOf(
ExtraType.GROUP to { getGallery(galleryBlock.id).groups.joinToString { it.wordCapitalize() } },
ExtraType.SERIES to { galleryBlock.series.joinToString { it.wordCapitalize() } },
ExtraType.TYPE to { galleryBlock.type.wordCapitalize() },
ExtraType.LANGUAGE to { languageMap[galleryBlock.language] ?: galleryBlock.language },
ExtraType.PAGECOUNT to { getGalleryInfo(galleryBlock.id).files.size.toString() }
),
galleryBlock.relatedTags
)
}
}

View File

@@ -0,0 +1,69 @@
/*
* Pupil, Hitomi.la viewer for Android
* Copyright (C) 2020 tom5079
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package xyz.quaver.pupil.sources.hitomi
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import xyz.quaver.hiyobi.*
import xyz.quaver.pupil.sources.SearchResult
import xyz.quaver.pupil.sources.Source
import xyz.quaver.pupil.util.wordCapitalize
class Hiyobi : Source<Enum<*>> {
override val querySortModeClass = null
override suspend fun query(query: String, range: IntRange, sortMode: Enum<*>?): Pair<Channel<SearchResult>, Int> {
val channel = Channel<SearchResult>()
val (results, total) = if (query.isEmpty())
list(range)
else
search(query, range)
CoroutineScope(Dispatchers.Unconfined).launch {
results.forEach {
channel.send(transform(it))
}
channel.close()
}
return Pair(channel, total)
}
companion object {
fun transform(galleryBlock: GalleryBlock): SearchResult =
SearchResult(
galleryBlock.id,
galleryBlock.title,
"https://cdn.$hiyobi/tn/${galleryBlock.id}.jpg",
galleryBlock.artists.joinToString { it.value.wordCapitalize() },
mapOf(
SearchResult.ExtraType.CHARACTER to { galleryBlock.characters.joinToString { it.value.wordCapitalize() } },
SearchResult.ExtraType.SERIES to { galleryBlock.parodys.joinToString { it.value.wordCapitalize() } },
SearchResult.ExtraType.TYPE to { galleryBlock.type.name.wordCapitalize() },
SearchResult.ExtraType.PAGECOUNT to { getGalleryInfo(galleryBlock.id).files.size.toString() }
),
galleryBlock.tags.map { it.value }
)
}
}