diff --git a/controllers/object.js b/controllers/object.js index ff82b9f3a..872080908 100644 --- a/controllers/object.js +++ b/controllers/object.js @@ -2,7 +2,7 @@ const fsProm = require('../persistence/fsProm.js'); const path = require('path'); const formidable = require('formidable'); const utilities = require('../libraries/utilities'); -const {fileExists, unlinkIfExists, mkdirIfNotExists} = utilities; +const {fileExists, listSplatFiles, splatFileExists, unlinkIfExists, mkdirIfNotExists} = utilities; const {startSplatTask, splatTasks} = require('./object/SplatTask.js'); const { beatPort } = require('../config.js'); @@ -447,6 +447,28 @@ const checkFileExists = async (objectId, filePath) => { return await fileExists(absoluteFilePath); }; +const checkSplatFileExists = async (objectId, filePath) => { + let object = utilities.getObject(objects, objectId); + if (!object) { + return false; + } + + let objectIdentityDir = path.join(objectsPath, object.name, identityFolderName); + let absoluteFilePath = path.join(objectIdentityDir, filePath); + return await splatFileExists(absoluteFilePath); +} + +const callListSplatFiles = async (objectId, filePath) => { + let object = utilities.getObject(objects, objectId); + if (!object) { + return []; + } + + let objectIdentityDir = path.join(objectsPath, object.name, identityFolderName); + let absoluteFilePath = path.join(objectIdentityDir, filePath); + return await listSplatFiles(absoluteFilePath); +} + /** * Check the status of all the possible target files that an object might have * @param {string} objectId @@ -462,7 +484,7 @@ const checkTargetFiles = async (objectId) => { checkFileExists(objectId, '/target/target.dat'), checkFileExists(objectId, '/target/target.jpg'), checkFileExists(objectId, '/target/target.3dt'), - checkFileExists(objectId, '/target/target.splat'), + checkSplatFileExists(objectId, '/target/target_splats'), ]); return { glbExists, @@ -592,7 +614,7 @@ const uploadTarget = async (objectName, req, res) => { let xmlPath = path.join(targetDir, 'target.xml'); let glbPath = path.join(targetDir, 'target.glb'); let tdtPath = path.join(targetDir, 'target.3dt'); - let splatPath = path.join(targetDir, 'target.splat'); + let splatPath = path.join(targetDir, 'target/target_splats'); let fileList = [jpgPath, xmlPath, datPath, glbPath, tdtPath, splatPath]; let sendObject = { @@ -604,7 +626,7 @@ const uploadTarget = async (objectName, req, res) => { datExists: await fileExists(datPath), glbExists: await fileExists(glbPath), tdtExists: await fileExists(tdtPath), - splatExists: await fileExists(splatPath) + splatExists: await splatFileExists(splatPath) }; object.tcs = utilities.generateChecksums(objects, fileList); @@ -678,6 +700,7 @@ module.exports = { setFrameSharingEnabled: setFrameSharingEnabled, checkFileExists: checkFileExists, checkTargetFiles: checkTargetFiles, + callListSplatFiles: callListSplatFiles, uploadTarget: uploadTarget, getObject: getObject, setup: setup, diff --git a/libraries/utilities.js b/libraries/utilities.js index 94d5082c6..5acc1838e 100644 --- a/libraries/utilities.js +++ b/libraries/utilities.js @@ -1167,6 +1167,36 @@ function fileExists(filePath) { } exports.fileExists = fileExists; +function listSplatFiles(splatFolderPath) { + let splatFiles = []; + return fsProm.access(splatFolderPath) + .then(() => { + return fsProm.readdir(splatFolderPath); + }) + .then((files) => { + let regex = /^target.*\.splat$/; + files.forEach((splatName) => { + if (regex.test(splatName)) splatFiles.push(path.join('target', 'target_splats', splatName)); + }); + return splatFiles; + }) + .catch((err) => { + console.error('Error accessing or reading the folder:', err); + return []; + }); +} + +exports.listSplatFiles = listSplatFiles; + +function splatFileExists(folderPath) { + return listSplatFiles(folderPath).then((splatFiles) => { + return splatFiles.length > 0; + }).catch(() => { + return false; + }) +} +exports.splatFileExists = splatFileExists; + /** * All-in-one mkdir solution. Wraps error because TOCTOU * @param {string} dirPath - path to folder diff --git a/routers/object.js b/routers/object.js index 88b457cfd..d35a7caff 100644 --- a/routers/object.js +++ b/routers/object.js @@ -454,6 +454,18 @@ router.get('/:objectName/checkTargetFiles/', (req, res) => { }); }); +router.get('/:objectName/listSplatFiles/', (req, res) => { + if (!utilities.isValidId(req.params.objectName)) { + res.status(400).send('Invalid object name. Must be alphanumeric.'); + return; + } + objectController.callListSplatFiles(req.params.objectName, 'target/target_splats').then(splatFiles => { + res.json(splatFiles); + }).catch(e => { + res.status(404).json({ error: e, exists: false }); + }) +}) + router.post('/:objectName/requestGaussianSplatting/', async function (req, res) { if (!utilities.isValidId(req.params.objectName)) { res.status(400).send('Invalid object name. Must be alphanumeric.'); diff --git a/server.js b/server.js index 69f1443fe..6b0bb777b 100644 --- a/server.js +++ b/server.js @@ -382,7 +382,7 @@ if (!isLightweightMobile) { // This file hosts all kinds of utilities programmed for the server const utilities = require('./libraries/utilities'); -const {fileExists, mkdirIfNotExists, rmdirIfExists, unlinkIfExists} = utilities; +const {fileExists, splatFileExists, mkdirIfNotExists, rmdirIfExists, unlinkIfExists} = utilities; const nodeUtilities = require('./libraries/nodeUtilities'); const recorder = require('./libraries/recorder'); @@ -1220,7 +1220,7 @@ async function objectBeatSender(PORT, thisId, thisIp, oneTimeOnly = false, immed let xmlPath = path.join(targetDir, 'target.xml'); let glbPath = path.join(targetDir, 'target.glb'); let tdtPath = path.join(targetDir, 'target.3dt'); - let splatPath = path.join(targetDir, 'target.splat'); + let splatPath = path.join(targetDir, 'target_splats'); var fileList = [jpgPath, xmlPath, datPath, glbPath, tdtPath, splatPath]; const tcs = await utilities.generateChecksums(objects, fileList); if (objects[thisId]) { @@ -1693,12 +1693,18 @@ function objectWebServer() { 'target.glb', 'target.unitypackage', 'target.3dt', - 'target.splat', ]; + let targetSplatFiles = 'target_splats'; if (targetFiles.includes(filename) && urlArray[urlArray.length - 2] === 'target') { urlArray[urlArray.length - 2] = identityFolderName + '/target'; switchToInteraceTool = false; + } else if (urlArray[urlArray.length - 2] === targetSplatFiles) { // for target_splats folder, eg: [ '_WORLD_SAGA', 'target', 'target_splats', 'target_1.splat' ] + let regex = /^target.*\.splat$/; + if (regex.test(filename)) { + urlArray[urlArray.length - 3] = identityFolderName + '/target'; + switchToInteraceTool = false; + } } if ((filename === 'memory.jpg' || filename === 'memoryThumbnail.jpg') @@ -2939,7 +2945,7 @@ function objectWebServer() { let xmlPath = path.join(folderD, identityFolderName, '/target/target.xml'); let glbPath = path.join(folderD, identityFolderName, '/target/target.glb'); let tdtPath = path.join(folderD, identityFolderName, '/target/target.3dt'); - let splatPath = path.join(folderD, identityFolderName, '/target/target.splat'); + let splatPath = path.join(folderD, identityFolderName, '/target/target_splats'); var fileList = [jpgPath, xmlPath, datPath, glbPath, tdtPath, splatPath]; @@ -2950,7 +2956,7 @@ function objectWebServer() { var xml = await fileExists(xmlPath); var glb = await fileExists(glbPath); var tdt = await fileExists(tdtPath); - var splat = await fileExists(splatPath); + var splat = await splatFileExists(splatPath); var sendObject = { id: thisObjectId,