Fix #4312 mostly functional chub import

979fe60ebca7ff529f8b5b0a6e2649ab72b7c9f0

Cohee <18619528+Cohee1207@users.noreply.github.com>

1 files changed, +38 -15Ignore whitespace
src/endpoints/content-manager.js+38 -15
@@ -369,7 +369,7 @@ async function downloadChubLorebook(id) {
369369
370async function downloadChubCharacter(id) {370async function downloadChubCharacter(id) {
371 const [creatorName, projectName] = id.split('/');371 const [creatorName, projectName] = id.split('/');
372 const result = await fetch(`https://api.chub.ai/api/characters/${creatorName}/${projectName}`, {372 const result = await fetch(`https://api.chub.ai/api/characters/${creatorName}/${projectName}?full=true`, {
373 method: 'GET',373 method: 'GET',
374 headers: { 'Accept': 'application/json', 'User-Agent': USER_AGENT },374 headers: { 'Accept': 'application/json', 'User-Agent': USER_AGENT },
375 });375 });
@@ -382,25 +382,48 @@ async function downloadChubCharacter(id) {
382382
383 /** @type {any} */383 /** @type {any} */
384 const metadata = await result.json();384 const metadata = await result.json();
385 const downloadUrl = metadata.node?.max_res_url;385 const { definition, topics } = metadata.node;
386
387 /** @type {TavernCardV2} */
388 const characterCard = {
389 data: {
390 name: definition.name,
391 description: definition.personality,
392 personality: definition.tavern_personality,
393 scenario: definition.scenario,
394 first_mes: definition.first_message,
395 mes_example: definition.example_dialogs,
396 creator_notes: definition.description,
397 system_prompt: definition.system_prompt,
398 post_history_instructions: definition.post_history_instructions,
399 alternate_greetings: definition.alternate_greetings,
400 tags: topics,
401 creator: creatorName,
402 character_version: '',
403 character_book: definition.embedded_lorebook,
404 extensions: definition.extensions,
405 },
406 spec: 'chara_card_v2',
407 spec_version: '2.0',
408 };
386409
387 if (!downloadUrl) {410 const defaultAvatarPath = path.join(serverDirectory, DEFAULT_AVATAR_PATH);
388 throw new Error('Download URL not found in character metadata');411 const defaultAvatarBuffer = fs.readFileSync(defaultAvatarPath);
389 }
390412
391 const downloadResult = await fetch(downloadUrl);413 let imageBuffer = defaultAvatarBuffer;
392414
393 if (!downloadResult.ok) {415 const imageUrl = metadata.node?.max_res_url;
394 const text = await downloadResult.text();416
395 console.error('Chub returned error', downloadResult.statusText, text);417 if (imageUrl) {
396 throw new Error('Failed to download character');418 const downloadResult = await fetch(imageUrl);
419 if (downloadResult.ok) {
420 imageBuffer = Buffer.from(await downloadResult.arrayBuffer());
421 }
397 }422 }
398423
399 const buffer = Buffer.from(await downloadResult.arrayBuffer());424 const buffer = write(imageBuffer, JSON.stringify(characterCard));
400 const fileName =425 const fileName = `${sanitize(characterCard.data.name)}.png`;
401 downloadResult.headers.get('content-disposition')?.split('filename=')[1]?.replace(/["']/g, '') ||426 const fileType = 'image/png';
402 `${sanitize(projectName)}.png`;
403 const fileType = downloadResult.headers.get('content-type');
404427
405 return { buffer, fileName, fileType };428 return { buffer, fileName, fileType };
406}429}