MCPcopy
hub / github.com/codedogQBY/ReadAny / downloadBookFile

Function downloadBookFile

packages/core/src/sync/sync-files.ts:1238–1372  ·  view source on GitHub ↗
(
  backend: ISyncBackend,
  bookId: string,
  filePath: string,
  onProgress?: (progress: { downloaded: number; total: number }) => void,
)

Source from the content-addressed store, hash-verified

1236 * pushed (and therefore not yet migrated) can still serve the book.
1237 */
1238export async function downloadBookFile(
1239 backend: ISyncBackend,
1240 bookId: string,
1241 filePath: string,
1242 onProgress?: (progress: { downloaded: number; total: number }) => void,
1243): Promise<DownloadBookOutcome> {
1244 const adapter = getSyncAdapter();
1245 const { setBookSyncStatus } = await import("../db/database");
1246
1247 try {
1248 const ext = getExt(filePath) || "epub";
1249
1250 // Resolve book title for new-path computation.
1251 const db = await getDB();
1252 const rows = await db.select<{ id: string; title: string }>(
1253 "SELECT id, title FROM books WHERE id = ?",
1254 [bookId],
1255 );
1256 const book = rows[0] ?? null;
1257
1258 const newPath = book ? buildBookRemoteFile(book, ext) : "";
1259 const legacyPath = `${REMOTE_FILES}/${bookId}.${ext}`;
1260
1261 onProgress?.({ downloaded: 0, total: 100 });
1262
1263 // Track whether *every* failure we saw was a 404. If so, the remote
1264 // genuinely doesn't have the file. If at least one attempt failed with
1265 // some other error, it's an "error" outcome — the caller can retry.
1266 let sawNon404Error = false;
1267 const noteFailure = (e: unknown) => {
1268 const msg = (e as { message?: string })?.message ?? "";
1269 if (!/404|not found/i.test(msg)) sawNon404Error = true;
1270 };
1271
1272 const appDataDir = await adapter.getAppDataDir();
1273 const localPath = isAbsoluteOrProtocolPath(filePath)
1274 ? filePath
1275 : adapter.joinPath(appDataDir, filePath);
1276 const reportDownloadProgress = (loaded: number, total: number) => {
1277 if (total > 0) onProgress?.({ downloaded: loaded, total });
1278 };
1279 let downloaded = false;
1280 if (newPath) {
1281 try {
1282 await downloadRemoteFileToPath(backend, newPath, localPath, reportDownloadProgress);
1283 downloaded = true;
1284 console.log(`[Sync] Downloaded ${newPath} (new layout)`);
1285 } catch (e) {
1286 noteFailure(e);
1287 const msg = (e as { message?: string })?.message ?? "";
1288 if (!/404|not found/i.test(msg)) {
1289 console.warn(`[Sync] New-layout fetch failed (${msg}); trying legacy path`);
1290 }
1291 }
1292 }
1293 if (!downloaded) {
1294 try {
1295 await downloadRemoteFileToPath(backend, legacyPath, localPath, reportDownloadProgress);

Callers 3

openDesktopBookFunction · 0.90
useBookDownloadFunction · 0.85
sync-files.test.tsFile · 0.85

Calls 15

getSyncAdapterFunction · 0.90
buildBookRemoteFileFunction · 0.90
sanitizeBookTitleForFsFunction · 0.90
parseBookFolderNameFunction · 0.90
getExtFunction · 0.85
getDBFunction · 0.85
isAbsoluteOrProtocolPathFunction · 0.85
downloadRemoteFileToPathFunction · 0.85
noteFailureFunction · 0.85
setBookSyncStatusFunction · 0.85
findMethod · 0.80
getAppDataDirMethod · 0.65

Tested by

no test coverage detected