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:
@@ -6,7 +6,21 @@ import tempfile
|
|||||||
import time
|
import time
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
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
|
import pkg_resources
|
||||||
|
def get_version(package_name: str) -> str:
|
||||||
|
return pkg_resources.get_distribution(package_name).version
|
||||||
|
PackageNotFoundError = pkg_resources.DistributionNotFound
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
@@ -422,7 +436,23 @@ def update_yt_dlp() -> bool:
|
|||||||
# Extra logic moved to src\utils\ytsage_constants.py
|
# Extra logic moved to src\utils\ytsage_constants.py
|
||||||
|
|
||||||
# For binaries downloaded with our app, use direct binary update approach
|
# 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
|
# We're using a binary installed by our app, update directly
|
||||||
logger.info(f"Updating yt-dlp binary at {yt_dlp_path}")
|
logger.info(f"Updating yt-dlp binary at {yt_dlp_path}")
|
||||||
|
|
||||||
@@ -468,9 +498,9 @@ def update_yt_dlp() -> bool:
|
|||||||
|
|
||||||
# Get current version
|
# Get current version
|
||||||
try:
|
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}")
|
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")
|
logger.info("yt-dlp not installed via pip, attempting update anyway")
|
||||||
current_version = "0.0.0" # Assume very old version to force update
|
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.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
|
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:
|
try:
|
||||||
import yt_dlp
|
import yt_dlp
|
||||||
|
|
||||||
@@ -117,7 +132,21 @@ class UpdateThread(QThread):
|
|||||||
self.update_progress.emit(20)
|
self.update_progress.emit(20)
|
||||||
|
|
||||||
# Extra logic moved to src\utils\ytsage_constants.py
|
# 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)
|
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:
|
if is_app_managed:
|
||||||
self.update_status.emit("📦 Updating app-managed yt-dlp binary...")
|
self.update_status.emit("📦 Updating app-managed yt-dlp binary...")
|
||||||
@@ -185,16 +214,14 @@ class UpdateThread(QThread):
|
|||||||
def _update_via_pip(self) -> bool:
|
def _update_via_pip(self) -> bool:
|
||||||
"""Update yt-dlp via pip."""
|
"""Update yt-dlp via pip."""
|
||||||
try:
|
try:
|
||||||
import pkg_resources
|
|
||||||
|
|
||||||
self.update_status.emit("🔍 Checking current pip installation...")
|
self.update_status.emit("🔍 Checking current pip installation...")
|
||||||
self.update_progress.emit(30)
|
self.update_progress.emit(30)
|
||||||
|
|
||||||
# Get current version
|
# Get current version
|
||||||
try:
|
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}")
|
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...")
|
self.update_status.emit("⚠️ yt-dlp not found via pip, attempting installation...")
|
||||||
current_version = "0.0.0"
|
current_version = "0.0.0"
|
||||||
|
|
||||||
@@ -544,7 +571,21 @@ class AutoUpdateThread(QThread):
|
|||||||
|
|
||||||
# Extra logic moved to src\utils\ytsage_constants.py
|
# 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)
|
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:
|
if is_app_managed:
|
||||||
logger.info("AutoUpdateThread: Updating app-managed yt-dlp binary...")
|
logger.info("AutoUpdateThread: Updating app-managed yt-dlp binary...")
|
||||||
@@ -594,15 +635,13 @@ class AutoUpdateThread(QThread):
|
|||||||
def _update_via_pip(self) -> bool:
|
def _update_via_pip(self) -> bool:
|
||||||
"""Update yt-dlp via pip (silent version)."""
|
"""Update yt-dlp via pip (silent version)."""
|
||||||
try:
|
try:
|
||||||
import pkg_resources
|
|
||||||
|
|
||||||
logger.info("AutoUpdateThread: Checking current pip installation...")
|
logger.info("AutoUpdateThread: Checking current pip installation...")
|
||||||
|
|
||||||
# Get current version
|
# Get current version
|
||||||
try:
|
try:
|
||||||
current_version = pkg_resources.get_distribution("yt-dlp").version
|
current_version = get_version("yt-dlp")
|
||||||
logger.info(f"AutoUpdateThread: Current version: {current_version}")
|
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...")
|
logger.warning("AutoUpdateThread: yt-dlp not found via pip, attempting installation...")
|
||||||
current_version = "0.0.0"
|
current_version = "0.0.0"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user