Reset settings option

This commit is contained in:
Cohee
2024-04-10 03:29:38 +03:00
parent 14d7665072
commit 2b29e14e9f
10 changed files with 129 additions and 34 deletions

View File

@@ -6,6 +6,7 @@ const PUBLIC_DIRECTORIES = {
};
const DEFAULT_AVATAR = '/img/ai4.png';
const SETTINGS_FILE = 'settings.json';
/**
* @type {import('./users').UserDirectoryList}
@@ -300,6 +301,7 @@ const OPENROUTER_KEYS = [
module.exports = {
DEFAULT_USER,
DEFAULT_AVATAR,
SETTINGS_FILE,
PUBLIC_DIRECTORIES,
USER_DIRECTORY_TEMPLATE,
UNSAFE_EXTENSIONS,

View File

@@ -15,6 +15,29 @@ const characterCardParser = require('../character-card-parser.js');
* @property {string} type
*/
/**
* @typedef {string} ContentType
* @enum {string}
*/
const CONTENT_TYPES = {
SETTINGS: 'settings',
CHARACTER: 'character',
SPRITES: 'sprites',
BACKGROUND: 'background',
WORLD: 'world',
AVATAR: 'avatar',
THEME: 'theme',
WORKFLOW: 'workflow',
KOBOLD_PRESET: 'kobold_preset',
OPENAI_PRESET: 'openai_preset',
NOVEL_PRESET: 'novel_preset',
TEXTGEN_PRESET: 'textgen_preset',
INSTRUCT: 'instruct',
CONTEXT: 'context',
MOVING_UI: 'moving_ui',
QUICK_REPLIES: 'quick_replies',
};
/**
* Gets the default presets from the content directory.
* @param {import('../users').UserDirectoryList} directories User directories
@@ -67,8 +90,9 @@ function getDefaultPresetFile(filename) {
* Seeds content for a user.
* @param {ContentItem[]} contentIndex Content index
* @param {import('../users').UserDirectoryList} directories User directories
* @param {string[]} forceCategories List of categories to force check (even if content check is skipped)
*/
async function seedContentForUser(contentIndex, directories) {
async function seedContentForUser(contentIndex, directories, forceCategories) {
if (!fs.existsSync(directories.root)) {
fs.mkdirSync(directories.root, { recursive: true });
}
@@ -78,7 +102,7 @@ async function seedContentForUser(contentIndex, directories) {
for (const contentItem of contentIndex) {
// If the content item is already in the log, skip it
if (contentLog.includes(contentItem.filename)) {
if (contentLog.includes(contentItem.filename) && !forceCategories?.includes(contentItem.type)) {
continue;
}
@@ -115,11 +139,12 @@ async function seedContentForUser(contentIndex, directories) {
/**
* Checks for new content and seeds it for all users.
* @param {import('../users').UserDirectoryList[]} directoriesList List of user directories
* @param {string[]} forceCategories List of categories to force check (even if content check is skipped)
* @returns {Promise<void>}
*/
async function checkForNewContent(directoriesList) {
async function checkForNewContent(directoriesList, forceCategories = []) {
try {
if (getConfigValue('skipContentCheck', false)) {
if (getConfigValue('skipContentCheck', false) && forceCategories?.length === 0) {
return;
}
@@ -127,7 +152,7 @@ async function checkForNewContent(directoriesList) {
const contentIndex = JSON.parse(contentIndexText);
for (const directories of directoriesList) {
await seedContentForUser(contentIndex, directories);
await seedContentForUser(contentIndex, directories, forceCategories);
}
} catch (err) {
console.log('Content check failed', err);
@@ -136,43 +161,43 @@ async function checkForNewContent(directoriesList) {
/**
* Gets the target directory for the specified asset type.
* @param {string} type Asset type
* @param {ContentType} type Asset type
* @param {import('../users').UserDirectoryList} directories User directories
* @returns {string | null} Target directory
*/
function getTargetByType(type, directories) {
switch (type) {
case 'settings':
case CONTENT_TYPES.SETTINGS:
return directories.root;
case 'character':
case CONTENT_TYPES.CHARACTER:
return directories.characters;
case 'sprites':
case CONTENT_TYPES.SPRITES:
return directories.characters;
case 'background':
case CONTENT_TYPES.BACKGROUND:
return directories.backgrounds;
case 'world':
case CONTENT_TYPES.WORLD:
return directories.worlds;
case 'avatar':
case CONTENT_TYPES.AVATAR:
return directories.avatars;
case 'theme':
case CONTENT_TYPES.THEME:
return directories.themes;
case 'workflow':
case CONTENT_TYPES.WORKFLOW:
return directories.comfyWorkflows;
case 'kobold_preset':
case CONTENT_TYPES.KOBOLD_PRESET:
return directories.koboldAI_Settings;
case 'openai_preset':
case CONTENT_TYPES.OPENAI_PRESET:
return directories.openAI_Settings;
case 'novel_preset':
case CONTENT_TYPES.NOVEL_PRESET:
return directories.novelAI_Settings;
case 'textgen_preset':
case CONTENT_TYPES.TEXTGEN_PRESET:
return directories.textGen_Settings;
case 'instruct':
case CONTENT_TYPES.INSTRUCT:
return directories.instruct;
case 'context':
case CONTENT_TYPES.CONTEXT:
return directories.context;
case 'moving_ui':
case CONTENT_TYPES.MOVING_UI:
return directories.movingUI;
case 'quick_replies':
case CONTENT_TYPES.QUICK_REPLIES:
return directories.quickreplies;
default:
return null;
@@ -477,6 +502,7 @@ router.post('/importUUID', jsonParser, async (request, response) => {
});
module.exports = {
CONTENT_TYPES,
checkForNewContent,
getDefaultPresets,
getDefaultPresetFile,

View File

@@ -2,12 +2,11 @@ const fs = require('fs');
const path = require('path');
const express = require('express');
const writeFileAtomicSync = require('write-file-atomic').sync;
const { PUBLIC_DIRECTORIES } = require('../constants');
const { PUBLIC_DIRECTORIES, SETTINGS_FILE } = require('../constants');
const { getConfigValue, generateTimestamp, removeOldBackups } = require('../util');
const { jsonParser } = require('../express-common');
const { getAllUserHandles, getUserDirectories } = require('../users');
const SETTINGS_FILE = 'settings.json';
const ENABLE_EXTENSIONS = getConfigValue('enableExtensions', true);
const ENABLE_ACCOUNTS = getConfigValue('enableUserAccounts', false);

View File

@@ -1,7 +1,11 @@
const path = require('path');
const fsPromises = require('fs').promises;
const storage = require('node-persist');
const express = require('express');
const { jsonParser } = require('../express-common');
const { getUserAvatar, toKey, getPasswordHash, getPasswordSalt, createBackupArchive } = require('../users');
const { SETTINGS_FILE } = require('../constants');
const contentManager = require('./content-manager');
const router = express.Router();
@@ -111,6 +115,19 @@ router.post('/backup', jsonParser, async (request, response) => {
}
});
router.post('/reset-settings', jsonParser, async (request, response) => {
try {
const pathToFile = path.join(request.user.directories.root, SETTINGS_FILE);
await fsPromises.rm(pathToFile, { force: true });
await contentManager.checkForNewContent([request.user.directories], [contentManager.CONTENT_TYPES.SETTINGS]);
return response.sendStatus(204);
} catch (error) {
console.error('Reset settings failed', error);
return response.sendStatus(500);
}
});
module.exports = {
router,
};

View File

@@ -10,7 +10,7 @@ const express = require('express');
const mime = require('mime-types');
const archiver = require('archiver');
const { USER_DIRECTORY_TEMPLATE, DEFAULT_USER, PUBLIC_DIRECTORIES, DEFAULT_AVATAR } = require('./constants');
const { USER_DIRECTORY_TEMPLATE, DEFAULT_USER, PUBLIC_DIRECTORIES, DEFAULT_AVATAR, SETTINGS_FILE } = require('./constants');
const { getConfigValue, color, delay, setConfigValue, generateTimestamp } = require('./util');
const { readSecret, writeSecret } = require('./endpoints/secrets');
@@ -431,7 +431,7 @@ function getUserDirectories(handle) {
function getUserAvatar(handle) {
try {
const directory = getUserDirectories(handle);
const pathToSettings = path.join(directory.root, 'settings.json');
const pathToSettings = path.join(directory.root, SETTINGS_FILE);
const settings = fs.existsSync(pathToSettings) ? JSON.parse(fs.readFileSync(pathToSettings, 'utf8')) : {};
const avatarFile = settings?.power_user?.default_persona || settings?.user_avatar;
if (!avatarFile) {