Add File Import URL (#640)
# PR Checklist Testing conducted in both Node environments. Due to some Tauri code under development, testing was performed on a previous commit before rewriting. # Description Add Import URLs for characters, modules, presets, etc., to RisuAI. These URLs can be used for purposes such as shortening when sharing character files, aiming to minimize external leakage of character files. It seems like it could be useful in character card sharing communities. Due to the large size of import files, a CORS proxy was not used, but it could be added if required.
This commit is contained in:
@@ -301,6 +301,14 @@ export async function characterURLImport() {
|
||||
|
||||
|
||||
const hash = location.hash
|
||||
if(hash.startsWith('#import=')){
|
||||
const url = hash.replace('#import=', '')
|
||||
const res = await fetch(url, {
|
||||
method: 'GET',
|
||||
})
|
||||
const data = new Uint8Array(await res.arrayBuffer())
|
||||
importFile(getFileName(res), data)
|
||||
}
|
||||
if(hash.startsWith('#import_module=')){
|
||||
const data = hash.replace('#import_module=', '')
|
||||
const importData = JSON.parse(Buffer.from(decodeURIComponent(data), 'base64').toString('utf-8'))
|
||||
@@ -375,31 +383,7 @@ export async function characterURLImport() {
|
||||
for(const f of files){
|
||||
const file = await f.getFile()
|
||||
const data = new Uint8Array(await file.arrayBuffer())
|
||||
if(f.name.endsWith('.charx')){
|
||||
await importCharacterProcess({
|
||||
name: f.name,
|
||||
data: data
|
||||
})
|
||||
}
|
||||
if(f.name.endsWith('.risupreset') || f.name.endsWith('.risup')){
|
||||
await importPreset({
|
||||
name: f.name,
|
||||
data: data
|
||||
})
|
||||
SettingsMenuIndex.set(1)
|
||||
settingsOpen.set(true)
|
||||
alertNormal(language.successImport)
|
||||
}
|
||||
if(f.name.endsWith('risum')){
|
||||
const md = await readModule(Buffer.from(data))
|
||||
md.id = v4()
|
||||
const db = get(DataBase)
|
||||
db.modules.push(md)
|
||||
setDatabase(db)
|
||||
alertNormal(language.successImport)
|
||||
SettingsMenuIndex.set(14)
|
||||
settingsOpen.set(true)
|
||||
}
|
||||
importFile(f.name, data);
|
||||
}
|
||||
}
|
||||
//@ts-ignore
|
||||
@@ -417,31 +401,7 @@ export async function characterURLImport() {
|
||||
if(files){
|
||||
for(const file of files){
|
||||
const data = await readFile(file)
|
||||
if(file.endsWith('.charx')){
|
||||
await importCharacterProcess({
|
||||
name: file,
|
||||
data: data
|
||||
})
|
||||
}
|
||||
if(file.endsWith('.risupreset') || file.endsWith('.risup')){
|
||||
await importPreset({
|
||||
name: file,
|
||||
data: data
|
||||
})
|
||||
SettingsMenuIndex.set(1)
|
||||
settingsOpen.set(true)
|
||||
alertNormal(language.successImport)
|
||||
}
|
||||
if(file.endsWith('risum')){
|
||||
const md = await readModule(Buffer.from(data))
|
||||
md.id = v4()
|
||||
const db = get(DataBase)
|
||||
db.modules.push(md)
|
||||
setDatabase(db)
|
||||
alertNormal(language.successImport)
|
||||
SettingsMenuIndex.set(14)
|
||||
settingsOpen.set(true)
|
||||
}
|
||||
importFile(file, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -460,6 +420,64 @@ export async function characterURLImport() {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function importFile(name:string, data:Uint8Array) {
|
||||
if(name.endsWith('.charx') || name.endsWith('.png')){
|
||||
await importCharacterProcess({
|
||||
name: name,
|
||||
data: data
|
||||
})
|
||||
return
|
||||
}
|
||||
if(name.endsWith('.risupreset') || name.endsWith('.risup')){
|
||||
await importPreset({
|
||||
name: name,
|
||||
data: data
|
||||
})
|
||||
SettingsMenuIndex.set(1)
|
||||
settingsOpen.set(true)
|
||||
alertNormal(language.successImport)
|
||||
return
|
||||
}
|
||||
if(name.endsWith('risum')){
|
||||
const md = await readModule(Buffer.from(data))
|
||||
md.id = v4()
|
||||
const db = get(DataBase)
|
||||
db.modules.push(md)
|
||||
setDatabase(db)
|
||||
alertNormal(language.successImport)
|
||||
SettingsMenuIndex.set(14)
|
||||
settingsOpen.set(true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function getFileName(res : Response) : string {
|
||||
return getFormContent(res.headers.get('content-disposition')) || getFromURL(res.url);
|
||||
|
||||
function getFormContent(contentDisposition : string) {
|
||||
if (!contentDisposition) return null;
|
||||
const pattern = /filename\*=UTF-8''([^"';\n]+)|filename[^;\n=]*=["']?([^"';\n]+)["']?/;
|
||||
const matches = contentDisposition.match(pattern);
|
||||
if (matches) {
|
||||
if (matches[1]) {
|
||||
return decodeURIComponent(matches[1]);
|
||||
} else if (matches[2]) {
|
||||
return matches[2];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getFromURL(url : string) : string {
|
||||
try {
|
||||
const path = new URL(url).pathname;
|
||||
return path.substring(path.lastIndexOf('/') + 1);
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user