86 lines
2.5 KiB
TypeScript
86 lines
2.5 KiB
TypeScript
import type { PrismaClient, Attachment, Meme } from '@prisma/client';
|
|
import type { Meilisearch } from 'meilisearch';
|
|
import type { Logger } from 'pino';
|
|
|
|
import _ from 'lodash'
|
|
|
|
import * as attachments from './attachments'
|
|
|
|
const STORAGE_BUCKET = process.env.STORAGE_BUCKET
|
|
|
|
function memeUrl(a: Attachment) {
|
|
const STORAGE_URL = process.env.STORAGE_URL
|
|
const u = new URL(`${STORAGE_BUCKET}/${attachments.objectName(a)}`, `https://${STORAGE_URL}`)
|
|
return u.href
|
|
}
|
|
|
|
export default async function memeService(baseLog: Logger, prisma: PrismaClient, meili: Meilisearch) {
|
|
const log = baseLog.child({ service: 'meme' })
|
|
|
|
function fromAttachment(a: Attachment) {
|
|
const text = a.vision.fullTextAnnotation?.text || ''
|
|
const tags = [
|
|
a.guild.name,
|
|
a.channel.name,
|
|
a.message.author.username,
|
|
]
|
|
|
|
const m: Meme = {
|
|
id: a.memeId,
|
|
url: memeUrl(a),
|
|
text,
|
|
tags: tags,
|
|
attachmentId: a.id,
|
|
postedAt: a.postedAt,
|
|
createdAt: undefined,
|
|
updatedAt: undefined
|
|
}
|
|
|
|
return m
|
|
}
|
|
|
|
async function ensureMeiliIndex() {
|
|
const task = await meili.createIndex('memes', { primaryKey: 'id' })
|
|
const result = await meili.waitForTask(task.taskUid)
|
|
log.debug(result);
|
|
const index = await meili.index('memes')
|
|
await index.updateSortableAttributes(['postedAt'])
|
|
return index;
|
|
}
|
|
|
|
// BLOWS IT UP
|
|
async function resetMeili() {
|
|
const delTask = await meili.deleteIndex('memes')
|
|
const delResult = await meili.waitForTask(delTask.taskUid)
|
|
const index = await ensureMeiliIndex()
|
|
const memes = (await prisma.meme.findMany())
|
|
.map(m => ({ ...m, postedAt: m.postedAt.valueOf() }));
|
|
|
|
for await (const batch of _.chunk(memes, 1000)) {
|
|
const task = await index.updateDocuments(batch)
|
|
const res = await meili.waitForTask(task.taskUid)
|
|
log.info({ res }, 'added meme batch')
|
|
}
|
|
}
|
|
|
|
async function persist(m: Meme) {
|
|
const index = meili.index('memes')
|
|
const doc = ({ ...m, postedAt: m.postedAt.valueOf() })
|
|
return index.updateDocuments([doc])
|
|
}
|
|
|
|
await ensureMeiliIndex();
|
|
|
|
// BAM
|
|
// await resetMeili();
|
|
|
|
return {
|
|
ensureMeiliIndex,
|
|
resetMeili,
|
|
fromAttachment,
|
|
persist,
|
|
}
|
|
}
|
|
|
|
export type MemeService = Awaited<ReturnType<typeof memeService>>
|