(WIP) Import JSON from .charx
This commit is contained in:
parent
a41fe1d801
commit
20d12dc98e
|
@ -4788,7 +4788,7 @@
|
|||
</div>
|
||||
<div id="rm_character_import" class="right_menu" style="display: none;">
|
||||
<form id="form_import" action="javascript:void(null);" method="post" enctype="multipart/form-data">
|
||||
<input multiple type="file" id="character_import_file" accept=".json, image/png, .yaml, .yml" name="avatar">
|
||||
<input multiple type="file" id="character_import_file" accept=".json, image/png, .yaml, .yml, .charx" name="avatar">
|
||||
<input id="character_import_file_type" name="file_type" class="text_pole" maxlength="999" size="2" value="" autocomplete="off">
|
||||
</form>
|
||||
<input type="file" id="character_replace_file" accept="image/png" name="replace_avatar" hidden>
|
||||
|
|
|
@ -8288,8 +8288,13 @@ export async function processDroppedFiles(files, preserveFileNames = false) {
|
|||
'text/x-yaml',
|
||||
];
|
||||
|
||||
const allowedExtensions = [
|
||||
'charx',
|
||||
];
|
||||
|
||||
for (const file of files) {
|
||||
if (allowedMimeTypes.includes(file.type)) {
|
||||
const extension = file.name.split('.').pop().toLowerCase();
|
||||
if (allowedMimeTypes.includes(file.type) || allowedExtensions.includes(extension)) {
|
||||
await importCharacter(file, preserveFileNames);
|
||||
} else {
|
||||
toastr.warning('Unsupported file type: ' + file.name);
|
||||
|
@ -8310,7 +8315,7 @@ async function importCharacter(file, preserveFileName = false) {
|
|||
}
|
||||
|
||||
const ext = file.name.match(/\.(\w+)$/);
|
||||
if (!ext || !(['json', 'png', 'yaml', 'yml'].includes(ext[1].toLowerCase()))) {
|
||||
if (!ext || !(['json', 'png', 'yaml', 'yml', 'charx'].includes(ext[1].toLowerCase()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ const jimp = require('jimp');
|
|||
|
||||
const { UPLOADS_PATH, AVATAR_WIDTH, AVATAR_HEIGHT } = require('../constants');
|
||||
const { jsonParser, urlencodedParser } = require('../express-common');
|
||||
const { deepMerge, humanizedISO8601DateTime, tryParse } = require('../util');
|
||||
const { deepMerge, humanizedISO8601DateTime, tryParse, extractFileFromZipBuffer } = require('../util');
|
||||
const { TavernCardValidator } = require('../validator/TavernCardValidator');
|
||||
const characterCardParser = require('../character-card-parser.js');
|
||||
const { readWorldInfoFile } = require('./worldinfo');
|
||||
|
@ -486,6 +486,37 @@ async function importFromYaml(uploadPath, context) {
|
|||
return result ? fileName : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a character card from CharX (ZIP) file.
|
||||
* @param {string} uploadPath
|
||||
* @param {object} params
|
||||
* @param {import('express').Request} params.request
|
||||
* @returns {Promise<string>} Internal name of the character
|
||||
*/
|
||||
async function importFromCharX(uploadPath, { request }) {
|
||||
const data = fs.readFileSync(uploadPath);
|
||||
fs.rmSync(uploadPath);
|
||||
console.log('Importing from CharX');
|
||||
const cardBuffer = await extractFileFromZipBuffer(data, 'card.json');
|
||||
|
||||
if (!cardBuffer) {
|
||||
throw new Error('Failed to extract card.json from CharX file');
|
||||
}
|
||||
|
||||
const card = readFromV2(JSON.parse(cardBuffer.toString()));
|
||||
|
||||
if (card.spec === undefined) {
|
||||
throw new Error('Invalid CharX card file: missing spec field');
|
||||
}
|
||||
|
||||
unsetFavFlag(card);
|
||||
card['create_date'] = humanizedISO8601DateTime();
|
||||
card.name = sanitize(card.name);
|
||||
const fileName = getPngName(card.name, request.user.directories);
|
||||
const result = await writeCharacterData(defaultAvatarPath, JSON.stringify(card), fileName, request);
|
||||
return result ? fileName : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a character from a JSON file.
|
||||
* @param {string} uploadPath Path to the uploaded file
|
||||
|
@ -1016,6 +1047,7 @@ router.post('/import', urlencodedParser, async function (request, response) {
|
|||
'yml': importFromYaml,
|
||||
'json': importFromJson,
|
||||
'png': importFromPng,
|
||||
'charx': importFromCharX,
|
||||
};
|
||||
|
||||
try {
|
||||
|
|
|
@ -149,7 +149,7 @@ async function extractFileFromZipBuffer(archiveBuffer, fileExtension) {
|
|||
|
||||
zipfile.readEntry();
|
||||
zipfile.on('entry', (entry) => {
|
||||
if (entry.fileName.endsWith(fileExtension)) {
|
||||
if (entry.fileName.endsWith(fileExtension) && !entry.fileName.startsWith('__MACOSX')) {
|
||||
console.log(`Extracting ${entry.fileName}`);
|
||||
zipfile.openReadStream(entry, (err, readStream) => {
|
||||
if (err) {
|
||||
|
|
Loading…
Reference in New Issue