Add refresh loras

This commit is contained in:
Will Miao
2025-01-26 23:32:17 +08:00
parent 72e121c145
commit 0c80555cc7
4 changed files with 79 additions and 17 deletions

View File

@@ -161,6 +161,7 @@ class LorasEndpoint:
"folder": lora["folder"],
"sha256": lora["sha256"],
"file_path": lora["file_path"],
"modified": lora["modified"],
"civitai": lora.get("civitai", {}) or {} # 确保当 civitai 为 None 时返回空字典
}
except Exception as e:
@@ -174,6 +175,7 @@ class LorasEndpoint:
"folder": lora.get("folder", ""),
"sha256": lora.get("sha256", ""),
"file_path": lora.get("file_path", ""),
"modified": lora.get("modified", ""),
"civitai": {
"id": "",
"modelId": "",
@@ -289,14 +291,17 @@ class LorasEndpoint:
# 更新模型名称优先使用CivitAI名称
if 'model' in civitai_metadata:
local_metadata['model_name'] = civitai_metadata['model'].get('name', local_metadata.get('model_name'))
# update base model
local_metadata['base_model'] = civitai_metadata.get('baseModel')
# 4. 下载预览图
first_image = next((img for img in civitai_metadata.get('images', []) if img.get('type') == 'image'), None)
if first_image:
preview_extension = os.path.splitext(first_image['url'])[-1] # Get the image file extension
first_preview = next((img for img in civitai_metadata.get('images', [])), None)
if first_preview:
preview_extension = '.mp4' if first_preview['type'] == 'video' else os.path.splitext(first_preview['url'])[-1] # Get the file extension
preview_filename = os.path.splitext(os.path.basename(data['file_path']))[0] + preview_extension
preview_path = os.path.join(os.path.dirname(data['file_path']), preview_filename)
await client.download_preview_image(first_image['url'], preview_path)
await client.download_preview_image(first_preview['url'], preview_path)
# 存储相对路径,使用正斜杠格式
local_metadata['preview_url'] = os.path.relpath(preview_path, self.loras_root).replace(os.sep, '/')

View File

@@ -2,15 +2,13 @@
function sortCards(sortBy) {
const grid = document.getElementById('loraGrid');
const cards = Array.from(grid.children);
cards.sort((a, b) => {
switch(sortBy) {
case 'name':
return a.dataset.name.localeCompare(b.dataset.name);
case 'date':
return new Date(b.dataset.date) - new Date(a.dataset.date);
case 'size':
return parseFloat(b.dataset.size) - parseFloat(a.dataset.size);
return b.dataset.modified - a.dataset.modified;
}
});
@@ -19,13 +17,59 @@ function sortCards(sortBy) {
// 刷新功能
async function refreshLoras() {
const loadingOverlay = document.getElementById('loading-overlay');
const loraGrid = document.getElementById('loraGrid');
const currentSort = document.getElementById('sortSelect').value;
const activeFolder = document.querySelector('.tag.active')?.dataset.folder;
try {
// Show loading overlay
loadingOverlay.style.display = 'flex';
// Fetch new data
const response = await fetch('/loras?refresh=true');
if (response.ok) {
location.reload();
if (!response.ok) throw new Error('Refresh failed');
// Parse the HTML response
const parser = new DOMParser();
const doc = parser.parseFromString(await response.text(), 'text/html');
// Get the new lora cards
const newLoraGrid = doc.getElementById('loraGrid');
// Update the grid content
loraGrid.innerHTML = newLoraGrid.innerHTML;
// Re-attach click listeners to new cards
document.querySelectorAll('.lora-card').forEach(card => {
card.addEventListener('click', () => {
const meta = JSON.parse(card.dataset.meta || '{}');
if (Object.keys(meta).length > 0) {
showModal(meta);
}
});
});
// Re-apply current sorting
sortCards(currentSort);
// Re-apply current folder filter if any
if (activeFolder) {
document.querySelectorAll('.lora-card').forEach(card => {
if (card.getAttribute('data-folder') === activeFolder) {
card.style.display = '';
} else {
card.style.display = 'none';
}
});
}
} catch (error) {
console.error('Refresh failed:', error);
alert('Failed to refresh loras');
} finally {
// Hide loading overlay
loadingOverlay.style.display = 'none';
}
}
@@ -94,10 +138,16 @@ async function deleteModel(fileName) {
}
// 初始化排序
document.getElementById('sortSelect').addEventListener('change', (e) => {
document.getElementById('sortSelect')?.addEventListener('change', (e) => {
sortCards(e.target.value);
});
// 立即执行初始排序
const sortSelect = document.getElementById('sortSelect');
if (sortSelect) {
sortCards(sortSelect.value);
}
// 添加搜索功能
document.getElementById('searchInput')?.addEventListener('input', (e) => {
const term = e.target.value.toLowerCase();
@@ -123,9 +173,9 @@ function showModal(lora) {
const modal = document.getElementById('loraModal');
modal.innerHTML = `
<div class="modal-content">
<h2>${lora.name}</h2>
<h2>${lora.model.name}</h2>
<div class="carousel">
${lora.images.map(img => `<img src="${img}" alt="Preview">`).join('')}
${lora.images.map(img => `<img src="${img.url}" alt="Preview">`).join('')}
</div>
<div class="description">${lora.description}</div>
<button class="close" onclick="closeModal()">&times;</button>

View File

@@ -37,7 +37,6 @@
<select id="sortSelect">
<option value="name">Name</option>
<option value="date">Date</option>
<option value="size">Size</option>
</select>
<button onclick="refreshLoras()"><i class="fas fa-sync"></i> Refresh</button>
<button onclick="fetchCivitai()" class="secondary"><i class="fas fa-download"></i> Fetch</button>
@@ -54,9 +53,17 @@
data-name="{{ lora.model_name }}"
data-file_name="{{ lora.file_name }}"
data-folder="{{ lora.folder }}"
data-modified="{{ lora.modified }}"
data-meta="{{ lora.civitai | default({}) | tojson | forceescape }}">
<div class="card-preview">
<img src="{{ ('/loras_static/previews/' + lora.preview_url) if lora.preview_url else '/loras_static/images/no-preview.png' }}" alt="{{ lora.name }}">
{% if lora.preview_url.endswith('.mp4') or lora.preview_url.endswith('.webm') %}
<video controls>
<source src="{{ '/loras_static/previews/' + lora.preview_url }}" type="video/mp4">
Your browser does not support the video tag.
</video>
{% else %}
<img src="{{ ('/loras_static/previews/' + lora.preview_url) if lora.preview_url else '/loras_static/images/no-preview.png' }}" alt="{{ lora.name }}">
{% endif %}
<div class="card-header">
<span class="base-model-label" title="{{ lora.base_model }}">
{{ lora.base_model }}
@@ -89,6 +96,6 @@
</div>
</div>
<script src="/loras_static/js/script.js"></script>
<script src="/loras_static/js/script.js" defer></script>
</body>
</html>

View File

@@ -6,7 +6,7 @@ BASE_MODEL_MAPPING = {
"sd-v2-1": "SD2.1",
"sdxl": "SDXL",
"sd-v2": "SD2.0",
"flux1": "Flux1.D",
"flux1": "Flux.1 D",
}
def determine_base_model(version_string: Optional[str]) -> str: