Read production LoRA names in Studio 2
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import { existsSync } from 'node:fs';
|
||||
import { studio2LoraCatalog } from '../../utils/studio2/lora-catalog';
|
||||
import { publicLibrary, stillPath, clipVideoPath } from '../../utils/library';
|
||||
export default defineEventHandler(event => {
|
||||
const { owner } = assertLibraryOwner(event);
|
||||
const library = publicLibrary(event);
|
||||
return {...library, stills:library.stills.filter(s=>existsSync(stillPath(owner,s.id))), clips:library.clips.filter(c=>existsSync(clipVideoPath(owner,c.id)))};
|
||||
const catalog=studio2LoraCatalog(owner);
|
||||
return {...library,loraAliases:catalog.aliases,loraTriggers:catalog.triggers, stills:library.stills.filter(s=>existsSync(stillPath(owner,s.id))), clips:library.clips.filter(c=>existsSync(clipVideoPath(owner,c.id)))};
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ import { join } from 'node:path';
|
||||
import { cachedLoras } from '~/shared/studio2/lora-cache.mjs';
|
||||
import { listStudioLoras } from '../../utils/loras';
|
||||
import { studio2Root } from '../../utils/studio2/store';
|
||||
import { getLoraAliases, getLoraTriggers } from '../../utils/library';
|
||||
import { studio2LoraCatalog } from '../../utils/studio2/lora-catalog';
|
||||
export default defineEventHandler(async event => {
|
||||
const {owner}=assertLibraryOwner(event),path=join(studio2Root(),`loras-${owner}.cache`);
|
||||
const listed=await cachedLoras({
|
||||
@@ -11,5 +11,5 @@ export default defineEventHandler(async event => {
|
||||
write:value=>{writeFileSync(path+'.tmp',JSON.stringify(value));renameSync(path+'.tmp',path);},
|
||||
live:()=>listStudioLoras({fresh:true}),fresh:getQuery(event).fresh==='1'
|
||||
});
|
||||
return {...listed,aliases:getLoraAliases(owner),triggers:getLoraTriggers(owner)};
|
||||
return {...listed,...studio2LoraCatalog(owner)};
|
||||
});
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
"""Export only LoRA labels/triggers; invoked by the host's catalog change watcher."""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
def export(source, destination):
|
||||
catalog = json.loads(Path(source).read_text())
|
||||
result = {key: {name: value for name, value in catalog.get(key, {}).items()
|
||||
if isinstance(value, str)} for key in ('loraAliases', 'loraTriggers')}
|
||||
target = Path(destination)
|
||||
content = json.dumps(result, ensure_ascii=False)
|
||||
if target.exists() and target.read_text() == content:
|
||||
return
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
temporary = target.with_suffix('.tmp')
|
||||
temporary.write_text(content)
|
||||
os.chmod(temporary, 0o644)
|
||||
temporary.replace(target)
|
||||
|
||||
if __name__ == '__main__':
|
||||
export(*sys.argv[1:])
|
||||
@@ -0,0 +1,15 @@
|
||||
import {readFileSync} from 'node:fs';
|
||||
import {getLoraAliases,getLoraTriggers} from '../library';
|
||||
import {loraIdentityKey} from '~/utils/loras';
|
||||
import {join} from 'node:path';
|
||||
import {studio2Root} from './store';
|
||||
|
||||
/** Optional metadata-only production export; no production media/catalog mount. */
|
||||
export function studio2LoraCatalog(owner: string) {
|
||||
const local={aliases:getLoraAliases(owner),triggers:getLoraTriggers(owner)};
|
||||
try {
|
||||
const source=JSON.parse(readFileSync(process.env.STUDIO2_LORA_CATALOG_PATH || join(studio2Root(),'shared-lora-catalog.cache'),'utf8'));
|
||||
const normalize=(map: any)=>Object.fromEntries(Object.entries(map || {}).filter(([,value])=>typeof value==='string').map(([key,value])=>[loraIdentityKey(key),value]));
|
||||
return {aliases:{...local.aliases,...normalize(source.loraAliases)},triggers:{...local.triggers,...normalize(source.loraTriggers)}};
|
||||
} catch { return local; }
|
||||
}
|
||||
Reference in New Issue
Block a user