fix: import html will delete existed folder, and no Chinese error message

fixes #488
This commit is contained in:
lin onetwo 2023-12-30 15:24:10 +08:00
parent 3aa18be2c5
commit 9c4aa82c8f
6 changed files with 118 additions and 87 deletions

View file

@ -408,7 +408,11 @@
"WikiRuntimeError": "E-13 Wiki Runtime Error", "WikiRuntimeError": "E-13 Wiki Runtime Error",
"WikiRuntimeErrorDescription": "E-13 There is an error while running the wiki. Please check the log file for the reason, and upload and submit an issue for repair.", "WikiRuntimeErrorDescription": "E-13 There is an error while running the wiki. Please check the log file for the reason, and upload and submit an issue for repair.",
"SubWikiSMainWikiNotExistError": "The main wiki to which the child wiki is attached does not exist", "SubWikiSMainWikiNotExistError": "The main wiki to which the child wiki is attached does not exist",
"SubWikiSMainWikiNotExistErrorDescription": "A sub-wiki must choose a main wiki to attach to when it is created, but now the main wiki that this sub-wiki should be attached to cannot be found and cannot be attached." "SubWikiSMainWikiNotExistErrorDescription": "A sub-wiki must choose a main wiki to attach to when it is created, but now the main wiki that this sub-wiki should be attached to cannot be found and cannot be attached.",
"HTMLCanNotLoadError": "Current HTML file path can't be used.",
"HTMLCanNotLoadErrorDescription": "Please enter a path to a valid tiddlywiki.html file.",
"ALreadyExistErrorDescription": "A folder already exists at this path, and a new knowledge base cannot be created here.",
"AlreadyExistError": "Folder already exist here."
}, },
"Loading": "Loading", "Loading": "Loading",
"Yes": "Yes", "Yes": "Yes",

View file

@ -445,7 +445,11 @@
"WikiRuntimeError": "E-13 维基运行时有错误", "WikiRuntimeError": "E-13 维基运行时有错误",
"WikiRuntimeErrorDescription": "E-13 维基运行时有错误,原因请查看 log 文件,并上传提交 issue 以便修复。", "WikiRuntimeErrorDescription": "E-13 维基运行时有错误,原因请查看 log 文件,并上传提交 issue 以便修复。",
"SubWikiSMainWikiNotExistError": "子 Wiki 所附着的主 Wiki 不存在", "SubWikiSMainWikiNotExistError": "子 Wiki 所附着的主 Wiki 不存在",
"SubWikiSMainWikiNotExistErrorDescription": "子 Wiki 在创建时必须选择一个附着到的主 Wiki但是现在这个子 Wiki 所应该附着的主 Wiki 找不到了,无法附着。" "SubWikiSMainWikiNotExistErrorDescription": "子 Wiki 在创建时必须选择一个附着到的主 Wiki但是现在这个子 Wiki 所应该附着的主 Wiki 找不到了,无法附着。",
"HTMLCanNotLoadError": "提供的 HTML 文件路径无法使用。",
"HTMLCanNotLoadErrorDescription": "请输入指向可用的 HTML 文件的路径。",
"ALreadyExistErrorDescription": "当前路径已有文件夹,新的知识库无法在此新建。",
"AlreadyExistError": "该处已被文件夹占用"
}, },
"Loading": "加载中", "Loading": "加载中",
"Delete": "删除", "Delete": "删除",

View file

@ -37,3 +37,19 @@ export class WikiRuntimeError extends Error {
this.stack = error.stack; this.stack = error.stack;
} }
} }
export class HTMLCanNotLoadError extends Error {
constructor(htmlWikiPath?: string) {
super(htmlWikiPath);
this.name = i18n.t('Error.HTMLCanNotLoadError');
this.message = `${i18n.t('Error.HTMLCanNotLoadErrorDescription')} ${htmlWikiPath ?? ''}`;
}
}
export class AlreadyExistError extends Error {
constructor(wikiFolderPath?: string) {
super(wikiFolderPath);
this.name = i18n.t('Error.AlreadyExistError');
this.message = `${i18n.t('Error.ALreadyExistErrorDescription')} ${wikiFolderPath ?? ''}`;
}
}

View file

@ -4,7 +4,7 @@
/* eslint-disable @typescript-eslint/no-dynamic-delete */ /* eslint-disable @typescript-eslint/no-dynamic-delete */
import { dialog, ipcMain } from 'electron'; import { dialog, ipcMain } from 'electron';
import { backOff } from 'exponential-backoff'; import { backOff } from 'exponential-backoff';
import fs from 'fs-extra'; import { copy, createSymlink, exists, mkdir, mkdirp, mkdirs, pathExists, readFile, remove, unlink } from 'fs-extra';
import { injectable } from 'inversify'; import { injectable } from 'inversify';
import path from 'path'; import path from 'path';
import { ModuleThread, spawn, Thread, Worker } from 'threads'; import { ModuleThread, spawn, Thread, Worker } from 'threads';
@ -26,7 +26,7 @@ import type { IWorkspace, IWorkspaceService } from '@services/workspaces/interfa
import type { IWorkspaceViewService } from '@services/workspacesView/interface'; import type { IWorkspaceViewService } from '@services/workspacesView/interface';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import type { IChangedTiddlers } from 'tiddlywiki'; import type { IChangedTiddlers } from 'tiddlywiki';
import { CopyWikiTemplateError, DoubleWikiInstanceError, SubWikiSMainWikiNotExistError, WikiRuntimeError } from './error'; import { AlreadyExistError, CopyWikiTemplateError, DoubleWikiInstanceError, HTMLCanNotLoadError, SubWikiSMainWikiNotExistError, WikiRuntimeError } from './error';
import { IWikiService, WikiControlActions } from './interface'; import { IWikiService, WikiControlActions } from './interface';
import { getSubWikiPluginContent, ISubWikiPluginContent, updateSubWikiPluginContent } from './plugin/subWikiPlugin'; import { getSubWikiPluginContent, ISubWikiPluginContent, updateSubWikiPluginContent } from './plugin/subWikiPlugin';
import type { IStartNodeJSWikiConfigs, WikiWorker } from './wikiWorker'; import type { IStartNodeJSWikiConfigs, WikiWorker } from './wikiWorker';
@ -38,6 +38,7 @@ import workerURL from 'threads-plugin/dist/loader?name=wikiWorker!./wikiWorker/i
import { LOG_FOLDER } from '@/constants/appPaths'; import { LOG_FOLDER } from '@/constants/appPaths';
import { isDevelopmentOrTest } from '@/constants/environment'; import { isDevelopmentOrTest } from '@/constants/environment';
import { isHtmlWiki } from '@/constants/fileNames';
import { defaultServerIP } from '@/constants/urls'; import { defaultServerIP } from '@/constants/urls';
import { IDatabaseService } from '@services/database/interface'; import { IDatabaseService } from '@services/database/interface';
import { IPreferenceService } from '@services/preferences/interface'; import { IPreferenceService } from '@services/preferences/interface';
@ -296,12 +297,16 @@ export class Wiki implements IWikiService {
// 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. // 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.
const worker = await spawn<WikiWorker>(new Worker(workerURL as string), { timeout: 1000 * 60 }); const worker = await spawn<WikiWorker>(new Worker(workerURL as string), { timeout: 1000 * 60 });
try { try {
if (!isHtmlWiki(htmlWikiPath)) {
throw new HTMLCanNotLoadError(htmlWikiPath);
}
if (await exists(saveWikiFolderPath)) {
throw new AlreadyExistError(saveWikiFolderPath);
}
await worker.extractWikiHTML(htmlWikiPath, saveWikiFolderPath, { TIDDLYWIKI_PACKAGE_FOLDER }); await worker.extractWikiHTML(htmlWikiPath, saveWikiFolderPath, { TIDDLYWIKI_PACKAGE_FOLDER });
} catch (error) { } catch (error) {
const result = (error as Error).message; const result = `${(error as Error).name} ${(error as Error).message}`;
logger.error(result, { worker: 'NodeJSWiki', method: 'extractWikiHTML', htmlWikiPath, saveWikiFolderPath }); logger.error(result, { worker: 'NodeJSWiki', method: 'extractWikiHTML', htmlWikiPath, saveWikiFolderPath });
// removes the folder function that failed to convert.
await fs.remove(saveWikiFolderPath);
return result; return result;
} }
// this worker is only for one time use. we will spawn a new one for starting wiki later. // this worker is only for one time use. we will spawn a new one for starting wiki later.
@ -373,10 +378,10 @@ export class Wiki implements IWikiService {
const subwikiSymlinkPath = path.join(mainWikiTiddlersFolderSubWikisPath, folderName); const subwikiSymlinkPath = path.join(mainWikiTiddlersFolderSubWikisPath, folderName);
try { try {
try { try {
await fs.remove(subwikiSymlinkPath); await remove(subwikiSymlinkPath);
} catch {} } catch {}
await fs.mkdirp(mainWikiTiddlersFolderSubWikisPath); await mkdirp(mainWikiTiddlersFolderSubWikisPath);
await fs.createSymlink(subWikiPath, subwikiSymlinkPath, 'junction'); await createSymlink(subWikiPath, subwikiSymlinkPath, 'junction');
this.logProgress(i18n.t('AddWorkspace.CreateLinkFromSubWikiToMainWikiSucceed')); this.logProgress(i18n.t('AddWorkspace.CreateLinkFromSubWikiToMainWikiSucceed'));
} catch (error: unknown) { } catch (error: unknown) {
throw new Error(i18n.t('AddWorkspace.CreateLinkFromSubWikiToMainWikiFailed', { subWikiPath, mainWikiTiddlersFolderPath: subwikiSymlinkPath, error })); throw new Error(i18n.t('AddWorkspace.CreateLinkFromSubWikiToMainWikiFailed', { subWikiPath, mainWikiTiddlersFolderPath: subwikiSymlinkPath, error }));
@ -386,17 +391,17 @@ export class Wiki implements IWikiService {
private async createWiki(newFolderPath: string, folderName: string): Promise<void> { private async createWiki(newFolderPath: string, folderName: string): Promise<void> {
this.logProgress(i18n.t('AddWorkspace.StartUsingTemplateToCreateWiki')); this.logProgress(i18n.t('AddWorkspace.StartUsingTemplateToCreateWiki'));
const newWikiPath = path.join(newFolderPath, folderName); const newWikiPath = path.join(newFolderPath, folderName);
if (!(await fs.pathExists(newFolderPath))) { if (!(await pathExists(newFolderPath))) {
throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: newFolderPath })); throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: newFolderPath }));
} }
if (!(await fs.pathExists(TIDDLYWIKI_TEMPLATE_FOLDER_PATH))) { if (!(await pathExists(TIDDLYWIKI_TEMPLATE_FOLDER_PATH))) {
throw new Error(i18n.t('AddWorkspace.WikiTemplateMissing', { TIDDLYWIKI_TEMPLATE_FOLDER_PATH })); throw new Error(i18n.t('AddWorkspace.WikiTemplateMissing', { TIDDLYWIKI_TEMPLATE_FOLDER_PATH }));
} }
if (await fs.pathExists(newWikiPath)) { if (await pathExists(newWikiPath)) {
throw new Error(i18n.t('AddWorkspace.WikiExisted', { newWikiPath })); throw new Error(i18n.t('AddWorkspace.WikiExisted', { newWikiPath }));
} }
try { try {
await fs.copy(TIDDLYWIKI_TEMPLATE_FOLDER_PATH, newWikiPath, { await copy(TIDDLYWIKI_TEMPLATE_FOLDER_PATH, newWikiPath, {
filter: (source: string, destination: string) => { filter: (source: string, destination: string) => {
// xxx/template/wiki/.gitignore // xxx/template/wiki/.gitignore
// xxx/template/wiki/.github // xxx/template/wiki/.github
@ -418,15 +423,15 @@ export class Wiki implements IWikiService {
public async createSubWiki(parentFolderLocation: string, folderName: string, mainWikiPath: string, tagName = '', onlyLink = false): Promise<void> { public async createSubWiki(parentFolderLocation: string, folderName: string, mainWikiPath: string, tagName = '', onlyLink = false): Promise<void> {
this.logProgress(i18n.t('AddWorkspace.StartCreatingSubWiki')); this.logProgress(i18n.t('AddWorkspace.StartCreatingSubWiki'));
const newWikiPath = path.join(parentFolderLocation, folderName); const newWikiPath = path.join(parentFolderLocation, folderName);
if (!(await fs.pathExists(parentFolderLocation))) { if (!(await pathExists(parentFolderLocation))) {
throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: parentFolderLocation })); throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: parentFolderLocation }));
} }
if (!onlyLink) { if (!onlyLink) {
if (await fs.pathExists(newWikiPath)) { if (await pathExists(newWikiPath)) {
throw new Error(i18n.t('AddWorkspace.WikiExisted', { newWikiPath })); throw new Error(i18n.t('AddWorkspace.WikiExisted', { newWikiPath }));
} }
try { try {
await fs.mkdirs(newWikiPath); await mkdirs(newWikiPath);
} catch { } catch {
throw new Error(i18n.t('AddWorkspace.CantCreateFolderHere', { newWikiPath })); throw new Error(i18n.t('AddWorkspace.CantCreateFolderHere', { newWikiPath }));
} }
@ -444,22 +449,22 @@ export class Wiki implements IWikiService {
public async removeWiki(wikiPath: string, mainWikiToUnLink?: string, onlyRemoveLink = false): Promise<void> { public async removeWiki(wikiPath: string, mainWikiToUnLink?: string, onlyRemoveLink = false): Promise<void> {
if (mainWikiToUnLink !== undefined) { if (mainWikiToUnLink !== undefined) {
const subWikiName = path.basename(wikiPath); const subWikiName = path.basename(wikiPath);
await fs.remove(path.join(mainWikiToUnLink, TIDDLERS_PATH, this.folderToContainSymlinks, subWikiName)); await remove(path.join(mainWikiToUnLink, TIDDLERS_PATH, this.folderToContainSymlinks, subWikiName));
} }
if (!onlyRemoveLink) { if (!onlyRemoveLink) {
await fs.remove(wikiPath); await remove(wikiPath);
} }
} }
public async ensureWikiExist(wikiPath: string, shouldBeMainWiki: boolean): Promise<void> { public async ensureWikiExist(wikiPath: string, shouldBeMainWiki: boolean): Promise<void> {
if (!(await fs.pathExists(wikiPath))) { if (!(await pathExists(wikiPath))) {
throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: wikiPath })); throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: wikiPath }));
} }
const wikiInfoPath = path.resolve(wikiPath, 'tiddlywiki.info'); const wikiInfoPath = path.resolve(wikiPath, 'tiddlywiki.info');
if (shouldBeMainWiki && !(await fs.pathExists(wikiInfoPath))) { if (shouldBeMainWiki && !(await pathExists(wikiInfoPath))) {
throw new Error(i18n.t('AddWorkspace.ThisPathIsNotAWikiFolder', { wikiPath, wikiInfoPath })); throw new Error(i18n.t('AddWorkspace.ThisPathIsNotAWikiFolder', { wikiPath, wikiInfoPath }));
} }
if (shouldBeMainWiki && !(await fs.pathExists(path.join(wikiPath, TIDDLERS_PATH)))) { if (shouldBeMainWiki && !(await pathExists(path.join(wikiPath, TIDDLERS_PATH)))) {
throw new Error(i18n.t('AddWorkspace.ThisPathIsNotAWikiFolder', { wikiPath })); throw new Error(i18n.t('AddWorkspace.ThisPathIsNotAWikiFolder', { wikiPath }));
} }
} }
@ -510,14 +515,14 @@ export class Wiki implements IWikiService {
public async cloneWiki(parentFolderLocation: string, wikiFolderName: string, gitRepoUrl: string, gitUserInfo: IGitUserInfos): Promise<void> { public async cloneWiki(parentFolderLocation: string, wikiFolderName: string, gitRepoUrl: string, gitUserInfo: IGitUserInfos): Promise<void> {
this.logProgress(i18n.t('AddWorkspace.StartCloningWiki')); this.logProgress(i18n.t('AddWorkspace.StartCloningWiki'));
const newWikiPath = path.join(parentFolderLocation, wikiFolderName); const newWikiPath = path.join(parentFolderLocation, wikiFolderName);
if (!(await fs.pathExists(parentFolderLocation))) { if (!(await pathExists(parentFolderLocation))) {
throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: parentFolderLocation })); throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: parentFolderLocation }));
} }
if (await fs.pathExists(newWikiPath)) { if (await pathExists(newWikiPath)) {
throw new Error(i18n.t('AddWorkspace.WikiExisted', { newWikiPath })); throw new Error(i18n.t('AddWorkspace.WikiExisted', { newWikiPath }));
} }
try { try {
await fs.mkdir(newWikiPath); await mkdir(newWikiPath);
} catch { } catch {
throw new Error(i18n.t('AddWorkspace.CantCreateFolderHere', { newWikiPath })); throw new Error(i18n.t('AddWorkspace.CantCreateFolderHere', { newWikiPath }));
} }
@ -534,14 +539,14 @@ export class Wiki implements IWikiService {
): Promise<void> { ): Promise<void> {
this.logProgress(i18n.t('AddWorkspace.StartCloningSubWiki')); this.logProgress(i18n.t('AddWorkspace.StartCloningSubWiki'));
const newWikiPath = path.join(parentFolderLocation, wikiFolderName); const newWikiPath = path.join(parentFolderLocation, wikiFolderName);
if (!(await fs.pathExists(parentFolderLocation))) { if (!(await pathExists(parentFolderLocation))) {
throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: parentFolderLocation })); throw new Error(i18n.t('AddWorkspace.PathNotExist', { path: parentFolderLocation }));
} }
if (await fs.pathExists(newWikiPath)) { if (await pathExists(newWikiPath)) {
throw new Error(i18n.t('AddWorkspace.WikiExisted', { newWikiPath })); throw new Error(i18n.t('AddWorkspace.WikiExisted', { newWikiPath }));
} }
try { try {
await fs.mkdir(newWikiPath); await mkdir(newWikiPath);
} catch { } catch {
throw new Error(i18n.t('AddWorkspace.CantCreateFolderHere', { newWikiPath })); throw new Error(i18n.t('AddWorkspace.CantCreateFolderHere', { newWikiPath }));
} }
@ -676,7 +681,7 @@ export class Wiki implements IWikiService {
// remove $:/StoryList, otherwise it sometimes cause $__StoryList_1.tid to be generated // remove $:/StoryList, otherwise it sometimes cause $__StoryList_1.tid to be generated
// and it will leak private sub-wiki's opened tiddler title // and it will leak private sub-wiki's opened tiddler title
try { try {
void fs.unlink(path.resolve(wikiFolderLocation, 'tiddlers', '$__StoryList')).catch(() => {}); void unlink(path.resolve(wikiFolderLocation, 'tiddlers', '$__StoryList')).catch(() => {});
} catch { } catch {
// do nothing // do nothing
} }
@ -793,7 +798,7 @@ export class Wiki implements IWikiService {
public async getWikiErrorLogs(workspaceID: string, wikiName: string): Promise<{ content: string; filePath: string }> { public async getWikiErrorLogs(workspaceID: string, wikiName: string): Promise<{ content: string; filePath: string }> {
const filePath = path.join(LOG_FOLDER, getWikiErrorLogFileName(workspaceID, wikiName)); const filePath = path.join(LOG_FOLDER, getWikiErrorLogFileName(workspaceID, wikiName));
const content = await fs.readFile(filePath, 'utf8'); const content = await readFile(filePath, 'utf8');
return { return {
content, content,
filePath, filePath,

View file

@ -0,0 +1,53 @@
import { isHtmlWiki } from '@/constants/fileNames';
import { TiddlyWiki } from '@tiddlygit/tiddlywiki';
import { remove } from 'fs-extra';
export async function extractWikiHTML(htmlWikiPath: string, saveWikiFolderPath: string, constants: { TIDDLYWIKI_PACKAGE_FOLDER: string }): Promise<void> {
// tiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder
// --savewikifolder <wikifolderpath> [<filter>]
// . /mywikifolder is the path where the tiddlder and plugins folders are stored
const { TIDDLYWIKI_PACKAGE_FOLDER } = constants;
try {
const wikiInstance = TiddlyWiki();
wikiInstance.boot.argv = ['--load', htmlWikiPath, '--savewikifolder', saveWikiFolderPath, 'explodePlugins=no'];
await new Promise<void>((resolve, reject) => {
try {
wikiInstance.boot.startup({
// passing bootPath inside TidGi app. fix The "path" argument must be of type string. Received undefined
bootPath: TIDDLYWIKI_PACKAGE_FOLDER,
callback: () => {
resolve();
},
});
} catch (error) {
reject(error);
}
});
} catch (error) {
// removes the folder function that failed to convert.
await remove(saveWikiFolderPath);
throw error;
}
}
export async function packetHTMLFromWikiFolder(folderWikiPath: string, pathOfNewHTML: string, constants: { TIDDLYWIKI_PACKAGE_FOLDER: string }): Promise<void> {
// 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
const { TIDDLYWIKI_PACKAGE_FOLDER } = constants;
const wikiInstance = TiddlyWiki();
// a .html file path should be provided, but if provided a folder path, we can add /index.html to fix it.
wikiInstance.boot.argv = [folderWikiPath, '--rendertiddler', '$:/core/save/all', isHtmlWiki(pathOfNewHTML) ? pathOfNewHTML : `${pathOfNewHTML}/index.html`, 'text/plain'];
await new Promise<void>((resolve, reject) => {
try {
wikiInstance.boot.startup({
// passing bootPath inside TidGi app. fix The "path" argument must be of type string. Received undefined
bootPath: TIDDLYWIKI_PACKAGE_FOLDER,
callback: () => {
resolve();
},
});
} catch (error) {
reject(error);
}
});
}

View file

@ -1,28 +1,28 @@
/* eslint-disable unicorn/prefer-native-coercion-functions */ /* eslint-disable unicorn/prefer-native-coercion-functions */
/** /**
* Worker environment is not part of electron environment, so don't import "@/constants/paths" here, as its process.resourcesPath will become undefined and throw Errors. * Worker environment is not part of electron environment, so don't import "@/constants/paths" here, as its process.resourcesPath will become undefined and throw Errors.
* *
* Don't use i18n and logger in worker thread. For example, 12b93020, will throw error "Electron failed to install correctly, please delete node_modules/electron and try installing again ...worker.js..." * Don't use i18n and logger in worker thread. For example, 12b93020, will throw error "Electron failed to install correctly, please delete node_modules/electron and try installing again ...worker.js..."
* *
* Import tw related things and typing from `@tiddlygit/tiddlywiki` instead of `tiddlywiki`, otherwise you will get `Unhandled Error ReferenceError: self is not defined at $:/boot/bootprefix.js:40749:36` because tiddlywiki * Import tw related things and typing from `@tiddlygit/tiddlywiki` instead of `tiddlywiki`, otherwise you will get `Unhandled Error ReferenceError: self is not defined at $:/boot/bootprefix.js:40749:36` because tiddlywiki
*/ */
import { uninstall } from '@/helpers/installV8Cache'; import { uninstall } from '@/helpers/installV8Cache';
import './preload'; import './preload';
import 'source-map-support/register'; import 'source-map-support/register';
import { type IUtils, TiddlyWiki } from '@tiddlygit/tiddlywiki'; import { type IUtils } from '@tiddlygit/tiddlywiki';
import Sqlite3Database from 'better-sqlite3'; import Sqlite3Database from 'better-sqlite3';
import { exists, mkdtemp } from 'fs-extra'; import { mkdtemp } from 'fs-extra';
import { tmpdir } from 'os'; import { tmpdir } from 'os';
import path from 'path'; import path from 'path';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { expose } from 'threads/worker'; import { expose } from 'threads/worker';
import { isHtmlWiki } from '@/constants/fileNames';
import { ISqliteDatabasePaths, SqliteDatabaseNotInitializedError, WikiWorkerDatabaseOperations } from '@services/database/wikiWorkerOperations'; import { ISqliteDatabasePaths, SqliteDatabaseNotInitializedError, WikiWorkerDatabaseOperations } from '@services/database/wikiWorkerOperations';
import { IWikiLogMessage, IZxWorkerMessage, ZxWorkerControlActions } from '../interface'; import { IWikiLogMessage, IZxWorkerMessage, ZxWorkerControlActions } from '../interface';
import { executeScriptInTWContext, executeScriptInZxScriptContext, extractTWContextScripts, type IVariableContextList } from '../plugin/zxPlugin'; import { executeScriptInTWContext, executeScriptInZxScriptContext, extractTWContextScripts, type IVariableContextList } from '../plugin/zxPlugin';
import { wikiOperationsInWikiWorker } from '../wikiOperations/executor/wikiOperationInServer'; import { wikiOperationsInWikiWorker } from '../wikiOperations/executor/wikiOperationInServer';
import { getWikiInstance, setCacheDatabase } from './globals'; import { getWikiInstance, setCacheDatabase } from './globals';
import { extractWikiHTML, packetHTMLFromWikiFolder } from './htmlWiki';
import { ipcServerRoutesMethods } from './ipcServerRoutes'; import { ipcServerRoutesMethods } from './ipcServerRoutes';
import { startNodeJSWiki } from './startNodeJSWiki'; import { startNodeJSWiki } from './startNodeJSWiki';
@ -120,57 +120,6 @@ function executeZxScript(file: IZxFileInput, zxPath: string): Observable<IZxWork
}); });
} }
async function extractWikiHTML(htmlWikiPath: string, saveWikiFolderPath: string, constants: { TIDDLYWIKI_PACKAGE_FOLDER: string }): Promise<void> {
// tiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder
// --savewikifolder <wikifolderpath> [<filter>]
// . /mywikifolder is the path where the tiddlder and plugins folders are stored
const { TIDDLYWIKI_PACKAGE_FOLDER } = constants;
if (!isHtmlWiki(htmlWikiPath)) {
throw new Error(`Please enter the path to the tiddlywiki.html file. Current path can't be used. ${htmlWikiPath}`);
}
if (await exists(saveWikiFolderPath)) {
throw new Error(`A folder already exists at this path, and a new knowledge base cannot be created here. ${saveWikiFolderPath}`);
}
const wikiInstance = TiddlyWiki();
wikiInstance.boot.argv = ['--load', htmlWikiPath, '--savewikifolder', saveWikiFolderPath, 'explodePlugins=no'];
await new Promise<void>((resolve, reject) => {
try {
wikiInstance.boot.startup({
// passing bootPath inside TidGi app. fix The "path" argument must be of type string. Received undefined
bootPath: TIDDLYWIKI_PACKAGE_FOLDER,
callback: () => {
resolve();
},
});
} catch (error) {
reject(error);
}
});
}
async function packetHTMLFromWikiFolder(folderWikiPath: string, pathOfNewHTML: string, constants: { TIDDLYWIKI_PACKAGE_FOLDER: string }): Promise<void> {
// 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
const { TIDDLYWIKI_PACKAGE_FOLDER } = constants;
const wikiInstance = TiddlyWiki();
// a .html file path should be provided, but if provided a folder path, we can add /index.html to fix it.
wikiInstance.boot.argv = [folderWikiPath, '--rendertiddler', '$:/core/save/all', isHtmlWiki(pathOfNewHTML) ? pathOfNewHTML : `${pathOfNewHTML}/index.html`, 'text/plain'];
await new Promise<void>((resolve, reject) => {
try {
wikiInstance.boot.startup({
// passing bootPath inside TidGi app. fix The "path" argument must be of type string. Received undefined
bootPath: TIDDLYWIKI_PACKAGE_FOLDER,
callback: () => {
resolve();
},
});
} catch (error) {
reject(error);
}
});
}
function beforeExit(): void { function beforeExit(): void {
uninstall?.uninstall(); uninstall?.uninstall();
} }