diff --git a/server.js b/server.js index a0b24bb5b..75cb57c62 100644 --- a/server.js +++ b/server.js @@ -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); diff --git a/src/endpoints/sprites.js b/src/endpoints/sprites.js index 67b282e9d..d43efefc4 100644 --- a/src/endpoints/sprites.js +++ b/src/endpoints/sprites.js @@ -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, };