[DO NOT USE] Restore ability to restore downloads

This commit is contained in:
tarsin committed 2023-06-06 00:28:21 +08:00
1 parent bc5a0f9140
commit f99575771c
3 files changed
+94 -26

No files matched your search

@@ -38,6 +38,7 @@ import com.hippo.ehviewer.yorozuya.ObjectUtils
import com.hippo.ehviewer.yorozuya.SimpleHandler
import com.hippo.ehviewer.yorozuya.collect.LongList
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.util.lang.withUIContext
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import splitties.init.appCtx
@@ -395,7 +396,7 @@ object DownloadManager : OnSpiderListener {
}
}
fun addDownload(galleryInfo: GalleryInfo, label: String?) {
suspend fun addDownload(galleryInfo: GalleryInfo, label: String?) {
if (containDownloadInfo(galleryInfo.gid)) {
// Contain
return
@@ -423,8 +424,10 @@ object DownloadManager : OnSpiderListener {
EhDB.putDownloadInfo(info)
// Notify
for (l in mDownloadInfoListeners) {
l!!.onAdd(info, list, list.size - 1)
withUIContext {
for (l in mDownloadInfoListeners) {
l!!.onAdd(info, list, list.size - 1)
}
}
}
@@ -65,6 +65,7 @@ fun AdvancedScreen() {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val snackbarHostState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope { Dispatchers.IO }
fun launchSnackBar(content: String) = coroutineScope.launch { snackbarHostState.showSnackbar(content) }
Scaffold(
topBar = {
TopAppBar(
@@ -111,10 +112,10 @@ fun AdvancedScreen() {
zipOs.putNextEntry(logcatEntry)
LogCat.save(zipOs)
}
snackbarHostState.showSnackbar(getString(R.string.settings_advanced_dump_logcat_to, uri.toString()))
launchSnackBar(getString(R.string.settings_advanced_dump_logcat_to, uri.toString()))
}
}.onFailure {
snackbarHostState.showSnackbar(dumpLogError)
launchSnackBar(dumpLogError)
it.printStackTrace()
}
}
@@ -179,18 +180,16 @@ fun AdvancedScreen() {
val exportLauncher = rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("application/vnd.sqlite3")) { uri ->
uri?.let {
coroutineScope.launch {
val alertDialog = withUIContext { BaseDialogBuilder(context).setCancelable(false).setView(R.layout.preference_dialog_task).show() }
context.runCatching {
grantUriPermission(BuildConfig.APPLICATION_ID, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
val alertDialog = withUIContext {
BaseDialogBuilder(context).setCancelable(false).setView(R.layout.preference_dialog_task).show()
}
EhDB.exportDB(context, uri)
if (alertDialog.isShowing) alertDialog.dismiss()
snackbarHostState.showSnackbar(getString(R.string.settings_advanced_export_data_to, uri.toString()))
launchSnackBar(getString(R.string.settings_advanced_export_data_to, uri.toString()))
}.onFailure {
it.printStackTrace()
snackbarHostState.showSnackbar(exportFailed)
launchSnackBar(exportFailed)
}
if (alertDialog.isShowing) alertDialog.dismiss()
}
}
}
@@ -204,18 +203,16 @@ fun AdvancedScreen() {
val importLauncher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
uri?.let {
coroutineScope.launch {
val alertDialog = withUIContext { BaseDialogBuilder(context).setCancelable(false).setView(R.layout.preference_dialog_task).show() }
context.runCatching {
grantUriPermission(BuildConfig.APPLICATION_ID, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
val alertDialog = withUIContext {
BaseDialogBuilder(context).setCancelable(false).setView(R.layout.preference_dialog_task).show()
}
EhDB.importDB(context, uri)
if (alertDialog.isShowing) alertDialog.dismiss()
snackbarHostState.showSnackbar(importSucceed)
launchSnackBar(importSucceed)
}.onFailure {
it.printStackTrace()
snackbarHostState.showSnackbar(importFailed)
launchSnackBar(importFailed)
}
if (alertDialog.isShowing) alertDialog.dismiss()
}
}
}
@@ -236,13 +233,13 @@ fun AdvancedScreen() {
tailrec suspend fun doBackup() {
val result = EhEngine.getFavorites(favListUrlBuilder.build())
if (result.galleryInfoList.isEmpty()) {
snackbarHostState.showSnackbar(backupNothing)
launchSnackBar(backupNothing)
} else {
if (favTotal == 0) favTotal = result.countArray.sum()
favIndex += result.galleryInfoList.size
val status = "($favIndex/$favTotal)"
EhDB.putLocalFavorites(result.galleryInfoList)
snackbarHostState.showSnackbar(context.getString(R.string.settings_advanced_backup_favorite_start, status))
launchSnackBar(context.getString(R.string.settings_advanced_backup_favorite_start, status))
if (result.next != null) {
delay(Settings.downloadDelay.toLong())
favListUrlBuilder.setIndex(result.next, true)
@@ -254,10 +251,10 @@ fun AdvancedScreen() {
runSuspendCatching {
doBackup()
}.onSuccess {
snackbarHostState.showSnackbar(backupSucceed)
launchSnackBar(backupSucceed)
}.onFailure {
it.printStackTrace()
snackbarHostState.showSnackbar(backupFailed)
launchSnackBar(backupFailed)
}
}
}
@@ -26,9 +26,16 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.hippo.ehviewer.AppConfig
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine.fillGalleryListByApi
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.data.BaseGalleryInfo
import com.hippo.ehviewer.download.DownloadManager
import com.hippo.ehviewer.download.downloadLocation
import com.hippo.ehviewer.spider.SpiderQueen
import com.hippo.ehviewer.spider.readCompatFromUniFile
import com.hippo.ehviewer.ui.compose.observed
import com.hippo.ehviewer.ui.compose.rememberedAccessor
import com.hippo.ehviewer.ui.keepNoMediaFileStatus
@@ -36,8 +43,11 @@ import com.hippo.ehviewer.ui.legacy.BaseDialogBuilder
import com.hippo.ehviewer.ui.login.LocalNavController
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
import eu.kanade.tachiyomi.util.lang.withUIContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import moe.tarsin.coroutines.runSuspendCatching
import splitties.init.appCtx
@Composable
fun DownloadScreen() {
@@ -46,6 +56,7 @@ fun DownloadScreen() {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope { Dispatchers.IO }
val snackbarHostState = remember { SnackbarHostState() }
fun launchSnackBar(content: String) = coroutineScope.launch { snackbarHostState.showSnackbar(content) }
Scaffold(
topBar = {
TopAppBar(
@@ -59,8 +70,8 @@ fun DownloadScreen() {
)
},
snackbarHost = { SnackbarHost(snackbarHostState) },
) {
Column(modifier = Modifier.padding(it).nestedScroll(scrollBehavior.nestedScrollConnection)) {
) { padding ->
Column(modifier = Modifier.padding(padding).nestedScroll(scrollBehavior.nestedScrollConnection)) {
var downloadLocationState by ::downloadLocation.observed
val cannotGetDownloadLocation = stringResource(id = R.string.settings_download_cant_get_download_location)
val selectDownloadDirLauncher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocumentTree()) { treeUri ->
@@ -75,7 +86,7 @@ fun DownloadScreen() {
}
}
}.onFailure {
snackbarHostState.showSnackbar(cannotGetDownloadLocation)
launchSnackBar(cannotGetDownloadLocation)
}
}
}
@@ -96,7 +107,7 @@ fun DownloadScreen() {
downloadLocationState = uniFile
coroutineScope.launchNonCancellable { keepNoMediaFileStatus() }
} else {
coroutineScope.launch { snackbarHostState.showSnackbar(cannotGetDownloadLocation) }
launchSnackBar(cannotGetDownloadLocation)
}
}
.show()
@@ -139,10 +150,63 @@ fun DownloadScreen() {
summary = stringResource(id = R.string.settings_download_download_origin_image_summary),
value = Settings::downloadOriginImage,
)
val restoreFailed = stringResource(id = R.string.settings_download_restore_failed)
Preference(
title = stringResource(id = R.string.settings_download_restore_download_items),
summary = stringResource(id = R.string.settings_download_restore_download_items_summary),
)
) {
var restoreDirCount = 0
fun getRestoreItem(file: UniFile): RestoreItem? {
if (!file.isDirectory) return null
val siFile = file.findFile(SpiderQueen.SPIDER_INFO_FILENAME) ?: return null
return runCatching {
val spiderInfo = readCompatFromUniFile(siFile) ?: return null
val gid = spiderInfo.gid
val dirname = file.name ?: return null
if (DownloadManager.containDownloadInfo(gid)) {
// Restore download dir to avoid redownload
val dbdirname = EhDB.getDownloadDirname(gid)
if (null == dbdirname || dirname != dbdirname) {
EhDB.putDownloadDirname(gid, dirname)
restoreDirCount++
}
return null
}
RestoreItem(dirname).also {
it.gid = spiderInfo.gid
it.token = spiderInfo.token
}
}.onFailure {
it.printStackTrace()
}.getOrNull()
}
coroutineScope.launch {
val alertDialog = withUIContext { BaseDialogBuilder(context).setCancelable(false).setView(R.layout.preference_dialog_task).show() }
context.runCatching {
val result = downloadLocation.listFiles()?.mapNotNull { getRestoreItem(it) }?.apply {
runSuspendCatching {
fillGalleryListByApi(this, EhUrl.referer)
}.onFailure {
it.printStackTrace()
}
}
if (result == null) {
launchSnackBar(restoreFailed)
} else {
if (result.isEmpty()) {
launchSnackBar(RESTORE_COUNT_MSG(restoreDirCount))
} else {
val count = result.filterNot { it.title.isNullOrBlank() }.map {
DownloadManager.addDownload(it, null)
EhDB.putDownloadDirname(it.gid, it.dirname)
}.size
launchSnackBar(RESTORE_COUNT_MSG(count + restoreDirCount))
}
}
}
if (alertDialog.isShowing) alertDialog.dismiss()
}
}
Preference(
title = stringResource(id = R.string.settings_download_clean_redundancy),
summary = stringResource(id = R.string.settings_download_clean_redundancy_summary),
@@ -150,3 +214,7 @@ fun DownloadScreen() {
}
}
}
private class RestoreItem(val dirname: String) : BaseGalleryInfo()
private val RESTORE_NOT_FOUND = appCtx.getString(R.string.settings_download_restore_not_found)
private val RESTORE_COUNT_MSG = { cnt: Int -> if (cnt == 0) RESTORE_NOT_FOUND else appCtx.getString(R.string.settings_download_restore_successfully, cnt) }