From 6cef4c25409c59c337b2e3f9fe3c9a4b54af40f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiss=20R=C3=B3bert?= Date: Sun, 2 Mar 2025 16:24:48 +0100 Subject: [PATCH] feat: fallback to bundled smart macro documentation --- .../src/services/smart-macro-doc.service.ts | 107 +++++++++++------- .../smart-macro-doc-renderer.service.ts | 4 +- .../store/actions/smart-macro-doc.action.ts | 4 +- packages/uhk-web/src/app/store/index.ts | 6 +- .../store/reducers/smart-macro-doc.reducer.ts | 13 ++- 5 files changed, 87 insertions(+), 47 deletions(-) diff --git a/packages/uhk-agent/src/services/smart-macro-doc.service.ts b/packages/uhk-agent/src/services/smart-macro-doc.service.ts index 78bdfabc3a6..c523a673deb 100644 --- a/packages/uhk-agent/src/services/smart-macro-doc.service.ts +++ b/packages/uhk-agent/src/services/smart-macro-doc.service.ts @@ -5,6 +5,7 @@ import getPort from 'get-port'; import { join } from 'path'; import fastify, { FastifyInstance } from 'fastify'; import { FirmwareRepoInfo, IpcEvents, LogService } from 'uhk-common'; +import { getPackageJsonFromPathAsync } from 'uhk-usb'; import { downloadSmartMacroDoc, downloadSmartMacroReferenceManual, REFERENCE_MANUAL_FILE_NAME } from 'uhk-smart-macro'; import { @@ -87,6 +88,68 @@ export class SmartMacroDocService { this.logService.misc(serviceLogMessage('stopped.')); } + private async downloadDocumentation(event: Electron.IpcMainEvent, firmwareRepoInfo: FirmwareRepoInfo): Promise { + this.logService.misc(serviceLogMessage('start downloading firmware documentation'), firmwareRepoInfo); + const [owner, repo] = firmwareRepoInfo.firmwareGitRepo.split('/'); + const downloadDirectory = join(this.rootPath, owner, repo, firmwareRepoInfo.firmwareGitTag); + const indexHtmlPath = join(downloadDirectory, 'index.html'); + + if (!await fse.pathExists(indexHtmlPath)) { + this.logService.misc(serviceLogMessage('firmware documentation downloading')); + + await downloadSmartMacroDoc({ + owner, + repo, + ref: firmwareRepoInfo.firmwareGitTag, + directory: downloadDirectory + }); + + this.logService.misc(serviceLogMessage('firmware documentation downloaded')); + } + else { + this.logService.misc(serviceLogMessage('firmware documentation downloaded earlier')); + } + + event.sender.send(IpcEvents.smartMacroDoc.downloadDocumentationReply, firmwareRepoInfo); + + const docDevDirectory = join(downloadDirectory, 'doc-dev'); + if (!await fse.pathExists(docDevDirectory)) { + this.logService.misc(serviceLogMessage('reference manual downloading')); + + await downloadSmartMacroReferenceManual({ + owner, + repo, + ref: firmwareRepoInfo.firmwareGitTag, + directory: docDevDirectory, + }); + + this.logService.misc(serviceLogMessage('reference manual downloaded')); + } + else { + this.logService.misc(serviceLogMessage('reference manual downloaded earlier')); + } + + const referenceManualPath = join(docDevDirectory, REFERENCE_MANUAL_FILE_NAME); + const referenceManual = await fse.readFile(referenceManualPath, 'utf8'); + event.sender.send(IpcEvents.smartMacroDoc.referenceManualReply, referenceManual); + } + + private async fallbackToBundledFirmware(event: Electron.IpcMainEvent): Promise { + this.logService.misc(serviceLogMessage('fallback to bundled firmware documentation')); + try { + const { packageJsonPath } = getDefaultFirmwarePath(this.rootDir); + const { gitInfo } = await getPackageJsonFromPathAsync(packageJsonPath); + const firmwareRepoInfo: FirmwareRepoInfo = { + firmwareGitRepo: gitInfo.repo, + firmwareGitTag: gitInfo.tag, + } + await this.downloadDocumentation(event, firmwareRepoInfo) + } + catch (error) { + this.logService.error(serviceLogMessage('failed to fallback to bundled documentation'), error); + } + } + private async handleAppStartInfo(event: Electron.IpcMainEvent): Promise { this.logService.misc(serviceLogMessage('getAppStartInfo')); @@ -97,48 +160,14 @@ export class SmartMacroDocService { try { const firmwareRepoInfo: FirmwareRepoInfo = args[0]; if (!firmwareRepoInfo.firmwareGitRepo || !firmwareRepoInfo.firmwareGitTag) { - this.logService.misc(serviceLogMessage('skip download firmware documentation because git repo or tag missing'), firmwareRepoInfo); - return; - } - - this.logService.misc(serviceLogMessage('start download firmware documentation'), firmwareRepoInfo); - const [owner, repo] = firmwareRepoInfo.firmwareGitRepo.split('/'); - const downloadDirectory = join(this.rootPath, owner, repo, firmwareRepoInfo.firmwareGitTag); - const indexHtmlPath = join(downloadDirectory, 'index.html'); - - if (!await fse.pathExists(indexHtmlPath)) { - this.logService.misc(serviceLogMessage('firmware documentation downloading')); - - await downloadSmartMacroDoc({ - owner, - repo, - ref: firmwareRepoInfo.firmwareGitTag, - directory: downloadDirectory - }); - } - - this.logService.misc(serviceLogMessage('firmware documentation downloaded')); - event.sender.send(IpcEvents.smartMacroDoc.downloadDocumentationReply); - - const docDevDirectory = join(downloadDirectory, 'doc-dev'); - if (!await fse.pathExists(docDevDirectory)) { - this.logService.misc(serviceLogMessage('reference manual downloading')); - - await downloadSmartMacroReferenceManual({ - owner, - repo, - ref: firmwareRepoInfo.firmwareGitTag, - directory: docDevDirectory - }); + this.logService.misc(serviceLogMessage('fallback to bundled firmware documentation because git repo or tag missing'), firmwareRepoInfo); + return this.fallbackToBundledFirmware(event); } - this.logService.misc(serviceLogMessage('reference manual downloaded')); - - const referenceManualPath = join(docDevDirectory, REFERENCE_MANUAL_FILE_NAME); - const referenceManual = await fse.readFile(referenceManualPath, 'utf8'); - event.sender.send(IpcEvents.smartMacroDoc.referenceManualReply, referenceManual); + return this.downloadDocumentation(event, firmwareRepoInfo); } catch (error) { - this.logService.error(serviceLogMessage('download documentation failed'), error); + this.logService.error(serviceLogMessage('download running firmware documentation failed'), error); + return this.fallbackToBundledFirmware(event); } } } diff --git a/packages/uhk-web/src/app/services/smart-macro-doc-renderer.service.ts b/packages/uhk-web/src/app/services/smart-macro-doc-renderer.service.ts index 47f6c4be46e..379d80f2886 100644 --- a/packages/uhk-web/src/app/services/smart-macro-doc-renderer.service.ts +++ b/packages/uhk-web/src/app/services/smart-macro-doc-renderer.service.ts @@ -27,8 +27,8 @@ export class SmartMacroDocRendererService { this.dispatchStoreAction(new ServiceListeningAction(arg)); }); - this.ipcRenderer.on(IpcEvents.smartMacroDoc.downloadDocumentationReply, () => { - this.dispatchStoreAction(new DownloadDocumentationSuccessAction()); + this.ipcRenderer.on(IpcEvents.smartMacroDoc.downloadDocumentationReply, (event : string, firmwareRepoInfo: FirmwareRepoInfo) => { + this.dispatchStoreAction(new DownloadDocumentationSuccessAction(firmwareRepoInfo)); }); this.ipcRenderer.on(IpcEvents.smartMacroDoc.referenceManualReply, (event: string, arg: string) => { diff --git a/packages/uhk-web/src/app/store/actions/smart-macro-doc.action.ts b/packages/uhk-web/src/app/store/actions/smart-macro-doc.action.ts index 596e3c2da7e..2798ee01cfe 100644 --- a/packages/uhk-web/src/app/store/actions/smart-macro-doc.action.ts +++ b/packages/uhk-web/src/app/store/actions/smart-macro-doc.action.ts @@ -1,9 +1,9 @@ import { Action } from "@ngrx/store"; +import { FirmwareRepoInfo } from 'uhk-common'; export enum ActionTypes { DownloadDocumentation = '[smart-macro-doc] download documentation', DownloadDocumentationSuccess = '[smart-macro-doc] download documentation success', - DownloadDocumentationFailed = '[smart-macro-doc] download documentation failed', PanelSizeChanged = '[smart-macro-doc] panel size changed', ReferenceManualChanged = '[smart-macro-doc] reference manual changed', ServiceListening = '[smart-macro-doc] service listening', @@ -17,6 +17,8 @@ export class DownloadDocumentationAction implements Action { export class DownloadDocumentationSuccessAction implements Action { type = ActionTypes.DownloadDocumentationSuccess; + + constructor(public payload: FirmwareRepoInfo) {} } export class PanelSizeChangedAction implements Action { diff --git a/packages/uhk-web/src/app/store/index.ts b/packages/uhk-web/src/app/store/index.ts index 91b2c34c335..465e0660a65 100644 --- a/packages/uhk-web/src/app/store/index.ts +++ b/packages/uhk-web/src/app/store/index.ts @@ -786,11 +786,11 @@ export const getSelectedLayerOptionAddKeymap = createSelector( export const smartMacroDocState = (state: AppState) => state.smartMacroDoc; export const selectSmartMacroDocUrl = createSelector( - runningInElectron, smartMacroDocState, getRightModuleFirmwareRepoInfo, - (isRunningInElectron, smartMacroState, firmwareRepoInfo) => { + runningInElectron, smartMacroDocState, + (isRunningInElectron, smartMacroState) => { if (isRunningInElectron) { if (smartMacroState.firmwareDocState === fromSmartMacroDoc.FirmwareDocState.Loaded) - return `http://127.0.0.1:${smartMacroState.port}/${firmwareRepoInfo.firmwareGitRepo}/${firmwareRepoInfo.firmwareGitTag}/index.html`; + return `http://127.0.0.1:${smartMacroState.port}/${smartMacroState.firmwareDocRepoInfo.firmwareGitRepo}/${smartMacroState.firmwareDocRepoInfo.firmwareGitTag}/index.html`; return `http://127.0.0.1:${smartMacroState.port}/loading.html`; } diff --git a/packages/uhk-web/src/app/store/reducers/smart-macro-doc.reducer.ts b/packages/uhk-web/src/app/store/reducers/smart-macro-doc.reducer.ts index af5bec7a292..c491ca61d86 100644 --- a/packages/uhk-web/src/app/store/reducers/smart-macro-doc.reducer.ts +++ b/packages/uhk-web/src/app/store/reducers/smart-macro-doc.reducer.ts @@ -1,6 +1,9 @@ +import { FirmwareRepoInfo } from 'uhk-common'; + import * as fromApp from '../actions/app'; import { ActionTypes, + DownloadDocumentationSuccessAction, PanelSizeChangedAction, SmartMacroDocActions } from '../actions/smart-macro-doc.action'; @@ -16,6 +19,7 @@ export enum FirmwareDocState { export interface State { firmwareDocState: FirmwareDocState; + firmwareDocRepoInfo: FirmwareRepoInfo; panelSize: number; panelVisible: boolean; port?: number; @@ -23,11 +27,15 @@ export interface State { export const initialState: State = { firmwareDocState: FirmwareDocState.Unknown, + firmwareDocRepoInfo: { + firmwareGitRepo: '', + firmwareGitTag: '', + }, panelSize: DEFAULT_PANEL_SIZE, panelVisible: false }; -export function reducer(state = initialState, action: SmartMacroDocActions | fromApp.Actions) { +export function reducer(state = initialState, action: SmartMacroDocActions | fromApp.Actions): State { switch (action.type) { case fromApp.ActionTypes.LoadApplicationSettingsSuccess: @@ -45,7 +53,8 @@ export function reducer(state = initialState, action: SmartMacroDocActions | fro case ActionTypes.DownloadDocumentationSuccess: return { ...state, - firmwareDocState: FirmwareDocState.Loaded + firmwareDocState: FirmwareDocState.Loaded, + firmwareDocRepoInfo: (action as DownloadDocumentationSuccessAction).payload, }; case ActionTypes.PanelSizeChanged: