#189 i have literally been putting this off for months but i finally figured out now to resolve file paths \ 😄 /

This commit is contained in:
Cassie Tarakajian 2016-11-08 16:50:21 -05:00
parent 081c7d521e
commit 2750b1f0ef
4 changed files with 63 additions and 22 deletions

View File

@ -1,8 +1,9 @@
import Project from '../models/project';
import escapeStringRegexp from 'escape-string-regexp';
const startTag = '@fs-';
import { resolvePathToFile } from '../utils/filePath';
function injectMediaUrls(filesToInject, mediaFiles, textFiles, projectId) {
function injectMediaUrls(filesToInject, allFiles, projectId) {
filesToInject.forEach(file => {
let fileStrings = file.content.match(/(['"])((\\\1|.)*?)\1/gm);
const fileStringRegex = /^('|")(?!(http:\/\/|https:\/\/)).*('|")$/i;
@ -11,19 +12,20 @@ function injectMediaUrls(filesToInject, mediaFiles, textFiles, projectId) {
//if string does not begin with http or https
if (fileString.match(fileStringRegex)) {
const filePath = fileString.substr(1, fileString.length - 2);
const filePathArray = filePath.split('/');
const fileName = filePathArray[filePathArray.length - 1];
mediaFiles.forEach(mediaFile => {
if (mediaFile.name === fileName) {
file.content = file.content.replace(filePath, mediaFile.url);
}
});
if (textFiles) {
textFiles.forEach(textFile => {
if (textFile.name === fileName) {
file.content = file.content.replace(filePath, `/api/projects/${projectId}/${textFile.name}`);
const resolvedFile = resolvePathToFile(filePath, allFiles);
if (resolvedFile) {
if (resolvedFile.url) {
file.content = file.content.replace(filePath,resolvedFile.url);
} else if (resolvedFile.name.match(/(.+\.json$|.+\.txt$|.+\.csv$)/i)) {
let resolvedFilePath = filePath;
if (resolvedFilePath.startsWith('.')) {
resolvedFilePath = resolvedFilePath.substr(1);
}
});
while (resolvedFilePath.startsWith('/')) {
resolvedFilePath = resolvedFilePath.substr(1);
}
file.content = file.content.replace(filePath, `/api/projects/${projectId}/${resolvedFilePath}`);
}
}
}
});
@ -33,15 +35,14 @@ function injectMediaUrls(filesToInject, mediaFiles, textFiles, projectId) {
export function serveProject(req, res) {
Project.findById(req.params.project_id)
.exec((err, project) => {
//TODO this does not parse html
const files = project.files;
let htmlFile = files.find(file => file.name.match(/\.html$/i)).content;
const jsFiles = files.filter(file => file.name.match(/\.js$/i));
const cssFiles = files.filter(file => file.name.match(/\.css$/i));
const mediaFiles = files.filter(file => file.url);
const textFiles = files.filter(file => file.name.match(/(.+\.json$|.+\.txt$|.+\.csv$)/i) && file.url === undefined);
injectMediaUrls(jsFiles, mediaFiles, textFiles, req.params.project_id);
injectMediaUrls(cssFiles, mediaFiles);
injectMediaUrls(jsFiles, files, req.params.project_id);
injectMediaUrls(cssFiles, files, req.params.project_id);
jsFiles.forEach(jsFile => {
const fileName = escapeStringRegexp(jsFile.name);

View File

@ -1,4 +1,5 @@
import Project from '../models/project';
import { resolvePathToFile } from '../utils/filePath';
// Bug -> timestamps don't get created, but it seems like this will
// be fixed in mongoose soon
@ -71,10 +72,11 @@ export function getFileContent(req, res) {
if (err) {
return res.status(404).send({success: false, message: 'Project with that id does not exist.'});
}
const file = project.files.find(file => file.name === req.params.file_name);
if (!file) {
return res.status(404).send({success: false, message: 'File with that name does not exist.'});
const filePath = req.params[0];
const resolvedFile = resolvePathToFile(filePath, project.files);
if (!resolvedFile) {
return res.status(404).send({success: false, message: 'File with that name and path does not exist.'});
}
res.send(file.content);
res.send(resolvedFile.content);
});
}

View File

@ -5,6 +5,6 @@ const router = new Router();
router.route('/projects/:project_id/files').post(FileController.createFile);
router.route('/projects/:project_id/files/:file_id').delete(FileController.deleteFile);
router.route('/projects/:project_id/:file_name').get(FileController.getFileContent);
router.route('/projects/:project_id/*?').get(FileController.getFileContent);
export default router;

38
server/utils/filePath.js Normal file
View File

@ -0,0 +1,38 @@
export function resolvePathToFile(filePath, files) {
const filePathArray = filePath.split('/');
let resolvedFile;
let currentFile;
filePathArray.some((filePathSegment, index) => {
if (filePathSegment === "" || filePathSegment === ".") {
return false;
} else if (filePathSegment === "..") {
return true;
} else {
if (!currentFile) {
const file = files.find(file => file.name === filePathSegment);
if (!file) {
return true;
}
currentFile = file;
if (index === filePathArray.length - 1) {
resolvedFile = file;
}
} else {
const childFiles = currentFile.children.map(childFileId => {
return files.find(file => {
return file._id.valueOf().toString() === childFileId.valueOf();
});
});
childFiles.some(childFile => {
if (childFile.name === filePathSegment) {
currentFile = childFile;
if (index === filePathArray.length - 1) {
resolvedFile = childFile;
}
}
});
}
}
});
return resolvedFile;
}