feat: improve flow of storing files to db

API respond now have new prop "repeated" to signify that the files were
already previously uploaded
This commit is contained in:
Bobby 2022-09-28 10:16:00 +07:00
parent 81c94a40d5
commit b3a2c93642
No known key found for this signature in database
GPG Key ID: 941839794CBF5A09

View File

@ -550,8 +550,8 @@ self.actuallyUpload = async (req, res, data = {}) => {
await self.stripTags(req, filesData) await self.stripTags(req, filesData)
const result = await self.storeFilesToDb(req, res, filesData) const stored = await self.storeFilesToDb(req, res, filesData)
return self.sendUploadResponse(req, res, result) return self.sendUploadResponse(req, res, stored)
} }
/** URL uploads */ /** URL uploads */
@ -767,8 +767,8 @@ self.actuallyUploadUrls = async (req, res, data = {}) => {
} }
} }
const result = await self.storeFilesToDb(req, res, filesData) const stored = await self.storeFilesToDb(req, res, filesData)
return self.sendUploadResponse(req, res, result) return self.sendUploadResponse(req, res, stored)
} }
/** Chunk uploads */ /** Chunk uploads */
@ -897,8 +897,8 @@ self.actuallyFinishChunks = async (req, res, files) => {
await self.stripTags(req, filesData) await self.stripTags(req, filesData)
const result = await self.storeFilesToDb(req, res, filesData) const stored = await self.storeFilesToDb(req, res, filesData)
return self.sendUploadResponse(req, res, result) return self.sendUploadResponse(req, res, stored)
} }
self.cleanUpChunks = async uuid => { self.cleanUpChunks = async uuid => {
@ -1028,8 +1028,7 @@ self.stripTags = async (req, filesData) => {
/** Database functions */ /** Database functions */
self.storeFilesToDb = async (req, res, filesData) => { self.storeFilesToDb = async (req, res, filesData) => {
const files = [] const stored = []
const exists = []
const albumids = [] const albumids = []
await Promise.all(filesData.map(async file => { await Promise.all(filesData.map(async file => {
@ -1062,7 +1061,10 @@ self.storeFilesToDb = async (req, res, filesData) => {
dbFile.original = file.originalname dbFile.original = file.originalname
} }
exists.push(dbFile) stored.push({
file: dbFile,
repeated: true
})
return return
} }
} }
@ -1091,7 +1093,7 @@ self.storeFilesToDb = async (req, res, filesData) => {
data.expirydate = data.timestamp + (file.age * 3600) // Hours to seconds data.expirydate = data.timestamp + (file.age * 3600) // Hours to seconds
} }
files.push(data) stored.push({ file: data })
// Generate thumbs, but do not wait // Generate thumbs, but do not wait
if (utils.mayGenerateThumb(file.extname)) { if (utils.mayGenerateThumb(file.extname)) {
@ -1099,7 +1101,8 @@ self.storeFilesToDb = async (req, res, filesData) => {
} }
})) }))
if (files.length) { const fresh = stored.filter(entry => !entry.repeated)
if (fresh.length) {
// albumids should be empty if non-registerd users (no auth requests) // albumids should be empty if non-registerd users (no auth requests)
let authorizedIds = [] let authorizedIds = []
if (albumids.length) { if (albumids.length) {
@ -1110,9 +1113,9 @@ self.storeFilesToDb = async (req, res, filesData) => {
.then(rows => rows.map(row => row.id)) .then(rows => rows.map(row => row.id))
// Remove albumid if user do not own the album // Remove albumid if user do not own the album
for (const file of files) { for (const entry of fresh) {
if (file.albumid !== null && !authorizedIds.includes(file.albumid)) { if (entry.file.albumid !== null && !authorizedIds.includes(entry.file.albumid)) {
file.albumid = null entry.file.albumid = null
} }
} }
} }
@ -1120,7 +1123,7 @@ self.storeFilesToDb = async (req, res, filesData) => {
await utils.db.transaction(async trx => { await utils.db.transaction(async trx => {
// Insert new files to DB // Insert new files to DB
await trx('files') await trx('files')
.insert(files) .insert(fresh.map(entry => entry.file))
utils.invalidateStatsCache('uploads') utils.invalidateStatsCache('uploads')
// Update albums' timestamp // Update albums' timestamp
@ -1133,35 +1136,39 @@ self.storeFilesToDb = async (req, res, filesData) => {
}) })
} }
return [...files, ...exists] return stored
} }
/** Final response */ /** Final response */
self.sendUploadResponse = async (req, res, result) => { self.sendUploadResponse = async (req, res, stored) => {
// Send response // Send response
return res.json({ return res.json({
success: true, success: true,
files: result.map(file => { files: stored.map(entry => {
const map = { const map = {
name: file.name, name: entry.file.name,
url: `${utils.conf.domain ? `${utils.conf.domain}/` : ''}${file.name}` url: `${utils.conf.domain ? `${utils.conf.domain}/` : ''}${entry.file.name}`
} }
// If a temporary upload, add expiry date // If a temporary upload, add expiry date
if (file.expirydate) { if (entry.file.expirydate) {
map.expirydate = file.expirydate map.expirydate = entry.file.expirydate
} }
// If on /nojs route, add original name // If on /nojs route, add original name
if (req.path === '/nojs') { if (req.path === '/nojs') {
map.original = file.original map.original = entry.file.original
} }
// If uploaded by user, add delete URL (intended for ShareX and its derivatives) // If uploaded by user, add delete URL (intended for ShareX and its derivatives)
// Homepage uploader will not use this (use dashboard instead) // Homepage uploader will not use this (use dashboard instead)
if (req.locals.user) { if (req.locals.user) {
map.deleteUrl = `${utils.conf.homeDomain || ''}/file/${file.name}?delete` map.deleteUrl = `${utils.conf.homeDomain || ''}/file/${entry.file.name}?delete`
}
if (entry.repeated) {
map.repeated = true
} }
return map return map