Skip to content

Commit

Permalink
修正帖子附件转换
Browse files Browse the repository at this point in the history
  • Loading branch information
bangbang93 committed Nov 15, 2021
1 parent 54b1ef8 commit ff03ac6
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/app/clean/clean.module.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import {Module} from '@nestjs/common'
import {CommandRunnerModule} from 'nest-commander'
import {ModelsModule} from '../models/models.module'
import {CleanCommand} from './clean.command'
import {CleanService} from './clean.service'
import {ConfirmQuestion} from './confirm.question'

@Module({
imports: [
ModelsModule,
CommandRunnerModule.forModule(CleanModule),
],
providers: [
CleanCommand,
ConfirmQuestion,
CleanService,
],
})
export class CleanModule {}
2 changes: 2 additions & 0 deletions src/app/convert/convert.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {PostService} from './converter/post.service'
import {SettingService} from './converter/setting.service'
import {ThreadService} from './converter/thread.service'
import {UserService} from './converter/user.service'
import {MessageService} from './message.service'

@Module({
imports: [
Expand All @@ -22,6 +23,7 @@ import {UserService} from './converter/user.service'
ThreadService,
PostService,
SettingService,
MessageService,
],
exports: [
ConvertService,
Expand Down
12 changes: 10 additions & 2 deletions src/app/convert/converter/post.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {ForumForumModel} from '../../models/x/forum-forum.model'
import {ForumPostModel, IForumPostSchema} from '../../models/x/forum-post.model'
import {ForumThreadModel} from '../../models/x/forum-thread.model'
import {BaseService} from '../base.service'
import {MessageService} from '../message.service'

interface IReply {
message: string
Expand All @@ -40,6 +41,7 @@ export class PostService extends BaseService {
private readonly forumForumModel: ForumForumModel,
private readonly userModel: UserModel,
private readonly threadModel: ThreadModel,
private readonly messageService: MessageService,
configService: ConfigService,
) {
super()
Expand All @@ -61,7 +63,7 @@ export class PostService extends BaseService {
const check = await this.postModel.check()
if (check) {
this.logger.error('Q帖子表中有数据,请先删除再执行命令')
return
// return
}

const start = new Date()
Expand Down Expand Up @@ -113,7 +115,7 @@ export class PostService extends BaseService {

const date = fromUnixTime(post.dateline)

const result: IReply = await this.piscina.run(post.message)
const result: IReply = await this.convertMessage(post.message)
const postData: IPostSchema = {
id: post.pid,
user_id: post.authorid,
Expand Down Expand Up @@ -178,6 +180,12 @@ export class PostService extends BaseService {
this.logger.info(`回复转换完成,耗时${formatDistanceToNow(start, {locale: zhCN})}`)
}

public async convertMessage(message: string): Promise<IReply> {
const reply: IReply = await this.piscina.run(message, {name: 'processMessage'})
reply.message = await this.messageService.processMessage(reply.message)
return reply
}

private async getPost(pid: number): Promise<IPostSchema> {
const post = this.queue.find((post) => post.id === pid)
if (post) return post
Expand Down
75 changes: 75 additions & 0 deletions src/app/convert/message.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {Injectable, OnModuleInit} from '@nestjs/common'
import * as DataLoader from 'dataloader'
import {AttachmentModel, IAttachmentSchema} from '../models/q/attachment.model'
import {CommonSmileyModel, ICommonSmileySchema} from '../models/x/common-smiley.model'
import {ForumImagetypeModel, IForumImagetypeSchema} from '../models/x/forum-imagetype.model'

@Injectable()
export class MessageService implements OnModuleInit {
private readonly attachmentIdLoader: DataLoader<number, IAttachmentSchema>

private readonly emojiType = new Map<number, string>()
private readonly emoji: Array<{search: string; replace: string}> = []

constructor(
private readonly forumImagetypeModel: ForumImagetypeModel,
private readonly commonSmileyModel: CommonSmileyModel,
attachmentModel: AttachmentModel,
) {
this.attachmentIdLoader = attachmentModel.getPkLoader()
}

public async onModuleInit(): Promise<void> {
const imageType: IForumImagetypeSchema[] = await this.forumImagetypeModel.query.select()
for (const type of imageType) {
this.emojiType.set(type.typeid, type.directory)
}
const smiles: ICommonSmileySchema[] = await this.commonSmileyModel.query.select()
for (const smile of smiles) {
this.emoji.push({
search: this.escapeHtml(smile.code),
replace: smile.code.replace('{', '[').replace('}', ']'),
})
}
}

public async processMessage(message: string): Promise<string> {
message = await this.replaceAttachment(message)
message = await this.replaceEmoji(message)
return message
}

private async replaceAttachment(message: string): Promise<string> {
const matches = message.match(/\[attach\](\d+)\[\/attach\]/iug)
if (matches) {
const ids = matches.slice(1).map((e) => parseInt(e, 10))
const attachments = await this.attachmentIdLoader.loadMany(ids)
for (const id of ids) {
const attachment = attachments.find((att) => att instanceof Error ? false : att.id === id) as IAttachmentSchema
if (!attachment || attachment.type !== 1) {
message.replace(`[attach]${id}[/attach]`, '')
} else {
message = message.replace(`[attach]${attachment.id}[/attach]`,
`[img alt="${attachment.id}" src="http://discuz" title="${attachment.id}" width="" height=""][/img]`)
}
}
}
return message
}

private async replaceEmoji(message: string): Promise<string> {
for (const emoji of this.emoji) {
message = message.replace(emoji.search, emoji.replace)
}
return message
}

private escapeHtml(unsafe: string): string {
return unsafe
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll('\'', '&#039;')
}
}
10 changes: 10 additions & 0 deletions src/app/models/q/q-base.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Inject, Injectable} from '@nestjs/common'
import {ConfigService} from '@nestjs/config'
import * as DataLoader from 'dataloader'
import {Knex} from 'knex'
import {QMysql} from '../models.constant'

Expand Down Expand Up @@ -28,6 +29,15 @@ export abstract class QBaseModel<T = unknown> {
public async insertMany(data: Array<Partial<T>>): Promise<void> {
await this.query.insert(data as any)
}

public getPkLoader(fields: (keyof T)[] = null, cache = false): DataLoader<string| number, T> {
return new DataLoader<string | number, T>(async (ids) => {
const rows = await this.query.whereIn(this.pk, ids).select(fields)
return ids.map((id) => rows.find((row) => row[this.pk] === id))
}, {
cache,
})
}
}

export abstract class QInitModel<T> extends QBaseModel<T> {
Expand Down
25 changes: 22 additions & 3 deletions src/worker.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import bbob from '@bbob/core'
import {render} from '@bbob/html/es'
import html5Preset from '@bbob/preset-html5/es'
import {NestFactory} from '@nestjs/core'
import {isEmpty} from 'lodash'
import * as TurndownService from 'turndown'
import {AppModule} from './app/app.module'
import {MessageService} from './app/convert/message.service'
import Piscina = require('piscina')

export interface IMessageData {
Expand All @@ -17,7 +20,22 @@ const turndownService = new TurndownService()

const convert = bbob(html5Preset())

export default function processMessage(message: string): IMessageData {
let messageService: MessageService

async function setupWorker(): Promise<typeof processMessage> {
const app = await NestFactory.createApplicationContext(AppModule, {
logger: ['error'],
})
await app.init()

messageService = await app.get(MessageService)

return processMessage
}

export default setupWorker()

export async function processMessage(message: string): Promise<IMessageData> {
let replyInfo = null
message = message.replace(/^\[quote]([\s\S]*?)\[\/quote]/, (_, matches) => {
if (matches[0]) {
Expand All @@ -32,16 +50,17 @@ export default function processMessage(message: string): IMessageData {
}
return ''
})
message = convertMessage(message)
message = await convertMessage(message)
return {
message,
replyInfo,
}
}

export function convertMessage(message: string): string {
export async function convertMessage(message: string): Promise<string> {
try {
message = replaceFontFamily(message)
message = await messageService.processMessage(message)
const html = convert.process(message, {render}).html
if (Piscina.workerData.mode === 'markdown') {
return turndownService.turndown(html)
Expand Down

0 comments on commit ff03ac6

Please sign in to comment.