mirror of
https://github.com/rebelonion/Dantotsu.git
synced 2026-01-28 03:41:01 +00:00
384 lines
16 KiB
Kotlin
384 lines
16 KiB
Kotlin
package ani.dantotsu.download
|
|
|
|
import android.content.Context
|
|
import android.net.Uri
|
|
import android.os.Environment
|
|
import android.widget.Toast
|
|
import ani.dantotsu.R
|
|
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
|
|
import ani.dantotsu.currActivity
|
|
import ani.dantotsu.currContext
|
|
import ani.dantotsu.download.anime.OfflineAnimeModel
|
|
import ani.dantotsu.download.manga.OfflineMangaModel
|
|
import ani.dantotsu.media.Media
|
|
import ani.dantotsu.media.MediaNameAdapter
|
|
import ani.dantotsu.media.MediaType
|
|
import ani.dantotsu.parsers.Episode
|
|
import ani.dantotsu.parsers.MangaChapter
|
|
import ani.dantotsu.parsers.MangaImage
|
|
import ani.dantotsu.parsers.Subtitle
|
|
import ani.dantotsu.parsers.SubtitleType
|
|
import ani.dantotsu.util.Logger
|
|
import com.google.gson.GsonBuilder
|
|
import com.google.gson.InstanceCreator
|
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
|
import eu.kanade.tachiyomi.animesource.model.SAnimeImpl
|
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
|
import eu.kanade.tachiyomi.animesource.model.SEpisodeImpl
|
|
import eu.kanade.tachiyomi.source.model.SChapter
|
|
import eu.kanade.tachiyomi.source.model.SChapterImpl
|
|
import eu.kanade.tachiyomi.source.model.SManga
|
|
import uy.kohesive.injekt.Injekt
|
|
import uy.kohesive.injekt.api.get
|
|
import java.io.File
|
|
import java.util.Locale
|
|
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
class DownloadCompat {
|
|
companion object {
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
fun loadMediaCompat(downloadedType: DownloadedType): Media? {
|
|
val type = when (downloadedType.type) {
|
|
MediaType.MANGA -> "Manga"
|
|
MediaType.ANIME -> "Anime"
|
|
else -> "Novel"
|
|
}
|
|
val directory = File(
|
|
currContext()?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"Dantotsu/$type/${downloadedType.titleName}"
|
|
)
|
|
//load media.json and convert to media class with gson
|
|
return try {
|
|
val gson = GsonBuilder()
|
|
.registerTypeAdapter(SChapter::class.java, InstanceCreator<SChapter> {
|
|
SChapterImpl() // Provide an instance of SChapterImpl
|
|
})
|
|
.registerTypeAdapter(SAnime::class.java, InstanceCreator<SAnime> {
|
|
SAnimeImpl() // Provide an instance of SAnimeImpl
|
|
})
|
|
.registerTypeAdapter(SEpisode::class.java, InstanceCreator<SEpisode> {
|
|
SEpisodeImpl() // Provide an instance of SEpisodeImpl
|
|
})
|
|
.create()
|
|
val media = File(directory, "media.json")
|
|
val mediaJson = media.readText()
|
|
gson.fromJson(mediaJson, Media::class.java)
|
|
} catch (e: Exception) {
|
|
Logger.log("Error loading media.json: ${e.message}")
|
|
Logger.log(e)
|
|
Injekt.get<CrashlyticsInterface>().logException(e)
|
|
null
|
|
}
|
|
}
|
|
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
fun loadOfflineAnimeModelCompat(downloadedType: DownloadedType): OfflineAnimeModel {
|
|
val type = when (downloadedType.type) {
|
|
MediaType.MANGA -> "Manga"
|
|
MediaType.ANIME -> "Anime"
|
|
else -> "Novel"
|
|
}
|
|
val directory = File(
|
|
currContext()?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"Dantotsu/$type/${downloadedType.titleName}"
|
|
)
|
|
//load media.json and convert to media class with gson
|
|
try {
|
|
val mediaModel = loadMediaCompat(downloadedType)!!
|
|
val cover = File(directory, "cover.jpg")
|
|
val coverUri: Uri? = if (cover.exists()) {
|
|
Uri.fromFile(cover)
|
|
} else null
|
|
val banner = File(directory, "banner.jpg")
|
|
val bannerUri: Uri? = if (banner.exists()) {
|
|
Uri.fromFile(banner)
|
|
} else null
|
|
val title = mediaModel.mainName()
|
|
val score = ((if (mediaModel.userScore == 0) (mediaModel.meanScore
|
|
?: 0) else mediaModel.userScore) / 10.0).toString()
|
|
val isOngoing =
|
|
mediaModel.status == currActivity()!!.getString(R.string.status_releasing)
|
|
val isUserScored = mediaModel.userScore != 0
|
|
val watchedEpisodes = (mediaModel.userProgress ?: "~").toString()
|
|
val totalEpisode =
|
|
if (mediaModel.anime?.nextAiringEpisode != null) (mediaModel.anime.nextAiringEpisode.toString() + " | " + (mediaModel.anime.totalEpisodes
|
|
?: "~").toString()) else (mediaModel.anime?.totalEpisodes ?: "~").toString()
|
|
val chapters = " Chapters"
|
|
val totalEpisodesList =
|
|
if (mediaModel.anime?.nextAiringEpisode != null) (mediaModel.anime.nextAiringEpisode.toString()) else (mediaModel.anime?.totalEpisodes
|
|
?: "~").toString()
|
|
return OfflineAnimeModel(
|
|
title,
|
|
score,
|
|
totalEpisode,
|
|
totalEpisodesList,
|
|
watchedEpisodes,
|
|
type,
|
|
chapters,
|
|
isOngoing,
|
|
isUserScored,
|
|
coverUri,
|
|
bannerUri
|
|
)
|
|
} catch (e: Exception) {
|
|
Logger.log("Error loading media.json: ${e.message}")
|
|
Logger.log(e)
|
|
Injekt.get<CrashlyticsInterface>().logException(e)
|
|
return OfflineAnimeModel(
|
|
downloadedType.titleName,
|
|
"0",
|
|
"??",
|
|
"??",
|
|
"??",
|
|
"movie",
|
|
"hmm",
|
|
isOngoing = false,
|
|
isUserScored = false,
|
|
null,
|
|
null
|
|
)
|
|
}
|
|
}
|
|
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
fun loadOfflineMangaModelCompat(downloadedType: DownloadedType): OfflineMangaModel {
|
|
val type = when (downloadedType.type) {
|
|
MediaType.MANGA -> "Manga"
|
|
MediaType.ANIME -> "Anime"
|
|
else -> "Novel"
|
|
}
|
|
val directory = File(
|
|
currContext()?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"Dantotsu/$type/${downloadedType.titleName}"
|
|
)
|
|
//load media.json and convert to media class with gson
|
|
try {
|
|
val mediaModel = loadMediaCompat(downloadedType)!!
|
|
val cover = File(directory, "cover.jpg")
|
|
val coverUri: Uri? = if (cover.exists()) {
|
|
Uri.fromFile(cover)
|
|
} else null
|
|
val banner = File(directory, "banner.jpg")
|
|
val bannerUri: Uri? = if (banner.exists()) {
|
|
Uri.fromFile(banner)
|
|
} else null
|
|
val title = mediaModel.mainName()
|
|
val score = ((if (mediaModel.userScore == 0) (mediaModel.meanScore
|
|
?: 0) else mediaModel.userScore) / 10.0).toString()
|
|
val isOngoing =
|
|
mediaModel.status == currActivity()!!.getString(R.string.status_releasing)
|
|
val isUserScored = mediaModel.userScore != 0
|
|
val readchapter = (mediaModel.userProgress ?: "~").toString()
|
|
val totalchapter = "${mediaModel.manga?.totalChapters ?: "??"}"
|
|
val chapters = " Chapters"
|
|
return OfflineMangaModel(
|
|
title,
|
|
score,
|
|
totalchapter,
|
|
readchapter,
|
|
type,
|
|
chapters,
|
|
isOngoing,
|
|
isUserScored,
|
|
coverUri,
|
|
bannerUri
|
|
)
|
|
} catch (e: Exception) {
|
|
Logger.log("Error loading media.json: ${e.message}")
|
|
Logger.log(e)
|
|
Injekt.get<CrashlyticsInterface>().logException(e)
|
|
return OfflineMangaModel(
|
|
downloadedType.titleName,
|
|
"0",
|
|
"??",
|
|
"??",
|
|
"movie",
|
|
"hmm",
|
|
isOngoing = false,
|
|
isUserScored = false,
|
|
null,
|
|
null
|
|
)
|
|
}
|
|
}
|
|
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
suspend fun loadEpisodesCompat(
|
|
animeLink: String,
|
|
extra: Map<String, String>?,
|
|
sAnime: SAnime
|
|
): List<Episode> {
|
|
|
|
val directory = File(
|
|
currContext()?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"${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 { MediaNameAdapter.findEpisodeNumber(it.number) }
|
|
return episodes
|
|
}
|
|
return emptyList()
|
|
}
|
|
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
suspend fun loadChaptersCompat(
|
|
mangaLink: String,
|
|
extra: Map<String, String>?,
|
|
sManga: SManga
|
|
): List<MangaChapter> {
|
|
val directory = File(
|
|
currContext()?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"Dantotsu/Manga/$mangaLink"
|
|
)
|
|
//get all of the folder names and add them to the list
|
|
val chapters = mutableListOf<MangaChapter>()
|
|
if (directory.exists()) {
|
|
directory.listFiles()?.forEach {
|
|
if (it.isDirectory) {
|
|
val chapter = MangaChapter(
|
|
it.name,
|
|
"$mangaLink/${it.name}",
|
|
it.name,
|
|
null,
|
|
"Unknown",
|
|
SChapter.create()
|
|
)
|
|
chapters.add(chapter)
|
|
}
|
|
}
|
|
chapters.sortBy { MediaNameAdapter.findChapterNumber(it.number) }
|
|
return chapters
|
|
}
|
|
return emptyList()
|
|
}
|
|
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
suspend fun loadImagesCompat(chapterLink: String, sChapter: SChapter): List<MangaImage> {
|
|
val directory = File(
|
|
currContext()?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"Dantotsu/Manga/$chapterLink"
|
|
)
|
|
val images = mutableListOf<MangaImage>()
|
|
val imageNumberRegex = Regex("""(\d+)\.jpg$""")
|
|
if (directory.exists()) {
|
|
directory.listFiles()?.forEach {
|
|
if (it.isFile) {
|
|
val image = MangaImage(it.absolutePath, false, null)
|
|
images.add(image)
|
|
}
|
|
}
|
|
images.sortBy { image ->
|
|
val matchResult = imageNumberRegex.find(image.url.url)
|
|
matchResult?.groups?.get(1)?.value?.toIntOrNull() ?: Int.MAX_VALUE
|
|
}
|
|
for (image in images) {
|
|
Logger.log("imageNumber: ${image.url.url}")
|
|
}
|
|
return images
|
|
}
|
|
return emptyList()
|
|
}
|
|
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
fun loadSubtitleCompat(title: String, episode: String): List<Subtitle>? {
|
|
currContext()?.let {
|
|
File(
|
|
it.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"$animeLocation/$title/$episode"
|
|
).listFiles()?.forEach {
|
|
if (it.name.contains("subtitle")) {
|
|
return listOf(
|
|
Subtitle(
|
|
"Downloaded Subtitle",
|
|
Uri.fromFile(it).toString(),
|
|
determineSubtitletype(it.absolutePath)
|
|
)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
private 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
|
|
}
|
|
}
|
|
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
fun removeMediaCompat(context: Context, title: String, type: MediaType) {
|
|
val subDirectory = if (type == MediaType.MANGA) {
|
|
"Manga"
|
|
} else if (type == MediaType.ANIME) {
|
|
"Anime"
|
|
} else {
|
|
"Novel"
|
|
}
|
|
val directory = File(
|
|
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"Dantotsu/$subDirectory/$title"
|
|
)
|
|
if (directory.exists()) {
|
|
directory.deleteRecursively()
|
|
}
|
|
}
|
|
|
|
@Deprecated("external storage is deprecated, use SAF instead")
|
|
fun removeDownloadCompat(context: Context, downloadedType: DownloadedType, toast: Boolean) {
|
|
val directory = if (downloadedType.type == MediaType.MANGA) {
|
|
File(
|
|
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"Dantotsu/Manga/${downloadedType.titleName}/${downloadedType.chapterName}"
|
|
)
|
|
} else if (downloadedType.type == MediaType.ANIME) {
|
|
File(
|
|
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"Dantotsu/Anime/${downloadedType.titleName}/${downloadedType.chapterName}"
|
|
)
|
|
} else {
|
|
File(
|
|
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
|
|
"Dantotsu/Novel/${downloadedType.titleName}/${downloadedType.chapterName}"
|
|
)
|
|
}
|
|
|
|
// Check if the directory exists and delete it recursively
|
|
if (directory.exists()) {
|
|
val deleted = directory.deleteRecursively()
|
|
if (toast) {
|
|
if (deleted) {
|
|
Toast.makeText(context, "Successfully deleted", Toast.LENGTH_SHORT).show()
|
|
} else {
|
|
Toast.makeText(context, "Failed to delete directory", Toast.LENGTH_SHORT)
|
|
.show()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private val animeLocation = "Dantotsu/Anime"
|
|
}
|
|
} |