mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2025-12-05 18:20:39 -08:00
feat: show better error message when html extract failed
This commit is contained in:
parent
494e688b00
commit
d6109f1540
8 changed files with 99 additions and 54 deletions
|
|
@ -39,11 +39,9 @@ export function ImportHtmlWikiForm({
|
|||
if (filePaths?.length > 0) {
|
||||
wikiHtmlPathSetter(filePaths[0]);
|
||||
const fileName = await window.service.native.path('basename', filePaths[0]);
|
||||
// DEBUG: console
|
||||
console.log(`fileName`, filePaths, fileName);
|
||||
if (fileName !== undefined) {
|
||||
// use html file name as default wiki name
|
||||
wikiFolderNameSetter(fileName);
|
||||
wikiFolderNameSetter(fileName.split('.')[0]);
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IErrorInWhichComponent, IWikiWorkspaceForm } from './useForm';
|
||||
import { updateErrorInWhichComponentSetterByErrorMessage } from './useIndicator';
|
||||
import { useValidateNewWiki, useNewWiki } from './useNewWiki';
|
||||
|
||||
export function useValidateHtmlWiki(
|
||||
|
|
@ -16,17 +17,15 @@ export function useValidateHtmlWiki(
|
|||
useValidateNewWiki(isCreateMainWorkspace, isCreateSyncedWorkspace, form, errorInWhichComponentSetter);
|
||||
useEffect(() => {
|
||||
if (!form.wikiHtmlPath) {
|
||||
// 判断wikiHtmlPath是否存在
|
||||
wikiCreationMessageSetter(`${t('AddWorkspace.NotFilled')}:${t('AddWorkspace.LocalWikiHtml')}`);
|
||||
errorInWhichComponentSetter({ wikiHtmlPath: true });
|
||||
hasErrorSetter(true);
|
||||
} else {
|
||||
wikiCreationMessageSetter('');
|
||||
errorInWhichComponentSetter({});
|
||||
hasErrorSetter(false);
|
||||
}
|
||||
}, [
|
||||
t,
|
||||
// 监听wikiHtmlPath,如果不存在就在提示用户。
|
||||
form.wikiHtmlPath,
|
||||
errorInWhichComponentSetter,
|
||||
]);
|
||||
}, [t, form.wikiHtmlPath, form.parentFolderLocation, form.wikiFolderName, errorInWhichComponentSetter]);
|
||||
|
||||
return [hasError, wikiCreationMessage, wikiCreationMessageSetter, hasErrorSetter];
|
||||
}
|
||||
|
|
@ -48,6 +47,7 @@ export function useImportHtmlWiki(
|
|||
wikiCreationMessageSetter,
|
||||
hasErrorSetter,
|
||||
errorInWhichComponentSetter,
|
||||
{ noCopyTemplate: true },
|
||||
);
|
||||
|
||||
const onSubmit = useCallback(async () => {
|
||||
|
|
@ -60,16 +60,15 @@ export function useImportHtmlWiki(
|
|||
}
|
||||
wikiCreationMessageSetter(t('AddWorkspace.Processing'));
|
||||
try {
|
||||
// 如果是HTML文件,即使转换错误,删掉在执行一次也不会出错。
|
||||
// 我希望判断用户输入的是否是HTML文件,如果不是就不予执行。然后在判断如果失败了就删除这个数据并且提示错误信息。如果输入的是html类型的文件是不会出错的,即使是非wiki类型的文件。如果输出的目录非空,那么会导致异常闪退。
|
||||
const extractState = await window.service.wiki.extractWikiHTML(wikiHtmlPath, wikiFolderLocation);
|
||||
if (!extractState) {
|
||||
const extractSuccess = await window.service.wiki.extractWikiHTML(wikiHtmlPath, wikiFolderLocation);
|
||||
if (extractSuccess === false) {
|
||||
hasErrorSetter(true);
|
||||
wikiCreationMessageSetter(t('AddWorkspace.BadWikiHtml'));
|
||||
errorInWhichComponentSetter({ wikiHtmlPath: true });
|
||||
return;
|
||||
} else if (typeof extractSuccess === 'string') {
|
||||
updateErrorInWhichComponentSetterByErrorMessage(t, extractSuccess, errorInWhichComponentSetter);
|
||||
}
|
||||
// 我希望在解压成功后设置好工作区的信息,执行打开解压后的wiki文件夹的操作。
|
||||
} catch (error) {
|
||||
wikiCreationMessageSetter(`${t('AddWorkspace.BadWikiHtml')}${(error as Error).message}`);
|
||||
errorInWhichComponentSetter({ wikiHtmlPath: true });
|
||||
|
|
|
|||
|
|
@ -50,4 +50,7 @@ export function updateErrorInWhichComponentSetterByErrorMessage(
|
|||
if (message.includes(t('AddWorkspace.ThisPathIsNotAWikiFolder').replace(/".*"/, ''))) {
|
||||
errorInWhichComponentSetter({ wikiFolderName: true, wikiFolderLocation: true });
|
||||
}
|
||||
if (message.includes('The unpackwiki command requires that the output wiki folder be empty')) {
|
||||
errorInWhichComponentSetter({ wikiFolderName: true, wikiFolderLocation: true });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ export function useNewWiki(
|
|||
wikiCreationMessageSetter: (m: string) => void,
|
||||
hasErrorSetter: (m: boolean) => void,
|
||||
errorInWhichComponentSetter: (errors: IErrorInWhichComponent) => void,
|
||||
options?: { noCopyTemplate?: boolean },
|
||||
): () => Promise<void> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
|
@ -72,7 +73,9 @@ export function useNewWiki(
|
|||
try {
|
||||
const newWorkspaceConfig = workspaceConfigFromForm(form, isCreateMainWorkspace, isCreateSyncedWorkspace);
|
||||
if (isCreateMainWorkspace) {
|
||||
if (options?.noCopyTemplate !== true) {
|
||||
await window.service.wiki.copyWikiTemplate(form.parentFolderLocation, form.wikiFolderName);
|
||||
}
|
||||
} else {
|
||||
await window.service.wiki.createSubWiki(form.parentFolderLocation, form.wikiFolderName, form.mainWikiToLink?.wikiFolderLocation, form.tagName);
|
||||
}
|
||||
|
|
@ -82,7 +85,16 @@ export function useNewWiki(
|
|||
updateErrorInWhichComponentSetterByErrorMessage(t, (error as Error).message, errorInWhichComponentSetter);
|
||||
hasErrorSetter(true);
|
||||
}
|
||||
}, [wikiCreationMessageSetter, t, hasErrorSetter, form, isCreateMainWorkspace, isCreateSyncedWorkspace, errorInWhichComponentSetter]);
|
||||
}, [
|
||||
wikiCreationMessageSetter,
|
||||
t,
|
||||
hasErrorSetter,
|
||||
form,
|
||||
isCreateMainWorkspace,
|
||||
isCreateSyncedWorkspace,
|
||||
options?.noCopyTemplate,
|
||||
errorInWhichComponentSetter,
|
||||
]);
|
||||
|
||||
return onSubmit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,20 +168,31 @@ export class Wiki implements IWikiService {
|
|||
});
|
||||
}
|
||||
|
||||
public async extractWikiHTML(htmlWikiPath: string, saveWikiFolderPath: string): Promise<boolean> {
|
||||
public async extractWikiHTML(htmlWikiPath: string, saveWikiFolderPath: string): Promise<boolean | string> {
|
||||
// hope saveWikiFolderPath = ParentFolderPath + wikifolderPath
|
||||
// await fs.remove(saveWikiFolderPath); removes the folder function that failed to convert.
|
||||
// We want the folder where the WIKI is saved to be empty, and we want the input htmlWiki to be an HTML file even if it is a non-wikiHTML file. Otherwise the program will exit abnormally.
|
||||
// this.wikiWorkers[saveWikiFolderPath] = worker;
|
||||
// Then, you can use this.getWorker (saveWikiFolderPath) method to call this wikiWorker that belongs to the HTMLWIKI after decompression
|
||||
const worker = await spawn<WikiWorker>(new Worker(workerURL as string), { timeout: 1000 * 60 });
|
||||
const result = await worker.ExtractWikiHTMLAndGetExtractState(htmlWikiPath, saveWikiFolderPath);
|
||||
let result: boolean | string = false;
|
||||
try {
|
||||
result = await worker.extractWikiHTML(htmlWikiPath, saveWikiFolderPath);
|
||||
} catch (error) {
|
||||
result = (error as Error).message;
|
||||
logger.error(result, { worker: 'NodeJSWiki', method: 'extractWikiHTML', htmlWikiPath, saveWikiFolderPath });
|
||||
// removes the folder function that failed to convert.
|
||||
try {
|
||||
await fs.remove(saveWikiFolderPath);
|
||||
} catch {}
|
||||
}
|
||||
// this worker is only for one time use. we will spawn a new one for starting wiki later.
|
||||
await Thread.terminate(worker);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async packetHTMLFromWikiFolder(folderWikiPath: string, saveWikiHtmlFolder: string): Promise<void> {
|
||||
const worker = await spawn<WikiWorker>(new Worker(workerURL as string), { timeout: 1000 * 60 });
|
||||
await worker.packetHTMLFromWikiFolder(folderWikiPath, saveWikiHtmlFolder);
|
||||
// this worker is only for one time use. we will spawn a new one for starting wiki later.
|
||||
await Thread.terminate(worker);
|
||||
}
|
||||
|
||||
public async stopWiki(wikiFolderLocation: string): Promise<void> {
|
||||
|
|
@ -667,7 +678,7 @@ export class Wiki implements IWikiService {
|
|||
|
||||
public async getWikiLogs(homePath: string): Promise<{ content: string; filePath: string }> {
|
||||
const filePath = getWikiLogFilePath(homePath);
|
||||
const content = await fs.readFile(filePath, 'utf-8');
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
return {
|
||||
content,
|
||||
filePath,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export interface IWikiService {
|
|||
*/
|
||||
createSubWiki(parentFolderLocation: string, folderName: string, mainWikiPath: string, tagName?: string, onlyLink?: boolean): Promise<void>;
|
||||
ensureWikiExist(wikiPath: string, shouldBeMainWiki: boolean): Promise<void>;
|
||||
extractWikiHTML(htmlWikiPath: string, saveWikiFolderPath: string): Promise<boolean>;
|
||||
extractWikiHTML(htmlWikiPath: string, saveWikiFolderPath: string): Promise<boolean | string>;
|
||||
getSubWikiPluginContent(mainWikiPath: string): Promise<ISubWikiPluginContent[]>;
|
||||
getTiddlerText(workspace: IWorkspace, title: string): Promise<string | undefined>;
|
||||
getWikiLogs(homePath: string): Promise<{ content: string; filePath: string }>;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Observable } from 'rxjs';
|
|||
import intercept from 'intercept-stdout';
|
||||
import { fork } from 'child_process';
|
||||
import { tmpdir } from 'os';
|
||||
import fs from 'fs';
|
||||
import { mkdtemp, writeFile } from 'fs-extra';
|
||||
|
||||
import { fixPath } from '@services/libs/fixPath';
|
||||
|
|
@ -131,22 +132,33 @@ function executeZxScript(file: IZxFileInput, zxPath: string): Observable<IZxWork
|
|||
});
|
||||
}
|
||||
|
||||
function extractWikiHTML(htmlWikiPath: string, saveWikiFolderPath: string): boolean {
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
function extractWikiHTML(htmlWikiPath: string, saveWikiFolderPath: string): Promise<boolean> {
|
||||
// tiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder
|
||||
// --savewikifolder <wikifolderpath> [<filter>]
|
||||
// . /mywikifolder is the path where the tiddlder and plugins folders are stored
|
||||
return new Promise((resolve, reject) => {
|
||||
let extractState = false;
|
||||
// eslint-disable-next-line prefer-regex-literals
|
||||
const reg = new RegExp(/(?:html|htm|Html|HTML|HTM)$/);
|
||||
const isHtmlWiki = reg.test(htmlWikiPath);
|
||||
if (!isHtmlWiki) {
|
||||
console.error('Please enter the path to the tiddlywiki.html file. But the current path is: ' + htmlWikiPath);
|
||||
return extractState;
|
||||
const message = 'Please enter the path to the tiddlywiki.html file. But the current path is: ' + htmlWikiPath;
|
||||
console.error(message);
|
||||
reject(message);
|
||||
} else if (fs.existsSync(saveWikiFolderPath)) {
|
||||
const message = 'Error: The unpackwiki command requires that the output wiki folder be empty: ' + htmlWikiPath;
|
||||
console.error(message);
|
||||
reject(message);
|
||||
} else {
|
||||
try {
|
||||
const wikiInstance = TiddlyWiki();
|
||||
wikiInstance.boot.argv = ['--load', htmlWikiPath, '--savewikifolder', saveWikiFolderPath];
|
||||
wikiInstance.boot.startup({});
|
||||
wikiInstance.boot.startup({
|
||||
callback: () => {
|
||||
resolve(true);
|
||||
},
|
||||
});
|
||||
// eslint-disable-next-line security-node/detect-crlf
|
||||
console.log('Extract Wiki Html Successful: ' + saveWikiFolderPath);
|
||||
extractState = true;
|
||||
|
|
@ -156,26 +168,35 @@ function extractWikiHTML(htmlWikiPath: string, saveWikiFolderPath: string): bool
|
|||
}
|
||||
}
|
||||
return extractState;
|
||||
});
|
||||
}
|
||||
|
||||
function packetHTMLFromWikiFolder(folderWikiPath: string, saveWikiHtmlFolder: string): void {
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
function packetHTMLFromWikiFolder(folderWikiPath: string, saveWikiHtmlFolder: string): Promise<boolean> {
|
||||
// tiddlywiki ./mywikifolder --rendertiddler '$:/core/save/all' mywiki.html text/plain
|
||||
// . /mywikifolder is the path to the wiki folder, which generally contains the tiddlder and plugins directories
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const wikiInstance = TiddlyWiki();
|
||||
wikiInstance.boot.argv = [folderWikiPath, '--rendertiddler', '$:/core/save/all', saveWikiHtmlFolder, 'text/plain'];
|
||||
wikiInstance.boot.startup({});
|
||||
wikiInstance.boot.startup({
|
||||
callback: () => {
|
||||
resolve(true);
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
const message = `Tiddlywiki packetHTMLFromWikiFolder with error ${(error as Error).message} ${(error as Error).stack ?? ''}`;
|
||||
console.error(message);
|
||||
reject(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const wikiWorker = {
|
||||
startNodeJSWiki,
|
||||
getTiddlerFileMetadata: (tiddlerTitle: string) => wikiInstance?.boot?.files?.[tiddlerTitle],
|
||||
executeZxScript,
|
||||
ExtractWikiHTMLAndGetExtractState: (htmlWikiPath: string, saveWikiFolderPath: string) => extractWikiHTML(htmlWikiPath, saveWikiFolderPath),
|
||||
extractWikiHTML,
|
||||
packetHTMLFromWikiFolder,
|
||||
};
|
||||
export type WikiWorker = typeof wikiWorker;
|
||||
|
|
|
|||
1
tiddlers/subwiki/tiddlywiki
Symbolic link
1
tiddlers/subwiki/tiddlywiki
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
/var/folders/23/77bfg9k134q78g5v66qr0_jr0000gp/T/tidgi-dev/tiddlywiki
|
||||
Loading…
Add table
Add a link
Reference in a new issue