160 lines
No EOL
5.2 KiB
Kotlin
160 lines
No EOL
5.2 KiB
Kotlin
package ani.dantotsu.parsers
|
|
|
|
import android.net.Uri
|
|
import android.os.Environment
|
|
import ani.dantotsu.currContext
|
|
import ani.dantotsu.download.DownloadsManager
|
|
import ani.dantotsu.media.anime.AnimeNameAdapter
|
|
import ani.dantotsu.tryWithSuspend
|
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
|
import eu.kanade.tachiyomi.animesource.model.SEpisodeImpl
|
|
import me.xdrop.fuzzywuzzy.FuzzySearch
|
|
import uy.kohesive.injekt.Injekt
|
|
import uy.kohesive.injekt.api.get
|
|
import java.io.File
|
|
import java.util.Locale
|
|
|
|
class OfflineAnimeParser : AnimeParser() {
|
|
private val downloadManager = Injekt.get<DownloadsManager>()
|
|
|
|
override val name = "Offline"
|
|
override val saveName = "Offline"
|
|
override val hostUrl = "Offline"
|
|
override val isNSFW = false
|
|
|
|
override suspend fun loadEpisodes(
|
|
animeLink: String,
|
|
extra: Map<String, String>?,
|
|
sAnime: SAnime
|
|
): List<Episode> {
|
|
val directory = File(
|
|
currContext()?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"${DownloadsManager.animeLocation}/$animeLink"
|
|
)
|
|
//get all of the folder names and add them to the list
|
|
val episodes = mutableListOf<Episode>()
|
|
if (directory.exists()) {
|
|
directory.listFiles()?.forEach {
|
|
//put the title and episdode number in the extra data
|
|
val extraData = mutableMapOf<String, String>()
|
|
extraData["title"] = animeLink
|
|
extraData["episode"] = it.name
|
|
if (it.isDirectory) {
|
|
val episode = Episode(
|
|
it.name,
|
|
"$animeLink - ${it.name}",
|
|
it.name,
|
|
null,
|
|
null,
|
|
extra = extraData,
|
|
sEpisode = SEpisodeImpl()
|
|
)
|
|
episodes.add(episode)
|
|
}
|
|
}
|
|
episodes.sortBy { AnimeNameAdapter.findEpisodeNumber(it.number) }
|
|
return episodes
|
|
}
|
|
return emptyList()
|
|
}
|
|
|
|
override suspend fun loadVideoServers(
|
|
episodeLink: String,
|
|
extra: Map<String, String>?,
|
|
sEpisode: SEpisode
|
|
): List<VideoServer> {
|
|
return listOf(
|
|
VideoServer(
|
|
episodeLink,
|
|
offline = true,
|
|
extraData = extra
|
|
)
|
|
)
|
|
}
|
|
|
|
|
|
override suspend fun search(query: String): List<ShowResponse> {
|
|
val titles = downloadManager.animeDownloadedTypes.map { it.title }.distinct()
|
|
val returnTitles: MutableList<String> = mutableListOf()
|
|
for (title in titles) {
|
|
if (FuzzySearch.ratio(title.lowercase(), query.lowercase()) > 80) {
|
|
returnTitles.add(title)
|
|
}
|
|
}
|
|
val returnList: MutableList<ShowResponse> = mutableListOf()
|
|
for (title in returnTitles) {
|
|
returnList.add(ShowResponse(title, title, title))
|
|
}
|
|
return returnList
|
|
}
|
|
|
|
override suspend fun loadByVideoServers(
|
|
episodeUrl: String,
|
|
extra: Map<String, String>?,
|
|
sEpisode: SEpisode,
|
|
callback: (VideoExtractor) -> Unit
|
|
) {
|
|
val server = loadVideoServers(episodeUrl, extra, sEpisode).first()
|
|
OfflineVideoExtractor(server).apply {
|
|
tryWithSuspend {
|
|
load()
|
|
}
|
|
callback.invoke(this)
|
|
}
|
|
}
|
|
|
|
override suspend fun getVideoExtractor(server: VideoServer): VideoExtractor {
|
|
return OfflineVideoExtractor(server)
|
|
}
|
|
|
|
}
|
|
|
|
class OfflineVideoExtractor(val videoServer: VideoServer) : VideoExtractor() {
|
|
override val server: VideoServer
|
|
get() = videoServer
|
|
|
|
override suspend fun extract(): VideoContainer {
|
|
val sublist = getSubtitle(
|
|
videoServer.extraData?.get("title") ?: "",
|
|
videoServer.extraData?.get("episode") ?: ""
|
|
) ?: emptyList()
|
|
//we need to return a "fake" video so that the app doesn't crash
|
|
val video = Video(
|
|
null,
|
|
VideoType.CONTAINER,
|
|
"",
|
|
)
|
|
return VideoContainer(listOf(video), sublist)
|
|
}
|
|
|
|
private fun getSubtitle(title: String, episode: String): List<Subtitle>? {
|
|
currContext()?.let {
|
|
DownloadsManager.getDirectory(
|
|
it,
|
|
ani.dantotsu.download.DownloadedType.Type.ANIME,
|
|
title,
|
|
episode
|
|
).listFiles()?.forEach {
|
|
if (it.name.contains("subtitle")) {
|
|
return listOf(
|
|
Subtitle(
|
|
"Downloaded Subtitle",
|
|
Uri.fromFile(it).toString(),
|
|
determineSubtitletype(it.absolutePath)
|
|
)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
fun determineSubtitletype(url: String): SubtitleType {
|
|
return when {
|
|
url.lowercase(Locale.ROOT).endsWith("ass") -> SubtitleType.ASS
|
|
url.lowercase(Locale.ROOT).endsWith("vtt") -> SubtitleType.VTT
|
|
else -> SubtitleType.SRT
|
|
}
|
|
}
|
|
} |