Merge pull request #2998 from specklesystems/previews-ioc-3
chore(server): previews IoC 3 - sendObjectPreviewFactory
This commit is contained in:
Коммит
f513053096
|
@ -1,5 +1,6 @@
|
|||
import { ObjectPreview } from '@/modules/previews/domain/types'
|
||||
import { Nullable, Optional } from '@speckle/shared'
|
||||
import express from 'express'
|
||||
|
||||
export type GetObjectPreviewInfo = (params: {
|
||||
streamId: string
|
||||
|
@ -17,7 +18,7 @@ export type GetPreviewImage = (params: {
|
|||
export type GetObjectPreviewBufferOrFilepath = (params: {
|
||||
streamId: string
|
||||
objectId: string
|
||||
angle: number
|
||||
angle?: string
|
||||
}) => Promise<
|
||||
| {
|
||||
type: 'file'
|
||||
|
@ -25,5 +26,13 @@ export type GetObjectPreviewBufferOrFilepath = (params: {
|
|||
error?: true
|
||||
errorCode?: string
|
||||
}
|
||||
| { type: 'buffer'; buffer: Buffer }
|
||||
| { type: 'buffer'; buffer: Buffer; error?: true; errorCode?: string }
|
||||
>
|
||||
|
||||
export type SendObjectPreview = (
|
||||
req: express.Request,
|
||||
res: express.Response,
|
||||
streamId: string,
|
||||
objectId: string,
|
||||
angle: string
|
||||
) => Promise<void>
|
||||
|
|
|
@ -6,7 +6,7 @@ export type ObjectPreview = {
|
|||
previewStatus: number
|
||||
priority: number
|
||||
lastUpdate: Date
|
||||
preview: Nullable<string>
|
||||
preview: Nullable<Record<string, string>>
|
||||
}
|
||||
|
||||
export type Preview = {
|
||||
|
|
|
@ -21,7 +21,8 @@ const httpErrorImage = (httpErrorCode) =>
|
|||
const cors = require('cors')
|
||||
const { db } = require('@/db/knex')
|
||||
const {
|
||||
getObjectPreviewBufferOrFilepathFactory
|
||||
getObjectPreviewBufferOrFilepathFactory,
|
||||
sendObjectPreviewFactory
|
||||
} = require('@/modules/previews/services/management')
|
||||
const { getObject } = require('@/modules/core/services/objects')
|
||||
const {
|
||||
|
@ -39,59 +40,17 @@ exports.init = (app, isInitial) => {
|
|||
moduleLogger.info('📸 Init object preview module')
|
||||
}
|
||||
|
||||
const DEFAULT_ANGLE = '0'
|
||||
|
||||
const sendObjectPreview = async (req, res, streamId, objectId, angle) => {
|
||||
const getObjectPreviewBufferOrFilepath = getObjectPreviewBufferOrFilepathFactory({
|
||||
getObject,
|
||||
getObjectPreviewInfo: getObjectPreviewInfoFactory({ db }),
|
||||
createObjectPreview: createObjectPreviewFactory({ db }),
|
||||
getPreviewImage: getPreviewImageFactory({ db })
|
||||
})
|
||||
let previewBufferOrFile = await getObjectPreviewBufferOrFilepath({
|
||||
streamId,
|
||||
objectId,
|
||||
angle
|
||||
})
|
||||
|
||||
if (req.query.postprocess === 'og') {
|
||||
const stream = await getStream({ streamId: req.params.streamId })
|
||||
const streamName = stream.name
|
||||
|
||||
if (previewBufferOrFile.type === 'file') {
|
||||
previewBufferOrFile = {
|
||||
type: 'buffer',
|
||||
buffer: await makeOgImage(previewBufferOrFile.file, streamName)
|
||||
}
|
||||
} else {
|
||||
previewBufferOrFile = {
|
||||
type: 'buffer',
|
||||
buffer: await makeOgImage(previewBufferOrFile.buffer, streamName)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (previewBufferOrFile.error) {
|
||||
res.set('X-Preview-Error', 'true')
|
||||
}
|
||||
if (previewBufferOrFile.errorCode) {
|
||||
res.set('X-Preview-Error-Code', previewBufferOrFile.errorCode)
|
||||
}
|
||||
if (previewBufferOrFile.type === 'file') {
|
||||
// we can't cache these cause they may switch to proper buffer previews in a sec
|
||||
// at least if they're not in the error state which they will not get out of (and thus can be cached in that scenario)
|
||||
if (previewBufferOrFile.error) {
|
||||
res.set('Cache-Control', 'private, max-age=604800')
|
||||
} else {
|
||||
res.set('Cache-Control', 'no-cache, no-store')
|
||||
}
|
||||
res.sendFile(previewBufferOrFile.file)
|
||||
} else {
|
||||
res.contentType('image/png')
|
||||
// If the preview is a buffer, it comes from the DB and can be cached on clients
|
||||
res.set('Cache-Control', 'private, max-age=604800')
|
||||
res.send(previewBufferOrFile.buffer)
|
||||
}
|
||||
}
|
||||
const getObjectPreviewBufferOrFilepath = getObjectPreviewBufferOrFilepathFactory({
|
||||
getObject,
|
||||
getObjectPreviewInfo: getObjectPreviewInfoFactory({ db }),
|
||||
createObjectPreview: createObjectPreviewFactory({ db }),
|
||||
getPreviewImage: getPreviewImageFactory({ db })
|
||||
})
|
||||
const sendObjectPreview = sendObjectPreviewFactory({
|
||||
getObject,
|
||||
getObjectPreviewBufferOrFilepath,
|
||||
makeOgImage
|
||||
})
|
||||
|
||||
const checkStreamPermissions = async (req) => {
|
||||
const stream = await getStream({
|
||||
|
@ -151,7 +110,7 @@ exports.init = (app, isInitial) => {
|
|||
res,
|
||||
req.params.streamId,
|
||||
lastCommit.referencedObject,
|
||||
req.params.angle || DEFAULT_ANGLE
|
||||
req.params.angle
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -187,7 +146,7 @@ exports.init = (app, isInitial) => {
|
|||
res,
|
||||
req.params.streamId,
|
||||
lastCommit.referencedObject,
|
||||
req.params.angle || DEFAULT_ANGLE
|
||||
req.params.angle
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -211,7 +170,7 @@ exports.init = (app, isInitial) => {
|
|||
res,
|
||||
req.params.streamId,
|
||||
commit.referencedObject,
|
||||
req.params.angle || DEFAULT_ANGLE
|
||||
req.params.angle
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -227,7 +186,7 @@ exports.init = (app, isInitial) => {
|
|||
res,
|
||||
req.params.streamId,
|
||||
req.params.objectId,
|
||||
req.params.angle || DEFAULT_ANGLE
|
||||
req.params.angle
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
import { logger } from '@/logging/logging'
|
||||
import { getStream } from '@/modules/core/repositories/streams'
|
||||
import { getObject } from '@/modules/core/services/objects'
|
||||
import {
|
||||
CreateObjectPreview,
|
||||
GetObjectPreviewBufferOrFilepath,
|
||||
GetObjectPreviewInfo,
|
||||
GetPreviewImage
|
||||
GetPreviewImage,
|
||||
SendObjectPreview
|
||||
} from '@/modules/previews/domain/operations'
|
||||
import { makeOgImage } from '@/modules/previews/ogImage'
|
||||
|
||||
const noPreviewImage = require.resolve('#/assets/previews/images/no_preview.png')
|
||||
const previewErrorImage = require.resolve('#/assets/previews/images/preview_error.png')
|
||||
const defaultAngle = '0'
|
||||
|
||||
export const getObjectPreviewBufferOrFilepathFactory =
|
||||
(deps: {
|
||||
|
@ -18,6 +22,8 @@ export const getObjectPreviewBufferOrFilepathFactory =
|
|||
getPreviewImage: GetPreviewImage
|
||||
}): GetObjectPreviewBufferOrFilepath =>
|
||||
async ({ streamId, objectId, angle }) => {
|
||||
angle = angle || defaultAngle
|
||||
|
||||
if (process.env.DISABLE_PREVIEWS) {
|
||||
return {
|
||||
type: 'file',
|
||||
|
@ -70,3 +76,55 @@ export const getObjectPreviewBufferOrFilepathFactory =
|
|||
}
|
||||
return { type: 'buffer', buffer: previewImg }
|
||||
}
|
||||
|
||||
export const sendObjectPreviewFactory =
|
||||
(deps: {
|
||||
getObjectPreviewBufferOrFilepath: GetObjectPreviewBufferOrFilepath
|
||||
getStream: typeof getStream
|
||||
makeOgImage: typeof makeOgImage
|
||||
}): SendObjectPreview =>
|
||||
async (req, res, streamId, objectId, angle) => {
|
||||
let previewBufferOrFile = await deps.getObjectPreviewBufferOrFilepath({
|
||||
streamId,
|
||||
objectId,
|
||||
angle
|
||||
})
|
||||
|
||||
if (req.query.postprocess === 'og') {
|
||||
const stream = await deps.getStream({ streamId: req.params.streamId })
|
||||
const streamName = stream!.name
|
||||
|
||||
if (previewBufferOrFile.type === 'file') {
|
||||
previewBufferOrFile = {
|
||||
type: 'buffer',
|
||||
buffer: await deps.makeOgImage(previewBufferOrFile.file, streamName)
|
||||
}
|
||||
} else {
|
||||
previewBufferOrFile = {
|
||||
type: 'buffer',
|
||||
buffer: await deps.makeOgImage(previewBufferOrFile.buffer, streamName)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (previewBufferOrFile.error) {
|
||||
res.set('X-Preview-Error', 'true')
|
||||
}
|
||||
if (previewBufferOrFile.errorCode) {
|
||||
res.set('X-Preview-Error-Code', previewBufferOrFile.errorCode)
|
||||
}
|
||||
if (previewBufferOrFile.type === 'file') {
|
||||
// we can't cache these cause they may switch to proper buffer previews in a sec
|
||||
// at least if they're not in the error state which they will not get out of (and thus can be cached in that scenario)
|
||||
if (previewBufferOrFile.error) {
|
||||
res.set('Cache-Control', 'private, max-age=604800')
|
||||
} else {
|
||||
res.set('Cache-Control', 'no-cache, no-store')
|
||||
}
|
||||
res.sendFile(previewBufferOrFile.file)
|
||||
} else {
|
||||
res.contentType('image/png')
|
||||
// If the preview is a buffer, it comes from the DB and can be cached on clients
|
||||
res.set('Cache-Control', 'private, max-age=604800')
|
||||
res.send(previewBufferOrFile.buffer)
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче