img conversion
This commit is contained in:
1 parent
38c5579fbb
commit
b655adc305
5 files changed
+927
-24
No files matched your search
+108
-3
@@ -1,6 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import path from 'path'
|
||||
|
||||
export default function scraper(discordAuth) {
|
||||
import axios from 'axios'
|
||||
import mime from 'mime-types'
|
||||
|
||||
import type { PrismaClient, Attachment } from '@prisma/client';
|
||||
import type { ImageAnnotatorClient } from '@google-cloud/vision';
|
||||
import type Minio from 'minio'
|
||||
|
||||
import sharp from 'sharp';
|
||||
|
||||
const IMAGE_TYPES = [
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'image/webp',
|
||||
'image/gif',
|
||||
]
|
||||
|
||||
const VIDEO_TYPES = [
|
||||
'video/mp4',
|
||||
'video/quicktime'
|
||||
]
|
||||
|
||||
const STORAGE_BUCKET = process.env.STORAGE_BUCKET
|
||||
|
||||
export default function scraper(discordAuth, vision: ImageAnnotatorClient, minio: Minio.Client) {
|
||||
const headers = {
|
||||
'Authorization': discordAuth,
|
||||
}
|
||||
@@ -25,12 +48,93 @@ export default function scraper(discordAuth) {
|
||||
return res.data
|
||||
}
|
||||
|
||||
async function detectText(attachment: Attachment) {
|
||||
// bail out of anything not an image
|
||||
if (!IMAGE_TYPES.includes(attachment.contentType)) return {}
|
||||
|
||||
const annotateRequest = {
|
||||
image: {
|
||||
source: {
|
||||
imageUri: attachment.url
|
||||
}
|
||||
},
|
||||
features: [{ type: 'TEXT_DETECTION' }],
|
||||
}
|
||||
const res = await vision.annotateImage(annotateRequest)
|
||||
// comes back as an array
|
||||
return res[0] || {}
|
||||
}
|
||||
|
||||
async function downloadAttachment(a: Attachment) {
|
||||
const download = await axios.get(a.url, { responseType: 'stream' })
|
||||
const isImage = IMAGE_TYPES.includes(a.contentType)
|
||||
|
||||
const objectName = () => {
|
||||
if (isImage)
|
||||
return `${a.memeId}.webp`
|
||||
|
||||
return `${a.memeId}.${mime.extension(a.contentType)}`
|
||||
}
|
||||
|
||||
const stream = async () => {
|
||||
if (isImage) {
|
||||
const converter = sharp().webp()
|
||||
download.data.pipe(converter)
|
||||
return converter
|
||||
}
|
||||
return download.data
|
||||
}
|
||||
|
||||
return minio.putObject(STORAGE_BUCKET, objectName(), await stream())
|
||||
}
|
||||
|
||||
function filterAttachments(messages, guild, channel) {
|
||||
const acceptedContentTypes = [
|
||||
...IMAGE_TYPES,
|
||||
...VIDEO_TYPES,
|
||||
]
|
||||
|
||||
return Promise.all(messages
|
||||
.filter(m => m.attachments)
|
||||
// bundle message and attachment together
|
||||
.map(m => m.attachments.map(a => [a, m]))
|
||||
.flat()
|
||||
.filter(([a, m]) => acceptedContentTypes.includes(a.content_type))
|
||||
.map(async ([a, m]) => {
|
||||
const attachment: Attachment = {
|
||||
id: BigInt(a.id),
|
||||
msgId: BigInt(m.id),
|
||||
channelId: BigInt(m.channel_id),
|
||||
url: a.url,
|
||||
contentType: a.content_type,
|
||||
message: m,
|
||||
|
||||
// create this ahead of time to associate with our copy of the media
|
||||
memeId: crypto.randomUUID(),
|
||||
|
||||
// @ts-ignore it's fine
|
||||
vision: {},
|
||||
guild,
|
||||
channel,
|
||||
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined
|
||||
}
|
||||
|
||||
const visionData = await detectText(attachment)
|
||||
return { ...attachment, vision: visionData }
|
||||
}))
|
||||
}
|
||||
|
||||
async function getChannelAttachments(channelId) {
|
||||
try {
|
||||
const channel = await fetchChannel(channelId)
|
||||
const guild = await fetchGuildDetails(channel.guild_id)
|
||||
const messages = await fetchChannelMessages(channelId)
|
||||
return { messages, channel, guild }
|
||||
|
||||
return filterAttachments(messages, guild, channel);
|
||||
|
||||
// return { messages, channel, guild }
|
||||
} catch (e) {
|
||||
console.error('scrape error', {
|
||||
err: e.toJSON(),
|
||||
@@ -41,6 +145,7 @@ export default function scraper(discordAuth) {
|
||||
|
||||
return {
|
||||
getChannelAttachments,
|
||||
downloadAttachment,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user