Use Express router for sprites endpoint

This commit is contained in:
valadaptive 2023-12-04 12:57:13 -05:00
parent 414c9bd5fb
commit 173bc5975f
2 changed files with 136 additions and 140 deletions

View File

@ -3600,7 +3600,7 @@ require('./src/endpoints/extensions').registerEndpoints(app, jsonParser);
require('./src/endpoints/assets').registerEndpoints(app, jsonParser); require('./src/endpoints/assets').registerEndpoints(app, jsonParser);
// Character sprite management // Character sprite management
require('./src/endpoints/sprites').registerEndpoints(app, jsonParser, urlencodedParser); app.use('/api/sprites', require('./src/endpoints/sprites').router);
// Custom content management // Custom content management
require('./src/endpoints/content-manager').registerEndpoints(app, jsonParser); require('./src/endpoints/content-manager').registerEndpoints(app, jsonParser);

View File

@ -1,11 +1,13 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const express = require('express');
const mime = require('mime-types'); const mime = require('mime-types');
const sanitize = require('sanitize-filename'); const sanitize = require('sanitize-filename');
const writeFileAtomicSync = require('write-file-atomic').sync; const writeFileAtomicSync = require('write-file-atomic').sync;
const { DIRECTORIES, UPLOADS_PATH } = require('../constants'); const { DIRECTORIES, UPLOADS_PATH } = require('../constants');
const { getImageBuffers } = require('../util'); const { getImageBuffers } = require('../util');
const { jsonParser, urlencodedParser } = require('../express-common');
/** /**
* Gets the path to the sprites folder for the provided character name * Gets the path to the sprites folder for the provided character name
@ -101,167 +103,161 @@ function importRisuSprites(data) {
} }
} }
/** const router = express.Router();
* Registers the endpoints for the sprite management.
* @param {import('express').Express} app Express app
* @param {any} jsonParser JSON parser middleware
* @param {any} urlencodedParser URL encoded parser middleware
*/
function registerEndpoints(app, jsonParser, urlencodedParser) {
app.get('/api/sprites/get', jsonParser, function (request, response) {
const name = String(request.query.name);
const isSubfolder = name.includes('/');
const spritesPath = getSpritesPath(name, isSubfolder);
let sprites = [];
try { router.get('/get', jsonParser, function (request, response) {
if (spritesPath && fs.existsSync(spritesPath) && fs.statSync(spritesPath).isDirectory()) { const name = String(request.query.name);
sprites = fs.readdirSync(spritesPath) const isSubfolder = name.includes('/');
.filter(file => { const spritesPath = getSpritesPath(name, isSubfolder);
const mimeType = mime.lookup(file); let sprites = [];
return mimeType && mimeType.startsWith('image/');
}) try {
.map((file) => { if (spritesPath && fs.existsSync(spritesPath) && fs.statSync(spritesPath).isDirectory()) {
const pathToSprite = path.join(spritesPath, file); sprites = fs.readdirSync(spritesPath)
return { .filter(file => {
label: path.parse(pathToSprite).name.toLowerCase(), const mimeType = mime.lookup(file);
path: `/characters/${name}/${file}`, return mimeType && mimeType.startsWith('image/');
}; })
}); .map((file) => {
const pathToSprite = path.join(spritesPath, file);
return {
label: path.parse(pathToSprite).name.toLowerCase(),
path: `/characters/${name}/${file}`,
};
});
}
}
catch (err) {
console.log(err);
}
return response.send(sprites);
});
router.post('/delete', jsonParser, async (request, response) => {
const label = request.body.label;
const name = request.body.name;
if (!label || !name) {
return response.sendStatus(400);
}
try {
const spritesPath = path.join(DIRECTORIES.characters, name);
// No sprites folder exists, or not a directory
if (!fs.existsSync(spritesPath) || !fs.statSync(spritesPath).isDirectory()) {
return response.sendStatus(404);
}
const files = fs.readdirSync(spritesPath);
// Remove existing sprite with the same label
for (const file of files) {
if (path.parse(file).name === label) {
fs.rmSync(path.join(spritesPath, file));
} }
} }
catch (err) {
console.log(err);
}
return response.send(sprites);
});
app.post('/api/sprites/delete', jsonParser, async (request, response) => { return response.sendStatus(200);
const label = request.body.label; } catch (error) {
const name = request.body.name; console.error(error);
return response.sendStatus(500);
}
});
if (!label || !name) { router.post('/upload-zip', urlencodedParser, async (request, response) => {
return response.sendStatus(400); const file = request.file;
const name = request.body.name;
if (!file || !name) {
return response.sendStatus(400);
}
try {
const spritesPath = path.join(DIRECTORIES.characters, name);
// Create sprites folder if it doesn't exist
if (!fs.existsSync(spritesPath)) {
fs.mkdirSync(spritesPath);
} }
try { // Path to sprites is not a directory. This should never happen.
const spritesPath = path.join(DIRECTORIES.characters, name); if (!fs.statSync(spritesPath).isDirectory()) {
return response.sendStatus(404);
}
// No sprites folder exists, or not a directory const spritePackPath = path.join(UPLOADS_PATH, file.filename);
if (!fs.existsSync(spritesPath) || !fs.statSync(spritesPath).isDirectory()) { const sprites = await getImageBuffers(spritePackPath);
return response.sendStatus(404); const files = fs.readdirSync(spritesPath);
}
const files = fs.readdirSync(spritesPath);
for (const [filename, buffer] of sprites) {
// Remove existing sprite with the same label // Remove existing sprite with the same label
for (const file of files) { const existingFile = files.find(file => path.parse(file).name === path.parse(filename).name);
if (path.parse(file).name === label) {
fs.rmSync(path.join(spritesPath, file)); if (existingFile) {
} fs.rmSync(path.join(spritesPath, existingFile));
} }
return response.sendStatus(200); // Write sprite buffer to disk
} catch (error) { const pathToSprite = path.join(spritesPath, filename);
console.error(error); writeFileAtomicSync(pathToSprite, buffer);
return response.sendStatus(500);
}
});
app.post('/api/sprites/upload-zip', urlencodedParser, async (request, response) => {
const file = request.file;
const name = request.body.name;
if (!file || !name) {
return response.sendStatus(400);
} }
try { // Remove uploaded ZIP file
const spritesPath = path.join(DIRECTORIES.characters, name); fs.rmSync(spritePackPath);
return response.send({ count: sprites.length });
} catch (error) {
console.error(error);
return response.sendStatus(500);
}
});
// Create sprites folder if it doesn't exist router.post('/upload', urlencodedParser, async (request, response) => {
if (!fs.existsSync(spritesPath)) { const file = request.file;
fs.mkdirSync(spritesPath); const label = request.body.label;
} const name = request.body.name;
// Path to sprites is not a directory. This should never happen. if (!file || !label || !name) {
if (!fs.statSync(spritesPath).isDirectory()) { return response.sendStatus(400);
return response.sendStatus(404); }
}
const spritePackPath = path.join(UPLOADS_PATH, file.filename); try {
const sprites = await getImageBuffers(spritePackPath); const spritesPath = path.join(DIRECTORIES.characters, name);
const files = fs.readdirSync(spritesPath);
for (const [filename, buffer] of sprites) { // Create sprites folder if it doesn't exist
// Remove existing sprite with the same label if (!fs.existsSync(spritesPath)) {
const existingFile = files.find(file => path.parse(file).name === path.parse(filename).name); fs.mkdirSync(spritesPath);
if (existingFile) {
fs.rmSync(path.join(spritesPath, existingFile));
}
// Write sprite buffer to disk
const pathToSprite = path.join(spritesPath, filename);
writeFileAtomicSync(pathToSprite, buffer);
}
// Remove uploaded ZIP file
fs.rmSync(spritePackPath);
return response.send({ count: sprites.length });
} catch (error) {
console.error(error);
return response.sendStatus(500);
}
});
app.post('/api/sprites/upload', urlencodedParser, async (request, response) => {
const file = request.file;
const label = request.body.label;
const name = request.body.name;
if (!file || !label || !name) {
return response.sendStatus(400);
} }
try { // Path to sprites is not a directory. This should never happen.
const spritesPath = path.join(DIRECTORIES.characters, name); if (!fs.statSync(spritesPath).isDirectory()) {
return response.sendStatus(404);
// Create sprites folder if it doesn't exist
if (!fs.existsSync(spritesPath)) {
fs.mkdirSync(spritesPath);
}
// Path to sprites is not a directory. This should never happen.
if (!fs.statSync(spritesPath).isDirectory()) {
return response.sendStatus(404);
}
const files = fs.readdirSync(spritesPath);
// Remove existing sprite with the same label
for (const file of files) {
if (path.parse(file).name === label) {
fs.rmSync(path.join(spritesPath, file));
}
}
const filename = label + path.parse(file.originalname).ext;
const spritePath = path.join(UPLOADS_PATH, file.filename);
const pathToFile = path.join(spritesPath, filename);
// Copy uploaded file to sprites folder
fs.cpSync(spritePath, pathToFile);
// Remove uploaded file
fs.rmSync(spritePath);
return response.sendStatus(200);
} catch (error) {
console.error(error);
return response.sendStatus(500);
} }
});
} const files = fs.readdirSync(spritesPath);
// Remove existing sprite with the same label
for (const file of files) {
if (path.parse(file).name === label) {
fs.rmSync(path.join(spritesPath, file));
}
}
const filename = label + path.parse(file.originalname).ext;
const spritePath = path.join(UPLOADS_PATH, file.filename);
const pathToFile = path.join(spritesPath, filename);
// Copy uploaded file to sprites folder
fs.cpSync(spritePath, pathToFile);
// Remove uploaded file
fs.rmSync(spritePath);
return response.sendStatus(200);
} catch (error) {
console.error(error);
return response.sendStatus(500);
}
});
module.exports = { module.exports = {
registerEndpoints, router,
importRisuSprites, importRisuSprites,
}; };