mirror of
https://github.com/esphome/esphome.git
synced 2025-11-08 19:11:49 +00:00
wip
This commit is contained in:
@@ -43,15 +43,31 @@ def patch_structhash():
|
||||
|
||||
|
||||
def patch_file_downloader():
|
||||
"""Patch PlatformIO's FileDownloader to add caching and retry on PackageException errors."""
|
||||
"""Patch PlatformIO's FileDownloader to add caching and retry on PackageException errors.
|
||||
|
||||
This function attempts to patch PlatformIO's internal download mechanism.
|
||||
If patching fails (due to API changes), it gracefully falls back to no caching.
|
||||
"""
|
||||
try:
|
||||
from platformio.package.download import FileDownloader
|
||||
from platformio.package.exception import PackageException
|
||||
except ImportError as e:
|
||||
_LOGGER.debug("Could not import PlatformIO modules for patching: %s", e)
|
||||
return
|
||||
|
||||
# Import our cache module
|
||||
from esphome.github_cache import GitHubCache
|
||||
|
||||
_LOGGER.debug("Applying GitHub download cache patch...")
|
||||
|
||||
# Verify the classes have the expected methods before patching
|
||||
if not hasattr(FileDownloader, "__init__") or not hasattr(FileDownloader, "start"):
|
||||
_LOGGER.warning(
|
||||
"PlatformIO FileDownloader API has changed, skipping cache patch"
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
original_init = FileDownloader.__init__
|
||||
original_start = FileDownloader.start
|
||||
|
||||
@@ -62,9 +78,13 @@ def patch_file_downloader():
|
||||
cache = GitHubCache(cache_dir=cache_dir)
|
||||
if not cache_dir_existed:
|
||||
_LOGGER.info("Created GitHub download cache at: %s", cache.cache_dir)
|
||||
except Exception as e:
|
||||
_LOGGER.warning("Failed to initialize GitHub download cache: %s", e)
|
||||
return
|
||||
|
||||
def patched_init(self, *args, **kwargs):
|
||||
"""Patched init that checks cache before making HTTP connection."""
|
||||
try:
|
||||
# Extract URL from args (first positional argument)
|
||||
url = args[0] if args else kwargs.get("url")
|
||||
dest_dir = args[1] if len(args) > 1 else kwargs.get("dest_dir")
|
||||
@@ -88,7 +108,9 @@ def patch_file_downloader():
|
||||
"[GitHub Cache] Found in cache: %s", self._esphome_use_cache
|
||||
)
|
||||
else:
|
||||
_LOGGER.debug("[GitHub Cache] Not in cache, will download and cache")
|
||||
_LOGGER.debug(
|
||||
"[GitHub Cache] Not in cache, will download and cache"
|
||||
)
|
||||
else:
|
||||
self._esphome_use_cache = None
|
||||
if url and str(url).startswith("http"):
|
||||
@@ -98,7 +120,12 @@ def patch_file_downloader():
|
||||
if self._esphome_use_cache:
|
||||
# Skip HTTP connection, we'll handle this in start()
|
||||
# Set minimal attributes to satisfy FileDownloader
|
||||
self._http_session = None
|
||||
# Create a mock session that can be safely closed in __del__
|
||||
class MockSession:
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
self._http_session = MockSession()
|
||||
self._http_response = None
|
||||
self._fname = Path(url.split("?")[0]).name
|
||||
self._destination = self._fname
|
||||
@@ -126,9 +153,16 @@ def patch_file_downloader():
|
||||
# Final attempt - re-raise
|
||||
raise
|
||||
return None
|
||||
except Exception as e:
|
||||
# If anything goes wrong in our cache logic, fall back to normal download
|
||||
_LOGGER.debug("Cache check failed, falling back to normal download: %s", e)
|
||||
self._esphome_cache_url = None
|
||||
self._esphome_use_cache = None
|
||||
return original_init(self, *args, **kwargs)
|
||||
|
||||
def patched_start(self, *args, **kwargs):
|
||||
"""Patched start that uses cache when available."""
|
||||
try:
|
||||
import shutil
|
||||
|
||||
# Get the cache URL and path that were set in __init__
|
||||
@@ -140,7 +174,8 @@ def patch_file_downloader():
|
||||
try:
|
||||
shutil.copy2(cached_file, self._destination)
|
||||
_LOGGER.info(
|
||||
"Restored %s from cache (avoided download)", Path(cached_file).name
|
||||
"Restored %s from cache (avoided download)",
|
||||
Path(cached_file).name,
|
||||
)
|
||||
return True
|
||||
except OSError as e:
|
||||
@@ -158,9 +193,18 @@ def patch_file_downloader():
|
||||
_LOGGER.debug("Failed to save to cache: %s", e)
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
# If anything goes wrong, fall back to normal download
|
||||
_LOGGER.debug("Cache restoration failed, using normal download: %s", e)
|
||||
return original_start(self, *args, **kwargs)
|
||||
|
||||
# Apply the patches
|
||||
try:
|
||||
FileDownloader.__init__ = patched_init
|
||||
FileDownloader.start = patched_start
|
||||
_LOGGER.debug("GitHub download cache patch applied successfully")
|
||||
except Exception as e:
|
||||
_LOGGER.warning("Failed to apply GitHub download cache patch: %s", e)
|
||||
|
||||
|
||||
IGNORE_LIB_WARNINGS = f"(?:{'|'.join(['Hash', 'Update'])})"
|
||||
|
||||
Reference in New Issue
Block a user