From 815f93d3ed9646fd34842c6cd243d0e24fbbdd12 Mon Sep 17 00:00:00 2001 From: Vali98 Date: Thu, 22 Aug 2024 22:19:37 +0800 Subject: [PATCH] fix: remote importing --- app/constants/APIState/KoboldAPI.ts | 8 +-- app/constants/Characters.ts | 75 ++++++++++++++++------------- package-lock.json | 47 ------------------ package.json | 1 - 4 files changed, 43 insertions(+), 88 deletions(-) diff --git a/app/constants/APIState/KoboldAPI.ts b/app/constants/APIState/KoboldAPI.ts index 610795d..124cd0f 100644 --- a/app/constants/APIState/KoboldAPI.ts +++ b/app/constants/APIState/KoboldAPI.ts @@ -2,7 +2,6 @@ import { Global } from '@constants/GlobalValues' import { Logger } from 'app/constants/Logger' import { mmkv } from 'app/constants/MMKV' import { SamplerID } from 'app/constants/SamplerData' -import axios from 'axios' import { APIBase, APISampler } from './BaseAPI' @@ -58,12 +57,7 @@ class KoboldAPI extends APIBase { return JSON.parse(item).token }, () => { - axios - .create({ timeout: 1000 }) - .post(new URL('/api/extra/abort', endpoint).toString()) - .catch(() => { - Logger.log(`Abort signal failed`) - }) + fetch(new URL('/api/extra/abort', endpoint).toString(), { method: 'GET' }) } ) } diff --git a/app/constants/Characters.ts b/app/constants/Characters.ts index 18d4f3a..a3d805c 100644 --- a/app/constants/Characters.ts +++ b/app/constants/Characters.ts @@ -1,6 +1,5 @@ import { db as database } from '@db' -import { copyFileRes } from '@dr.pogodin/react-native-fs' -import axios from 'axios' +import { copyFileRes, writeFile } from '@dr.pogodin/react-native-fs' import { characterGreetings, characterTags, characters, tags } from 'db/schema' import { eq, inArray, notInArray } from 'drizzle-orm' import { randomUUID } from 'expo-crypto' @@ -300,10 +299,13 @@ export namespace Characters { }) .returning({ id: characters.id, image_id: characters.image_id }) - const greetingdata = data.alternate_greetings.map((item) => ({ - character_id: id, - greeting: item, - })) + const greetingdata = + typeof data?.alternate_greetings === 'object' + ? data?.alternate_greetings?.map((item) => ({ + character_id: id, + greeting: item, + })) ?? [] + : [] if (greetingdata.length > 0) for (const greeting of greetingdata) await tx.insert(characterGreetings).values(greeting) @@ -400,22 +402,23 @@ export namespace Characters { export const importCharacterFromChub = async (character_id: string) => { Logger.log(`Importing character from Chub: ${character_id}`, true) try { - const res = await axios.create({ timeout: 10000 }).post( - 'https://api.chub.ai/api/characters/download', - { + const res = await fetch('https://api.chub.ai/api/characters/download', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ format: 'tavern', fullPath: character_id, - }, - { responseType: 'arraybuffer' } - ) - - const response = Buffer.from(res.data, 'base64').toString('base64') - const uuid = randomUUID() - return FS.writeAsStringAsync(`${FS.cacheDirectory}${uuid}.png`, response, { - encoding: FS.EncodingType.Base64, - }).then(async () => { - return createCharacterFromImage(`${FS.cacheDirectory}${uuid}.png`) + }), }) + const data = await res.arrayBuffer() + const dataArray = new Uint8Array(data) + let binaryString = '' + dataArray.forEach((byte) => (binaryString += String.fromCharCode(byte))) + const cardCacheDir = `${FS.cacheDirectory}${randomUUID()}.png` + await writeFile(cardCacheDir, btoa(binaryString), 'base64') + return createCharacterFromImage(cardCacheDir) } catch (error) { Logger.log(`Could not retreive card. ${error}`) } @@ -424,40 +427,48 @@ export namespace Characters { export const importCharacterFromPyg = async (character_id: string) => { Logger.log(`Loading from Pygmalion with id: ${character_id}`, true) - const data = await fetch( + const query = await fetch( `https://server.pygmalion.chat/api/export/character/${character_id}/v2`, { method: 'GET', headers: { accept: 'application/json', - 'content-type': 'application/json', + 'Content-Type': 'application/json', }, } ) - if (data.status !== 200) { - Logger.log(`Failed to retrieve card from Pygmalion: ${data.status}`, true) + if (query.status !== 200) { + Logger.log(`Failed to retrieve card from Pygmalion: ${query.status}`, true) return } - const { character } = await data.json() + const { character } = await query.json() const res = await fetch(character.data.avatar, { method: 'GET', }) - const buffer = await res.arrayBuffer() - const image = Buffer.from(buffer).toString('base64') + const data = await res.arrayBuffer() + const dataArray = new Uint8Array(data) + let binaryString = '' + dataArray.forEach((byte) => (binaryString += String.fromCharCode(byte))) const uuid = randomUUID() - return FS.writeAsStringAsync(`${FS.cacheDirectory}${uuid}.png`, image, { - encoding: FS.EncodingType.Base64, - }).then(async () => { - return db.mutate.createCharacter(character, `${FS.cacheDirectory}${uuid}.png`) - }) + + await writeFile(`${FS.cacheDirectory}${uuid}.png`, btoa(binaryString), 'base64') + await db.mutate.createCharacter(character, `${FS.cacheDirectory}${uuid}.png`) + Logger.log('Imported Character: ' + character.data.name) } export const importCharacterFromRemote = async (text: string) => { // UUID standard RFC 4122, only used by pyg for now const uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/ + + if (uuidRegex.test(text)) { + return importCharacterFromPyg(text) + } + + if (/^[^/]+\/[^/]+$/.test(text)) return importCharacterFromChub(text) + const url = new URL(text) if (/pygmalion.chat/.test(url.hostname)) { const param = new URLSearchParams(text) @@ -481,8 +492,6 @@ export namespace Characters { } // Regex checks for format of [name][/][character] - if (/^[^/]+\/[^/]+$/.test(text)) return importCharacterFromChub(text) - if (uuidRegex.test(text)) return importCharacterFromPyg(text) Logger.log(`URL not recognized`, true) } diff --git a/package-lock.json b/package-lock.json index 067b5a9..37c28e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,6 @@ "@react-navigation/drawer": "^6.6.4", "@react-navigation/native": "^6.0.2", "@shopify/flash-list": "1.6.4", - "axios": "^1.7.4", "babel-plugin-inline-import": "^3.0.0", "babel-plugin-react-compiler": "^0.0.0-experimental-696af53-20240625", "cui-llama.rn": "^1.1.1", @@ -12824,29 +12823,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axios/node_modules/form-data": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -18466,25 +18442,6 @@ "node": ">=0.4.0" } }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/fontfaceobserver": { "version": "2.3.0", "license": "BSD-2-Clause" @@ -25994,10 +25951,6 @@ "react-is": "^16.13.1" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "license": "MIT" - }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", diff --git a/package.json b/package.json index 7a3c332..61845a0 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ "@react-navigation/drawer": "^6.6.4", "@react-navigation/native": "^6.0.2", "@shopify/flash-list": "1.6.4", - "axios": "^1.7.4", "babel-plugin-inline-import": "^3.0.0", "babel-plugin-react-compiler": "^0.0.0-experimental-696af53-20240625", "cui-llama.rn": "^1.1.1",