From c92a7802453719c6036fa3757093ea026be544d0 Mon Sep 17 00:00:00 2001
From: jarvis2f <137974272+jarvis2f@users.noreply.github.com>
Date: Tue, 14 Jan 2025 18:21:12 +0800
Subject: [PATCH] =?UTF-8?q?=F0=9F=94=8D=EF=B8=8F=20feat:=20Optimize=20undo?=
 =?UTF-8?q?wnloaded=20file=20acquisition=20logic.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../main/java/telegram/files/TdApiHelp.java   | 36 ++++++++++++---
 .../java/telegram/files/TelegramVerticle.java | 45 +++++++++++++++----
 2 files changed, 66 insertions(+), 15 deletions(-)

diff --git a/api/src/main/java/telegram/files/TdApiHelp.java b/api/src/main/java/telegram/files/TdApiHelp.java
index 95515be..b82edeb 100644
--- a/api/src/main/java/telegram/files/TdApiHelp.java
+++ b/api/src/main/java/telegram/files/TdApiHelp.java
@@ -223,6 +223,8 @@ public TdApi.File getPreviewFileId(Tuple tuple) {
         public T getContent() {
             return content;
         }
+
+        public abstract TdApi.File getFile();
     }
 
     public static class PhotoHandler extends FileHandler<TdApi.MessagePhoto> {
@@ -263,17 +265,17 @@ public TdApi.File getPreviewFileId(Tuple tuple) {
 
         @Override
         public FileRecord convertFileRecord(long telegramId) {
-            TdApi.PhotoSize photoSize = content.photo.sizes[content.photo.sizes.length - 1];
+            TdApi.File file = getFile();
             return new FileRecord(
                     getFileId(),
-                    photoSize.photo.remote.uniqueId,
+                    file.remote.uniqueId,
                     telegramId,
                     message.chatId,
                     message.id,
                     message.date,
                     message.hasSensitiveContent,
-                    photoSize.photo.size == 0 ? photoSize.photo.expectedSize : photoSize.photo.size,
-                    photoSize.photo.local == null ? 0 : photoSize.photo.local.downloadedSize,
+                    file.size == 0 ? file.expectedSize : file.size,
+                    file.local == null ? 0 : file.local.downloadedSize,
                     "photo",
                     null,
                     null,
@@ -285,6 +287,11 @@ public FileRecord convertFileRecord(long telegramId) {
                     null
             );
         }
+
+        @Override
+        public TdApi.File getFile() {
+            return content.photo.sizes[content.photo.sizes.length - 1].photo;
+        }
     }
 
     public static class VideoHandler extends FileHandler<TdApi.MessageVideo> {
@@ -318,7 +325,7 @@ public TdApi.File getPreviewFileId(Tuple tuple) {
 
         @Override
         public FileRecord convertFileRecord(long telegramId) {
-            TdApi.File file = content.video.video;
+            TdApi.File file = getFile();
             return new FileRecord(
                     file.id,
                     file.remote.uniqueId,
@@ -340,6 +347,11 @@ public FileRecord convertFileRecord(long telegramId) {
                     null
             );
         }
+
+        @Override
+        public TdApi.File getFile() {
+            return content.video.video;
+        }
     }
 
     public static class AudioHandler extends FileHandler<TdApi.MessageAudio> {
@@ -360,7 +372,7 @@ public String getFileUniqueId() {
 
         @Override
         public FileRecord convertFileRecord(long telegramId) {
-            TdApi.File file = content.audio.audio;
+            TdApi.File file = getFile();
             return new FileRecord(
                     file.id,
                     file.remote.uniqueId,
@@ -382,6 +394,11 @@ public FileRecord convertFileRecord(long telegramId) {
                     null
             );
         }
+
+        @Override
+        public TdApi.File getFile() {
+            return content.audio.audio;
+        }
     }
 
     public static class DocumentHandler extends FileHandler<TdApi.MessageDocument> {
@@ -402,7 +419,7 @@ public String getFileUniqueId() {
 
         @Override
         public FileRecord convertFileRecord(long telegramId) {
-            TdApi.File file = content.document.document;
+            TdApi.File file = getFile();
             return new FileRecord(
                     file.id,
                     file.remote.uniqueId,
@@ -424,6 +441,11 @@ public FileRecord convertFileRecord(long telegramId) {
                     null
             );
         }
+
+        @Override
+        public TdApi.File getFile() {
+            return content.document.document;
+        }
     }
 
     public static class ComparablePhotoSize implements Comparable<TdApi.PhotoSize> {
diff --git a/api/src/main/java/telegram/files/TelegramVerticle.java b/api/src/main/java/telegram/files/TelegramVerticle.java
index 831c920..dbdec4d 100644
--- a/api/src/main/java/telegram/files/TelegramVerticle.java
+++ b/api/src/main/java/telegram/files/TelegramVerticle.java
@@ -259,14 +259,41 @@ public Future<JsonObject> getChatFiles(long chatId, MultiMap filter) {
             searchChatMessages.limit = Convert.toInt(filter.get("limit"), 20);
             searchChatMessages.filter = TdApiHelp.getSearchMessagesFilter(filter.get("type"));
 
-            return this.execute(searchChatMessages)
+            return (Objects.equals(filter.get("status"), FileRecord.DownloadStatus.idle.name()) ?
+                    this.getIdleChatFiles(searchChatMessages) :
+                    this.execute(searchChatMessages))
                     .compose(foundChatMessages ->
                             DataVerticle.fileRepository.getFilesByUniqueId(TdApiHelp.getFileUniqueIds(Arrays.asList(foundChatMessages.messages)))
                                     .map(fileRecords -> Tuple.tuple(foundChatMessages, fileRecords)))
-                    .compose(r -> this.convertFiles(r, filter));
+                    .compose(this::convertFiles);
         }
     }
 
+    private Future<TdApi.FoundChatMessages> getIdleChatFiles(TdApi.SearchChatMessages searchChatMessages) {
+        return this.execute(searchChatMessages)
+                .compose(foundChatMessages -> {
+                    TdApi.Message[] messages = Stream.of(foundChatMessages.messages)
+                            .filter(message ->
+                                    TdApiHelp.getFileHandler(message)
+                                            .map(TdApiHelp.FileHandler::getFile)
+                                            .map(file -> file.local == null || (
+                                                    !file.local.isDownloadingActive
+                                                    && !file.local.isDownloadingCompleted
+                                                    && file.local.downloadedSize == 0
+                                            ))
+                                            .orElse(false)
+                            )
+                            .toArray(TdApi.Message[]::new);
+                    if (ArrayUtil.isEmpty(messages)) {
+                        searchChatMessages.fromMessageId = foundChatMessages.nextFromMessageId;
+                        return getIdleChatFiles(searchChatMessages);
+                    } else {
+                        foundChatMessages.messages = messages;
+                        return Future.succeededFuture(foundChatMessages);
+                    }
+                });
+    }
+
     public Future<JsonObject> getChatFilesCount(long chatId) {
         return Future.all(
                 Stream.of(new TdApi.SearchMessagesFilterPhotoAndVideo(),
@@ -363,7 +390,13 @@ public Future<TdApi.File> startDownload(Long chatId, Long messageId, Integer fil
                     TdApi.Message message = results.resultAt(1);
                     if (file.local != null) {
                         if (file.local.isDownloadingCompleted) {
-                            return Future.failedFuture("File already downloaded");
+                            return DataVerticle.fileRepository.updateStatus(
+                                    file.id,
+                                    file.remote.uniqueId,
+                                    file.local.path,
+                                    FileRecord.DownloadStatus.completed,
+                                    System.currentTimeMillis()
+                            ).compose(r -> Future.failedFuture("File is already downloaded successfully"));
                         }
                         if (file.local.isDownloadingActive) {
                             return Future.failedFuture("File is downloading");
@@ -862,10 +895,9 @@ private Future<JsonArray> convertChat(List<TdApi.Chat> chats) {
                 ));
     }
 
-    private Future<JsonObject> convertFiles(Tuple2<TdApi.FoundChatMessages, Map<String, FileRecord>> tuple, MultiMap filter) {
+    private Future<JsonObject> convertFiles(Tuple2<TdApi.FoundChatMessages, Map<String, FileRecord>> tuple) {
         TdApi.FoundChatMessages foundChatMessages = tuple.v1;
         Map<String, FileRecord> fileRecords = tuple.v2;
-        boolean searchIdle = Objects.equals(filter.get("status"), FileRecord.DownloadStatus.idle.name());
 
         return DataVerticle.settingRepository.<Boolean>getByKey(SettingKey.uniqueOnly)
                 .map(uniqueOnly -> {
@@ -890,9 +922,6 @@ private Future<JsonObject> convertFiles(Tuple2<TdApi.FoundChatMessages, Map<Stri
                                 } else {
                                     fileRecord = fileRecord.withSourceField(source.id(), source.downloadedSize());
                                 }
-                                if (searchIdle && !Objects.equals(fileRecord.downloadStatus(), FileRecord.DownloadStatus.idle.name())) {
-                                    return null;
-                                }
 
                                 //TODO Processing of the same file under different accounts