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.pageId !== req.form.page.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.pageId !== req.form.page.UUID ) { return res.status(400) .message('Invalid parentUUID') .api() } } const box = new FileBox({ name: req.body.name, pageId: req.form.page.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 } = 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, }) 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() return res.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