mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-24 14:42:11 -03:00
Implement paginated LoRA data fetching with caching and infinite scroll
This commit is contained in:
@@ -1,15 +1,91 @@
|
||||
import os
|
||||
import logging
|
||||
from typing import List, Dict
|
||||
import time
|
||||
from typing import List, Dict, Optional
|
||||
from dataclasses import dataclass
|
||||
from operator import itemgetter
|
||||
from ..config import config
|
||||
from ..utils.file_utils import load_metadata, get_file_info, save_metadata
|
||||
from ..utils.lora_metadata import extract_lora_metadata
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@dataclass
|
||||
class LoraCache:
|
||||
"""Cache structure for LoRA data"""
|
||||
raw_data: List[Dict]
|
||||
sorted_by_name: List[Dict]
|
||||
sorted_by_date: List[Dict]
|
||||
folders: List[str]
|
||||
timestamp: float
|
||||
|
||||
class LoraScanner:
|
||||
"""Service for scanning and managing LoRA files"""
|
||||
|
||||
def __init__(self):
|
||||
self._cache: Optional[LoraCache] = None
|
||||
self.cache_ttl = 300 # 5 minutes cache TTL
|
||||
|
||||
async def get_cached_data(self, force_refresh: bool = False) -> LoraCache:
|
||||
"""Get cached LoRA data, refresh if needed"""
|
||||
current_time = time.time()
|
||||
|
||||
if (self._cache is None or
|
||||
force_refresh or
|
||||
current_time - self._cache.timestamp > self.cache_ttl):
|
||||
|
||||
# Scan for new data
|
||||
raw_data = await self.scan_all_loras()
|
||||
|
||||
# Create sorted views
|
||||
sorted_by_name = sorted(raw_data, key=itemgetter('model_name'))
|
||||
sorted_by_date = sorted(raw_data, key=itemgetter('modified'), reverse=True)
|
||||
folders = sorted(list(set(l['folder'] for l in raw_data)))
|
||||
|
||||
# Update cache
|
||||
self._cache = LoraCache(
|
||||
raw_data=raw_data,
|
||||
sorted_by_name=sorted_by_name,
|
||||
sorted_by_date=sorted_by_date,
|
||||
folders=folders,
|
||||
timestamp=current_time
|
||||
)
|
||||
|
||||
return self._cache
|
||||
|
||||
async def get_paginated_data(self,
|
||||
page: int,
|
||||
page_size: int,
|
||||
sort_by: str = 'date',
|
||||
folder: Optional[str] = None) -> Dict:
|
||||
"""Get paginated LoRA data"""
|
||||
cache = await self.get_cached_data()
|
||||
|
||||
# Select sorted data based on sort_by parameter
|
||||
data = (cache.sorted_by_date if sort_by == 'date'
|
||||
else cache.sorted_by_name)
|
||||
|
||||
# Apply folder filter if specified
|
||||
if folder is not None:
|
||||
data = [item for item in data if item['folder'] == folder]
|
||||
|
||||
# Calculate pagination
|
||||
total_items = len(data)
|
||||
start_idx = (page - 1) * page_size
|
||||
end_idx = min(start_idx + page_size, total_items)
|
||||
|
||||
return {
|
||||
'items': data[start_idx:end_idx],
|
||||
'total': total_items,
|
||||
'page': page,
|
||||
'page_size': page_size,
|
||||
'total_pages': (total_items + page_size - 1) // page_size
|
||||
}
|
||||
|
||||
def invalidate_cache(self):
|
||||
"""Invalidate the current cache"""
|
||||
self._cache = None
|
||||
|
||||
async def scan_all_loras(self) -> List[Dict]:
|
||||
"""Scan all LoRA directories and return metadata"""
|
||||
all_loras = []
|
||||
|
||||
Reference in New Issue
Block a user