Files
behavior3editor/fs-tree-view/server/server.js
T
2020-11-19 18:18:45 +08:00

158 lines
4.5 KiB
JavaScript

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const fs = require("fs");
const fsx = require("fs-extra");
const path = require("path");
const rimraf = require("rimraf");
const glob = require("glob");
const sanitize = require("sanitize-filename");
function decodeUrlParam(s) {
return decodeURIComponent(s);
}
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Tree
app.get("/", (req, res) => {
const dirPath = decodeUrlParam(req.query.path) || "";
fs.readdir(dirPath, (err, files) => {
if (!files) {
console.log("No Files", dirPath);
return res.json({});
}
let finalList = {};
files.forEach((file) => {
try {
const fullPath = path.join(dirPath, file);
const isDirectory = fs.lstatSync(fullPath).isDirectory();
let fileProperties = {
[fullPath]: {
name: file,
path: fullPath,
size: fs.statSync(fullPath).size,
extension: path.extname(file),
type: isDirectory ? "directory" : "file",
isOpen: false,
},
};
if (isDirectory) {
delete fileProperties[fullPath].extension;
fileProperties[fullPath].children = {};
// Directories should appear on top
finalList = { ...fileProperties, ...finalList };
} else {
// Files should appear at the end
finalList = { ...finalList, ...fileProperties };
}
} catch (error) {
console.log("Error:", error);
return res.json({});
}
});
return res.json(finalList);
});
});
// Search
app.get("/search", (req, res) => {
const dirPath = decodeUrlParam(req.query.path) || "";
let query = decodeUrlParam(req.query.query) || "";
query = sanitize(query);
const maxResults = 20;
glob(`${dirPath}/**/*.*`, {}, function (er, files) {
const final = [];
let counter = 0;
for (const file of files) {
// Dont show more than maxResults
if (counter >= maxResults) {
break;
}
let pattern;
try {
pattern = new RegExp(query, "gi");
} catch (error) {
query = query.replace(/[|&;$%@"<>()+,*]/g, "");
pattern = new RegExp(query, "gi");
}
if (pattern.test(path.basename(file))) {
final.push({
name: path.basename(file),
path: file,
type: "file",
extension: path.extname(file),
});
counter++;
}
}
return res.json(final);
});
});
// For Drag and Drop
app.post("/dragdrop", (req, res) => {
const { source, destination, overwrite } = req.body;
const filename = path.basename(source);
const destinationPath = `${destination}${path.sep}${filename}`;
fsx.move(source, destinationPath, { overwrite }, (error) => {
if (error) {
return res.status(400).send("NOT_OK");
}
return res.status(201).send("OK");
});
});
// Rename a file/folder
app.put("/rename", (req, res) => {
const oldPath = decodeUrlParam(req.body.oldPath);
const newFileName = decodeUrlParam(req.body.newFileName);
const newFilePath = `${path.dirname(oldPath)}${path.sep}${sanitize(newFileName)}`;
if (oldPath == newFilePath) {
return res.json({
newFilePath,
});
} else {
fsx.move(oldPath, newFilePath, { overwrite: false }, (error) => {
if (error) {
console.log("Error", error);
return res.status(400).send("NOT_OK");
}
return res.json({
newFilePath,
});
});
}
});
// Delete file/folder
app.delete("/", (req, res) => {
rimraf(decodeUrlParam(req.query.fullPath), (error) => {
if (error) {
return res.status(400).send(error);
} else {
return res.status(200).send("OK");
}
});
});
app.listen(5000, () => {
console.log("Server running on port 5000");
});