mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-02-23 15:37:50 +01:00
Added import function for AICharacterCards.com cards
Added ability to import cards directly from aicharactercards.com via it's api like Chub and Janny. Video of it in action: https://streamable.com/gbfdtw Just pass the last two slash vars from the url (the author and card title) from a page. EX: aicharcards/the-game-master to: https://aicharactercards.com/wp-json/pngapi/v1/image/ In this example: https://aicharactercards.com/wp-json/pngapi/v1/image/aicharcards/the-game-master
This commit is contained in:
parent
47b6562605
commit
305afb3713
@ -10552,6 +10552,7 @@ jQuery(async function () {
|
||||
<li>Chub Lorebook (Direct Link or ID)<br>Example: <tt>lorebooks/bartleby/example-lorebook</tt></li>
|
||||
<li>JanitorAI Character (Direct Link or UUID)<br>Example: <tt>ddd1498a-a370-4136-b138-a8cd9461fdfe_character-aqua-the-useless-goddess</tt></li>
|
||||
<li>Pygmalion.chat Character (Direct Link or UUID)<br>Example: <tt>a7ca95a1-0c88-4e23-91b3-149db1e78ab9</tt></li>
|
||||
<li>AICharacterCard.com Character (Direct Link or ID)<br>Example: <tt>AICC/aicharcards/the-game-master</tt></li>
|
||||
<li>More coming soon...</li>
|
||||
<ul>`;
|
||||
const input = await callPopup(html, 'input', '', { okButton: 'Import', rows: 4 });
|
||||
|
@ -345,6 +345,40 @@ async function downloadJannyCharacter(uuid) {
|
||||
throw new Error('Failed to download character');
|
||||
}
|
||||
|
||||
//Download Character Cards from AICharactersCards.com (AICC) API.
|
||||
async function downloadAICCCharacter(id) {
|
||||
const apiURL = `https://aicharactercards.com/wp-json/pngapi/v1/image/${id}`;
|
||||
try {
|
||||
const response = await fetch(apiURL);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to download character: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const contentType = response.headers.get('content-type') || 'image/png'; // Default to 'image/png' if header is missing
|
||||
const buffer = await response.buffer();
|
||||
const fileName = `${sanitize(id)}.png`; // Assuming PNG, but adjust based on actual content or headers
|
||||
|
||||
return {
|
||||
buffer: buffer,
|
||||
fileName: fileName,
|
||||
fileType: contentType
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error downloading character:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function parseAICC(url) {
|
||||
const pattern = /^https?:\/\/aicharactercards\.com\/character-cards\/([^\/]+)\/([^\/]+)\/?$|([^\/]+)\/([^\/]+)$/;
|
||||
const match = url.match(pattern);
|
||||
if (match) {
|
||||
// Match group 1 & 2 for full URL, 3 & 4 for relative path
|
||||
return match[1] && match[2] ? `${match[1]}/${match[2]}` : `${match[3]}/${match[4]}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} url
|
||||
* @returns {String | null } UUID of the character
|
||||
@ -373,6 +407,7 @@ router.post('/importURL', jsonParser, async (request, response) => {
|
||||
|
||||
const isJannnyContent = url.includes('janitorai');
|
||||
const isPygmalionContent = url.includes('pygmalion.chat');
|
||||
const isAICharacterCardsContent = url.includes('aicharactercards.com');
|
||||
|
||||
if (isPygmalionContent) {
|
||||
const uuid = getUuidFromUrl(url);
|
||||
@ -390,6 +425,13 @@ router.post('/importURL', jsonParser, async (request, response) => {
|
||||
|
||||
type = 'character';
|
||||
result = await downloadJannyCharacter(uuid);
|
||||
} else if (isAICharacterCardsContent) {
|
||||
const AICCParsed = parseAICC(url);
|
||||
if (!AICCParsed) {
|
||||
return response.sendStatus(404);
|
||||
}
|
||||
type = 'character';
|
||||
result = await downloadAICCCharacter(AICCParsed);
|
||||
} else {
|
||||
const chubParsed = parseChubUrl(url);
|
||||
type = chubParsed?.type;
|
||||
@ -428,6 +470,7 @@ router.post('/importUUID', jsonParser, async (request, response) => {
|
||||
|
||||
const isJannny = uuid.includes('_character');
|
||||
const isPygmalion = (!isJannny && uuid.length == 36);
|
||||
const isAICC = uuid.startsWith('AICC/');
|
||||
const uuidType = uuid.includes('lorebook') ? 'lorebook' : 'character';
|
||||
|
||||
if (isPygmalion) {
|
||||
@ -436,6 +479,10 @@ router.post('/importUUID', jsonParser, async (request, response) => {
|
||||
} else if (isJannny) {
|
||||
console.log('Downloading Janitor character:', uuid.split('_')[0]);
|
||||
result = await downloadJannyCharacter(uuid.split('_')[0]);
|
||||
} else if (isAICC) {
|
||||
const [, author, card] = uuid.split('/');
|
||||
console.log('Downloading AICC character:', `${author}/${card}`);
|
||||
result = await downloadAICCCharacter(`${author}/${card}`);
|
||||
} else {
|
||||
if (uuidType === 'character') {
|
||||
console.log('Downloading chub character:', uuid);
|
||||
|
Loading…
x
Reference in New Issue
Block a user