From f57b23e5153dbd03cafd3b0281ee187dac0b3ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AF=BB?= Date: Wed, 8 Mar 2023 11:40:42 +0800 Subject: [PATCH] feat: auto download admin (#1005 * feat: auto download admin Signed-off-by: Innei * fix: update Signed-off-by: Innei * fix: update Signed-off-by: Innei --------- Signed-off-by: Innei --- src/modules/pageproxy/pageproxy.controller.ts | 87 ++++++++++++++++++- src/modules/pageproxy/pageproxy.module.ts | 2 + src/modules/update/update.module.ts | 1 + src/modules/update/update.service.ts | 4 +- 4 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/modules/pageproxy/pageproxy.controller.ts b/src/modules/pageproxy/pageproxy.controller.ts index b842e7d4..42f092ec 100644 --- a/src/modules/pageproxy/pageproxy.controller.ts +++ b/src/modules/pageproxy/pageproxy.controller.ts @@ -5,6 +5,7 @@ import { isNull } from 'lodash' import { lookup } from 'mime-types' import PKG from 'package.json' import { extname, join } from 'path' +import { Observable } from 'rxjs' import { Controller, @@ -24,6 +25,7 @@ import { CacheService } from '~/processors/redis/cache.service' import { getRedisKey } from '~/utils/redis.util' import { dashboard } from '../../../package.json' +import { UpdateService } from '../update/update.service' import { PageProxyDebugDto } from './pageproxy.dto' import { PageProxyService } from './pageproxy.service' @@ -33,6 +35,7 @@ export class PageProxyController { constructor( private readonly cacheService: CacheService, private readonly service: PageProxyService, + private readonly updateService: UpdateService, ) {} @Get('/qaqdmin') @@ -150,21 +153,97 @@ export class PageProxyController { return reply.type('text/html').send(entry) } + private fetchObserver$: Observable | null + private fetchLogs: string[] | null + private fetchErrorMsg: string | null + @Get('/proxy/qaqdmin') @HTTPDecorators.Bypass - async getLocalBundledAdmin(@Res() reply: FastifyReply) { + async getLocalBundledAdmin(@Query() query: any, @Res() reply: FastifyReply) { if ((await this.service.checkCanAccessAdminProxy()) === false) { return reply.type('application/json').status(403).send({ message: 'admin proxy not enabled', }) } + if (this.fetchObserver$ && query.log) { + if (this.fetchLogs === null) { + return reply.code(204) + } + const log = this.fetchLogs.pop() || '...' + + reply.code(200).type('text/html').send(`${log}`) + return + } + + if (query.log) { + if (this.fetchErrorMsg) { + reply.code(403).type('text/html').send(this.fetchErrorMsg) + this.fetchErrorMsg = null + } else { + reply.code(200).type('text/html').send('...') + } + return + } + const entryPath = path.join(LOCAL_ADMIN_ASSET_PATH, 'index.html') const isAssetPathIsExist = existsSync(entryPath) if (!isAssetPathIsExist) { + this.fetchLogs = [] reply.code(404).type('text/html') - .send(`

Local Admin Assets is not found. Navigator to page proxy in 3 second.

`) + .send(` +

Local Admin Assets is not found. Downloading start...

+

If finished download but page not reload or logs are not output for a period of time, please reload page manually.

+

+        `)
+
+      this.fetchObserver$ = this.updateService.downloadAdminAsset(
+        await this.updateService.getLatestAdminVersion().catch((err) => {
+          this.fetchErrorMsg = err.message
+
+          throw err
+        }),
+      )
+
+      const cleanup = () => {
+        this.fetchObserver$ = null
+        this.fetchLogs = null
+      }
+
+      this.fetchObserver$.subscribe({
+        next: (value) => {
+          this.fetchLogs?.push(value)
+        },
+        error: cleanup,
+        complete: cleanup,
+      })
+
       return
     }
     try {
diff --git a/src/modules/pageproxy/pageproxy.module.ts b/src/modules/pageproxy/pageproxy.module.ts
index 404a7c4f..ae0e4a50 100644
--- a/src/modules/pageproxy/pageproxy.module.ts
+++ b/src/modules/pageproxy/pageproxy.module.ts
@@ -1,10 +1,12 @@
 import { Module } from '@nestjs/common'
 
+import { UpdateModule } from '../update/update.module'
 import { PageProxyController } from './pageproxy.controller'
 import { PageProxyService } from './pageproxy.service'
 
 @Module({
   controllers: [PageProxyController],
   providers: [PageProxyService],
+  imports: [UpdateModule],
 })
 export class PageProxyModule {}
diff --git a/src/modules/update/update.module.ts b/src/modules/update/update.module.ts
index d1af7e18..4b0e49ff 100644
--- a/src/modules/update/update.module.ts
+++ b/src/modules/update/update.module.ts
@@ -6,5 +6,6 @@ import { UpdateService } from './update.service'
 @Module({
   controllers: [UpdateController],
   providers: [UpdateService],
+  exports: [UpdateService],
 })
 export class UpdateModule {}
diff --git a/src/modules/update/update.service.ts b/src/modules/update/update.service.ts
index 794dab82..cff66847 100644
--- a/src/modules/update/update.service.ts
+++ b/src/modules/update/update.service.ts
@@ -31,6 +31,8 @@ export class UpdateService {
           })
 
         if (!json) {
+          subscriber.next(chalk.red('Fetching error, json is empty. \n'))
+          subscriber.complete()
           return
         }
 
@@ -130,7 +132,7 @@ export class UpdateService {
     return res.data.tag_name.replace(/^v/, '')
   }
 
-  runShellCommandPipeOutput(
+  private runShellCommandPipeOutput(
     command: string,
     args: any[],
     subscriber: Subscriber,