diff --git a/src/app.module.ts b/src/app.module.ts index d96c5dd1..884fe858 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -15,10 +15,10 @@ import { ResponseInterceptor, } from './common/interceptors/response.interceptors' import { - ASSET_DIR, DATA_DIR, LOGGER_DIR, TEMP_DIR, + USER_ASSET_DIR, } from './constants/path.constant' import { AggregateModule } from './modules/aggregate/aggregate.module' import { AnalyzeModule } from './modules/analyze/analyze.module' @@ -57,8 +57,8 @@ function mkdirs() { Logger.log(chalk.blue('临时目录已经建好: ' + TEMP_DIR)) mkdirSync(LOGGER_DIR, { recursive: true }) Logger.log(chalk.blue('日志目录已经建好: ' + LOGGER_DIR)) - mkdirSync(ASSET_DIR, { recursive: true }) - Logger.log(chalk.blue('资源目录已经建好: ' + ASSET_DIR)) + mkdirSync(USER_ASSET_DIR, { recursive: true }) + Logger.log(chalk.blue('资源目录已经建好: ' + USER_ASSET_DIR)) } mkdirs() diff --git a/src/constants/path.constant.ts b/src/constants/path.constant.ts index 2d414534..bf76fe9c 100644 --- a/src/constants/path.constant.ts +++ b/src/constants/path.constant.ts @@ -10,7 +10,7 @@ export const DATA_DIR = isDev ? join(process.cwd(), './tmp') : join(HOME, '.mx-space') -export const ASSET_DIR = join(DATA_DIR, 'assets') +export const USER_ASSET_DIR = join(DATA_DIR, 'assets') export const LOGGER_DIR = join(DATA_DIR, 'log') export const LOCAL_BOT_LIST_DATA_FILE_PATH = join(DATA_DIR, 'bot_list.json') diff --git a/src/modules/markdown/markdown.controller.ts b/src/modules/markdown/markdown.controller.ts index 9ab0f776..e32a85b5 100644 --- a/src/modules/markdown/markdown.controller.ts +++ b/src/modules/markdown/markdown.controller.ts @@ -13,7 +13,6 @@ import dayjs from 'dayjs' import { render } from 'ejs' import { minify } from 'html-minifier' import JSZip from 'jszip' -import { sample } from 'lodash' import { join } from 'path' import { performance } from 'perf_hooks' import { Readable } from 'stream' @@ -198,14 +197,10 @@ export class MarkdownController { const structure = await this.service.getRenderedMarkdownHtmlStructure( markdown, document.title, + theme, ) const html = render(await this.service.getMarkdownEjsRenderTemplate(), { - theme: - theme === 'random' - ? sample(this.service.getMarkdownRenderTheme()) - : xss(theme), - ...structure, title: document.title, @@ -246,11 +241,12 @@ export class MarkdownController { const structure = await this.service.getRenderedMarkdownHtmlStructure( html, title, + theme, ) return minify( render(await this.service.getMarkdownEjsRenderTemplate(), { ...structure, - theme: xss(theme), + title: xss(title), }), ) diff --git a/src/modules/markdown/markdown.service.ts b/src/modules/markdown/markdown.service.ts index b690b826..6ea81f53 100644 --- a/src/modules/markdown/markdown.service.ts +++ b/src/modules/markdown/markdown.service.ts @@ -321,10 +321,19 @@ ${text.trim()} return marked(text) } - async getRenderedMarkdownHtmlStructure(html: string, title: string) { + async getRenderedMarkdownHtmlStructure( + html: string, + title: string, + theme = 'newsprint', + ) { const style = await this.assetService.getAsset('/markdown/markdown.css', { encoding: 'utf8', }) + + const themeStyleSheet = await this.assetService.getAsset( + '/markdown/theme/' + theme + '.css', + { encoding: 'utf-8' }, + ) return { body: [`

${title}

${html}
`], extraScripts: [ @@ -342,7 +351,7 @@ ${text.trim()} link: [ '', ], - style: [style], + style: [style, themeStyleSheet], } } @@ -352,7 +361,7 @@ ${text.trim()} }) } - getMarkdownRenderTheme() { - return ['newsprint', 'github', 'han', 'gothic'] as const - } + // getMarkdownRenderTheme() { + // return ['newsprint', 'github', 'han', 'gothic'] as const + // } } diff --git a/src/processors/helper/helper.email.service.ts b/src/processors/helper/helper.email.service.ts index 8484287e..0290dc25 100644 --- a/src/processors/helper/helper.email.service.ts +++ b/src/processors/helper/helper.email.service.ts @@ -45,13 +45,13 @@ export class EmailService { writeTemplate(type: ReplyMailType, source: string) { switch (type) { case ReplyMailType.Guest: - return this.assetService.writeAsset( + return this.assetService.writeUserCustomAsset( '/email-template/guest.template.ejs', source, { encoding: 'utf-8' }, ) case ReplyMailType.Owner: - return this.assetService.writeAsset( + return this.assetService.writeUserCustomAsset( '/email-template/owner.template.ejs', source, { encoding: 'utf-8' }, diff --git a/src/processors/helper/hepler.asset.service.ts b/src/processors/helper/hepler.asset.service.ts index 0f1ac6c4..c190777a 100644 --- a/src/processors/helper/hepler.asset.service.ts +++ b/src/processors/helper/hepler.asset.service.ts @@ -6,7 +6,8 @@ import { Injectable, Logger } from '@nestjs/common' import fs from 'fs' import path, { join } from 'path' -import { ASSET_DIR } from '~/constants/path.constant' +import { promisify } from 'util' +import { USER_ASSET_DIR } from '~/constants/path.constant' import { HttpService } from './helper.http.service' // 先从 ASSET_DIR 找用户自定义的资源, 没有就从默认的 ASSET_DIR 找, 没有就从网上拉取, 存到默认的 ASSET_DIR @@ -17,6 +18,9 @@ export class AssetService { this.logger = new Logger(AssetService.name) } + /** + * 内置资源地址 + */ public embedAssetPath = path.resolve(process.cwd(), 'assets') // 在线资源的地址 `/` 结尾 private onlineAssetPath = @@ -49,8 +53,8 @@ export class AssetService { path: string, options: Parameters[1], ) { - if (fs.existsSync(join(ASSET_DIR, path))) { - return fs.readFileSync(join(ASSET_DIR, path), options) + if (fs.existsSync(join(USER_ASSET_DIR, path))) { + return await promisify(fs.readFile)(join(USER_ASSET_DIR, path), options) } return null } @@ -77,28 +81,32 @@ export class AssetService { })(), { recursive: true }, ) - fs.writeFileSync(join(this.embedAssetPath, path), data, options) + promisify(fs.writeFile)(join(this.embedAssetPath, path), data, options) return data } catch (e) { this.logger.error('本地资源不存在,线上资源无法拉取') throw e } } - return fs.readFileSync(join(this.embedAssetPath, path), options) + return promisify(fs.readFile)(join(this.embedAssetPath, path), options) } - public writeAsset( + public writeUserCustomAsset( path: string, data: any, options: Parameters[2], ) { fs.mkdirSync( (() => { - const p = join(ASSET_DIR, path).split('/') + const p = join(USER_ASSET_DIR, path).split('/') return p.slice(0, p.length - 1).join('/') })(), { recursive: true }, ) - fs.writeFileSync(join(ASSET_DIR, path), data, options) + fs.writeFileSync(join(USER_ASSET_DIR, path), data, options) + } + + public async removeUserCustomAsset(path: string) { + return promisify(fs.unlink)(join(USER_ASSET_DIR, path)) } }