Add Deno version detection and caching support
Introduces functions to detect Deno version directly and with caching in ytsage_deno.py and ytsage_utils.py. Updates the About dialog to display Deno status, version, and path if available. Also extends version cache refresh logic to include Deno.
This commit is contained in:
@@ -462,6 +462,50 @@ def get_deno_path() -> Path:
|
|||||||
return "deno" # type: ignore[return-value]
|
return "deno" # type: ignore[return-value]
|
||||||
|
|
||||||
|
|
||||||
|
def get_deno_version_direct(deno_path=None) -> str:
|
||||||
|
"""
|
||||||
|
Get Deno version directly without caching.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
deno_path: Optional path to Deno binary. If None, uses get_deno_path()
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Version string or error message
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if deno_path is None:
|
||||||
|
deno_path = get_deno_path()
|
||||||
|
|
||||||
|
if not deno_path or deno_path == "deno":
|
||||||
|
return "Not found"
|
||||||
|
|
||||||
|
result = subprocess.run(
|
||||||
|
[str(deno_path), "--version"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10,
|
||||||
|
creationflags=SUBPROCESS_CREATIONFLAGS
|
||||||
|
)
|
||||||
|
|
||||||
|
if result.returncode == 0:
|
||||||
|
# Deno outputs: "deno 1.38.0 (release, x86_64-pc-windows-msvc)"
|
||||||
|
# Extract version from first line
|
||||||
|
lines = result.stdout.strip().split("\n")
|
||||||
|
if lines:
|
||||||
|
first_line = lines[0]
|
||||||
|
# Extract version number (e.g., "1.38.0" from "deno 1.38.0 ...")
|
||||||
|
parts = first_line.split()
|
||||||
|
if len(parts) >= 2 and parts[0] == "deno":
|
||||||
|
return parts[1]
|
||||||
|
return first_line.strip()
|
||||||
|
return "Unknown version"
|
||||||
|
else:
|
||||||
|
return "Error getting version"
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"Error getting Deno version: {e}")
|
||||||
|
return "Error getting version"
|
||||||
|
|
||||||
|
|
||||||
def setup_deno(parent_widget=None):
|
def setup_deno(parent_widget=None):
|
||||||
"""
|
"""
|
||||||
Show the Deno setup dialog and handle the result.
|
Show the Deno setup dialog and handle the result.
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ except ImportError:
|
|||||||
_version_cache = {
|
_version_cache = {
|
||||||
"ytdlp": {"version": None, "path": None, "last_check": 0, "path_mtime": 0},
|
"ytdlp": {"version": None, "path": None, "last_check": 0, "path_mtime": 0},
|
||||||
"ffmpeg": {"version": None, "path": None, "last_check": 0, "path_mtime": 0},
|
"ffmpeg": {"version": None, "path": None, "last_check": 0, "path_mtime": 0},
|
||||||
|
"deno": {"version": None, "path": None, "last_check": 0, "path_mtime": 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Cache expiry time in seconds (5 minutes)
|
# Cache expiry time in seconds (5 minutes)
|
||||||
@@ -173,8 +174,34 @@ def get_ffmpeg_version_cached() -> str:
|
|||||||
return "Error getting version"
|
return "Error getting version"
|
||||||
|
|
||||||
|
|
||||||
|
def get_deno_version_cached() -> str:
|
||||||
|
"""Get Deno version with caching support."""
|
||||||
|
try:
|
||||||
|
from src.core.ytsage_deno import get_deno_path
|
||||||
|
|
||||||
|
current_path = get_deno_path()
|
||||||
|
|
||||||
|
# Check if we need to refresh cache
|
||||||
|
if not should_refresh_cache("deno", current_path):
|
||||||
|
cached_version = _version_cache["deno"].get("version")
|
||||||
|
if cached_version:
|
||||||
|
return cached_version
|
||||||
|
|
||||||
|
# Get fresh version info
|
||||||
|
from src.core.ytsage_deno import get_deno_version_direct
|
||||||
|
version_info = get_deno_version_direct(current_path)
|
||||||
|
|
||||||
|
# Update cache
|
||||||
|
update_version_cache("deno", version_info, current_path)
|
||||||
|
|
||||||
|
return version_info
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"Error getting cached Deno version: {e}")
|
||||||
|
return "Error getting version"
|
||||||
|
|
||||||
|
|
||||||
def refresh_version_cache(force=False) -> bool:
|
def refresh_version_cache(force=False) -> bool:
|
||||||
"""Manually refresh version cache for both tools."""
|
"""Manually refresh version cache for all tools."""
|
||||||
try:
|
try:
|
||||||
# Refresh yt-dlp
|
# Refresh yt-dlp
|
||||||
current_path = get_yt_dlp_path()
|
current_path = get_yt_dlp_path()
|
||||||
@@ -185,6 +212,12 @@ def refresh_version_cache(force=False) -> bool:
|
|||||||
version_info = get_ffmpeg_version_direct()
|
version_info = get_ffmpeg_version_direct()
|
||||||
update_version_cache("ffmpeg", version_info, "ffmpeg", force_save=True)
|
update_version_cache("ffmpeg", version_info, "ffmpeg", force_save=True)
|
||||||
|
|
||||||
|
# Refresh Deno
|
||||||
|
from src.core.ytsage_deno import get_deno_path, get_deno_version_direct
|
||||||
|
deno_path = get_deno_path()
|
||||||
|
version_info = get_deno_version_direct(deno_path)
|
||||||
|
update_version_cache("deno", version_info, deno_path, force_save=True)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f"Error refreshing version cache: {e}")
|
logger.exception(f"Error refreshing version cache: {e}")
|
||||||
@@ -201,6 +234,11 @@ def get_ffmpeg_version() -> str:
|
|||||||
return get_ffmpeg_version_cached()
|
return get_ffmpeg_version_cached()
|
||||||
|
|
||||||
|
|
||||||
|
def get_deno_version() -> str:
|
||||||
|
"""Get the version of Deno (uses cached version for performance)."""
|
||||||
|
return get_deno_version_cached()
|
||||||
|
|
||||||
|
|
||||||
def get_ytdlp_version_direct(yt_dlp_path=None) -> str:
|
def get_ytdlp_version_direct(yt_dlp_path=None) -> str:
|
||||||
"""Get yt-dlp version directly without caching."""
|
"""Get yt-dlp version directly without caching."""
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ from src import __version__ as APP_VERSION
|
|||||||
from src.utils.ytsage_localization import _
|
from src.utils.ytsage_localization import _
|
||||||
|
|
||||||
from src.core.ytsage_ffmpeg import get_ffmpeg_path
|
from src.core.ytsage_ffmpeg import get_ffmpeg_path
|
||||||
from src.core.ytsage_utils import _version_cache, check_ffmpeg, get_ffmpeg_version, get_ytdlp_version, refresh_version_cache
|
from src.core.ytsage_utils import _version_cache, check_ffmpeg, get_ffmpeg_version, get_ytdlp_version, get_deno_version, refresh_version_cache
|
||||||
from src.core.ytsage_yt_dlp import check_ytdlp_installed, get_yt_dlp_path
|
from src.core.ytsage_yt_dlp import check_ytdlp_installed, get_yt_dlp_path
|
||||||
|
from src.core.ytsage_deno import check_deno_installed, get_deno_path
|
||||||
|
|
||||||
|
|
||||||
class LogWindow(QDialog):
|
class LogWindow(QDialog):
|
||||||
@@ -442,6 +443,42 @@ class AboutDialog(QDialog):
|
|||||||
)
|
)
|
||||||
self.status_container.addWidget(ffmpeg_item)
|
self.status_container.addWidget(ffmpeg_item)
|
||||||
|
|
||||||
|
# Deno Status - compact version with path (only show path if in app bin directory)
|
||||||
|
deno_found = check_deno_installed()
|
||||||
|
deno_status_text = (
|
||||||
|
f"<span style='color: #4CAF50;'>{_('about.detected')}</span>" if deno_found else f"<span style='color: #F44336;'>{_('about.missing')}</span>"
|
||||||
|
)
|
||||||
|
deno_version = get_deno_version() if deno_found else _('about.not_available')
|
||||||
|
|
||||||
|
# Get Deno path - only show if in app bin directory
|
||||||
|
deno_path_text = None
|
||||||
|
if deno_found:
|
||||||
|
deno_path = get_deno_path()
|
||||||
|
# Only show path if it's not the fallback "deno" and the file exists
|
||||||
|
if deno_path and deno_path != "deno":
|
||||||
|
from pathlib import Path
|
||||||
|
from src.utils.ytsage_constants import DENO_APP_BIN_PATH
|
||||||
|
# Check if the path is our managed binary
|
||||||
|
if Path(deno_path).resolve() == DENO_APP_BIN_PATH.resolve():
|
||||||
|
deno_path_text = deno_path
|
||||||
|
|
||||||
|
# Simplified cache status for Deno
|
||||||
|
deno_cache = _version_cache.get("deno", {})
|
||||||
|
last_check = deno_cache.get("last_check", 0)
|
||||||
|
cache_status = ""
|
||||||
|
if last_check > 0 and deno_found:
|
||||||
|
cache_time = datetime.fromtimestamp(last_check).strftime("%H:%M")
|
||||||
|
cache_status = f" <span style='color: #888; font-size: 10px;'>({cache_time})</span>"
|
||||||
|
|
||||||
|
deno_item = self._create_status_item(
|
||||||
|
"🦕",
|
||||||
|
"Deno",
|
||||||
|
deno_status_text,
|
||||||
|
deno_version + cache_status,
|
||||||
|
deno_path_text,
|
||||||
|
)
|
||||||
|
self.status_container.addWidget(deno_item)
|
||||||
|
|
||||||
def refresh_version_info(self) -> None:
|
def refresh_version_info(self) -> None:
|
||||||
"""Refresh version information manually."""
|
"""Refresh version information manually."""
|
||||||
self.refresh_btn.setText(_('about.refreshing'))
|
self.refresh_btn.setText(_('about.refreshing'))
|
||||||
|
|||||||
Reference in New Issue
Block a user