Improve yt-dlp version detection and binary management

Refactored version detection to use importlib.metadata when available, with fallback to pkg_resources for older Python versions. Enhanced app-managed binary detection by safely comparing paths and handling missing files, improving robustness in update logic for both core and GUI update threads.
This commit is contained in:
Your Name
2025-09-04 00:16:02 +03:00
parent b8af75848d
commit 90b173c389
2 changed files with 83 additions and 14 deletions
+34 -4
View File
@@ -6,7 +6,21 @@ import tempfile
import time
from pathlib import Path
import pkg_resources
try:
from importlib.metadata import version as importlib_version
from importlib.metadata import PackageNotFoundError as ImportlibPackageNotFoundError
def get_version(package_name: str) -> str:
return importlib_version(package_name)
PackageNotFoundError = ImportlibPackageNotFoundError
except ImportError:
# Fallback for older Python versions
import pkg_resources
def get_version(package_name: str) -> str:
return pkg_resources.get_distribution(package_name).version
PackageNotFoundError = pkg_resources.DistributionNotFound
import requests
from packaging import version
@@ -422,7 +436,23 @@ def update_yt_dlp() -> bool:
# Extra logic moved to src\utils\ytsage_constants.py
# For binaries downloaded with our app, use direct binary update approach
if yt_dlp_path.samefile(YTDLP_APP_BIN_PATH):
# Check if this is an app-managed binary by comparing paths safely
is_app_managed = False
try:
# Only compare if both files exist
if yt_dlp_path.exists() and YTDLP_APP_BIN_PATH.exists():
is_app_managed = yt_dlp_path.samefile(YTDLP_APP_BIN_PATH)
elif str(yt_dlp_path) == str(YTDLP_APP_BIN_PATH):
# If paths are identical as strings, consider it app-managed
is_app_managed = True
else:
# If app binary doesn't exist, this is definitely not app-managed
is_app_managed = False
except (OSError, IOError) as e:
logger.debug(f"Error comparing paths in update_yt_dlp: {e}")
is_app_managed = False
if is_app_managed:
# We're using a binary installed by our app, update directly
logger.info(f"Updating yt-dlp binary at {yt_dlp_path}")
@@ -468,9 +498,9 @@ def update_yt_dlp() -> bool:
# Get current version
try:
current_version = pkg_resources.get_distribution("yt-dlp").version
current_version = get_version("yt-dlp")
logger.info(f"Current yt-dlp version: {current_version}")
except pkg_resources.DistributionNotFound:
except PackageNotFoundError:
logger.info("yt-dlp not installed via pip, attempting update anyway")
current_version = "0.0.0" # Assume very old version to force update
@@ -19,6 +19,21 @@ from src.core.ytsage_utils import get_ytdlp_version, load_config, save_config
from src.core.ytsage_yt_dlp import get_yt_dlp_path
from src.utils.ytsage_constants import OS_NAME, SUBPROCESS_CREATIONFLAGS, YTDLP_APP_BIN_PATH, YTDLP_DOWNLOAD_URL
try:
from importlib.metadata import version as importlib_version
from importlib.metadata import PackageNotFoundError as ImportlibPackageNotFoundError
def get_version(package_name: str) -> str:
return importlib_version(package_name)
PackageNotFoundError = ImportlibPackageNotFoundError
except ImportError:
# Fallback for older Python versions
import pkg_resources
def get_version(package_name: str) -> str:
return pkg_resources.get_distribution(package_name).version
PackageNotFoundError = pkg_resources.DistributionNotFound
try:
import yt_dlp
@@ -117,7 +132,21 @@ class UpdateThread(QThread):
self.update_progress.emit(20)
# Extra logic moved to src\utils\ytsage_constants.py
# Check if this is an app-managed binary by comparing paths safely
is_app_managed = False
try:
# Only compare if both files exist
if yt_dlp_path.exists() and YTDLP_APP_BIN_PATH.exists():
is_app_managed = yt_dlp_path.samefile(YTDLP_APP_BIN_PATH)
elif str(yt_dlp_path) == str(YTDLP_APP_BIN_PATH):
# If paths are identical as strings, consider it app-managed
is_app_managed = True
else:
# If app binary doesn't exist, this is definitely not app-managed
is_app_managed = False
except (OSError, IOError) as e:
logger.debug(f"Error comparing paths: {e}")
is_app_managed = False
if is_app_managed:
self.update_status.emit("📦 Updating app-managed yt-dlp binary...")
@@ -185,16 +214,14 @@ class UpdateThread(QThread):
def _update_via_pip(self) -> bool:
"""Update yt-dlp via pip."""
try:
import pkg_resources
self.update_status.emit("🔍 Checking current pip installation...")
self.update_progress.emit(30)
# Get current version
try:
current_version = pkg_resources.get_distribution("yt-dlp").version
current_version = get_version("yt-dlp")
self.update_status.emit(f"📋 Current version: {current_version}")
except pkg_resources.DistributionNotFound:
except PackageNotFoundError:
self.update_status.emit("⚠️ yt-dlp not found via pip, attempting installation...")
current_version = "0.0.0"
@@ -544,7 +571,21 @@ class AutoUpdateThread(QThread):
# Extra logic moved to src\utils\ytsage_constants.py
# Check if this is an app-managed binary by comparing paths safely
is_app_managed = False
try:
# Only compare if both files exist
if yt_dlp_path.exists() and YTDLP_APP_BIN_PATH.exists():
is_app_managed = yt_dlp_path.samefile(YTDLP_APP_BIN_PATH)
elif str(yt_dlp_path) == str(YTDLP_APP_BIN_PATH):
# If paths are identical as strings, consider it app-managed
is_app_managed = True
else:
# If app binary doesn't exist, this is definitely not app-managed
is_app_managed = False
except (OSError, IOError) as e:
logger.debug(f"AutoUpdateThread: Error comparing paths: {e}")
is_app_managed = False
if is_app_managed:
logger.info("AutoUpdateThread: Updating app-managed yt-dlp binary...")
@@ -594,15 +635,13 @@ class AutoUpdateThread(QThread):
def _update_via_pip(self) -> bool:
"""Update yt-dlp via pip (silent version)."""
try:
import pkg_resources
logger.info("AutoUpdateThread: Checking current pip installation...")
# Get current version
try:
current_version = pkg_resources.get_distribution("yt-dlp").version
current_version = get_version("yt-dlp")
logger.info(f"AutoUpdateThread: Current version: {current_version}")
except pkg_resources.DistributionNotFound:
except PackageNotFoundError:
logger.warning("AutoUpdateThread: yt-dlp not found via pip, attempting installation...")
current_version = "0.0.0"