better handle export folder doesn't exist issues
This commit is contained in:
parent
82d48fcfd8
commit
900d69a60d
|
@ -113,7 +113,7 @@ export default function ExportModal(props: Props) {
|
||||||
// =======================
|
// =======================
|
||||||
|
|
||||||
const verifyExportFolderExists = () => {
|
const verifyExportFolderExists = () => {
|
||||||
if (!exportFolder || !exportService.exists(exportFolder)) {
|
if (!exportService.exportFolderExists(exportFolder)) {
|
||||||
appContext.setDialogMessage(
|
appContext.setDialogMessage(
|
||||||
getExportDirectoryDoesNotExistMessage()
|
getExportDirectoryDoesNotExistMessage()
|
||||||
);
|
);
|
||||||
|
@ -123,17 +123,25 @@ export default function ExportModal(props: Props) {
|
||||||
|
|
||||||
const syncExportRecord = async (exportFolder: string): Promise<void> => {
|
const syncExportRecord = async (exportFolder: string): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
|
if (!exportService.exportFolderExists(exportFolder)) {
|
||||||
|
const fileExportStats = await exportService.getFileExportStats(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
setFileExportStats(fileExportStats);
|
||||||
|
}
|
||||||
const exportRecord = await exportService.getExportRecord(
|
const exportRecord = await exportService.getExportRecord(
|
||||||
exportFolder
|
exportFolder
|
||||||
);
|
);
|
||||||
setExportStage(exportRecord?.stage ?? ExportStage.INIT);
|
setExportStage(exportRecord.stage);
|
||||||
setLastExportTime(exportRecord?.lastAttemptTimestamp ?? 0);
|
setLastExportTime(exportRecord.lastAttemptTimestamp);
|
||||||
const fileExportStats = await exportService.getFileExportStats(
|
const fileExportStats = await exportService.getFileExportStats(
|
||||||
exportRecord
|
exportRecord
|
||||||
);
|
);
|
||||||
setFileExportStats(fileExportStats);
|
setFileExportStats(fileExportStats);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'syncExportRecord failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
|
logError(e, 'syncExportRecord failed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -257,17 +257,20 @@ export default function App(props) {
|
||||||
try {
|
try {
|
||||||
addLogLine('init export');
|
addLogLine('init export');
|
||||||
const exportSettings = exportService.getExportSettings();
|
const exportSettings = exportService.getExportSettings();
|
||||||
|
if (!exportService.exportFolderExists(exportSettings?.folder)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const exportRecord = await exportService.getExportRecord(
|
const exportRecord = await exportService.getExportRecord(
|
||||||
exportSettings?.folder
|
exportSettings.folder
|
||||||
);
|
);
|
||||||
await exportService.runMigration(
|
await exportService.runMigration(
|
||||||
exportSettings?.folder,
|
exportSettings.folder,
|
||||||
exportRecord
|
exportRecord
|
||||||
);
|
);
|
||||||
if (exportSettings?.continuousExport) {
|
if (exportSettings.continuousExport) {
|
||||||
exportService.enableContinuousExport();
|
exportService.enableContinuousExport();
|
||||||
}
|
}
|
||||||
if (exportRecord?.stage === ExportStage.INPROGRESS) {
|
if (exportRecord.stage === ExportStage.INPROGRESS) {
|
||||||
addLogLine('export was in progress, resuming');
|
addLogLine('export was in progress, resuming');
|
||||||
exportService.scheduleExport();
|
exportService.scheduleExport();
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,14 @@ const EXPORT_RECORD_FILE_NAME = 'export_status.json';
|
||||||
|
|
||||||
export const ENTE_EXPORT_DIRECTORY = 'ente Photos';
|
export const ENTE_EXPORT_DIRECTORY = 'ente Photos';
|
||||||
|
|
||||||
|
export const NULL_EXPORT_RECORD: ExportRecord = {
|
||||||
|
version: 3,
|
||||||
|
lastAttemptTimestamp: null,
|
||||||
|
stage: ExportStage.INIT,
|
||||||
|
fileExportNames: {},
|
||||||
|
collectionExportNames: {},
|
||||||
|
};
|
||||||
|
|
||||||
class ExportService {
|
class ExportService {
|
||||||
private electronAPIs: ElectronAPIs;
|
private electronAPIs: ElectronAPIs;
|
||||||
private exportInProgress: boolean = false;
|
private exportInProgress: boolean = false;
|
||||||
|
@ -115,11 +123,13 @@ class ExportService {
|
||||||
|
|
||||||
async runMigration(exportDir: string, exportRecord: ExportRecord) {
|
async runMigration(exportDir: string, exportRecord: ExportRecord) {
|
||||||
try {
|
try {
|
||||||
|
addLogLine('running migration');
|
||||||
this.migrationInProgress = migrateExportJSON(
|
this.migrationInProgress = migrateExportJSON(
|
||||||
exportDir,
|
exportDir,
|
||||||
exportRecord
|
exportRecord
|
||||||
);
|
);
|
||||||
await this.migrationInProgress;
|
await this.migrationInProgress;
|
||||||
|
addLogLine('migration completed');
|
||||||
this.migrationInProgress = null;
|
this.migrationInProgress = null;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'migration failed');
|
logError(e, 'migration failed');
|
||||||
|
@ -263,7 +273,8 @@ class ExportService {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async preExport() {
|
async preExport(exportFolder: string) {
|
||||||
|
this.verifyExportFolderExists(exportFolder);
|
||||||
this.stopExport = false;
|
this.stopExport = false;
|
||||||
await this.updateExportStage(ExportStage.INPROGRESS);
|
await this.updateExportStage(ExportStage.INPROGRESS);
|
||||||
this.updateExportProgress({
|
this.updateExportProgress({
|
||||||
|
@ -274,14 +285,24 @@ class ExportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async postExport() {
|
async postExport() {
|
||||||
await this.updateExportStage(ExportStage.FINISHED);
|
try {
|
||||||
await this.updateLastExportTime(Date.now());
|
const exportSettings = this.getExportSettings();
|
||||||
|
if (!this.exportFolderExists(exportSettings?.folder)) {
|
||||||
|
this.uiUpdater.setExportStage(ExportStage.INIT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await this.updateExportStage(ExportStage.FINISHED);
|
||||||
|
await this.updateLastExportTime(Date.now());
|
||||||
|
|
||||||
const exportSettings = this.getExportSettings();
|
const exportRecord = await this.getExportRecord(
|
||||||
const exportRecord = await this.getExportRecord(exportSettings?.folder);
|
exportSettings?.folder
|
||||||
|
);
|
||||||
|
|
||||||
const fileExportStats = await this.getFileExportStats(exportRecord);
|
const fileExportStats = await this.getFileExportStats(exportRecord);
|
||||||
this.uiUpdater.setFileExportStats(fileExportStats);
|
this.uiUpdater.setFileExportStats(fileExportStats);
|
||||||
|
} catch (e) {
|
||||||
|
logError(e, 'postExport failed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopRunningExport() {
|
async stopRunningExport() {
|
||||||
|
@ -310,9 +331,11 @@ class ExportService {
|
||||||
this.migrationInProgress = null;
|
this.migrationInProgress = null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await this.preExport();
|
const exportSettings = this.getExportSettings();
|
||||||
|
const exportFolder = exportSettings?.folder;
|
||||||
|
await this.preExport(exportFolder);
|
||||||
addLogLine('export started');
|
addLogLine('export started');
|
||||||
await this.runExport();
|
await this.runExport(exportFolder);
|
||||||
addLogLine('export completed');
|
addLogLine('export completed');
|
||||||
} finally {
|
} finally {
|
||||||
this.exportInProgress = false;
|
this.exportInProgress = false;
|
||||||
|
@ -330,12 +353,8 @@ class ExportService {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private async runExport() {
|
private async runExport(exportFolder: string) {
|
||||||
try {
|
try {
|
||||||
const exportSettings = this.getExportSettings();
|
|
||||||
if (!exportSettings?.folder) {
|
|
||||||
throw new Error(CustomError.NO_EXPORT_FOLDER_SELECTED);
|
|
||||||
}
|
|
||||||
const user: User = getData(LS_KEYS.USER);
|
const user: User = getData(LS_KEYS.USER);
|
||||||
const files = mergeMetadata(await getLocalFiles());
|
const files = mergeMetadata(await getLocalFiles());
|
||||||
const personalFiles = getPersonalFiles(files, user);
|
const personalFiles = getPersonalFiles(files, user);
|
||||||
|
@ -347,9 +366,7 @@ class ExportService {
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
const exportRecord = await this.getExportRecord(
|
const exportRecord = await this.getExportRecord(exportFolder);
|
||||||
exportSettings.folder
|
|
||||||
);
|
|
||||||
const collectionIDExportNameMap =
|
const collectionIDExportNameMap =
|
||||||
convertCollectionIDExportNameObjectToMap(
|
convertCollectionIDExportNameObjectToMap(
|
||||||
exportRecord.collectionExportNames
|
exportRecord.collectionExportNames
|
||||||
|
@ -412,7 +429,7 @@ class ExportService {
|
||||||
if (renamedCollections?.length > 0) {
|
if (renamedCollections?.length > 0) {
|
||||||
addLogLine(`renaming ${renamedCollections.length} collections`);
|
addLogLine(`renaming ${renamedCollections.length} collections`);
|
||||||
this.collectionRenamer(
|
this.collectionRenamer(
|
||||||
exportSettings.folder,
|
exportFolder,
|
||||||
collectionIDExportNameMap,
|
collectionIDExportNameMap,
|
||||||
renamedCollections,
|
renamedCollections,
|
||||||
incrementSuccess,
|
incrementSuccess,
|
||||||
|
@ -423,7 +440,7 @@ class ExportService {
|
||||||
if (removedFileUIDs?.length > 0) {
|
if (removedFileUIDs?.length > 0) {
|
||||||
addLogLine(`trashing ${removedFileUIDs.length} files`);
|
addLogLine(`trashing ${removedFileUIDs.length} files`);
|
||||||
await this.fileTrasher(
|
await this.fileTrasher(
|
||||||
exportSettings.folder,
|
exportFolder,
|
||||||
collectionIDExportNameMap,
|
collectionIDExportNameMap,
|
||||||
removedFileUIDs,
|
removedFileUIDs,
|
||||||
incrementSuccess,
|
incrementSuccess,
|
||||||
|
@ -436,7 +453,7 @@ class ExportService {
|
||||||
filesToExport,
|
filesToExport,
|
||||||
collectionIDNameMap,
|
collectionIDNameMap,
|
||||||
collectionIDExportNameMap,
|
collectionIDExportNameMap,
|
||||||
exportSettings.folder,
|
exportFolder,
|
||||||
incrementSuccess,
|
incrementSuccess,
|
||||||
incrementFailed
|
incrementFailed
|
||||||
);
|
);
|
||||||
|
@ -447,13 +464,16 @@ class ExportService {
|
||||||
);
|
);
|
||||||
await this.collectionRemover(
|
await this.collectionRemover(
|
||||||
deletedExportedCollections,
|
deletedExportedCollections,
|
||||||
exportSettings.folder,
|
exportFolder,
|
||||||
incrementSuccess,
|
incrementSuccess,
|
||||||
incrementFailed
|
incrementFailed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'runExport failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
|
logError(e, 'runExport failed');
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,6 +487,7 @@ class ExportService {
|
||||||
try {
|
try {
|
||||||
for (const collection of renamedCollections) {
|
for (const collection of renamedCollections) {
|
||||||
try {
|
try {
|
||||||
|
this.verifyExportFolderExists(exportFolder);
|
||||||
const oldCollectionExportName =
|
const oldCollectionExportName =
|
||||||
collectionIDExportNameMap.get(collection.id);
|
collectionIDExportNameMap.get(collection.id);
|
||||||
const oldCollectionExportPath = getCollectionExportPath(
|
const oldCollectionExportPath = getCollectionExportPath(
|
||||||
|
@ -509,14 +530,17 @@ class ExportService {
|
||||||
logError(e, 'collectionRenamer failed a collection');
|
logError(e, 'collectionRenamer failed a collection');
|
||||||
if (
|
if (
|
||||||
e.message ===
|
e.message ===
|
||||||
CustomError.ADD_FILE_EXPORTED_RECORD_FAILED
|
CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
|
||||||
|
e.message === CustomError.EXPORT_FOLDER_DOES_NOT_EXIST
|
||||||
) {
|
) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'collectionRenamer failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
|
logError(e, 'collectionRenamer failed');
|
||||||
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -535,6 +559,7 @@ class ExportService {
|
||||||
);
|
);
|
||||||
for (const collectionID of deletedExportedCollectionIDs) {
|
for (const collectionID of deletedExportedCollectionIDs) {
|
||||||
try {
|
try {
|
||||||
|
this.verifyExportFolderExists(exportFolder);
|
||||||
addLocalLog(
|
addLocalLog(
|
||||||
() =>
|
() =>
|
||||||
`removing collection with id ${collectionID} from export folder`
|
`removing collection with id ${collectionID} from export folder`
|
||||||
|
@ -571,14 +596,17 @@ class ExportService {
|
||||||
logError(e, 'collectionRemover failed a collection');
|
logError(e, 'collectionRemover failed a collection');
|
||||||
if (
|
if (
|
||||||
e.message ===
|
e.message ===
|
||||||
CustomError.ADD_FILE_EXPORTED_RECORD_FAILED
|
CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
|
||||||
|
e.message === CustomError.EXPORT_FOLDER_DOES_NOT_EXIST
|
||||||
) {
|
) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'collectionRemover failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
|
logError(e, 'collectionRemover failed');
|
||||||
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -605,6 +633,7 @@ class ExportService {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
this.verifyExportFolderExists(exportDir);
|
||||||
let collectionExportName = collectionIDFolderNameMap.get(
|
let collectionExportName = collectionIDFolderNameMap.get(
|
||||||
file.collectionID
|
file.collectionID
|
||||||
);
|
);
|
||||||
|
@ -624,19 +653,14 @@ class ExportService {
|
||||||
file.collectionID,
|
file.collectionID,
|
||||||
collectionExportName
|
collectionExportName
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
const collectionExportPath = getCollectionExportPath(
|
|
||||||
exportDir,
|
|
||||||
collectionExportName
|
|
||||||
);
|
|
||||||
await this.electronAPIs.checkExistsAndCreateDir(
|
|
||||||
collectionExportPath
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
const collectionExportPath = getCollectionExportPath(
|
const collectionExportPath = getCollectionExportPath(
|
||||||
exportDir,
|
exportDir,
|
||||||
collectionExportName
|
collectionExportName
|
||||||
);
|
);
|
||||||
|
await this.electronAPIs.checkExistsAndCreateDir(
|
||||||
|
collectionExportPath
|
||||||
|
);
|
||||||
const fileExportName = await this.downloadAndSave(
|
const fileExportName = await this.downloadAndSave(
|
||||||
collectionExportPath,
|
collectionExportPath,
|
||||||
file
|
file
|
||||||
|
@ -652,14 +676,17 @@ class ExportService {
|
||||||
logError(e, 'export failed for a file');
|
logError(e, 'export failed for a file');
|
||||||
if (
|
if (
|
||||||
e.message ===
|
e.message ===
|
||||||
CustomError.ADD_FILE_EXPORTED_RECORD_FAILED
|
CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
|
||||||
|
e.message === CustomError.EXPORT_FOLDER_DOES_NOT_EXIST
|
||||||
) {
|
) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'fileExporter failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
|
logError(e, 'fileExporter failed');
|
||||||
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -677,6 +704,7 @@ class ExportService {
|
||||||
exportRecord.fileExportNames
|
exportRecord.fileExportNames
|
||||||
);
|
);
|
||||||
for (const fileUID of removedFileUIDs) {
|
for (const fileUID of removedFileUIDs) {
|
||||||
|
this.verifyExportFolderExists(exportDir);
|
||||||
addLocalLog(() => `trashing file with id ${fileUID}`);
|
addLocalLog(() => `trashing file with id ${fileUID}`);
|
||||||
if (this.stopExport) {
|
if (this.stopExport) {
|
||||||
break;
|
break;
|
||||||
|
@ -773,14 +801,17 @@ class ExportService {
|
||||||
logError(e, 'trashing failed for a file');
|
logError(e, 'trashing failed for a file');
|
||||||
if (
|
if (
|
||||||
e.message ===
|
e.message ===
|
||||||
CustomError.ADD_FILE_EXPORTED_RECORD_FAILED
|
CustomError.UPDATE_EXPORTED_RECORD_FAILED ||
|
||||||
|
e.message === CustomError.EXPORT_FOLDER_DOES_NOT_EXIST
|
||||||
) {
|
) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'fileTrasher failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
|
logError(e, 'fileTrasher failed');
|
||||||
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -802,8 +833,10 @@ class ExportService {
|
||||||
};
|
};
|
||||||
await this.updateExportRecord(exportRecord, folder);
|
await this.updateExportRecord(exportRecord, folder);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'addFileExportedRecord failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
throw Error(CustomError.ADD_FILE_EXPORTED_RECORD_FAILED);
|
logError(e, 'addFileExportedRecord failed');
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,8 +857,10 @@ class ExportService {
|
||||||
|
|
||||||
await this.updateExportRecord(exportRecord, folder);
|
await this.updateExportRecord(exportRecord, folder);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'addCollectionExportedRecord failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
throw Error(CustomError.ADD_FILE_EXPORTED_RECORD_FAILED);
|
logError(e, 'addCollectionExportedRecord failed');
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,8 +876,10 @@ class ExportService {
|
||||||
|
|
||||||
await this.updateExportRecord(exportRecord, folder);
|
await this.updateExportRecord(exportRecord, folder);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'removeCollectionExportedRecord failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
throw Error(CustomError.ADD_FILE_EXPORTED_RECORD_FAILED);
|
logError(e, 'removeCollectionExportedRecord failed');
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,8 +893,10 @@ class ExportService {
|
||||||
);
|
);
|
||||||
await this.updateExportRecord(exportRecord, folder);
|
await this.updateExportRecord(exportRecord, folder);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'removeFileExportedRecord failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
throw Error(CustomError.ADD_FILE_EXPORTED_RECORD_FAILED);
|
logError(e, 'removeFileExportedRecord failed');
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,28 +917,35 @@ class ExportService {
|
||||||
}
|
}
|
||||||
const exportRecord = await this.getExportRecord(folder);
|
const exportRecord = await this.getExportRecord(folder);
|
||||||
const newRecord: ExportRecord = { ...exportRecord, ...newData };
|
const newRecord: ExportRecord = { ...exportRecord, ...newData };
|
||||||
await this.electronAPIs.setExportRecord(
|
await this.electronAPIs.saveFileToDisk(
|
||||||
`${folder}/${EXPORT_RECORD_FILE_NAME}`,
|
`${folder}/${EXPORT_RECORD_FILE_NAME}`,
|
||||||
JSON.stringify(newRecord, null, 2)
|
JSON.stringify(newRecord, null, 2)
|
||||||
);
|
);
|
||||||
return newRecord;
|
return newRecord;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (e.message === CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
logError(e, 'error updating Export Record');
|
logError(e, 'error updating Export Record');
|
||||||
throw e;
|
throw Error(CustomError.UPDATE_EXPORTED_RECORD_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getExportRecord(folder: string): Promise<ExportRecord> {
|
async getExportRecord(folder: string): Promise<ExportRecord> {
|
||||||
try {
|
try {
|
||||||
if (!folder || !this.exists(folder)) {
|
this.verifyExportFolderExists(folder);
|
||||||
return null;
|
const exportRecordJSONPath = `${folder}/${EXPORT_RECORD_FILE_NAME}`;
|
||||||
|
if (!this.exists(exportRecordJSONPath)) {
|
||||||
|
return this.createEmptyExportRecord(folder);
|
||||||
}
|
}
|
||||||
const recordFile = await this.electronAPIs.getExportRecord(
|
const recordFile = await this.electronAPIs.readTextFile(
|
||||||
`${folder}/${EXPORT_RECORD_FILE_NAME}`
|
exportRecordJSONPath
|
||||||
);
|
);
|
||||||
return JSON.parse(recordFile);
|
return JSON.parse(recordFile);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'export Record JSON parsing failed');
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
|
logError(e, 'export Record JSON parsing failed');
|
||||||
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -909,6 +955,7 @@ class ExportService {
|
||||||
collectionID: number,
|
collectionID: number,
|
||||||
collectionIDNameMap: Map<number, string>
|
collectionIDNameMap: Map<number, string>
|
||||||
) {
|
) {
|
||||||
|
this.verifyExportFolderExists(exportFolder);
|
||||||
const collectionName = collectionIDNameMap.get(collectionID);
|
const collectionName = collectionIDNameMap.get(collectionID);
|
||||||
const collectionExportName = getUniqueCollectionExportName(
|
const collectionExportName = getUniqueCollectionExportName(
|
||||||
exportFolder,
|
exportFolder,
|
||||||
|
@ -1057,5 +1104,31 @@ class ExportService {
|
||||||
checkExistsAndCreateDir = (path: string) => {
|
checkExistsAndCreateDir = (path: string) => {
|
||||||
return this.electronAPIs.checkExistsAndCreateDir(path);
|
return this.electronAPIs.checkExistsAndCreateDir(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exportFolderExists = (exportFolder: string) => {
|
||||||
|
return exportFolder && this.exists(exportFolder);
|
||||||
|
};
|
||||||
|
|
||||||
|
private verifyExportFolderExists = (exportFolder: string) => {
|
||||||
|
try {
|
||||||
|
if (!this.exportFolderExists(exportFolder)) {
|
||||||
|
throw Error(CustomError.EXPORT_FOLDER_DOES_NOT_EXIST);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
|
||||||
|
logError(e, 'verifyExportFolderExists failed');
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private createEmptyExportRecord = async (exportFolder: string) => {
|
||||||
|
const exportRecord: ExportRecord = NULL_EXPORT_RECORD;
|
||||||
|
await this.electronAPIs.saveFileToDisk(
|
||||||
|
`${exportFolder}/${EXPORT_RECORD_FILE_NAME}`,
|
||||||
|
JSON.stringify(exportRecord, null, 2)
|
||||||
|
);
|
||||||
|
return exportRecord;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
export default new ExportService();
|
export default new ExportService();
|
||||||
|
|
|
@ -38,7 +38,6 @@ import { FILE_TYPE } from 'constants/file';
|
||||||
import { decodeLivePhoto } from 'services/livePhotoService';
|
import { decodeLivePhoto } from 'services/livePhotoService';
|
||||||
import downloadManager from 'services/downloadManager';
|
import downloadManager from 'services/downloadManager';
|
||||||
import { retryAsyncFunction } from 'utils/network';
|
import { retryAsyncFunction } from 'utils/network';
|
||||||
import { CustomError } from 'utils/error';
|
|
||||||
|
|
||||||
export async function migrateExportJSON(
|
export async function migrateExportJSON(
|
||||||
exportDir: string,
|
exportDir: string,
|
||||||
|
@ -67,12 +66,6 @@ async function migrateExport(
|
||||||
exportRecord: ExportRecordV1 | ExportRecordV2 | ExportRecord
|
exportRecord: ExportRecordV1 | ExportRecordV2 | ExportRecord
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
if (!exportRecord?.version) {
|
|
||||||
exportRecord = {
|
|
||||||
...exportRecord,
|
|
||||||
version: 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
addLogLine(`current export version: ${exportRecord.version}`);
|
addLogLine(`current export version: ${exportRecord.version}`);
|
||||||
if (exportRecord.version === 0) {
|
if (exportRecord.version === 0) {
|
||||||
addLogLine('migrating export to version 1');
|
addLogLine('migrating export to version 1');
|
||||||
|
@ -371,6 +364,6 @@ async function addCollectionExportedRecordV1(
|
||||||
await exportService.updateExportRecord(exportRecord, folder);
|
await exportService.updateExportRecord(exportRecord, folder);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError(e, 'addCollectionExportedRecord failed');
|
logError(e, 'addCollectionExportedRecord failed');
|
||||||
throw Error(CustomError.ADD_FILE_EXPORTED_RECORD_FAILED);
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,7 @@ export interface ElectronAPIs {
|
||||||
saveFileToDisk: (path: string, file: any) => Promise<void>;
|
saveFileToDisk: (path: string, file: any) => Promise<void>;
|
||||||
selectRootDirectory: () => Promise<string>;
|
selectRootDirectory: () => Promise<string>;
|
||||||
sendNotification: (content: string) => void;
|
sendNotification: (content: string) => void;
|
||||||
getExportRecord: (filePath: string) => Promise<string>;
|
readTextFile: (path: string) => Promise<string>;
|
||||||
setExportRecord: (filePath: string, data: string) => Promise<void>;
|
|
||||||
showUploadFilesDialog: () => Promise<ElectronFile[]>;
|
showUploadFilesDialog: () => Promise<ElectronFile[]>;
|
||||||
showUploadDirsDialog: () => Promise<ElectronFile[]>;
|
showUploadDirsDialog: () => Promise<ElectronFile[]>;
|
||||||
getPendingUploads: () => Promise<{
|
getPendingUploads: () => Promise<{
|
||||||
|
|
|
@ -55,7 +55,7 @@ export const CustomError = {
|
||||||
'Windows native image processing is not supported',
|
'Windows native image processing is not supported',
|
||||||
NETWORK_ERROR: 'Network Error',
|
NETWORK_ERROR: 'Network Error',
|
||||||
NOT_FILE_OWNER: 'not file owner',
|
NOT_FILE_OWNER: 'not file owner',
|
||||||
ADD_FILE_EXPORTED_RECORD_FAILED: 'add file exported record failed',
|
UPDATE_EXPORTED_RECORD_FAILED: 'update file exported record failed',
|
||||||
NO_EXPORT_FOLDER_SELECTED: 'no export folder selected',
|
NO_EXPORT_FOLDER_SELECTED: 'no export folder selected',
|
||||||
EXPORT_FOLDER_DOES_NOT_EXIST: 'export folder does not exist',
|
EXPORT_FOLDER_DOES_NOT_EXIST: 'export folder does not exist',
|
||||||
NO_INTERNET_CONNECTION: 'no internet connection',
|
NO_INTERNET_CONNECTION: 'no internet connection',
|
||||||
|
|
Loading…
Reference in a new issue