mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add backgrounds thumbnailing
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@ public/css/bg_load.css
|
|||||||
config.conf
|
config.conf
|
||||||
.DS_Store
|
.DS_Store
|
||||||
public/settings.json
|
public/settings.json
|
||||||
|
/thumbnails
|
||||||
|
@ -590,11 +590,11 @@ async function getBackgrounds() {
|
|||||||
const getData = await response.json();
|
const getData = await response.json();
|
||||||
//background = getData;
|
//background = getData;
|
||||||
//console.log(getData.length);
|
//console.log(getData.length);
|
||||||
for (var i = 0; i < getData.length; i++) {
|
for (const bg of getData) {
|
||||||
//console.log(1);
|
const thumbPath = `/thumbnail?type=bg&file=${bg}`;
|
||||||
$("#bg_menu_content").append(
|
$("#bg_menu_content").append(
|
||||||
`<div class="bg_example" bgfile="${getData[i]}" class="bg_example_img" style="background-image: url(backgrounds/${getData[i]});">
|
`<div class="bg_example" bgfile="${bg}" class="bg_example_img" style="background-image: url('${thumbPath}');">
|
||||||
<div bgfile="${getData[i]}" class=bg_example_cross style="background-image: url(img/cross.png);">
|
<div bgfile="${bg}" class=bg_example_cross style="background-image: url(img/cross.png);">
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2585,9 +2585,8 @@ function read_bg_load(input) {
|
|||||||
"url(" + e.target.result + ")"
|
"url(" + e.target.result + ")"
|
||||||
);
|
);
|
||||||
$("#form_bg_download").after(
|
$("#form_bg_download").after(
|
||||||
`<div class=bg_example>
|
`<div class=bg_example bgfile="${html}" style="background-image: url('/thumbnail?type=bg&file=${html}');">
|
||||||
<img bgfile="${html}" class="bg_example_img" style="background-image: url(backgrounds/"${html});">
|
<img class=bg_example_cross src="img/cross.png">
|
||||||
<img bgfile="${html}" class=bg_example_cross src="img/cross.png">
|
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
84
server.js
84
server.js
@ -102,6 +102,9 @@ const directories = {
|
|||||||
novelAI_Settings: 'public/NovelAI Settings',
|
novelAI_Settings: 'public/NovelAI Settings',
|
||||||
koboldAI_Settings: 'public/KoboldAI Settings',
|
koboldAI_Settings: 'public/KoboldAI Settings',
|
||||||
openAI_Settings: 'public/OpenAI Settings',
|
openAI_Settings: 'public/OpenAI Settings',
|
||||||
|
thumbnails: 'thumbnails/',
|
||||||
|
thumbnailsBg: 'thumbnails/bg/',
|
||||||
|
thumbnailsAvatar: 'thumbnails/avatar/',
|
||||||
};
|
};
|
||||||
|
|
||||||
// CSRF Protection //
|
// CSRF Protection //
|
||||||
@ -805,6 +808,7 @@ app.post("/delbackground", jsonParser, function (request, response) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fs.rmSync(fileName);
|
fs.rmSync(fileName);
|
||||||
|
invalidateThumbnail('bg', request.body.bg);
|
||||||
return response.send('ok');
|
return response.send('ok');
|
||||||
});
|
});
|
||||||
app.post("/downloadbackground", urlencodedParser, function (request, response) {
|
app.post("/downloadbackground", urlencodedParser, function (request, response) {
|
||||||
@ -824,6 +828,7 @@ app.post("/downloadbackground", urlencodedParser, function (request, response) {
|
|||||||
if (filedata.mimetype == "image/gif") fileType = ".gif";
|
if (filedata.mimetype == "image/gif") fileType = ".gif";
|
||||||
if (filedata.mimetype == "image/bmp") fileType = ".bmp";
|
if (filedata.mimetype == "image/bmp") fileType = ".bmp";
|
||||||
fs.copyFile(img_path + img_file, 'public/backgrounds/' + img_file + fileType, (err) => {
|
fs.copyFile(img_path + img_file, 'public/backgrounds/' + img_file + fileType, (err) => {
|
||||||
|
invalidateThumbnail('bg', img_file + fileType);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
||||||
return console.log(err);
|
return console.log(err);
|
||||||
@ -1574,6 +1579,83 @@ app.post('/deletegroup', jsonParser, async (request, response) => {
|
|||||||
return response.send({ ok: true });
|
return response.send({ ok: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getThumbnailFolder(type) {
|
||||||
|
let thumbnailFolder;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'bg':
|
||||||
|
thumbnailFolder = directories.thumbnailsBg;
|
||||||
|
break;
|
||||||
|
case 'avatar':
|
||||||
|
thumbnailFolder = directories.thumbnailsAvatar;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return thumbnailFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOriginalFolder(type) {
|
||||||
|
let originalFolder;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'bg':
|
||||||
|
originalFolder = directories.backgrounds;
|
||||||
|
break;
|
||||||
|
case 'avatar':
|
||||||
|
originalFolder = directories.characters;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
function invalidateThumbnail(type, file) {
|
||||||
|
const folder = getThumbnailFolder(type);
|
||||||
|
const pathToThumbnail = path.join(folder, file);
|
||||||
|
|
||||||
|
if (fs.existsSync(pathToThumbnail)) {
|
||||||
|
fs.rmSync(pathToThumbnail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.get('/thumbnail', jsonParser, async function (request, response) {
|
||||||
|
const type = request.query.type;
|
||||||
|
const file = request.query.file;
|
||||||
|
|
||||||
|
if (!type || !file) {
|
||||||
|
return response.sendStatus(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(type == 'bg' || type == 'avatar')) {
|
||||||
|
return response.sendStatus(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sanitize(file) !== file) {
|
||||||
|
console.error('Malicious filename prevented');
|
||||||
|
return response.sendStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathToCachedFile = path.join(getThumbnailFolder(type), file);
|
||||||
|
|
||||||
|
if (fs.existsSync(pathToCachedFile)) {
|
||||||
|
return response.sendFile(pathToCachedFile, { root : __dirname});
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathToOriginalFile = path.join(getOriginalFolder(type), file);
|
||||||
|
|
||||||
|
if (!fs.existsSync(pathToOriginalFile)) {
|
||||||
|
return response.sendStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageSizes = { 'bg': [160, 90], 'avatar': [42, 42] };
|
||||||
|
const mySize = imageSizes[type];
|
||||||
|
|
||||||
|
const image = await jimp.read(pathToOriginalFile);
|
||||||
|
await image.cover(mySize[0], mySize[1]).quality(60).writeAsync(pathToCachedFile);
|
||||||
|
|
||||||
|
return response.sendFile(pathToCachedFile, { root : __dirname});
|
||||||
|
});
|
||||||
|
|
||||||
/* OpenAI */
|
/* OpenAI */
|
||||||
app.post("/getstatus_openai", jsonParser, function(request, response_getstatus_openai = response){
|
app.post("/getstatus_openai", jsonParser, function(request, response_getstatus_openai = response){
|
||||||
if(!request.body) return response_getstatus_openai.sendStatus(400);
|
if(!request.body) return response_getstatus_openai.sendStatus(400);
|
||||||
@ -1960,7 +2042,7 @@ function getCharacterFile2(directories, i) {
|
|||||||
function ensurePublicDirectoriesExist() {
|
function ensurePublicDirectoriesExist() {
|
||||||
for (const dir of Object.values(directories)) {
|
for (const dir of Object.values(directories)) {
|
||||||
if (!fs.existsSync(dir)) {
|
if (!fs.existsSync(dir)) {
|
||||||
fs.mkdirSync(dir);
|
fs.mkdirSync(dir, { recursive: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user