Skip to content

Commit

Permalink
💄 improve change checkpoint command
Browse files Browse the repository at this point in the history
  • Loading branch information
ImDarkTom committed Jan 18, 2024
1 parent 3766f93 commit dc365da
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 26 deletions.
39 changes: 39 additions & 0 deletions src/buttons/action/loadCheckpoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//@ts-check
const { ButtonInteraction, Client, EmbedBuilder } = require("discord.js");
const sendRequest = require("../../utils/SD/sendRequest");

module.exports = {
id: 'loadCheckpoint',
ownerOnly: false,

/**
*
* @param {Client} _client
* @param {ButtonInteraction} interaction
*/
callback: async (_client, interaction) => {
const modelName = interaction.message.embeds[0].title;

await interaction.message.delete();

const loadingEmbed = new EmbedBuilder()
.setColor(0xfde395)
.setTitle('Loading checkpoint...')
.setDescription(`Loading "**${modelName}**".`)

await interaction.reply({content: "", embeds: [loadingEmbed]});

let options = await sendRequest('sdapi/v1/options', {}, "get");

options["sd_model_checkpoint"] = modelName;

await sendRequest('sdapi/v1/options', options, "post");

const finishedEmbed = new EmbedBuilder()
.setColor(0x82d17b)
.setTitle('Checkpoint loaded!')
.setDescription(`Checkpoint "**${modelName}**" has successfully loaded.`)

await interaction.editReply({content: "", embeds: [finishedEmbed]});
},
};
16 changes: 9 additions & 7 deletions src/commands/sdInfo/changeModel.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { EmbedBuilder, ActionRowBuilder, StringSelectMenuBuilder, Client, ChatInputCommandInteraction } = require("discord.js");
const { ActionRowBuilder, StringSelectMenuBuilder, Client, ChatInputCommandInteraction, ApplicationCommandOptionType } = require("discord.js");
const sdConfig = require('../../../sdConfig.json')
const sendRequest = require("../../utils/SD/sendRequest");

Expand All @@ -8,6 +8,13 @@ module.exports = {
// devOnly: Boolean,
// testOnly: Boolean,
// deleted: Boolean,
options: [
{
name: 'checkpoint',
description: 'Change the current checkpoint.',
type: ApplicationCommandOptionType.Subcommand
}
],

/**
*
Expand All @@ -16,7 +23,6 @@ module.exports = {
*/
callback: async (_client, interaction) => {
let modelList = [];
let embed;
const modelsResponse = await sendRequest('sdapi/v1/sd-models', {}, "get");

for (const model of modelsResponse) {
Expand All @@ -27,10 +33,6 @@ module.exports = {
});
}

embed = new EmbedBuilder()
.setTitle("Please select a model from the dropdown...")
.setColor(0x7ba4d1)

const dropdown = new StringSelectMenuBuilder()
.setCustomId(`modelDropdown-${interaction.user.id}`)
.setPlaceholder(`Default: ${sdConfig.generationDefaults.defaultModel}`)
Expand All @@ -39,6 +41,6 @@ module.exports = {
const row = new ActionRowBuilder()
.addComponents(dropdown)

await interaction.reply({content: "", embeds: [embed], components: [row]})
await interaction.reply({content: "Select a checkpoint", components: [row]})
},
};
72 changes: 54 additions & 18 deletions src/menus/SD/modelDropdown.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//@ts-check
const { EmbedBuilder, Client, StringSelectMenuInteraction } = require('discord.js');
const { EmbedBuilder, Client, StringSelectMenuInteraction, AttachmentBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
const sendRequest = require('../../utils/SD/sendRequest');
const { default:axios } = require('axios');
const sharp = require('sharp');
const sdConfig = require('../../../sdConfig.json');

module.exports = {
id: 'modelDropdown',
Expand All @@ -12,29 +14,63 @@ module.exports = {
* @param {StringSelectMenuInteraction} interaction
*/
callback: async (_client, interaction) => {
const modelValue = interaction.values[0];
let embed;
const selectedModelName = interaction.values[0];

embed = new EmbedBuilder()
.setColor(0x7ba4d1)
.setTitle('Loading checkpoint...')
.setDescription(`Loading "**${modelValue}**". Please wait for the checkpoint to load.`)
const allModelsInfo = await sendRequest('sdapi/v1/sd-models', {}, "get");
const selectedModelInfo = allModelsInfo.filter((model) => model.model_name == selectedModelName)[0];
const modelFileName = selectedModelInfo.filename;

await interaction.reply({content: "", embeds: [embed]});
//Get model thumbnail
let thumbnailImageBuffer, thumbnailFileExtension;
const fileNameNoExt = modelFileName.substring(0, modelFileName.lastIndexOf('.'));
for (const fileExtension of ['png', 'jpg', 'jpeg', 'webp', 'gif']) {
const generatedImageFileName = `${fileNameNoExt}.${fileExtension}`;
const generatedUrl = `${sdConfig.baseUrl}:${sdConfig.port}/sd_extra_networks/thumb?filename=${generatedImageFileName}`;

interaction.message.delete();
try {
const response = await axios.get(generatedUrl, { responseType: 'arraybuffer'});

if (response.status === 404) {
continue;
}

thumbnailImageBuffer = sharp(response.data);
thumbnailFileExtension = fileExtension;
break;

let options = await sendRequest('sdapi/v1/options', {}, "get");
} catch (error) {
if (!(error.response && error.response.status == 404)) {
//If not 404
console.error(`Error fetching ${generatedUrl}: ${error.message}`);
}
}
}

options["sd_model_checkpoint"] = modelValue;
if (thumbnailImageBuffer == undefined) {
const response = await axios.get(`${sdConfig.baseUrl}:${sdConfig.port}/file=html/card-no-preview.png`, { responseType: 'arraybuffer' });

await sendRequest('sdapi/v1/options', options, "post");
thumbnailImageBuffer = sharp(response.data);
thumbnailFileExtension = "png";
}

embed = new EmbedBuilder()
.setColor(0x82d17b)
.setTitle('Checkpoint loaded!')
.setDescription(`Checkpoint "**${modelValue}**" has successfully loaded.`)
const attachment = new AttachmentBuilder(thumbnailImageBuffer, {name: `thumbnail.${thumbnailFileExtension}`, description: ""});

await interaction.editReply({content: "", embeds: [embed]});
const embed = new EmbedBuilder()
.setTitle(selectedModelInfo.model_name)
.setDescription(selectedModelInfo.title)
.setThumbnail(`attachment://thumbnail.${thumbnailFileExtension}`)
.setColor('Aqua')

const buttonRow = new ActionRowBuilder();

const loadButton = new ButtonBuilder()
.setCustomId('loadCheckpoint')
.setLabel('Load Checkpoint')
.setEmoji('💾')
.setStyle(ButtonStyle.Primary)

buttonRow.addComponents(loadButton);

await interaction.reply({content: "", embeds: [embed], files: [attachment], components: [buttonRow] });
},
};
2 changes: 1 addition & 1 deletion src/utils/SD/base64ToAttachment.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const sharp = require('sharp');
/**
* Turns a Base64 encoded image into an attachment.
* @param {String} encodedString Base64 encoded image string.
* @param {keyof sharp.FormatEnum} resultFormat The image format to return the buffer as, default png.
* @param {keyof sharp.FormatEnum|String} resultFormat The image format to return the buffer as, default png.
* @param {String} filename The filename of the atachment, default is 'image'.
* @returns {Promise<Attachment>}
*/
Expand Down

0 comments on commit dc365da

Please sign in to comment.