(backend: ISyncBackend, info: BookInfo)
| 964 | } |
| 965 | |
| 966 | function buildUploadFileTask(backend: ISyncBackend, info: BookInfo): FileTask { |
| 967 | const bookTitle = info.book.title || "未知书籍"; |
| 968 | return { |
| 969 | label: bookTitle, |
| 970 | run: async (onProgress) => { |
| 971 | const taskStart = Date.now(); |
| 972 | try { |
| 973 | console.log(`[Sync] 📤 Uploading book: ${bookTitle} → ${info.remoteFilePath}`); |
| 974 | const bytes = await uploadFileToRemote( |
| 975 | backend, |
| 976 | info.remoteFilePath, |
| 977 | info.localFilePath, |
| 978 | onProgress, |
| 979 | ); |
| 980 | const size = bytes === null ? "" : ` (${(bytes / 1024 / 1024).toFixed(2)} MB)`; |
| 981 | console.log(`[Sync] ✓ Uploaded "${bookTitle}"${size} in ${Date.now() - taskStart}ms`); |
| 982 | return true; |
| 983 | } catch (e) { |
| 984 | console.log(`[Sync] ✗ Failed to upload "${bookTitle}": ${e}`); |
| 985 | return false; |
| 986 | } |
| 987 | }, |
| 988 | }; |
| 989 | } |
| 990 | |
| 991 | function buildDownloadFileTask( |
| 992 | backend: ISyncBackend, |
no test coverage detected