diff --git a/server.js b/server.js index ac329220d..c90aa86c3 100644 --- a/server.js +++ b/server.js @@ -63,7 +63,9 @@ const utf8Encode = new TextEncoder(); const utf8Decode = new TextDecoder('utf-8', { ignoreBOM: true }); const commandExistsSync = require('command-exists').sync; +const characterCardParser = require('./src/character-card-parser.js'); const config = require(path.join(process.cwd(), './config.conf')); + const server_port = process.env.SILLY_TAVERN_PORT || config.port; const whitelistPath = path.join(process.cwd(), "./whitelist.txt"); @@ -913,61 +915,7 @@ async function tryReadImage(img_url, crop) { } async function charaRead(img_url, input_format) { - let format; - if (input_format === undefined) { - if (img_url.indexOf('.webp') !== -1) { - format = 'webp'; - } else { - format = 'png'; - } - } else { - format = input_format; - } - - switch (format) { - case 'webp': - try { - const exif_data = await ExifReader.load(fs.readFileSync(img_url)); - let char_data; - - if (exif_data['UserComment']['description']) { - let description = exif_data['UserComment']['description']; - if (description === 'Undefined' && exif_data['UserComment'].value && exif_data['UserComment'].value.length === 1) { - description = exif_data['UserComment'].value[0]; - } - try { - json5.parse(description); - char_data = description; - } catch { - const byteArr = description.split(",").map(Number); - const uint8Array = new Uint8Array(byteArr); - const char_data_string = utf8Decode.decode(uint8Array); - char_data = char_data_string; - } - } else { - console.log('No description found in EXIF data.'); - return false; - } - return char_data; - } - catch (err) { - console.log(err); - return false; - } - case 'png': - const buffer = fs.readFileSync(img_url); - const chunks = extract(buffer); - - const textChunks = chunks.filter(function (chunk) { - return chunk.name === 'tEXt'; - }).map(function (chunk) { - return PNGtext.decode(chunk.data); - }); - var base64DecodedData = Buffer.from(textChunks[0].text, 'base64').toString('utf8'); - return base64DecodedData;//textChunks[0].text; - default: - break; - } + return characterCardParser.parse(img_url, input_format); } app.post("/getcharacters", jsonParser, function (request, response) { diff --git a/src/character-card-parser.js b/src/character-card-parser.js new file mode 100644 index 000000000..e97a66bf0 --- /dev/null +++ b/src/character-card-parser.js @@ -0,0 +1,72 @@ +const fs = require('fs'); +const json5 = require('json5'); +const ExifReader = require('exifreader'); + +const extract = require('png-chunks-extract'); +const PNGtext = require('png-chunk-text'); + +const utf8Decode = new TextDecoder('utf-8', { ignoreBOM: true }); + +const parse = async (cardUrl, format) => { + let fileFormat; + if (format === undefined) { + if (cardUrl.indexOf('.webp') !== -1) + fileFormat = 'webp'; + else + fileFormat = 'png'; + } + else + fileFormat = format; + + switch (fileFormat) { + case 'webp': + try { + const exif_data = await ExifReader.load(fs.readFileSync(cardUrl)); + let char_data; + + if (exif_data['UserComment']['description']) { + let description = exif_data['UserComment']['description']; + if (description === 'Undefined' && exif_data['UserComment'].value && exif_data['UserComment'].value.length === 1) { + description = exif_data['UserComment'].value[0]; + } + + try { + json5.parse(description); + char_data = description; + } catch { + const byteArr = description.split(",").map(Number); + const uint8Array = new Uint8Array(byteArr); + const char_data_string = utf8Decode.decode(uint8Array); + char_data = char_data_string; + } + } + else { + console.log('No description found in EXIF data.'); + return false; + } + + return char_data; + } + catch (err) { + console.log(err); + return false; + } + case 'png': + const buffer = fs.readFileSync(cardUrl); + const chunks = extract(buffer); + + const textChunks = chunks.filter(function (chunk) { + return chunk.name === 'tEXt'; + }).map(function (chunk) { + return PNGtext.decode(chunk.data); + }); + + return Buffer.from(textChunks[0].text, 'base64').toString('utf8'); + default: + break; + } +}; + +module.exports = { + parse: parse +};