diff --git a/src/main/kotlin/OneDriveTransferCenter.kt b/src/main/kotlin/OneDriveTransferCenter.kt index 4b5bcf3..e6fce28 100644 --- a/src/main/kotlin/OneDriveTransferCenter.kt +++ b/src/main/kotlin/OneDriveTransferCenter.kt @@ -53,55 +53,71 @@ object DefaultOneDriveTransferCallback : OneDriveTransferCallback { } override fun onTransferStart(progress: OneDriveTransferWorkerProgress) { - progress.currentTask.bot.execute( - EditMessageText.builder() - .chatId(progress.currentTask.extra["chatId"].toString().toLong()) - .messageId(progress.currentTask.extra["messageId"].toString().toInt()) - .text( - """ + val newMessage = EditMessageText.builder() + .chatId(progress.currentTask.extra["chatId"].toString().toLong()) + .messageId(progress.currentTask.extra["messageId"].toString().toInt()) + .text( + """ OneDrive 中转任务开始执行 正在获取文件信息...(需要一些时间从 Telegram 服务器下载文件) 文件名: ${progress.currentTask.document.fileName} """.trimIndent() - ) - .build() - ) + ) + .build().orSendMessage(progress.currentTask.bot, progress.currentTask.extra["messageId"].toString().toInt()) + if (newMessage != null) { + progress.currentTask.extra["messageId"] = newMessage.messageId + } } override fun onProgress(progress: OneDriveTransferWorkerProgress) { - progress.currentTask.bot.execute(EditMessageText.builder() + val newMessage = EditMessageText.builder() .chatId(progress.currentTask.extra["chatId"].toString().toLong()) .messageId(progress.currentTask.extra["messageId"].toString().toInt()) - .text(""" + .text( + """ OneDrive 中转任务执行中 文件名: ${progress.currentTask.document.fileName} 进度:${String.format("%.3f", progress.progress.get() * 100)}% - """.trimIndent()) - .build()) + """.trimIndent() + ) + .build().orSendMessage(progress.currentTask.bot, progress.currentTask.extra["messageId"].toString().toInt()) + if (newMessage != null) { + progress.currentTask.extra["messageId"] = newMessage.messageId + } } override fun onTransferFailure(task: OneDriveTransferTask, progress: OneDriveTransferWorkerProgress) { - task.bot.execute(EditMessageText.builder() + val newMessage = EditMessageText.builder() .chatId(task.extra["chatId"].toString().toLong()) .messageId(task.extra["messageId"].toString().toInt()) - .text(""" + .text( + """ OneDrive 中转任务执行失败 文件名: ${task.document.fileName} 错误信息:${progress.exception?.message} - """.trimIndent()) - .build()) + """.trimIndent() + ) + .build().orSendMessage(progress.currentTask.bot, progress.currentTask.extra["messageId"].toString().toInt()) + if (newMessage != null) { + progress.currentTask.extra["messageId"] = newMessage.messageId + } } override fun onTransferSuccess(task: OneDriveTransferTask, progress: OneDriveTransferWorkerProgress) { - task.bot.execute(EditMessageText.builder() + val newMessage = EditMessageText.builder() .chatId(task.extra["chatId"].toString().toLong()) .messageId(task.extra["messageId"].toString().toInt()) - .text(""" + .text( + """ OneDrive 中转任务执行成功 文件名: ${task.document.fileName} OneDrive 文件路径:${progress.driveItem?.webUrl} - """.trimIndent()) - .build()) + """.trimIndent() + ) + .build().orSendMessage(progress.currentTask.bot, progress.currentTask.extra["messageId"].toString().toInt()) + if (newMessage != null) { + progress.currentTask.extra["messageId"] = newMessage.messageId + } } } @@ -126,7 +142,7 @@ class OneDriveTransferTaskExecutor( .build() ) { - private val logger = KotlinLogging.logger { } + private val logger = KotlinLogging.logger { } val threadStatusMap = ConcurrentHashMap() @@ -202,7 +218,8 @@ class OneDriveTransferTaskExecutor( logger.debug { "成功获取文件信息:$tempFile" } val graphClient = task.service.createGraphClient(task.tgUserId) - val drive = graphClient.drives(task.onedriveId).buildRequest().get() ?: throw IllegalStateException("无法获取 OneDrive 驱动器.") + val drive = graphClient.drives(task.onedriveId).buildRequest().get() + ?: throw IllegalStateException("无法获取 OneDrive 驱动器.") if (file.fileSize > drive.quota!!.remaining!!) { throw IllegalStateException("OneDrive 剩余空间不足.") } @@ -219,9 +236,11 @@ class OneDriveTransferTaskExecutor( progress.progress.set(1.0) } else { val uploadSession = graphClient.drives(task.onedriveId).root().itemWithPath(filePath) - .createUploadSession(DriveItemCreateUploadSessionParameterSet.newBuilder() - .withItem(DriveItemUploadableProperties()) - .build()) + .createUploadSession( + DriveItemCreateUploadSessionParameterSet.newBuilder() + .withItem(DriveItemUploadableProperties()) + .build() + ) .buildRequest() .post() ?: throw IllegalStateException("无法创建 OneDrive 上传会话.") val progressCallback = IProgressCallback { current, max -> @@ -261,13 +280,22 @@ class OneDriveTransferTaskExecutor( return bot.downloadFileAsStream(filePath) } - private fun checkAndGetPath(graphClient: GraphServiceClient, driveId: String, storagePath: String, originFileName: String): String { + private fun checkAndGetPath( + graphClient: GraphServiceClient, + driveId: String, + storagePath: String, + originFileName: String + ): String { val folderPath = checkAndCreateFolder(graphClient, driveId, storagePath) val fileName = checkFileName(graphClient, driveId, folderPath, originFileName) return "$folderPath$fileName" } - private fun checkAndCreateFolder(graphClient: GraphServiceClient, driveId: String, folderPath: String): String { + private fun checkAndCreateFolder( + graphClient: GraphServiceClient, + driveId: String, + folderPath: String + ): String { if (folderPath.trim() == "/") { return "" } @@ -332,7 +360,12 @@ class OneDriveTransferTaskExecutor( return currentPath.trimStart('/') } - private fun checkFileName(graphClient: GraphServiceClient, driveId: String, folderPath: String, fileName: String): String { + private fun checkFileName( + graphClient: GraphServiceClient, + driveId: String, + folderPath: String, + fileName: String + ): String { try { graphClient.drives(driveId).root().itemWithPath("$folderPath$fileName").buildRequest().get() } catch (e: GraphServiceException) { diff --git a/src/main/kotlin/Utils.kt b/src/main/kotlin/Utils.kt index 3e766a5..d8ffa36 100644 --- a/src/main/kotlin/Utils.kt +++ b/src/main/kotlin/Utils.kt @@ -1,6 +1,12 @@ package net.lamgc.scext.onedrive_transfer import com.google.common.cache.Cache +import org.telegram.abilitybots.api.bot.BaseAbilityBot +import org.telegram.telegrambots.meta.api.methods.send.SendMessage +import org.telegram.telegrambots.meta.api.methods.updatingmessages.DeleteMessage +import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageText +import org.telegram.telegrambots.meta.api.objects.Message +import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException import java.net.URL import java.net.URLDecoder @@ -27,3 +33,32 @@ fun Cache.putToken(value: String, tokenLength: Int = 16, tokenPr put(token, value) return "$tokenPrefix$token" } + +fun EditMessageText.orSendMessage(bot: BaseAbilityBot, replyMessageId: Int, tryRemove: Boolean = true): Message? { + try { + bot.execute(this) + return null + } catch (e: TelegramApiRequestException) { + if (e.errorCode != 400 || e.apiResponse != "message can't be edited") { + throw e + } + return bot.execute( + SendMessage.builder() + .replyToMessageId(replyMessageId) + .chatId(chatId.toString()) + .text(text) + .build() + ) + } finally { + if (tryRemove) { + try { + bot.execute( + DeleteMessage.builder() + .messageId(messageId) + .build() + ) + } catch (_: Exception) { + } + } + } +}