瀏覽代碼

Remove implicit electron dependency

Manav Rathi 1 年之前
父節點
當前提交
ea34eebfc9

+ 14 - 5
web/apps/photos/src/services/export/index.ts

@@ -485,6 +485,7 @@ class ExportService {
         renamedCollections: Collection[],
         renamedCollections: Collection[],
         isCanceled: CancellationStatus,
         isCanceled: CancellationStatus,
     ) {
     ) {
+        const fs = ensureElectron().fs;
         try {
         try {
             for (const collection of renamedCollections) {
             for (const collection of renamedCollections) {
                 try {
                 try {
@@ -498,6 +499,7 @@ class ExportService {
                     const newCollectionExportName = await safeDirectoryName(
                     const newCollectionExportName = await safeDirectoryName(
                         exportFolder,
                         exportFolder,
                         getCollectionUserFacingName(collection),
                         getCollectionUserFacingName(collection),
+                        fs.exists,
                     );
                     );
                     log.info(
                     log.info(
                         `renaming collection with id ${collection.id} from ${oldCollectionExportName} to ${newCollectionExportName}`,
                         `renaming collection with id ${collection.id} from ${oldCollectionExportName} to ${newCollectionExportName}`,
@@ -513,7 +515,7 @@ class ExportService {
                         newCollectionExportName,
                         newCollectionExportName,
                     );
                     );
                     try {
                     try {
-                        await ensureElectron().fs.rename(
+                        await fs.rename(
                             oldCollectionExportPath,
                             oldCollectionExportPath,
                             newCollectionExportPath,
                             newCollectionExportPath,
                         );
                         );
@@ -1017,15 +1019,17 @@ class ExportService {
         collectionID: number,
         collectionID: number,
         collectionIDNameMap: Map<number, string>,
         collectionIDNameMap: Map<number, string>,
     ) {
     ) {
+        const electron = ensureElectron();
         await this.verifyExportFolderExists(exportFolder);
         await this.verifyExportFolderExists(exportFolder);
         const collectionName = collectionIDNameMap.get(collectionID);
         const collectionName = collectionIDNameMap.get(collectionID);
         const collectionExportName = await safeDirectoryName(
         const collectionExportName = await safeDirectoryName(
             exportFolder,
             exportFolder,
             collectionName,
             collectionName,
+            electron.fs.exists,
         );
         );
         const collectionExportPath = `${exportFolder}/${collectionExportName}`;
         const collectionExportPath = `${exportFolder}/${collectionExportName}`;
-        await ensureElectron().checkExistsAndCreateDir(collectionExportPath);
-        await ensureElectron().checkExistsAndCreateDir(
+        await electron.checkExistsAndCreateDir(collectionExportPath);
+        await electron.checkExistsAndCreateDir(
             getMetadataFolderExportPath(collectionExportPath),
             getMetadataFolderExportPath(collectionExportPath),
         );
         );
 
 
@@ -1037,6 +1041,7 @@ class ExportService {
         collectionExportPath: string,
         collectionExportPath: string,
         file: EnteFile,
         file: EnteFile,
     ): Promise<void> {
     ): Promise<void> {
+        const electron = ensureElectron();
         try {
         try {
             const fileUID = getExportRecordFileUID(file);
             const fileUID = getExportRecordFileUID(file);
             const originalFileStream = await downloadManager.getFile(file);
             const originalFileStream = await downloadManager.getFile(file);
@@ -1060,6 +1065,7 @@ class ExportService {
                 const fileExportName = await safeFileName(
                 const fileExportName = await safeFileName(
                     collectionExportPath,
                     collectionExportPath,
                     file.metadata.title,
                     file.metadata.title,
+                    electron.fs.exists,
                 );
                 );
                 await this.addFileExportedRecord(
                 await this.addFileExportedRecord(
                     exportDir,
                     exportDir,
@@ -1072,7 +1078,7 @@ class ExportService {
                         fileExportName,
                         fileExportName,
                         file,
                         file,
                     );
                     );
-                    await ensureElectron().saveStreamToDisk(
+                    await electron.saveStreamToDisk(
                         `${collectionExportPath}/${fileExportName}`,
                         `${collectionExportPath}/${fileExportName}`,
                         updatedFileStream,
                         updatedFileStream,
                     );
                     );
@@ -1094,15 +1100,18 @@ class ExportService {
         fileStream: ReadableStream<any>,
         fileStream: ReadableStream<any>,
         file: EnteFile,
         file: EnteFile,
     ) {
     ) {
+        const electron = ensureElectron();
         const fileBlob = await new Response(fileStream).blob();
         const fileBlob = await new Response(fileStream).blob();
         const livePhoto = await decodeLivePhoto(file, fileBlob);
         const livePhoto = await decodeLivePhoto(file, fileBlob);
         const imageExportName = await safeFileName(
         const imageExportName = await safeFileName(
             collectionExportPath,
             collectionExportPath,
             livePhoto.imageNameTitle,
             livePhoto.imageNameTitle,
+            electron.fs.exists,
         );
         );
         const videoExportName = await safeFileName(
         const videoExportName = await safeFileName(
             collectionExportPath,
             collectionExportPath,
             livePhoto.videoNameTitle,
             livePhoto.videoNameTitle,
+            electron.fs.exists,
         );
         );
         const livePhotoExportName = getLivePhotoExportName(
         const livePhotoExportName = getLivePhotoExportName(
             imageExportName,
             imageExportName,
@@ -1120,7 +1129,7 @@ class ExportService {
                 imageExportName,
                 imageExportName,
                 file,
                 file,
             );
             );
-            await ensureElectron().saveStreamToDisk(
+            await electron.saveStreamToDisk(
                 `${collectionExportPath}/${imageExportName}`,
                 `${collectionExportPath}/${imageExportName}`,
                 imageStream,
                 imageStream,
             );
             );

+ 3 - 0
web/apps/photos/src/services/export/migration.ts

@@ -208,6 +208,7 @@ async function migrateCollectionFolders(
         const newCollectionExportPath = await safeDirectoryName(
         const newCollectionExportPath = await safeDirectoryName(
             exportDir,
             exportDir,
             collection.name,
             collection.name,
+            fs.exists,
         );
         );
         collectionIDPathMap.set(collection.id, newCollectionExportPath);
         collectionIDPathMap.set(collection.id, newCollectionExportPath);
         if (!(await fs.exists(oldCollectionExportPath))) continue;
         if (!(await fs.exists(oldCollectionExportPath))) continue;
@@ -228,6 +229,7 @@ async function migrateFiles(
     files: EnteFile[],
     files: EnteFile[],
     collectionIDPathMap: Map<number, string>,
     collectionIDPathMap: Map<number, string>,
 ) {
 ) {
+    const fs = ensureElectron().fs;
     for (const file of files) {
     for (const file of files) {
         const collectionPath = collectionIDPathMap.get(file.collectionID);
         const collectionPath = collectionIDPathMap.get(file.collectionID);
         const metadataPath = `${collectionPath}/${exportMetadataDirectoryName}`;
         const metadataPath = `${collectionPath}/${exportMetadataDirectoryName}`;
@@ -239,6 +241,7 @@ async function migrateFiles(
         const newFileName = await safeFileName(
         const newFileName = await safeFileName(
             collectionPath,
             collectionPath,
             file.metadata.title,
             file.metadata.title,
+            fs.exists,
         );
         );
         const newFilePath = `${collectionPath}/${newFileName}`;
         const newFilePath = `${collectionPath}/${newFileName}`;
         const newFileMetadataPath = `${metadataPath}/${newFileName}.json`;
         const newFileMetadataPath = `${metadataPath}/${newFileName}.json`;

+ 2 - 0
web/apps/photos/src/utils/collection/index.ts

@@ -1,3 +1,4 @@
+import { ensureElectron } from "@/next/electron";
 import log from "@/next/log";
 import log from "@/next/log";
 import { CustomError } from "@ente/shared/error";
 import { CustomError } from "@ente/shared/error";
 import { getAlbumsURL } from "@ente/shared/network/api";
 import { getAlbumsURL } from "@ente/shared/network/api";
@@ -172,6 +173,7 @@ async function createCollectionDownloadFolder(
     const collectionDownloadName = await safeDirectoryName(
     const collectionDownloadName = await safeDirectoryName(
         downloadDirPath,
         downloadDirPath,
         collectionName,
         collectionName,
+        ensureElectron().fs.exists,
     );
     );
     const collectionDownloadPath = `${downloadDirPath}/${collectionDownloadName}`;
     const collectionDownloadPath = `${downloadDirPath}/${collectionDownloadName}`;
     await exportService.checkExistsAndCreateDir(collectionDownloadPath);
     await exportService.checkExistsAndCreateDir(collectionDownloadPath);

+ 3 - 0
web/apps/photos/src/utils/file/index.ts

@@ -815,6 +815,7 @@ async function downloadFileDesktop(
         const imageExportName = await safeFileName(
         const imageExportName = await safeFileName(
             downloadPath,
             downloadPath,
             livePhoto.imageNameTitle,
             livePhoto.imageNameTitle,
+            electron.fs.exists,
         );
         );
         const imageStream = generateStreamFromArrayBuffer(livePhoto.image);
         const imageStream = generateStreamFromArrayBuffer(livePhoto.image);
         await electron.saveStreamToDisk(
         await electron.saveStreamToDisk(
@@ -825,6 +826,7 @@ async function downloadFileDesktop(
             const videoExportName = await safeFileName(
             const videoExportName = await safeFileName(
                 downloadPath,
                 downloadPath,
                 livePhoto.videoNameTitle,
                 livePhoto.videoNameTitle,
+                electron.fs.exists,
             );
             );
             const videoStream = generateStreamFromArrayBuffer(livePhoto.video);
             const videoStream = generateStreamFromArrayBuffer(livePhoto.video);
             await electron.saveStreamToDisk(
             await electron.saveStreamToDisk(
@@ -839,6 +841,7 @@ async function downloadFileDesktop(
         const fileExportName = await safeFileName(
         const fileExportName = await safeFileName(
             downloadPath,
             downloadPath,
             file.metadata.title,
             file.metadata.title,
+            electron.fs.exists,
         );
         );
         await electron.saveStreamToDisk(
         await electron.saveStreamToDisk(
             `${downloadPath}/${fileExportName}`,
             `${downloadPath}/${fileExportName}`,

+ 13 - 18
web/apps/photos/src/utils/native-fs.ts

@@ -1,12 +1,10 @@
 /**
 /**
- * @file Native filesystem access using custom Node.js functionality provided by
- * our desktop app.
+ * @file Utilities for native filesystem access.
  *
  *
- * Precondition: Unless mentioned otherwise, the functions in these file only
- * work when we are running in our desktop app.
+ * While they don't have any direct dependencies to our desktop app, they were
+ * written for use by the code that runs in our desktop app.
  */
  */
 
 
-import { ensureElectron } from "@/next/electron";
 import { nameAndExtension } from "@/next/file";
 import { nameAndExtension } from "@/next/file";
 import sanitize from "sanitize-filename";
 import sanitize from "sanitize-filename";
 import {
 import {
@@ -31,15 +29,15 @@ export const sanitizeFilename = (s: string) =>
  * We also ensure we don't return names which might collide with our own special
  * We also ensure we don't return names which might collide with our own special
  * directories.
  * directories.
  *
  *
- * This function only works when we are running inside an electron app (since it
- * requires permissionless access to the native filesystem to find a new
- * filename that doesn't conflict with any existing items).
+ * @param exists A function to check if an item already exists at the given
+ * path. Usually, you'd pass `fs.exists` from {@link Electron}.
  *
  *
- * See also: {@link safeDirectoryName}
+ * See also: {@link safeFileame}
  */
  */
 export const safeDirectoryName = async (
 export const safeDirectoryName = async (
     directoryPath: string,
     directoryPath: string,
     name: string,
     name: string,
+    exists: (path: string) => Promise<boolean>,
 ): Promise<string> => {
 ): Promise<string> => {
     const specialDirectoryNames = [
     const specialDirectoryNames = [
         exportTrashDirectoryName,
         exportTrashDirectoryName,
@@ -62,10 +60,13 @@ export const safeDirectoryName = async (
  * Return a new sanitized and unique file name based on {@link name} that is not
  * Return a new sanitized and unique file name based on {@link name} that is not
  * the same as any existing item in the given {@link directoryPath}.
  * the same as any existing item in the given {@link directoryPath}.
  *
  *
- * This function only works when we are running inside an electron app.
- * @see {@link safeDirectoryName}.
+ * This is a sibling of {@link safeDirectoryName} for use with file names.
  */
  */
-export const safeFileName = async (directoryPath: string, name: string) => {
+export const safeFileName = async (
+    directoryPath: string,
+    name: string,
+    exists: (path: string) => Promise<boolean>,
+) => {
     let result = sanitizeFilename(name);
     let result = sanitizeFilename(name);
     let count = 1;
     let count = 1;
     while (await exists(`${directoryPath}/${result}`)) {
     while (await exists(`${directoryPath}/${result}`)) {
@@ -76,9 +77,3 @@ export const safeFileName = async (directoryPath: string, name: string) => {
     }
     }
     return result;
     return result;
 };
 };
-
-/**
- * Return true if an item exists an the given {@link path} on the user's local
- * filesystem.
- */
-const exists = (path: string) => ensureElectron().fs.exists(path);