mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
#517 Export chats as JSONL
This commit is contained in:
@ -2870,9 +2870,10 @@
|
||||
<div class="select_chat_block_mes"></div>
|
||||
</div>
|
||||
<div class="flex-container height100pSpaceEvenly">
|
||||
<div class="renameChatButton fa-solid fa-pen"></div>
|
||||
<div class="exportChatButton fa-solid fa-file-export"></div>
|
||||
<div file_name="" class="PastChat_cross fa-solid fa-circle-xmark"></div>
|
||||
<div title="Rename chat file" class="renameChatButton fa-solid fa-pen"></div>
|
||||
<div title="Export JSONL chat file" data-format="jsonl" class="exportRawChatButton fa-solid fa-file-export"></div>
|
||||
<div title="Download chat as plain text document" data-format="txt" class="exportChatButton fa-solid fa-file-lines"></div>
|
||||
<div title="Delete chat file" file_name="" class="PastChat_cross fa-solid fa-circle-xmark"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6551,15 +6551,19 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("click", ".exportChatButton", async function () {
|
||||
$(document).on("click", ".exportChatButton, .exportRawChatButton", async function () {
|
||||
const format = $(this).data('format') || 'txt';
|
||||
await saveChatConditional();
|
||||
const filenamefull = $(this).closest('.select_chat_block_wrapper').find('.select_chat_block_filename').text();
|
||||
console.log(`exporting ${filenamefull} in ${format} format`);
|
||||
|
||||
const filename = filenamefull.replace('.jsonl', '');
|
||||
const body = {
|
||||
is_group: !!selected_group,
|
||||
avatar_url: characters[this_chid]?.avatar,
|
||||
file: `${filename}.jsonl`,
|
||||
exportfilename: `${filename}.txt`,
|
||||
exportfilename: `${filename}.${format}`,
|
||||
format: format,
|
||||
}
|
||||
console.log(body);
|
||||
try {
|
||||
@ -6576,11 +6580,12 @@ $(document).ready(function () {
|
||||
toastr.error(`Error: ${data.message}`);
|
||||
return;
|
||||
} else {
|
||||
const mimeType = format == 'txt' ? 'text/plain' : 'application/json';
|
||||
// success, handle response data
|
||||
console.log(data);
|
||||
await delay(250);
|
||||
toastr.success(data.message);
|
||||
download(data.result, body.exportfilename, 'text/plain');
|
||||
download(data.result, body.exportfilename, mimeType);
|
||||
}
|
||||
} catch (error) {
|
||||
// display error message
|
||||
|
@ -2689,6 +2689,7 @@ h5 {
|
||||
}
|
||||
|
||||
.renameChatButton,
|
||||
.exportRawChatButton,
|
||||
.exportChatButton {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
23
server.js
23
server.js
@ -1847,8 +1847,29 @@ app.post("/exportchat", jsonParser, async function (request, response) {
|
||||
return response.status(404).json(errorMessage);
|
||||
}
|
||||
try {
|
||||
// Short path for JSONL files
|
||||
if (request.body.format == 'jsonl') {
|
||||
try {
|
||||
const rawFile = fs.readFileSync(filename, 'utf8');
|
||||
const successMessage = {
|
||||
message: `Chat saved to ${exportfilename}`,
|
||||
result: rawFile,
|
||||
}
|
||||
|
||||
console.log(`Chat exported as ${exportfilename}`);
|
||||
return response.status(200).json(successMessage);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
const errorMessage = {
|
||||
message: `Could not read JSONL file to export. Source chat file: ${filename}.`
|
||||
}
|
||||
console.log(errorMessage.message);
|
||||
return response.status(500).json(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
const readline = require('readline');
|
||||
const fs = require('fs');
|
||||
const readStream = fs.createReadStream(filename);
|
||||
const rl = readline.createInterface({
|
||||
input: readStream,
|
||||
|
Reference in New Issue
Block a user