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);
// Character sprite management
require('./src/endpoints/sprites').registerEndpoints(app, jsonParser, urlencodedParser);
app.use('/api/sprites', require('./src/endpoints/sprites').router);
// Custom content management
require('./src/endpoints/content-manager').registerEndpoints(app, jsonParser);

View File

@ -1,11 +1,13 @@
const fs = require('fs');
const path = require('path');
const express = require('express');
const mime = require('mime-types');
const sanitize = require('sanitize-filename');
const writeFileAtomicSync = require('write-file-atomic').sync;
const { DIRECTORIES, UPLOADS_PATH } = require('../constants');
const { getImageBuffers } = require('../util');
const { jsonParser, urlencodedParser } = require('../express-common');
/**
* Gets the path to the sprites folder for the provided character name
@ -101,167 +103,161 @@ function importRisuSprites(data) {
}
}
/**
* 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 = [];
const router = express.Router();
try {
if (spritesPath && fs.existsSync(spritesPath) && fs.statSync(spritesPath).isDirectory()) {
sprites = fs.readdirSync(spritesPath)
.filter(file => {
const mimeType = mime.lookup(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}`,
};
});
router.get('/get', jsonParser, function (request, response) {
const name = String(request.query.name);
const isSubfolder = name.includes('/');
const spritesPath = getSpritesPath(name, isSubfolder);
let sprites = [];
try {
if (spritesPath && fs.existsSync(spritesPath) && fs.statSync(spritesPath).isDirectory()) {
sprites = fs.readdirSync(spritesPath)
.filter(file => {
const mimeType = mime.lookup(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) => {
const label = request.body.label;
const name = request.body.name;
return response.sendStatus(200);
} catch (error) {
console.error(error);
return response.sendStatus(500);
}
});
if (!label || !name) {
return response.sendStatus(400);
router.post('/upload-zip', urlencodedParser, async (request, response) => {
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 {
const spritesPath = path.join(DIRECTORIES.characters, name);
// Path to sprites is not a directory. This should never happen.
if (!fs.statSync(spritesPath).isDirectory()) {
return response.sendStatus(404);
}
// 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);
const spritePackPath = path.join(UPLOADS_PATH, file.filename);
const sprites = await getImageBuffers(spritePackPath);
const files = fs.readdirSync(spritesPath);
for (const [filename, buffer] of sprites) {
// 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 existingFile = files.find(file => path.parse(file).name === path.parse(filename).name);
if (existingFile) {
fs.rmSync(path.join(spritesPath, existingFile));
}
return response.sendStatus(200);
} catch (error) {
console.error(error);
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);
// Write sprite buffer to disk
const pathToSprite = path.join(spritesPath, filename);
writeFileAtomicSync(pathToSprite, buffer);
}
try {
const spritesPath = path.join(DIRECTORIES.characters, name);
// Remove uploaded ZIP file
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
if (!fs.existsSync(spritesPath)) {
fs.mkdirSync(spritesPath);
}
router.post('/upload', urlencodedParser, async (request, response) => {
const file = request.file;
const label = request.body.label;
const name = request.body.name;
// Path to sprites is not a directory. This should never happen.
if (!fs.statSync(spritesPath).isDirectory()) {
return response.sendStatus(404);
}
if (!file || !label || !name) {
return response.sendStatus(400);
}
const spritePackPath = path.join(UPLOADS_PATH, file.filename);
const sprites = await getImageBuffers(spritePackPath);
const files = fs.readdirSync(spritesPath);
try {
const spritesPath = path.join(DIRECTORIES.characters, name);
for (const [filename, buffer] of sprites) {
// Remove existing sprite with the same label
const existingFile = files.find(file => path.parse(file).name === path.parse(filename).name);
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);
// Create sprites folder if it doesn't exist
if (!fs.existsSync(spritesPath)) {
fs.mkdirSync(spritesPath);
}
try {
const spritesPath = path.join(DIRECTORIES.characters, name);
// 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);
// 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);
}
});
module.exports = {
registerEndpoints,
router,
importRisuSprites,
};