140 lines
5.2 KiB
Kotlin
140 lines
5.2 KiB
Kotlin
package suwayomi.anime.impl
|
|
|
|
/*
|
|
* Copyright (C) Contributors to the Suwayomi project
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
|
import eu.kanade.tachiyomi.network.GET
|
|
import org.jetbrains.exposed.sql.select
|
|
import org.jetbrains.exposed.sql.transactions.transaction
|
|
import org.jetbrains.exposed.sql.update
|
|
import org.kodein.di.DI
|
|
import org.kodein.di.conf.global
|
|
import org.kodein.di.instance
|
|
import suwayomi.anime.impl.AnimeList.proxyThumbnailUrl
|
|
import suwayomi.anime.impl.Source.getAnimeSource
|
|
import suwayomi.anime.impl.util.GetAnimeHttpSource.getAnimeHttpSource
|
|
import suwayomi.anime.model.dataclass.AnimeDataClass
|
|
import suwayomi.anime.model.table.AnimeStatus
|
|
import suwayomi.anime.model.table.AnimeTable
|
|
import suwayomi.server.ApplicationDirs
|
|
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
|
import suwayomi.tachidesk.impl.util.network.await
|
|
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.clearCachedImage
|
|
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
|
import java.io.InputStream
|
|
|
|
object Anime {
|
|
private fun truncate(text: String?, maxLength: Int): String? {
|
|
return if (text?.length ?: 0 > maxLength)
|
|
text?.take(maxLength - 3) + "..."
|
|
else
|
|
text
|
|
}
|
|
|
|
suspend fun getAnime(animeId: Int, onlineFetch: Boolean = false): AnimeDataClass {
|
|
var animeEntry = transaction { AnimeTable.select { AnimeTable.id eq animeId }.first() }
|
|
|
|
return if (animeEntry[AnimeTable.initialized] && !onlineFetch) {
|
|
AnimeDataClass(
|
|
animeId,
|
|
animeEntry[AnimeTable.sourceReference].toString(),
|
|
|
|
animeEntry[AnimeTable.url],
|
|
animeEntry[AnimeTable.title],
|
|
proxyThumbnailUrl(animeId),
|
|
|
|
true,
|
|
|
|
animeEntry[AnimeTable.artist],
|
|
animeEntry[AnimeTable.author],
|
|
animeEntry[AnimeTable.description],
|
|
animeEntry[AnimeTable.genre],
|
|
AnimeStatus.valueOf(animeEntry[AnimeTable.status]).name,
|
|
animeEntry[AnimeTable.inLibrary],
|
|
getAnimeSource(animeEntry[AnimeTable.sourceReference]),
|
|
false
|
|
)
|
|
} else { // initialize anime
|
|
val source = getAnimeHttpSource(animeEntry[AnimeTable.sourceReference])
|
|
val fetchedAnime = source.fetchAnimeDetails(
|
|
SAnime.create().apply {
|
|
url = animeEntry[AnimeTable.url]
|
|
title = animeEntry[AnimeTable.title]
|
|
}
|
|
).awaitSingle()
|
|
|
|
transaction {
|
|
AnimeTable.update({ AnimeTable.id eq animeId }) {
|
|
|
|
it[AnimeTable.initialized] = true
|
|
|
|
it[AnimeTable.artist] = fetchedAnime.artist
|
|
it[AnimeTable.author] = fetchedAnime.author
|
|
it[AnimeTable.description] = truncate(fetchedAnime.description, 4096)
|
|
it[AnimeTable.genre] = fetchedAnime.genre
|
|
it[AnimeTable.status] = fetchedAnime.status
|
|
if (fetchedAnime.thumbnail_url != null && fetchedAnime.thumbnail_url.orEmpty().isNotEmpty())
|
|
it[AnimeTable.thumbnail_url] = fetchedAnime.thumbnail_url
|
|
}
|
|
}
|
|
|
|
clearAnimeThumbnail(animeId)
|
|
|
|
animeEntry = transaction { AnimeTable.select { AnimeTable.id eq animeId }.first() }
|
|
|
|
AnimeDataClass(
|
|
animeId,
|
|
animeEntry[AnimeTable.sourceReference].toString(),
|
|
|
|
animeEntry[AnimeTable.url],
|
|
animeEntry[AnimeTable.title],
|
|
proxyThumbnailUrl(animeId),
|
|
|
|
true,
|
|
|
|
fetchedAnime.artist,
|
|
fetchedAnime.author,
|
|
fetchedAnime.description,
|
|
fetchedAnime.genre,
|
|
AnimeStatus.valueOf(fetchedAnime.status).name,
|
|
animeEntry[AnimeTable.inLibrary],
|
|
getAnimeSource(animeEntry[AnimeTable.sourceReference]),
|
|
true
|
|
)
|
|
}
|
|
}
|
|
|
|
private val applicationDirs by DI.global.instance<ApplicationDirs>()
|
|
suspend fun getAnimeThumbnail(animeId: Int): Pair<InputStream, String> {
|
|
val saveDir = applicationDirs.animeThumbnailsRoot
|
|
val fileName = animeId.toString()
|
|
|
|
return getCachedImageResponse(saveDir, fileName) {
|
|
getAnime(animeId) // make sure is initialized
|
|
|
|
val animeEntry = transaction { AnimeTable.select { AnimeTable.id eq animeId }.first() }
|
|
|
|
val sourceId = animeEntry[AnimeTable.sourceReference]
|
|
val source = getAnimeHttpSource(sourceId)
|
|
|
|
val thumbnailUrl = animeEntry[AnimeTable.thumbnail_url]!!
|
|
|
|
source.client.newCall(
|
|
GET(thumbnailUrl, source.headers)
|
|
).await()
|
|
}
|
|
}
|
|
|
|
private fun clearAnimeThumbnail(animeId: Int) {
|
|
val saveDir = applicationDirs.animeThumbnailsRoot
|
|
val fileName = animeId.toString()
|
|
|
|
clearCachedImage(saveDir, fileName)
|
|
}
|
|
}
|