Simple way to build clouds from nothing
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

201 lines
5.0 KiB

const express = require('express')
const router = express.Router()
const async = require('async')
const path = require('path')
const multer = require('multer')
const fs = require('fs-extra')
const upload = multer({ dest: 'uploads' })
const sharp = require('sharp')
const TOL = require('../../tools/common')
const CFG = require('../../config')
var CTX = null
module.exports = function (pCtx) {
CTX = pCtx
router.post('/upload', upload.single('media'), handleUploadedMedia)
router.get('/get/:id', function (req, res) {
let mediaId = req.params.id
CTX.restapi.media.__services.readOne(mediaId, {projection: {path: 1}}, function (pErr, pResult) {
if (pErr) {
return res.status(404).send('Media:Media:NotFound')
}
let mediaPath = path.join(CFG.media.documents, pResult.data.path)
fs.access(mediaPath, fs.constants.F_OK, function (pErr) {
if (pErr) {
return res.status(404).send('Media:File:NotFound')
}
res.sendFile(mediaPath)
})
})
})
router.get('/preview/:id', function (req, res) {
let mediaId = req.params.id
CTX.restapi.media.__services.readOne(mediaId, {projection: {mimetype: 1, path: 1}}, function (pErr, pResult) {
if (pErr) {
return res.sendFile(CFG.media['404'])
}
let media = pResult.data
let mimetypes = media.mimetype.split('/')
let type = mimetypes[0]
let subtype = mimetypes[1]
switch (type) {
case 'image':
let mediaPath = path.join(CFG.media.documents, media.path)
getPreviewFromImage(res, mediaPath, req.query)
break
default:
res.sendFile(CFG.media['404'])
}
})
})
return router
}
function getPreviewFromImage (res, pPath, pQuery, pMedia) {
let query = pQuery
query.width = parseInt(query.width) || null
query.height = parseInt(query.height) || null
query.fit = query.fit || 'cover'
if (!query.width && !query.height) {
query.width = 1024
}
let outName = TOL.createHash(JSON.stringify(query), 'sha1')
let outPath = path.join(CFG.media.cache, generatePathFromMediaId(outName))
let outFull = path.join(outPath, `${outName}.jpg`)
let tasks = []
tasks.push(function (pCb) {
fs.ensureDir(outPath, pErr => pCb(pErr))
})
tasks.push(function (pCb) {
sharp(pPath)
.resize(query.width, query.height, {fit: query.fit})
.toFile(outFull, function (pErr) {
pCb(pErr)
})
})
async.waterfall(tasks, function (pErr) {
if (pErr) {
console.log(pErr)
res.sendFile(CFG.media['404'])
} else {
res.sendFile(outFull)
}
})
}
function handleUploadedMedia (req, res) {
let tasks = []
let file = req.file
let fileKey = {
coll: '__default',
id: '',
path: ''
}
let ext = getExtensionFromMimetype(file.mimetype)
let currentDate = new Date()
if (req.body.docColl && req.body.docId && req.body.docPath) {
fileKey = {
coll: req.body.docColl,
id: req.body.docId,
path: req.body.docPath
}
}
let mediaId = TOL.createHash(JSON.stringify(fileKey.coll === '__default' ? file : fileKey), 'sha1')
let outPath = path.join(CFG.media.documents, generatePathFromMediaId(mediaId))
let outName = `media.${ext}`
let outFull = path.join(outPath, outName)
let isAlreadyExisting = false
file.createdAt = currentDate
file.fileKey = fileKey
tasks.push(function (pCb) {
fs.ensureDir(outPath, pErr => pCb(pErr))
})
tasks.push(function (pCb) {
fs.move(file.path, outFull, { overwrite: true }, pErr => pCb(pErr))
})
tasks.push(function (pCb) {
fs.writeFile(path.join(outPath, 'info'), JSON.stringify(file, null, 2), 'utf8', pErr => pCb(pErr))
})
tasks.push(function (pCb) {
CTX.restapi.media.__services.readOne(mediaId, {projection: {_id: 1}}, function (pErr, pResult) {
if (pResult && pResult.ok) {
isAlreadyExisting = true
}
pCb()
})
})
tasks.push(function (pCb) {
let doc = {
_id: mediaId,
name: outName,
originalName: file.originalname,
extension: ext,
path: path.join(generatePathFromMediaId(mediaId), outName),
fileKey: fileKey,
mimetype: file.mimetype,
size: file.size
}
if (isAlreadyExisting) {
CTX.restapi.media.__services.update(mediaId, doc, req.user, 'media', function (pErr, pResult) {
pCb(pErr)
})
} else {
CTX.restapi.media.__services.create(doc, req.user, function (pErr, pResult) {
pCb(pErr)
})
}
})
async.waterfall(tasks, function (pErr) {
res.done(pErr, {
ok: pErr ? 0 : 1,
mediaId: mediaId
})
})
}
function generatePathFromMediaId (pMediaId) {
let outSubf = pMediaId.slice(0, 4)
return path.join(outSubf, pMediaId)
}
function getExtensionFromMimetype (pMimetype) {
let ext = 'unknown'
let mimetypes = pMimetype.split('/')
let type = mimetypes[0]
let subtype = mimetypes[1]
switch (type) {
case 'audio':
case 'video':
case 'image':
ext = subtype
break
case 'application/pdf':
ext = 'pdf'
break
default:
}
return ext
}