#1579 Add ooba character yaml import

This commit is contained in:
Cohee
2023-12-21 21:46:09 +02:00
parent 4621834c87
commit 09fd772a20
3 changed files with 170 additions and 134 deletions

View File

@@ -3838,7 +3838,7 @@
</div> </div>
<div id="rm_character_import" class="right_menu" style="display: none;"> <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"> <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" name="avatar"> <input multiple type="file" id="character_import_file" accept=".json, image/png, .yaml, .yml" name="avatar">
<input id="character_import_file_type" name="file_type" class="text_pole" maxlength="999" size="2" value="" autocomplete="off"> <input id="character_import_file_type" name="file_type" class="text_pole" maxlength="999" size="2" value="" autocomplete="off">
</form> </form>
</div> </div>

View File

@@ -7649,6 +7649,10 @@ export async function processDroppedFiles(files) {
const allowedMimeTypes = [ const allowedMimeTypes = [
'application/json', 'application/json',
'image/png', 'image/png',
'application/yaml',
'application/x-yaml',
'text/yaml',
'text/x-yaml',
]; ];
for (const file of files) { for (const file of files) {
@@ -7662,10 +7666,7 @@ export async function processDroppedFiles(files) {
async function importCharacter(file) { async function importCharacter(file) {
const ext = file.name.match(/\.(\w+)$/); const ext = file.name.match(/\.(\w+)$/);
if ( if (!ext || !(['json', 'png', 'yaml', 'yml'].includes(ext[1].toLowerCase()))) {
!ext ||
(ext[1].toLowerCase() != 'json' && ext[1].toLowerCase() != 'png')
) {
return; return;
} }

View File

@@ -4,6 +4,7 @@ const readline = require('readline');
const express = require('express'); const express = require('express');
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 yaml = require('yaml');
const _ = require('lodash'); const _ = require('lodash');
const encode = require('png-chunks-encode'); const encode = require('png-chunks-encode');
@@ -19,6 +20,7 @@ const characterCardParser = require('../character-card-parser.js');
const { readWorldInfoFile } = require('./worldinfo'); const { readWorldInfoFile } = require('./worldinfo');
const { invalidateThumbnail } = require('./thumbnails'); const { invalidateThumbnail } = require('./thumbnails');
const { importRisuSprites } = require('./sprites'); const { importRisuSprites } = require('./sprites');
const defaultAvatarPath = './public/img/ai4.png';
let characters = {}; let characters = {};
@@ -394,6 +396,36 @@ function convertWorldInfoToCharacterBook(name, entries) {
return result; return result;
} }
/**
* Import a character from a YAML file.
* @param {string} uploadPath Path to the uploaded file
* @param {import('express').Response} response Express response object
*/
function importFromYaml(uploadPath, response) {
const fileText = fs.readFileSync(uploadPath, 'utf8');
fs.rmSync(uploadPath);
const yamlData = yaml.parse(fileText);
console.log('importing from yaml');
yamlData.name = sanitize(yamlData.name);
const fileName = getPngName(yamlData.name);
let char = convertToV2({
'name': yamlData.name,
'description': yamlData.context ?? '',
'first_mes': yamlData.greeting ?? '',
'create_date': humanizedISO8601DateTime(),
'chat': `${yamlData.name} - ${humanizedISO8601DateTime()}`,
'personality': '',
'creatorcomment': '',
'avatar': 'none',
'mes_example': '',
'scenario': '',
'talkativeness': 0.5,
'creator': '',
'tags': '',
});
charaWrite(defaultAvatarPath, JSON.stringify(char), fileName, response, { file_name: fileName });
}
const router = express.Router(); const router = express.Router();
router.post('/create', urlencodedParser, async function (request, response) { router.post('/create', urlencodedParser, async function (request, response) {
@@ -760,17 +792,21 @@ function getPngName(file) {
} }
router.post('/import', urlencodedParser, async function (request, response) { router.post('/import', urlencodedParser, async function (request, response) {
if (!request.body || !request.file) return response.sendStatus(400);
if (!request.body || request.file === undefined) return response.sendStatus(400);
let png_name = ''; let png_name = '';
let filedata = request.file; let filedata = request.file;
let uploadPath = path.join(UPLOADS_PATH, filedata.filename); let uploadPath = path.join(UPLOADS_PATH, filedata.filename);
var format = request.body.file_type; let format = request.body.file_type;
const defaultAvatarPath = './public/img/ai4.png';
//console.log(format); if (format == 'yaml' || format == 'yml') {
if (filedata) { try {
if (format == 'json') { importFromYaml(uploadPath, response);
} catch (err) {
console.log(err);
response.send({ error: true });
}
} else if (format == 'json') {
fs.readFile(uploadPath, 'utf8', async (err, data) => { fs.readFile(uploadPath, 'utf8', async (err, data) => {
fs.unlinkSync(uploadPath); fs.unlinkSync(uploadPath);
@@ -899,7 +935,6 @@ router.post('/import', urlencodedParser, async function (request, response) {
response.send({ error: true }); response.send({ error: true });
} }
} }
}
}); });
router.post('/duplicate', jsonParser, async function (request, response) { router.post('/duplicate', jsonParser, async function (request, response) {