fix: some download optimizations
This commit is contained in:
parent
b30047804a
commit
5800dcf3e7
6 changed files with 107 additions and 63 deletions
|
@ -125,7 +125,7 @@ class DownloadCompat {
|
||||||
Logger.log(e)
|
Logger.log(e)
|
||||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||||
return OfflineAnimeModel(
|
return OfflineAnimeModel(
|
||||||
"unknown",
|
downloadedType.titleName,
|
||||||
"0",
|
"0",
|
||||||
"??",
|
"??",
|
||||||
"??",
|
"??",
|
||||||
|
@ -188,7 +188,7 @@ class DownloadCompat {
|
||||||
Logger.log(e)
|
Logger.log(e)
|
||||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||||
return OfflineMangaModel(
|
return OfflineMangaModel(
|
||||||
"unknown",
|
downloadedType.titleName,
|
||||||
"0",
|
"0",
|
||||||
"??",
|
"??",
|
||||||
"??",
|
"??",
|
||||||
|
|
|
@ -181,7 +181,6 @@ class AnimeDownloaderService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateNotification() {
|
private fun updateNotification() {
|
||||||
// Update the notification to reflect the current state of the queue
|
|
||||||
val pendingDownloads = AnimeServiceDataSingleton.downloadQueue.size
|
val pendingDownloads = AnimeServiceDataSingleton.downloadQueue.size
|
||||||
val text = if (pendingDownloads > 0) {
|
val text = if (pendingDownloads > 0) {
|
||||||
"Pending downloads: $pendingDownloads"
|
"Pending downloads: $pendingDownloads"
|
||||||
|
@ -201,7 +200,7 @@ class AnimeDownloaderService : Service() {
|
||||||
|
|
||||||
@androidx.annotation.OptIn(UnstableApi::class)
|
@androidx.annotation.OptIn(UnstableApi::class)
|
||||||
suspend fun download(task: AnimeDownloadTask) {
|
suspend fun download(task: AnimeDownloadTask) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val notifi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
val notifi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
ContextCompat.checkSelfPermission(
|
ContextCompat.checkSelfPermission(
|
||||||
|
@ -214,13 +213,21 @@ class AnimeDownloaderService : Service() {
|
||||||
|
|
||||||
builder.setContentText("Downloading ${getTaskName(task.title, task.episode)}")
|
builder.setContentText("Downloading ${getTaskName(task.title, task.episode)}")
|
||||||
if (notifi) {
|
if (notifi) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val outputDir = getSubDirectory(
|
val baseOutputDir = getSubDirectory(
|
||||||
this@AnimeDownloaderService,
|
this@AnimeDownloaderService,
|
||||||
MediaType.ANIME,
|
MediaType.ANIME,
|
||||||
false,
|
false,
|
||||||
|
task.title
|
||||||
|
) ?: throw Exception("Failed to create output directory")
|
||||||
|
val outputDir = getSubDirectory(
|
||||||
|
this@AnimeDownloaderService,
|
||||||
|
MediaType.ANIME,
|
||||||
|
true,
|
||||||
task.title,
|
task.title,
|
||||||
task.episode
|
task.episode
|
||||||
) ?: throw Exception("Failed to create output directory")
|
) ?: throw Exception("Failed to create output directory")
|
||||||
|
@ -277,7 +284,7 @@ class AnimeDownloaderService : Service() {
|
||||||
currentTasks.find { it.getTaskName() == task.getTaskName() }?.sessionId =
|
currentTasks.find { it.getTaskName() == task.getTaskName() }?.sessionId =
|
||||||
ffTask
|
ffTask
|
||||||
|
|
||||||
saveMediaInfo(task)
|
saveMediaInfo(task, baseOutputDir)
|
||||||
|
|
||||||
// periodically check if the download is complete
|
// periodically check if the download is complete
|
||||||
while (ffExtension.getState(ffTask) != "COMPLETED") {
|
while (ffExtension.getState(ffTask) != "COMPLETED") {
|
||||||
|
@ -291,7 +298,11 @@ class AnimeDownloaderService : Service() {
|
||||||
)
|
)
|
||||||
} Download failed"
|
} Download failed"
|
||||||
)
|
)
|
||||||
|
if (notifi) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
toast("${getTaskName(task.title, task.episode)} Download failed")
|
toast("${getTaskName(task.title, task.episode)} Download failed")
|
||||||
Logger.log("Download failed: ${ffExtension.getStackTrace(ffTask)}")
|
Logger.log("Download failed: ${ffExtension.getStackTrace(ffTask)}")
|
||||||
downloadsManager.removeDownload(
|
downloadsManager.removeDownload(
|
||||||
|
@ -324,8 +335,10 @@ class AnimeDownloaderService : Service() {
|
||||||
percent.coerceAtMost(99)
|
percent.coerceAtMost(99)
|
||||||
)
|
)
|
||||||
if (notifi) {
|
if (notifi) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
kotlinx.coroutines.delay(2000)
|
kotlinx.coroutines.delay(2000)
|
||||||
}
|
}
|
||||||
if (ffExtension.getState(ffTask) == "COMPLETED") {
|
if (ffExtension.getState(ffTask) == "COMPLETED") {
|
||||||
|
@ -339,7 +352,11 @@ class AnimeDownloaderService : Service() {
|
||||||
)
|
)
|
||||||
} Download failed"
|
} Download failed"
|
||||||
)
|
)
|
||||||
|
if (notifi) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
snackString("${getTaskName(task.title, task.episode)} Download failed")
|
snackString("${getTaskName(task.title, task.episode)} Download failed")
|
||||||
downloadsManager.removeDownload(
|
downloadsManager.removeDownload(
|
||||||
DownloadedType(
|
DownloadedType(
|
||||||
|
@ -371,7 +388,11 @@ class AnimeDownloaderService : Service() {
|
||||||
)
|
)
|
||||||
} Download completed"
|
} Download completed"
|
||||||
)
|
)
|
||||||
|
if (notifi) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
snackString("${getTaskName(task.title, task.episode)} Download completed")
|
snackString("${getTaskName(task.title, task.episode)} Download completed")
|
||||||
PrefManager.getAnimeDownloadPreferences().edit().putString(
|
PrefManager.getAnimeDownloadPreferences().edit().putString(
|
||||||
task.getTaskName(),
|
task.getTaskName(),
|
||||||
|
@ -401,11 +422,8 @@ class AnimeDownloaderService : Service() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveMediaInfo(task: AnimeDownloadTask) {
|
private fun saveMediaInfo(task: AnimeDownloadTask, directory: DocumentFile) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val directory =
|
|
||||||
getSubDirectory(this@AnimeDownloaderService, MediaType.ANIME, false, task.title)
|
|
||||||
?: throw Exception("Directory not found")
|
|
||||||
directory.findFile("media.json")?.forceDelete(this@AnimeDownloaderService)
|
directory.findFile("media.json")?.forceDelete(this@AnimeDownloaderService)
|
||||||
val file = directory.createFile("application/json", "media.json")
|
val file = directory.createFile("application/json", "media.json")
|
||||||
?: throw Exception("File not created")
|
?: throw Exception("File not created")
|
||||||
|
|
|
@ -30,6 +30,7 @@ import ani.dantotsu.bottomBar
|
||||||
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
|
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
|
||||||
import ani.dantotsu.currActivity
|
import ani.dantotsu.currActivity
|
||||||
import ani.dantotsu.currContext
|
import ani.dantotsu.currContext
|
||||||
|
import ani.dantotsu.download.DownloadCompat
|
||||||
import ani.dantotsu.download.DownloadCompat.Companion.loadMediaCompat
|
import ani.dantotsu.download.DownloadCompat.Companion.loadMediaCompat
|
||||||
import ani.dantotsu.download.DownloadCompat.Companion.loadOfflineAnimeModelCompat
|
import ani.dantotsu.download.DownloadCompat.Companion.loadOfflineAnimeModelCompat
|
||||||
import ani.dantotsu.download.DownloadedType
|
import ani.dantotsu.download.DownloadedType
|
||||||
|
@ -319,17 +320,20 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener {
|
||||||
)
|
)
|
||||||
val gson = GsonBuilder()
|
val gson = GsonBuilder()
|
||||||
.registerTypeAdapter(SChapter::class.java, InstanceCreator<SChapter> {
|
.registerTypeAdapter(SChapter::class.java, InstanceCreator<SChapter> {
|
||||||
SChapterImpl() // Provide an instance of SChapterImpl
|
SChapterImpl()
|
||||||
})
|
})
|
||||||
.registerTypeAdapter(SAnime::class.java, InstanceCreator<SAnime> {
|
.registerTypeAdapter(SAnime::class.java, InstanceCreator<SAnime> {
|
||||||
SAnimeImpl() // Provide an instance of SAnimeImpl
|
SAnimeImpl()
|
||||||
})
|
})
|
||||||
.registerTypeAdapter(SEpisode::class.java, InstanceCreator<SEpisode> {
|
.registerTypeAdapter(SEpisode::class.java, InstanceCreator<SEpisode> {
|
||||||
SEpisodeImpl() // Provide an instance of SEpisodeImpl
|
SEpisodeImpl()
|
||||||
})
|
})
|
||||||
.create()
|
.create()
|
||||||
val media = directory?.findFile("media.json")
|
val media = directory?.findFile("media.json")
|
||||||
?: return loadMediaCompat(downloadedType)
|
if (media == null) {
|
||||||
|
Logger.log("No media.json found at ${directory?.uri?.path}")
|
||||||
|
return loadMediaCompat(downloadedType)
|
||||||
|
}
|
||||||
val mediaJson =
|
val mediaJson =
|
||||||
media.openInputStream(context ?: currContext()!!)?.bufferedReader().use {
|
media.openInputStream(context ?: currContext()!!)?.bufferedReader().use {
|
||||||
it?.readText()
|
it?.readText()
|
||||||
|
@ -394,6 +398,7 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener {
|
||||||
bannerUri
|
bannerUri
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Logger.log(e)
|
||||||
return try {
|
return try {
|
||||||
loadOfflineAnimeModelCompat(downloadedType)
|
loadOfflineAnimeModelCompat(downloadedType)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -401,7 +406,7 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener {
|
||||||
Logger.log(e)
|
Logger.log(e)
|
||||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||||
OfflineAnimeModel(
|
OfflineAnimeModel(
|
||||||
"unknown",
|
downloadedType.titleName,
|
||||||
"0",
|
"0",
|
||||||
"??",
|
"??",
|
||||||
"??",
|
"??",
|
||||||
|
|
|
@ -134,15 +134,15 @@ class MangaDownloaderService : Service() {
|
||||||
mutex.withLock {
|
mutex.withLock {
|
||||||
downloadJobs[task.chapter] = job
|
downloadJobs[task.chapter] = job
|
||||||
}
|
}
|
||||||
job.join() // Wait for the job to complete before continuing to the next task
|
job.join()
|
||||||
mutex.withLock {
|
mutex.withLock {
|
||||||
downloadJobs.remove(task.chapter)
|
downloadJobs.remove(task.chapter)
|
||||||
}
|
}
|
||||||
updateNotification() // Update the notification after each task is completed
|
updateNotification()
|
||||||
}
|
}
|
||||||
if (MangaServiceDataSingleton.downloadQueue.isEmpty()) {
|
if (MangaServiceDataSingleton.downloadQueue.isEmpty()) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
stopSelf() // Stop the service when the queue is empty
|
stopSelf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ class MangaDownloaderService : Service() {
|
||||||
|
|
||||||
suspend fun download(task: DownloadTask) {
|
suspend fun download(task: DownloadTask) {
|
||||||
try {
|
try {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.IO) {
|
||||||
val notifi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
val notifi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
ContextCompat.checkSelfPermission(
|
ContextCompat.checkSelfPermission(
|
||||||
this@MangaDownloaderService,
|
this@MangaDownloaderService,
|
||||||
|
@ -194,18 +194,27 @@ class MangaDownloaderService : Service() {
|
||||||
val deferredMap = mutableMapOf<Int, Deferred<Bitmap?>>()
|
val deferredMap = mutableMapOf<Int, Deferred<Bitmap?>>()
|
||||||
builder.setContentText("Downloading ${task.title} - ${task.chapter}")
|
builder.setContentText("Downloading ${task.title} - ${task.chapter}")
|
||||||
if (notifi) {
|
if (notifi) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getSubDirectory(
|
val baseOutputDir = getSubDirectory(
|
||||||
|
this@MangaDownloaderService,
|
||||||
|
MediaType.MANGA,
|
||||||
|
false,
|
||||||
|
task.title
|
||||||
|
) ?: throw Exception("Base output directory not found")
|
||||||
|
val outputDir = getSubDirectory(
|
||||||
this@MangaDownloaderService,
|
this@MangaDownloaderService,
|
||||||
MediaType.MANGA,
|
MediaType.MANGA,
|
||||||
false,
|
false,
|
||||||
task.title,
|
task.title,
|
||||||
task.chapter
|
task.chapter
|
||||||
)?.deleteRecursively(this@MangaDownloaderService)
|
) ?: throw Exception("Output directory not found")
|
||||||
|
|
||||||
|
outputDir.deleteRecursively(this@MangaDownloaderService, true)
|
||||||
|
|
||||||
// Loop through each ImageData object from the task
|
|
||||||
var farthest = 0
|
var farthest = 0
|
||||||
for ((index, image) in task.imageData.withIndex()) {
|
for ((index, image) in task.imageData.withIndex()) {
|
||||||
if (deferredMap.size >= task.simultaneousDownloads) {
|
if (deferredMap.size >= task.simultaneousDownloads) {
|
||||||
|
@ -226,30 +235,36 @@ class MangaDownloaderService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
saveToDisk("$index.jpg", bitmap, task.title, task.chapter)
|
saveToDisk("$index.jpg", outputDir, bitmap)
|
||||||
}
|
}
|
||||||
farthest++
|
farthest++
|
||||||
|
|
||||||
builder.setProgress(task.imageData.size, farthest, false)
|
builder.setProgress(task.imageData.size, farthest, false)
|
||||||
|
|
||||||
broadcastDownloadProgress(
|
broadcastDownloadProgress(
|
||||||
task.chapter,
|
task.chapter,
|
||||||
farthest * 100 / task.imageData.size
|
farthest * 100 / task.imageData.size
|
||||||
)
|
)
|
||||||
if (notifi) {
|
if (notifi) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bitmap
|
bitmap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for any remaining deferred to complete
|
|
||||||
deferredMap.values.awaitAll()
|
deferredMap.values.awaitAll()
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
builder.setContentText("${task.title} - ${task.chapter} Download complete")
|
builder.setContentText("${task.title} - ${task.chapter} Download complete")
|
||||||
.setProgress(0, 0, false)
|
.setProgress(0, 0, false)
|
||||||
|
if (notifi) {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
saveMediaInfo(task)
|
saveMediaInfo(task, baseOutputDir)
|
||||||
downloadsManager.addDownload(
|
downloadsManager.addDownload(
|
||||||
DownloadedType(
|
DownloadedType(
|
||||||
task.title,
|
task.title,
|
||||||
|
@ -269,17 +284,16 @@ class MangaDownloaderService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun saveToDisk(fileName: String, bitmap: Bitmap, title: String, chapter: String) {
|
private fun saveToDisk(
|
||||||
|
fileName: String,
|
||||||
|
directory: DocumentFile,
|
||||||
|
bitmap: Bitmap
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
// Define the directory within the private external storage space
|
|
||||||
val directory = getSubDirectory(this, MediaType.MANGA, false, title, chapter)
|
|
||||||
?: throw Exception("Directory not found")
|
|
||||||
directory.findFile(fileName)?.forceDelete(this)
|
directory.findFile(fileName)?.forceDelete(this)
|
||||||
// Create a file reference within that directory for the image
|
|
||||||
val file =
|
val file =
|
||||||
directory.createFile("image/jpeg", fileName) ?: throw Exception("File not created")
|
directory.createFile("image/jpeg", fileName) ?: throw Exception("File not created")
|
||||||
|
|
||||||
// Use a FileOutputStream to write the bitmap to the file
|
|
||||||
file.openOutputStream(this, false).use { outputStream ->
|
file.openOutputStream(this, false).use { outputStream ->
|
||||||
if (outputStream == null) throw Exception("Output stream is null")
|
if (outputStream == null) throw Exception("Output stream is null")
|
||||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
|
||||||
|
@ -292,11 +306,8 @@ class MangaDownloaderService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
private fun saveMediaInfo(task: DownloadTask) {
|
private fun saveMediaInfo(task: DownloadTask, directory: DocumentFile) {
|
||||||
launchIO {
|
launchIO {
|
||||||
val directory =
|
|
||||||
getSubDirectory(this@MangaDownloaderService, MediaType.MANGA, false, task.title)
|
|
||||||
?: throw Exception("Directory not found")
|
|
||||||
directory.findFile("media.json")?.forceDelete(this@MangaDownloaderService)
|
directory.findFile("media.json")?.forceDelete(this@MangaDownloaderService)
|
||||||
val file = directory.createFile("application/json", "media.json")
|
val file = directory.createFile("application/json", "media.json")
|
||||||
?: throw Exception("File not created")
|
?: throw Exception("File not created")
|
||||||
|
|
|
@ -171,7 +171,11 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
val item = adapter.getItem(position) as OfflineMangaModel
|
val item = adapter.getItem(position) as OfflineMangaModel
|
||||||
val media =
|
val media =
|
||||||
downloadManager.mangaDownloadedTypes.firstOrNull { it.titleName.compareName(item.title) }
|
downloadManager.mangaDownloadedTypes.firstOrNull { it.titleName.compareName(item.title) }
|
||||||
?: downloadManager.novelDownloadedTypes.firstOrNull { it.titleName.compareName(item.title) }
|
?: downloadManager.novelDownloadedTypes.firstOrNull {
|
||||||
|
it.titleName.compareName(
|
||||||
|
item.title
|
||||||
|
)
|
||||||
|
}
|
||||||
media?.let {
|
media?.let {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
ContextCompat.startActivity(
|
ContextCompat.startActivity(
|
||||||
|
@ -279,10 +283,12 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
downloads = listOf()
|
downloads = listOf()
|
||||||
downloadsJob = Job()
|
downloadsJob = Job()
|
||||||
CoroutineScope(Dispatchers.IO + downloadsJob).launch {
|
CoroutineScope(Dispatchers.IO + downloadsJob).launch {
|
||||||
val mangaTitles = downloadManager.mangaDownloadedTypes.map { it.titleName.findValidName() }.distinct()
|
val mangaTitles =
|
||||||
|
downloadManager.mangaDownloadedTypes.map { it.titleName.findValidName() }.distinct()
|
||||||
val newMangaDownloads = mutableListOf<OfflineMangaModel>()
|
val newMangaDownloads = mutableListOf<OfflineMangaModel>()
|
||||||
for (title in mangaTitles) {
|
for (title in mangaTitles) {
|
||||||
val tDownloads = downloadManager.mangaDownloadedTypes.filter { it.titleName.findValidName() == title }
|
val tDownloads =
|
||||||
|
downloadManager.mangaDownloadedTypes.filter { it.titleName.findValidName() == title }
|
||||||
val download = tDownloads.firstOrNull() ?: continue
|
val download = tDownloads.firstOrNull() ?: continue
|
||||||
val offlineMangaModel = loadOfflineMangaModel(download)
|
val offlineMangaModel = loadOfflineMangaModel(download)
|
||||||
newMangaDownloads += offlineMangaModel
|
newMangaDownloads += offlineMangaModel
|
||||||
|
@ -291,7 +297,8 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
val novelTitles = downloadManager.novelDownloadedTypes.map { it.titleName }.distinct()
|
val novelTitles = downloadManager.novelDownloadedTypes.map { it.titleName }.distinct()
|
||||||
val newNovelDownloads = mutableListOf<OfflineMangaModel>()
|
val newNovelDownloads = mutableListOf<OfflineMangaModel>()
|
||||||
for (title in novelTitles) {
|
for (title in novelTitles) {
|
||||||
val tDownloads = downloadManager.novelDownloadedTypes.filter { it.titleName.findValidName() == title }
|
val tDownloads =
|
||||||
|
downloadManager.novelDownloadedTypes.filter { it.titleName.findValidName() == title }
|
||||||
val download = tDownloads.firstOrNull() ?: continue
|
val download = tDownloads.firstOrNull() ?: continue
|
||||||
val offlineMangaModel = loadOfflineMangaModel(download)
|
val offlineMangaModel = loadOfflineMangaModel(download)
|
||||||
newNovelDownloads += offlineMangaModel
|
newNovelDownloads += offlineMangaModel
|
||||||
|
@ -320,11 +327,14 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
)
|
)
|
||||||
val gson = GsonBuilder()
|
val gson = GsonBuilder()
|
||||||
.registerTypeAdapter(SChapter::class.java, InstanceCreator<SChapter> {
|
.registerTypeAdapter(SChapter::class.java, InstanceCreator<SChapter> {
|
||||||
SChapterImpl() // Provide an instance of SChapterImpl
|
SChapterImpl()
|
||||||
})
|
})
|
||||||
.create()
|
.create()
|
||||||
val media = directory?.findFile("media.json")
|
val media = directory?.findFile("media.json")
|
||||||
?: return DownloadCompat.loadMediaCompat(downloadedType)
|
if (media == null) {
|
||||||
|
Logger.log("No media.json found at ${directory?.uri?.path}")
|
||||||
|
return DownloadCompat.loadMediaCompat(downloadedType)
|
||||||
|
}
|
||||||
val mediaJson =
|
val mediaJson =
|
||||||
media.openInputStream(context ?: currContext()!!)?.bufferedReader().use {
|
media.openInputStream(context ?: currContext()!!)?.bufferedReader().use {
|
||||||
it?.readText()
|
it?.readText()
|
||||||
|
@ -340,7 +350,6 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
|
|
||||||
private suspend fun loadOfflineMangaModel(downloadedType: DownloadedType): OfflineMangaModel {
|
private suspend fun loadOfflineMangaModel(downloadedType: DownloadedType): OfflineMangaModel {
|
||||||
val type = downloadedType.type.asText()
|
val type = downloadedType.type.asText()
|
||||||
//load media.json and convert to media class with gson
|
|
||||||
try {
|
try {
|
||||||
val directory = getSubDirectory(
|
val directory = getSubDirectory(
|
||||||
context ?: currContext()!!, downloadedType.type,
|
context ?: currContext()!!, downloadedType.type,
|
||||||
|
@ -378,6 +387,7 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
bannerUri
|
bannerUri
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Logger.log(e)
|
||||||
return try {
|
return try {
|
||||||
loadOfflineMangaModelCompat(downloadedType)
|
loadOfflineMangaModelCompat(downloadedType)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -385,7 +395,7 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
||||||
Logger.log(e)
|
Logger.log(e)
|
||||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||||
return OfflineMangaModel(
|
return OfflineMangaModel(
|
||||||
"unknown",
|
downloadedType.titleName,
|
||||||
"0",
|
"0",
|
||||||
"??",
|
"??",
|
||||||
"??",
|
"??",
|
||||||
|
|
|
@ -239,6 +239,13 @@ class NovelDownloaderService : Service() {
|
||||||
return@withContext
|
return@withContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val baseDirectory = getSubDirectory(
|
||||||
|
this@NovelDownloaderService,
|
||||||
|
MediaType.NOVEL,
|
||||||
|
false,
|
||||||
|
task.title
|
||||||
|
) ?: throw Exception("Directory not found")
|
||||||
|
|
||||||
// Start the download
|
// Start the download
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
@ -334,7 +341,7 @@ class NovelDownloaderService : Service() {
|
||||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
saveMediaInfo(task)
|
saveMediaInfo(task, baseDirectory)
|
||||||
downloadsManager.addDownload(
|
downloadsManager.addDownload(
|
||||||
DownloadedType(
|
DownloadedType(
|
||||||
task.title,
|
task.title,
|
||||||
|
@ -354,15 +361,8 @@ class NovelDownloaderService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
private fun saveMediaInfo(task: DownloadTask) {
|
private fun saveMediaInfo(task: DownloadTask, directory: DocumentFile) {
|
||||||
launchIO {
|
launchIO {
|
||||||
val directory =
|
|
||||||
getSubDirectory(
|
|
||||||
this@NovelDownloaderService,
|
|
||||||
MediaType.NOVEL,
|
|
||||||
false,
|
|
||||||
task.title
|
|
||||||
) ?: throw Exception("Directory not found")
|
|
||||||
directory.findFile("media.json")?.forceDelete(this@NovelDownloaderService)
|
directory.findFile("media.json")?.forceDelete(this@NovelDownloaderService)
|
||||||
val file = directory.createFile("application/json", "media.json")
|
val file = directory.createFile("application/json", "media.json")
|
||||||
?: throw Exception("File not created")
|
?: throw Exception("File not created")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue