backend/app/controllers/api/v1/FileBox.controller.js
garrettmills f58fcd85b1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
Noded/frontend#75 - support searching file boxes and files from universal search
2021-02-04 20:41:03 -06:00

249 lines
6.7 KiB
JavaScript

const { Controller } = require('libflitter')
class FileBoxController extends Controller {
static get services() {
return [...super.services, 'models']
}
async create(req, res, next) {
const FileBox = this.models.get('api:files:FileBox')
if ( !req.body.name ) {
return res.message('Missing required field: name')
.status(400)
.api()
}
if ( req.body.rootUUID ) {
const root = await FileBox.findOne({
active: true,
UUID: req.body.rootUUID,
})
if ( !root || root.nodeId !== req.form.node.UUID ) {
return res.status(400)
.message('Invalid rootUUID.')
.api()
}
}
if ( req.body.parentUUID ) {
if ( !req.body.rootUUID ) {
return res.status(400)
.message('File boxes with a parent MUST also have a root.')
.api()
}
const parent = await FileBox.findOne({
active: true,
UUID: req.body.parentUUID,
})
if ( !parent || parent.nodeId !== req.form.node.UUID ) {
return res.status(400)
.message('Invalid parentUUID')
.api()
}
}
const box = new FileBox({
name: req.body.name,
pageId: req.form.page.UUID,
nodeId: req.form.node.UUID,
})
if ( req.body.rootUUID ) {
box.rootUUID = req.body.rootUUID
}
if ( req.body.parentUUID ) {
box.parentUUID = req.body.parentUUID
}
await box.save()
if ( !req.body.rootUUID && !box.rootUUID ) {
box.rootUUID = box.UUID
await box.save()
}
return res.api(await box.to_api())
}
async update(req, res, next) {
const FileBox = this.models.get('api:files:FileBox')
const { file_box, page, node } = req.form
if ( req.body.name ) {
file_box.name = req.body.name
}
if ( req.body.parentUUID && req.body.parentUUID !== file_box.parentUUID ) {
const new_parent = await FileBox.findOne({
UUID: req.body.parentUUID,
active: true,
rootUUID: file_box.rootUUID,
pageId: page.UUID,
nodeId: node.UUID,
})
if ( !new_parent || new_parent.UUID === file_box.UUID ) {
return res.status(400)
.message('Invalid parentUUID.')
.api()
}
file_box.parentUUID = new_parent.UUID
}
await file_box.save()
return res.api(await file_box.to_api())
}
async update_file(req, res, next) {
const FileBox = this.models.get('api:files:FileBox')
const { file_box, file } = req.form
if ( req.body.name ) {
file.original_name = req.body.name
}
if ( req.body.parentUUID && req.body.parentUUID !== file_box.UUID ) {
const new_parent = await FileBox.findOne({
active: true,
UUID: req.body.parentUUID,
rootUUID: file_box.rootUUID,
})
if ( !new_parent ) {
return res.status(400)
.message('Invalid parentUUID.')
.api()
}
file_box.fileIds = file_box.fileIds.filter(x => `${x}` !== `${file.id}`)
new_parent.fileIds.push(file.id)
await new_parent.save()
await file_box.save()
}
await file.save()
return res.api(this.file_to_api(file))
}
async download_file(req, res, next) {
const { file_box, file } = req.form
return file.send(res)
}
async upload_files(req, res, next) {
const { file_box } = req.form
// const n_files = Object.values(req.uploads).length
for ( const key in req.uploads ) {
if ( !req.uploads.hasOwnProperty(key) ) continue
if ( !key.startsWith('uploaded_file_') ) continue
file_box.fileIds.push(req.uploads[key].id)
}
await file_box.save()
return res.api()
}
async get_box(req, res, next) {
return res.api(await req.form.file_box.to_api())
}
async get_children(req, res, next) {
const { file_box } = req.form
const children = await file_box.children()
return res.api(await Promise.all(children.map(x => x.to_api())));
}
async get_files(req, res, next) {
const { file_box, page } = req.form
const files = await file_box.files()
return res.api(files.map(x => this.file_to_api(x)))
}
async delete_box(req, res, next) {
const { file_box } = req.form
file_box.active = false;
await file_box.save()
return res.api()
}
async delete_file(req, res, next) {
const { file_box, file } = req.form
file_box.fileIds = file_box.fileIds.filter(x => `${x}` !== `${file.id}`)
await file_box.save()
await file.delete()
return res.api()
}
async get_box_history_path(req, res, next) {
const { file_box } = req.form
const history = []
let current = file_box
while ( current.parentUUID ) {
current = await current.parent()
history.push(current)
}
return res.api(await Promise.all(history.reverse().map(x => x.to_api())))
}
file_to_api(file) {
return {
type: 'file',
title: file.original_name,
mime: file.mime_type,
uploaded: file.upload_date,
category: this.get_file_category(file.mime_type),
id: file.id,
_id: file._id,
}
}
get_file_category(mime) {
if ( mime.includes('opendocument.text') || mime.includes('.document') ) {
return 'document';
}
if ( mime.includes('.spreadsheet') || mime.includes('.sheet') ) {
return 'spreadsheet';
}
if ( mime.includes('.presentation') ) {
return 'presentation';
}
if ( mime.includes('image/') ) {
return 'image';
}
if ( mime === 'application/pdf' ) {
return 'pdf';
}
if ( mime.includes('video/') ) {
return 'video';
}
if ( mime.includes('script') ) {
return 'code';
}
if ( mime.includes('text/') ) {
return 'text';
}
return 'other';
}
}
module.exports = exports = FileBoxController