mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
#1579 Add ooba character yaml import
This commit is contained in:
@@ -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>
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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) {
|
||||||
|
Reference in New Issue
Block a user