first working version of anime downloads

This commit is contained in:
Finnley Somdahl 2023-12-30 05:12:46 -06:00
parent 41830dba4d
commit d16fbd9a43
19 changed files with 402 additions and 156 deletions

View file

@ -12,11 +12,17 @@ object AnimeSources : WatchSources() {
suspend fun init(fromExtensions: StateFlow<List<AnimeExtension.Installed>>) {
// Initialize with the first value from StateFlow
val initialExtensions = fromExtensions.first()
list = createParsersFromExtensions(initialExtensions)
list = createParsersFromExtensions(initialExtensions) + Lazier(
{ OfflineAnimeParser() },
"Downloaded"
)
// Update as StateFlow emits new values
fromExtensions.collect { extensions ->
list = createParsersFromExtensions(extensions)
list = createParsersFromExtensions(extensions) + Lazier(
{ OfflineAnimeParser() },
"Downloaded"
)
}
}

View file

@ -616,17 +616,18 @@ class VideoServerPassthrough(val videoServer: VideoServer) : VideoExtractor() {
val fileName = queryPairs.find { it.first == "file" }?.second ?: ""
format = getVideoType(fileName)
if (format == null) {
val networkHelper = Injekt.get<NetworkHelper>()
format = headRequest(videoUrl, networkHelper)
}
// this solves a problem no one has, so I'm commenting it out for now
//if (format == null) {
// val networkHelper = Injekt.get<NetworkHelper>()
// format = headRequest(videoUrl, networkHelper)
//}
}
// If the format is still undetermined, log an error or handle it appropriately
// If the format is still undetermined, log an error
if (format == null) {
logger("Unknown video format: $videoUrl")
FirebaseCrashlytics.getInstance()
.recordException(Exception("Unknown video format: $videoUrl"))
//FirebaseCrashlytics.getInstance()
// .recordException(Exception("Unknown video format: $videoUrl"))
format = VideoType.CONTAINER
}
val headersMap: Map<String, String> =

View file

@ -46,6 +46,19 @@ abstract class WatchSources : BaseSources() {
sEpisode = it.sEpisode
)
}
} else if (parser is OfflineAnimeParser) {
parser.loadEpisodes(showLink, extra, SAnime.create()).forEach {
map[it.number] = Episode(
it.number,
it.link,
it.title,
it.description,
it.thumbnail,
it.isFiller,
extra = it.extra,
sEpisode = it.sEpisode
)
}
}
}
return map

View file

@ -7,9 +7,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
object MangaSources : MangaReadSources() {
// Instantiate the static parser
private val offlineMangaParser by lazy { OfflineMangaParser() }
override var list: List<Lazier<BaseParser>> = emptyList()
suspend fun init(fromExtensions: StateFlow<List<MangaExtension.Installed>>) {

View file

@ -0,0 +1,106 @@
package ani.dantotsu.parsers
import android.os.Environment
import ani.dantotsu.currContext
import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.logger
import ani.dantotsu.media.anime.AnimeNameAdapter
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
class OfflineAnimeParser : AnimeParser() {
private val downloadManager = Injekt.get<DownloadsManager>()
override val name = "Offline"
override val saveName = "Offline"
override val hostUrl = "Offline"
override val isDubAvailableSeparately = false
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 {
if (it.isDirectory) {
val episode = Episode(
it.name,
"$animeLink - ${it.name}",
it.name,
null,
null,
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
)
)
}
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 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 = emptyList<Subtitle>()
//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)
}
}

View file

@ -76,7 +76,7 @@ class OfflineMangaParser : MangaParser() {
}
override suspend fun search(query: String): List<ShowResponse> {
val titles = downloadManager.mangaDownloads.map { it.title }.distinct()
val titles = downloadManager.mangaDownloadedTypes.map { it.title }.distinct()
val returnTitles: MutableList<String> = mutableListOf()
for (title in titles) {
if (FuzzySearch.ratio(title.lowercase(), query.lowercase()) > 80) {

View file

@ -3,10 +3,7 @@ package ani.dantotsu.parsers
import android.os.Environment
import ani.dantotsu.currContext
import ani.dantotsu.download.DownloadsManager
import ani.dantotsu.logger
import ani.dantotsu.media.manga.MangaNameAdapter
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import me.xdrop.fuzzywuzzy.FuzzySearch
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -53,7 +50,7 @@ class OfflineNovelParser: NovelParser() {
}
override suspend fun search(query: String): List<ShowResponse> {
val titles = downloadManager.novelDownloads.map { it.title }.distinct()
val titles = downloadManager.novelDownloadedTypes.map { it.title }.distinct()
val returnTitles: MutableList<String> = mutableListOf()
for (title in titles) {
if (FuzzySearch.ratio(title.lowercase(), query.lowercase()) > 80) {

View file

@ -57,11 +57,15 @@ data class VideoServer(
val name: String,
val embed: FileUrl,
val extraData: Map<String, String>? = null,
val video: eu.kanade.tachiyomi.animesource.model.Video? = null
val video: eu.kanade.tachiyomi.animesource.model.Video? = null,
val offline: Boolean = false
) : Serializable {
constructor(name: String, embedUrl: String, extraData: Map<String, String>? = null)
: this(name, FileUrl(embedUrl), extraData)
constructor(name: String, offline: Boolean)
: this(name, FileUrl(""), null, null, offline)
constructor(
name: String,
embedUrl: String,