Backup creation and restore gql endpoints (#587)

This commit is contained in:
Mitchell Syer
2023-07-02 11:45:44 -04:00
committed by GitHub
parent 1a9a0b3394
commit a11b654c3d
13 changed files with 477 additions and 43 deletions

View File

@@ -0,0 +1,85 @@
package suwayomi.tachidesk.graphql.mutations
import io.javalin.http.UploadedFile
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeout
import suwayomi.tachidesk.graphql.server.TemporaryFileStorage
import suwayomi.tachidesk.graphql.types.BackupRestoreState
import suwayomi.tachidesk.graphql.types.BackupRestoreStatus
import suwayomi.tachidesk.graphql.types.toStatus
import suwayomi.tachidesk.manga.impl.backup.BackupFlags
import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupExport
import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupImport
import suwayomi.tachidesk.server.JavalinSetup.future
import java.text.SimpleDateFormat
import java.util.Date
import java.util.concurrent.CompletableFuture
import kotlin.time.Duration.Companion.seconds
class BackupMutation {
data class RestoreBackupInput(
val clientMutationId: String? = null,
val backup: UploadedFile
)
data class RestoreBackupPayload(
val clientMutationId: String?,
val status: BackupRestoreStatus
)
@OptIn(DelicateCoroutinesApi::class)
fun restoreBackup(
input: RestoreBackupInput
): CompletableFuture<RestoreBackupPayload> {
val (clientMutationId, backup) = input
return future {
GlobalScope.launch {
ProtoBackupImport.performRestore(backup.content)
}
val status = withTimeout(10.seconds) {
ProtoBackupImport.backupRestoreState.first {
it != ProtoBackupImport.BackupRestoreState.Idle
}.toStatus()
}
RestoreBackupPayload(clientMutationId, status)
}
}
data class CreateBackupInput(
val clientMutationId: String? = null,
val includeChapters: Boolean? = null,
val includeCategories: Boolean? = null
)
data class CreateBackupPayload(
val clientMutationId: String?,
val url: String
)
fun createBackup(
input: CreateBackupInput? = null
): CreateBackupPayload {
val currentDate = SimpleDateFormat("yyyy-MM-dd_HH-mm").format(Date())
val filename = "tachidesk_$currentDate.proto.gz"
val backup = ProtoBackupExport.createBackup(
BackupFlags(
includeManga = true,
includeCategories = input?.includeCategories ?: true,
includeChapters = input?.includeChapters ?: true,
includeTracking = true,
includeHistory = true
)
)
TemporaryFileStorage.saveFile(filename, backup)
return CreateBackupPayload(
clientMutationId = input?.clientMutationId,
url = "/api/graphql/files/backup/$filename"
)
}
}