mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
feat: add functionality to open file location from model modal and update translations, fixes #405
This commit is contained in:
@@ -678,7 +678,12 @@
|
||||
"editBaseModel": "Basis-Modell bearbeiten",
|
||||
"viewOnCivitai": "Auf Civitai anzeigen",
|
||||
"viewOnCivitaiText": "Auf Civitai anzeigen",
|
||||
"viewCreatorProfile": "Ersteller-Profil anzeigen"
|
||||
"viewCreatorProfile": "Ersteller-Profil anzeigen",
|
||||
"openFileLocation": "Dateispeicherort öffnen"
|
||||
},
|
||||
"openFileLocation": {
|
||||
"success": "Dateispeicherort erfolgreich geöffnet",
|
||||
"failed": "Fehler beim Öffnen des Dateispeicherorts"
|
||||
},
|
||||
"metadata": {
|
||||
"version": "Version",
|
||||
|
||||
@@ -678,7 +678,12 @@
|
||||
"editBaseModel": "Edit base model",
|
||||
"viewOnCivitai": "View on Civitai",
|
||||
"viewOnCivitaiText": "View on Civitai",
|
||||
"viewCreatorProfile": "View Creator Profile"
|
||||
"viewCreatorProfile": "View Creator Profile",
|
||||
"openFileLocation": "Open File Location"
|
||||
},
|
||||
"openFileLocation": {
|
||||
"success": "File location opened successfully",
|
||||
"failed": "Failed to open file location"
|
||||
},
|
||||
"metadata": {
|
||||
"version": "Version",
|
||||
|
||||
@@ -678,7 +678,12 @@
|
||||
"editBaseModel": "Editar modelo base",
|
||||
"viewOnCivitai": "Ver en Civitai",
|
||||
"viewOnCivitaiText": "Ver en Civitai",
|
||||
"viewCreatorProfile": "Ver perfil del creador"
|
||||
"viewCreatorProfile": "Ver perfil del creador",
|
||||
"openFileLocation": "Abrir ubicación del archivo"
|
||||
},
|
||||
"openFileLocation": {
|
||||
"success": "Ubicación del archivo abierta exitosamente",
|
||||
"failed": "Error al abrir la ubicación del archivo"
|
||||
},
|
||||
"metadata": {
|
||||
"version": "Versión",
|
||||
|
||||
@@ -678,7 +678,12 @@
|
||||
"editBaseModel": "Modifier le modèle de base",
|
||||
"viewOnCivitai": "Voir sur Civitai",
|
||||
"viewOnCivitaiText": "Voir sur Civitai",
|
||||
"viewCreatorProfile": "Voir le profil du créateur"
|
||||
"viewCreatorProfile": "Voir le profil du créateur",
|
||||
"openFileLocation": "Ouvrir l'emplacement du fichier"
|
||||
},
|
||||
"openFileLocation": {
|
||||
"success": "Emplacement du fichier ouvert avec succès",
|
||||
"failed": "Échec de l'ouverture de l'emplacement du fichier"
|
||||
},
|
||||
"metadata": {
|
||||
"version": "Version",
|
||||
|
||||
@@ -678,7 +678,12 @@
|
||||
"editBaseModel": "ベースモデルを編集",
|
||||
"viewOnCivitai": "Civitaiで表示",
|
||||
"viewOnCivitaiText": "Civitaiで表示",
|
||||
"viewCreatorProfile": "作成者プロフィールを表示"
|
||||
"viewCreatorProfile": "作成者プロフィールを表示",
|
||||
"openFileLocation": "ファイルの場所を開く"
|
||||
},
|
||||
"openFileLocation": {
|
||||
"success": "ファイルの場所を正常に開きました",
|
||||
"failed": "ファイルの場所を開くのに失敗しました"
|
||||
},
|
||||
"metadata": {
|
||||
"version": "バージョン",
|
||||
|
||||
@@ -678,7 +678,12 @@
|
||||
"editBaseModel": "베이스 모델 편집",
|
||||
"viewOnCivitai": "Civitai에서 보기",
|
||||
"viewOnCivitaiText": "Civitai에서 보기",
|
||||
"viewCreatorProfile": "제작자 프로필 보기"
|
||||
"viewCreatorProfile": "제작자 프로필 보기",
|
||||
"openFileLocation": "파일 위치 열기"
|
||||
},
|
||||
"openFileLocation": {
|
||||
"success": "파일 위치가 성공적으로 열렸습니다",
|
||||
"failed": "파일 위치 열기에 실패했습니다"
|
||||
},
|
||||
"metadata": {
|
||||
"version": "버전",
|
||||
|
||||
@@ -678,7 +678,12 @@
|
||||
"editBaseModel": "Редактировать базовую модель",
|
||||
"viewOnCivitai": "Посмотреть на Civitai",
|
||||
"viewOnCivitaiText": "Посмотреть на Civitai",
|
||||
"viewCreatorProfile": "Посмотреть профиль создателя"
|
||||
"viewCreatorProfile": "Посмотреть профиль создателя",
|
||||
"openFileLocation": "Открыть расположение файла"
|
||||
},
|
||||
"openFileLocation": {
|
||||
"success": "Расположение файла успешно открыто",
|
||||
"failed": "Не удалось открыть расположение файла"
|
||||
},
|
||||
"metadata": {
|
||||
"version": "Версия",
|
||||
|
||||
@@ -678,7 +678,12 @@
|
||||
"editBaseModel": "编辑基础模型",
|
||||
"viewOnCivitai": "在 Civitai 查看",
|
||||
"viewOnCivitaiText": "在 Civitai 查看",
|
||||
"viewCreatorProfile": "查看创作者主页"
|
||||
"viewCreatorProfile": "查看创作者主页",
|
||||
"openFileLocation": "打开文件位置"
|
||||
},
|
||||
"openFileLocation": {
|
||||
"success": "文件位置已成功打开",
|
||||
"failed": "打开文件位置失败"
|
||||
},
|
||||
"metadata": {
|
||||
"version": "版本",
|
||||
|
||||
@@ -678,7 +678,12 @@
|
||||
"editBaseModel": "編輯基礎模型",
|
||||
"viewOnCivitai": "在 Civitai 查看",
|
||||
"viewOnCivitaiText": "在 Civitai 查看",
|
||||
"viewCreatorProfile": "查看創作者個人檔案"
|
||||
"viewCreatorProfile": "查看創作者個人檔案",
|
||||
"openFileLocation": "開啟檔案位置"
|
||||
},
|
||||
"openFileLocation": {
|
||||
"success": "檔案位置已成功開啟",
|
||||
"failed": "開啟檔案位置失敗"
|
||||
},
|
||||
"metadata": {
|
||||
"version": "版本",
|
||||
|
||||
@@ -3,6 +3,7 @@ import os
|
||||
import sys
|
||||
import threading
|
||||
import asyncio
|
||||
import subprocess
|
||||
from server import PromptServer # type: ignore
|
||||
from aiohttp import web
|
||||
from ..services.settings_manager import settings
|
||||
@@ -90,6 +91,8 @@ class MiscRoutes:
|
||||
|
||||
app.router.add_get('/api/health-check', lambda request: web.json_response({'status': 'ok'}))
|
||||
|
||||
app.router.add_post('/api/open-file-location', MiscRoutes.open_file_location)
|
||||
|
||||
# Usage stats routes
|
||||
app.router.add_post('/api/update-usage-stats', MiscRoutes.update_usage_stats)
|
||||
app.router.add_get('/api/get-usage-stats', MiscRoutes.get_usage_stats)
|
||||
@@ -770,3 +773,54 @@ class MiscRoutes:
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}, status=500)
|
||||
|
||||
@staticmethod
|
||||
async def open_file_location(request):
|
||||
"""
|
||||
Open the folder containing the specified file and select the file in the file explorer.
|
||||
|
||||
Expects a JSON request body with:
|
||||
{
|
||||
"file_path": "absolute/path/to/file"
|
||||
}
|
||||
"""
|
||||
try:
|
||||
data = await request.json()
|
||||
file_path = data.get('file_path')
|
||||
|
||||
if not file_path:
|
||||
return web.json_response({
|
||||
'success': False,
|
||||
'error': 'Missing file_path parameter'
|
||||
}, status=400)
|
||||
|
||||
file_path = os.path.abspath(file_path)
|
||||
|
||||
if not os.path.isfile(file_path):
|
||||
return web.json_response({
|
||||
'success': False,
|
||||
'error': 'File does not exist'
|
||||
}, status=404)
|
||||
|
||||
# Open the folder and select the file
|
||||
if os.name == 'nt': # Windows
|
||||
# explorer /select,"C:\path\to\file"
|
||||
subprocess.Popen(['explorer', '/select,', file_path])
|
||||
elif os.name == 'posix':
|
||||
if sys.platform == 'darwin': # macOS
|
||||
subprocess.Popen(['open', '-R', file_path])
|
||||
else: # Linux (selecting file is not standard, just open folder)
|
||||
folder = os.path.dirname(file_path)
|
||||
subprocess.Popen(['xdg-open', folder])
|
||||
|
||||
return web.json_response({
|
||||
'success': True,
|
||||
'message': f'Opened folder and selected file: {file_path}'
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to open file location: {e}", exc_info=True)
|
||||
return web.json_response({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}, status=500)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
from aiohttp import web
|
||||
|
||||
@@ -67,6 +67,14 @@
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.file-path[data-action="open-file-location"] {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.file-path[data-action="open-file-location"]:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
line-height: 1.5;
|
||||
max-height: 100px;
|
||||
|
||||
@@ -166,10 +166,14 @@ export async function showModelModal(model, modelType) {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-item location-size">
|
||||
<div class="info-item">
|
||||
<div class="location-wrapper">
|
||||
<label>${translate('modals.model.metadata.location', {}, 'Location')}</label>
|
||||
<span class="file-path">${modelWithFullData.file_path.replace(/[^/]+$/, '') || 'N/A'}</span>
|
||||
<span class="file-path" title="${translate('modals.model.actions.openFileLocation', {}, 'Open file location')}"
|
||||
data-action="open-file-location"
|
||||
data-filepath="${modelWithFullData.file_path}">
|
||||
${modelWithFullData.file_path.replace(/[^/]+$/, '') || 'N/A'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-item base-size">
|
||||
@@ -318,6 +322,12 @@ function setupEventHandlers(filePath) {
|
||||
window.open(`https://civitai.com/user/${username}`, '_blank');
|
||||
}
|
||||
break;
|
||||
case 'open-file-location':
|
||||
const filePath = target.dataset.filepath;
|
||||
if (filePath) {
|
||||
openFileLocation(filePath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,6 +454,24 @@ async function saveNotes(filePath) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call backend to open file location and select the file
|
||||
* @param {string} filePath
|
||||
*/
|
||||
async function openFileLocation(filePath) {
|
||||
try {
|
||||
const resp = await fetch('/api/open-file-location', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ 'file_path': filePath })
|
||||
});
|
||||
if (!resp.ok) throw new Error('Failed to open file location');
|
||||
showToast('modals.model.openFileLocation.success', {}, 'success');
|
||||
} catch (err) {
|
||||
showToast('modals.model.openFileLocation.failed', {}, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Export the model modal API
|
||||
const modelModal = {
|
||||
show: showModelModal,
|
||||
|
||||
Reference in New Issue
Block a user