mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2024-12-16 11:19:40 +01:00
165 lines
5.2 KiB
JavaScript
165 lines
5.2 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const express = require('express');
|
|
const writeFileAtomicSync = require('write-file-atomic').sync;
|
|
const { DIRECTORIES } = require('../constants');
|
|
const { getConfigValue, generateTimestamp, removeOldBackups } = require('../util');
|
|
const { jsonParser } = require('../express-common');
|
|
const { migrateSecrets } = require('./secrets');
|
|
|
|
const enableExtensions = getConfigValue('enableExtensions', true);
|
|
const SETTINGS_FILE = './public/settings.json';
|
|
|
|
function readAndParseFromDirectory(directoryPath, fileExtension = '.json') {
|
|
const files = fs
|
|
.readdirSync(directoryPath)
|
|
.filter(x => path.parse(x).ext == fileExtension)
|
|
.sort();
|
|
|
|
const parsedFiles = [];
|
|
|
|
files.forEach(item => {
|
|
try {
|
|
const file = fs.readFileSync(path.join(directoryPath, item), 'utf-8');
|
|
parsedFiles.push(fileExtension == '.json' ? JSON.parse(file) : file);
|
|
}
|
|
catch {
|
|
// skip
|
|
}
|
|
});
|
|
|
|
return parsedFiles;
|
|
}
|
|
|
|
function sortByName(_) {
|
|
return (a, b) => a.localeCompare(b);
|
|
}
|
|
|
|
function readPresetsFromDirectory(directoryPath, options = {}) {
|
|
const {
|
|
sortFunction,
|
|
removeFileExtension = false,
|
|
fileExtension = '.json',
|
|
} = options;
|
|
|
|
const files = fs.readdirSync(directoryPath).sort(sortFunction).filter(x => path.parse(x).ext == fileExtension);
|
|
const fileContents = [];
|
|
const fileNames = [];
|
|
|
|
files.forEach(item => {
|
|
try {
|
|
const file = fs.readFileSync(path.join(directoryPath, item), 'utf8');
|
|
JSON.parse(file);
|
|
fileContents.push(file);
|
|
fileNames.push(removeFileExtension ? item.replace(/\.[^/.]+$/, '') : item);
|
|
} catch {
|
|
// skip
|
|
console.log(`${item} is not a valid JSON`);
|
|
}
|
|
});
|
|
|
|
return { fileContents, fileNames };
|
|
}
|
|
|
|
function backupSettings() {
|
|
try {
|
|
if (!fs.existsSync(DIRECTORIES.backups)) {
|
|
fs.mkdirSync(DIRECTORIES.backups);
|
|
}
|
|
|
|
const backupFile = path.join(DIRECTORIES.backups, `settings_${generateTimestamp()}.json`);
|
|
fs.copyFileSync(SETTINGS_FILE, backupFile);
|
|
|
|
removeOldBackups('settings_');
|
|
} catch (err) {
|
|
console.log('Could not backup settings file', err);
|
|
}
|
|
}
|
|
|
|
const router = express.Router();
|
|
|
|
router.post('/save', jsonParser, function (request, response) {
|
|
try {
|
|
writeFileAtomicSync('public/settings.json', JSON.stringify(request.body, null, 4), 'utf8');
|
|
response.send({ result: 'ok' });
|
|
} catch (err) {
|
|
console.log(err);
|
|
response.send(err);
|
|
}
|
|
});
|
|
|
|
// Wintermute's code
|
|
router.post('/get', jsonParser, (request, response) => {
|
|
let settings;
|
|
try {
|
|
settings = fs.readFileSync('public/settings.json', 'utf8');
|
|
} catch (e) {
|
|
return response.sendStatus(500);
|
|
}
|
|
|
|
// NovelAI Settings
|
|
const { fileContents: novelai_settings, fileNames: novelai_setting_names }
|
|
= readPresetsFromDirectory(DIRECTORIES.novelAI_Settings, {
|
|
sortFunction: sortByName(DIRECTORIES.novelAI_Settings),
|
|
removeFileExtension: true,
|
|
});
|
|
|
|
// OpenAI Settings
|
|
const { fileContents: openai_settings, fileNames: openai_setting_names }
|
|
= readPresetsFromDirectory(DIRECTORIES.openAI_Settings, {
|
|
sortFunction: sortByName(DIRECTORIES.openAI_Settings), removeFileExtension: true,
|
|
});
|
|
|
|
// TextGenerationWebUI Settings
|
|
const { fileContents: textgenerationwebui_presets, fileNames: textgenerationwebui_preset_names }
|
|
= readPresetsFromDirectory(DIRECTORIES.textGen_Settings, {
|
|
sortFunction: sortByName(DIRECTORIES.textGen_Settings), removeFileExtension: true,
|
|
});
|
|
|
|
//Kobold
|
|
const { fileContents: koboldai_settings, fileNames: koboldai_setting_names }
|
|
= readPresetsFromDirectory(DIRECTORIES.koboldAI_Settings, {
|
|
sortFunction: sortByName(DIRECTORIES.koboldAI_Settings), removeFileExtension: true,
|
|
});
|
|
|
|
const worldFiles = fs
|
|
.readdirSync(DIRECTORIES.worlds)
|
|
.filter(file => path.extname(file).toLowerCase() === '.json')
|
|
.sort((a, b) => a.localeCompare(b));
|
|
const world_names = worldFiles.map(item => path.parse(item).name);
|
|
|
|
const themes = readAndParseFromDirectory(DIRECTORIES.themes);
|
|
const movingUIPresets = readAndParseFromDirectory(DIRECTORIES.movingUI);
|
|
const quickReplyPresets = readAndParseFromDirectory(DIRECTORIES.quickreplies);
|
|
|
|
const instruct = readAndParseFromDirectory(DIRECTORIES.instruct);
|
|
const context = readAndParseFromDirectory(DIRECTORIES.context);
|
|
|
|
response.send({
|
|
settings,
|
|
koboldai_settings,
|
|
koboldai_setting_names,
|
|
world_names,
|
|
novelai_settings,
|
|
novelai_setting_names,
|
|
openai_settings,
|
|
openai_setting_names,
|
|
textgenerationwebui_presets,
|
|
textgenerationwebui_preset_names,
|
|
themes,
|
|
movingUIPresets,
|
|
quickReplyPresets,
|
|
instruct,
|
|
context,
|
|
enable_extensions: enableExtensions,
|
|
});
|
|
});
|
|
|
|
// Sync for now, but should probably be migrated to async file APIs
|
|
async function init() {
|
|
backupSettings();
|
|
migrateSecrets(SETTINGS_FILE);
|
|
}
|
|
|
|
module.exports = { router, init };
|