Merge pull request #1475 from valadaptive/groups-endpoint
Move group endpoints into their own module
This commit is contained in:
commit
acd5acf2b0
|
@ -251,7 +251,7 @@ async function convertSoloToGroupChat() {
|
|||
const metadata = Object.assign({}, chat_metadata);
|
||||
delete metadata.main_chat;
|
||||
|
||||
const createGroupResponse = await fetch('/creategroup', {
|
||||
const createGroupResponse = await fetch('/api/groups/create', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
|
|
|
@ -116,7 +116,7 @@ setInterval(groupChatAutoModeWorker, 5000);
|
|||
const saveGroupDebounced = debounce(async (group, reload) => await _save(group, reload), 500);
|
||||
|
||||
async function _save(group, reload = true) {
|
||||
await fetch('/editgroup', {
|
||||
await fetch('/api/groups/edit', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify(group),
|
||||
|
@ -476,7 +476,7 @@ export async function renameGroupMember(oldAvatar, newAvatar, newName) {
|
|||
}
|
||||
|
||||
async function getGroups() {
|
||||
const response = await fetch('/getgroups', {
|
||||
const response = await fetch('/api/groups/all', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
});
|
||||
|
@ -968,7 +968,7 @@ function activateNaturalOrder(members, input, lastMessage, allowSelfResponses, i
|
|||
async function deleteGroup(id) {
|
||||
const group = groups.find((x) => x.id === id);
|
||||
|
||||
const response = await fetch('/deletegroup', {
|
||||
const response = await fetch('/api/groups/delete', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({ id: id }),
|
||||
|
@ -1521,7 +1521,7 @@ async function createGroup() {
|
|||
const chatName = humanizedDateTime();
|
||||
const chats = [chatName];
|
||||
|
||||
const createGroupResponse = await fetch('/creategroup', {
|
||||
const createGroupResponse = await fetch('/api/groups/create', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
|
|
131
server.js
131
server.js
|
@ -47,7 +47,7 @@ const { jsonParser, urlencodedParser } = require('./src/express-common.js');
|
|||
const contentManager = require('./src/endpoints/content-manager');
|
||||
const statsHelpers = require('./statsHelpers.js');
|
||||
const { readSecret, migrateSecrets, SECRET_KEYS } = require('./src/endpoints/secrets');
|
||||
const { delay, getVersion, getConfigValue, color, uuidv4, humanizedISO8601DateTime, tryParse, clientRelativePath, removeFileExtension, generateTimestamp, removeOldBackups } = require('./src/util');
|
||||
const { delay, getVersion, getConfigValue, color, uuidv4, tryParse, clientRelativePath, removeFileExtension, generateTimestamp, removeOldBackups } = require('./src/util');
|
||||
const { invalidateThumbnail, ensureThumbnailCache } = require('./src/endpoints/thumbnails');
|
||||
const { getTokenizerModel, getTiktokenTokenizer, loadTokenizers, TEXT_COMPLETION_MODELS, getSentencepiceTokenizer, sentencepieceTokenizers } = require('./src/endpoints/tokenizers');
|
||||
const { convertClaudePrompt } = require('./src/chat-completion');
|
||||
|
@ -1300,126 +1300,6 @@ app.post('/listimgfiles/:folder', (req, res) => {
|
|||
});
|
||||
|
||||
|
||||
app.post('/getgroups', jsonParser, (_, response) => {
|
||||
const groups = [];
|
||||
|
||||
if (!fs.existsSync(DIRECTORIES.groups)) {
|
||||
fs.mkdirSync(DIRECTORIES.groups);
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(DIRECTORIES.groups).filter(x => path.extname(x) === '.json');
|
||||
const chats = fs.readdirSync(DIRECTORIES.groupChats).filter(x => path.extname(x) === '.jsonl');
|
||||
|
||||
files.forEach(function (file) {
|
||||
try {
|
||||
const filePath = path.join(DIRECTORIES.groups, file);
|
||||
const fileContents = fs.readFileSync(filePath, 'utf8');
|
||||
const group = JSON.parse(fileContents);
|
||||
const groupStat = fs.statSync(filePath);
|
||||
group['date_added'] = groupStat.birthtimeMs;
|
||||
group['create_date'] = humanizedISO8601DateTime(groupStat.birthtimeMs);
|
||||
|
||||
let chat_size = 0;
|
||||
let date_last_chat = 0;
|
||||
|
||||
if (Array.isArray(group.chats) && Array.isArray(chats)) {
|
||||
for (const chat of chats) {
|
||||
if (group.chats.includes(path.parse(chat).name)) {
|
||||
const chatStat = fs.statSync(path.join(DIRECTORIES.groupChats, chat));
|
||||
chat_size += chatStat.size;
|
||||
date_last_chat = Math.max(date_last_chat, chatStat.mtimeMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group['date_last_chat'] = date_last_chat;
|
||||
group['chat_size'] = chat_size;
|
||||
groups.push(group);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
return response.send(groups);
|
||||
});
|
||||
|
||||
app.post('/creategroup', jsonParser, (request, response) => {
|
||||
if (!request.body) {
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
|
||||
const id = String(Date.now());
|
||||
const groupMetadata = {
|
||||
id: id,
|
||||
name: request.body.name ?? 'New Group',
|
||||
members: request.body.members ?? [],
|
||||
avatar_url: request.body.avatar_url,
|
||||
allow_self_responses: !!request.body.allow_self_responses,
|
||||
activation_strategy: request.body.activation_strategy ?? 0,
|
||||
generation_mode: request.body.generation_mode ?? 0,
|
||||
disabled_members: request.body.disabled_members ?? [],
|
||||
chat_metadata: request.body.chat_metadata ?? {},
|
||||
fav: request.body.fav,
|
||||
chat_id: request.body.chat_id ?? id,
|
||||
chats: request.body.chats ?? [id],
|
||||
};
|
||||
const pathToFile = path.join(DIRECTORIES.groups, `${id}.json`);
|
||||
const fileData = JSON.stringify(groupMetadata);
|
||||
|
||||
if (!fs.existsSync(DIRECTORIES.groups)) {
|
||||
fs.mkdirSync(DIRECTORIES.groups);
|
||||
}
|
||||
|
||||
writeFileAtomicSync(pathToFile, fileData);
|
||||
return response.send(groupMetadata);
|
||||
});
|
||||
|
||||
app.post('/editgroup', jsonParser, (request, response) => {
|
||||
if (!request.body || !request.body.id) {
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
const id = request.body.id;
|
||||
const pathToFile = path.join(DIRECTORIES.groups, `${id}.json`);
|
||||
const fileData = JSON.stringify(request.body);
|
||||
|
||||
writeFileAtomicSync(pathToFile, fileData);
|
||||
return response.send({ ok: true });
|
||||
});
|
||||
|
||||
app.post('/deletegroup', jsonParser, async (request, response) => {
|
||||
if (!request.body || !request.body.id) {
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
|
||||
const id = request.body.id;
|
||||
const pathToGroup = path.join(DIRECTORIES.groups, sanitize(`${id}.json`));
|
||||
|
||||
try {
|
||||
// Delete group chats
|
||||
const group = JSON.parse(fs.readFileSync(pathToGroup, 'utf8'));
|
||||
|
||||
if (group && Array.isArray(group.chats)) {
|
||||
for (const chat of group.chats) {
|
||||
console.log('Deleting group chat', chat);
|
||||
const pathToFile = path.join(DIRECTORIES.groupChats, `${id}.jsonl`);
|
||||
|
||||
if (fs.existsSync(pathToFile)) {
|
||||
fs.rmSync(pathToFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Could not delete group chats. Clean them up manually.', error);
|
||||
}
|
||||
|
||||
if (fs.existsSync(pathToGroup)) {
|
||||
fs.rmSync(pathToGroup);
|
||||
}
|
||||
|
||||
return response.send({ ok: true });
|
||||
});
|
||||
|
||||
function cleanUploads() {
|
||||
try {
|
||||
if (fs.existsSync(UPLOADS_PATH)) {
|
||||
|
@ -2248,6 +2128,12 @@ redirect('/getgroupchat', '/api/chats/group/get');
|
|||
redirect('/deletegroupchat', '/api/chats/group/delete');
|
||||
redirect('/savegroupchat', '/api/chats/group/save');
|
||||
|
||||
// Redirect deprecated group API endpoints
|
||||
redirect('/getgroups', '/api/groups/all');
|
||||
redirect('/creategroup', '/api/groups/create');
|
||||
redirect('/editgroup', '/api/groups/edit');
|
||||
redirect('/deletegroup', '/api/groups/delete');
|
||||
|
||||
// ** REST CLIENT ASYNC WRAPPERS **
|
||||
|
||||
/**
|
||||
|
@ -2302,6 +2188,9 @@ app.use('/api/characters', require('./src/endpoints/characters').router);
|
|||
// Chat management
|
||||
app.use('/api/chats', require('./src/endpoints/chats').router);
|
||||
|
||||
// Group management
|
||||
app.use('/api/groups', require('./src/endpoints/groups').router);
|
||||
|
||||
// Character sprite management
|
||||
app.use('/api/sprites', require('./src/endpoints/sprites').router);
|
||||
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const express = require('express');
|
||||
const sanitize = require('sanitize-filename');
|
||||
const writeFileAtomicSync = require('write-file-atomic').sync;
|
||||
|
||||
const { jsonParser } = require('../express-common');
|
||||
const { DIRECTORIES } = require('../constants');
|
||||
const { humanizedISO8601DateTime } = require('../util');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.post('/all', jsonParser, (_, response) => {
|
||||
const groups = [];
|
||||
|
||||
if (!fs.existsSync(DIRECTORIES.groups)) {
|
||||
fs.mkdirSync(DIRECTORIES.groups);
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(DIRECTORIES.groups).filter(x => path.extname(x) === '.json');
|
||||
const chats = fs.readdirSync(DIRECTORIES.groupChats).filter(x => path.extname(x) === '.jsonl');
|
||||
|
||||
files.forEach(function (file) {
|
||||
try {
|
||||
const filePath = path.join(DIRECTORIES.groups, file);
|
||||
const fileContents = fs.readFileSync(filePath, 'utf8');
|
||||
const group = JSON.parse(fileContents);
|
||||
const groupStat = fs.statSync(filePath);
|
||||
group['date_added'] = groupStat.birthtimeMs;
|
||||
group['create_date'] = humanizedISO8601DateTime(groupStat.birthtimeMs);
|
||||
|
||||
let chat_size = 0;
|
||||
let date_last_chat = 0;
|
||||
|
||||
if (Array.isArray(group.chats) && Array.isArray(chats)) {
|
||||
for (const chat of chats) {
|
||||
if (group.chats.includes(path.parse(chat).name)) {
|
||||
const chatStat = fs.statSync(path.join(DIRECTORIES.groupChats, chat));
|
||||
chat_size += chatStat.size;
|
||||
date_last_chat = Math.max(date_last_chat, chatStat.mtimeMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group['date_last_chat'] = date_last_chat;
|
||||
group['chat_size'] = chat_size;
|
||||
groups.push(group);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
return response.send(groups);
|
||||
});
|
||||
|
||||
router.post('/create', jsonParser, (request, response) => {
|
||||
if (!request.body) {
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
|
||||
const id = String(Date.now());
|
||||
const groupMetadata = {
|
||||
id: id,
|
||||
name: request.body.name ?? 'New Group',
|
||||
members: request.body.members ?? [],
|
||||
avatar_url: request.body.avatar_url,
|
||||
allow_self_responses: !!request.body.allow_self_responses,
|
||||
activation_strategy: request.body.activation_strategy ?? 0,
|
||||
generation_mode: request.body.generation_mode ?? 0,
|
||||
disabled_members: request.body.disabled_members ?? [],
|
||||
chat_metadata: request.body.chat_metadata ?? {},
|
||||
fav: request.body.fav,
|
||||
chat_id: request.body.chat_id ?? id,
|
||||
chats: request.body.chats ?? [id],
|
||||
};
|
||||
const pathToFile = path.join(DIRECTORIES.groups, `${id}.json`);
|
||||
const fileData = JSON.stringify(groupMetadata);
|
||||
|
||||
if (!fs.existsSync(DIRECTORIES.groups)) {
|
||||
fs.mkdirSync(DIRECTORIES.groups);
|
||||
}
|
||||
|
||||
writeFileAtomicSync(pathToFile, fileData);
|
||||
return response.send(groupMetadata);
|
||||
});
|
||||
|
||||
router.post('/edit', jsonParser, (request, response) => {
|
||||
if (!request.body || !request.body.id) {
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
const id = request.body.id;
|
||||
const pathToFile = path.join(DIRECTORIES.groups, `${id}.json`);
|
||||
const fileData = JSON.stringify(request.body);
|
||||
|
||||
writeFileAtomicSync(pathToFile, fileData);
|
||||
return response.send({ ok: true });
|
||||
});
|
||||
|
||||
router.post('/delete', jsonParser, async (request, response) => {
|
||||
if (!request.body || !request.body.id) {
|
||||
return response.sendStatus(400);
|
||||
}
|
||||
|
||||
const id = request.body.id;
|
||||
const pathToGroup = path.join(DIRECTORIES.groups, sanitize(`${id}.json`));
|
||||
|
||||
try {
|
||||
// Delete group chats
|
||||
const group = JSON.parse(fs.readFileSync(pathToGroup, 'utf8'));
|
||||
|
||||
if (group && Array.isArray(group.chats)) {
|
||||
for (const chat of group.chats) {
|
||||
console.log('Deleting group chat', chat);
|
||||
const pathToFile = path.join(DIRECTORIES.groupChats, `${id}.jsonl`);
|
||||
|
||||
if (fs.existsSync(pathToFile)) {
|
||||
fs.rmSync(pathToFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Could not delete group chats. Clean them up manually.', error);
|
||||
}
|
||||
|
||||
if (fs.existsSync(pathToGroup)) {
|
||||
fs.rmSync(pathToGroup);
|
||||
}
|
||||
|
||||
return response.send({ ok: true });
|
||||
});
|
||||
|
||||
module.exports = { router };
|
Loading…
Reference in New Issue