Releases: Geek-MD/Advanced_Downloader
Releases · Geek-MD/Advanced_Downloader
v1.2.6
v1.2.6 - 2026-03-18
Fixed
- Blocking
open()call inside the event loop: replaced the synchronousopen(tmp_path, "wb")used during chunk-writing withaiofiles.open()so that file I/O is no longer performed on the event-loop thread. This resolves thehomeassistant.util.loopwarning "Detected blocking call to open … inside the event loop".aiofiles>=23.1.0has been added as a runtime requirement.
v1.2.5
v1.2.5 - 2026-03-11
Changed
- Rebranding: "Video Normalizer" renamed to "Video Tools". All references to the
video_normalizerintegration (dependency declaration, import path, conflict-detection logic, persistent notification messages, and documentation) have been updated tovideo_tools.
v1.2.4
v1.2.4 - 2026-03-11
Fixed
AttributeError: 'HomeAssistant' object has no attribute 'async_at_start': replaced the invalidhass.async_at_start()call with the correcthomeassistant.helpers.start.async_at_start(hass, callback)helper. This caused the entire integration setup to fail, making all services (advanced_downloader.download_file, etc.) unavailable.
v1.2.3
v1.2.3 - 2026-03-11
Fixed
- False-positive core Downloader conflict notification: the check that detects whether the built-in
downloaderintegration is active was incorrectly usinghass.config.components, which can contain"downloader"even whendownloader:is not present inconfiguration.yaml(HA may register available built-in integrations at boot). The check now inspectshass.services.async_services()instead, which only lists domains with registered services — a reliable indicator thatasync_setup()was actually called for that integration. Additionally, the check is now deferred until after HA has fully started (viahass.async_at_start()) to guarantee all YAML-configured integrations have had a chance to register their services before the conflict detection runs.
v1.2.2
v1.2.2 - 2026-03-10
Fixed
- Renamed brand images directory from
custom_components/advanced_downloader/brands/tocustom_components/advanced_downloader/brand/to match the standard Home Assistant brands directory name.
Removed
- Automatic release GitHub Action (
.github/workflows/release.yml). Releases are now created manually.
v1.2.1
v1.2.1 - 2026-03-10
Added
- Core
downloaderintegration conflict detection: if the built-indownloaderintegration is loaded (i.e.downloader:is present inconfiguration.yaml), a persistent notification now appears at startup. The notification explains that Advanced Downloader is a full superset and guides the user to removedownloader:fromconfiguration.yamland restart Home Assistant. target_aspect_ratioparameter fordownload_file: the service now accepts an optionaltarget_aspect_ratio(float, e.g.1.777for 16:9) that is forwarded to Video Normalizer'sVideoProcessor.process_videoduring aspect normalisation. This replaces the equivalent parameter that was previously only available via the standalonevideo_normalizer.normalize_videoservice.last_jobattribute onsensor.advanced_downloader_status: the sensor now exposes alast_jobattribute (null,success, orfailed) that reflects the outcome of the most recent download job, providing parity with thelast_jobattribute previously available onsensor.video_normalizer_status.- Automation migration guide added to README, showing step-by-step how to replace automations that combined the core
downloaderintegration with the standalone Video Normalizer integration.
Fixed
- The Video Normalizer conflict notification import (
persistent_notification) is now hoisted and shared between both conflict checks, removing a redundant in-block import.
v1.2.0
v1.2.0 - 2026-03-10
⚠️ Breaking change: The integration domain has changed frommedia_downloadertoadvanced_downloader. Update any automations, scripts, or templates that referencemedia_downloader.*services ormedia_downloader_*events.
Added
- Video Normalizer is now a required dependency. All video post-processing (aspect ratio normalization, thumbnail generation/embedding, and optional resizing) is delegated to Video Normalizer's
VideoProcessor, eliminating duplicated logic. - Startup conflict detection: if Video Normalizer is also configured as a standalone integration, a persistent Home Assistant notification is created to guide the user to remove that config entry (while keeping the HACS package installed, since Advanced Downloader still requires its code).
issue_trackerfield added tomanifest.json.- Brand images (
icon.png,icon@2x.png,logo.png,logo@2x.png) added tocustom_components/advanced_downloader/brands/.
Changed
- Integration renamed from Media Downloader to Advanced Downloader.
- Domain changed from
media_downloadertoadvanced_downloader.- Integration folder:
custom_components/advanced_downloader/ - All service names:
advanced_downloader.download_file,advanced_downloader.delete_file,advanced_downloader.delete_files_in_directory - All event names:
advanced_downloader_download_completed,advanced_downloader_download_failed,advanced_downloader_aspect_normalized,advanced_downloader_thumbnail_embedded,advanced_downloader_resize_completed,advanced_downloader_resize_failed,advanced_downloader_job_completed - Status sensor entity:
sensor.advanced_downloader_status
- Integration folder:
video_utils.pysimplified to path/filename utilities only (sanitize_filename,ensure_within_base,guess_filename_from_url). All video-processing functions removed in favour of the Video Normalizer dependency.
v1.1.6
What's Changed
- Address code review feedback: improve error logging and fix shell escaping (ed9fb09)
- Fix subprocess calls and update release workflow for v1.1.6 (239e8d6)
- Initial plan for v1.1.6 release (74b37ff)
- Initial plan (21a0d9f)
Full Changelog: v1.1.5...v1.1.6
What's Changed
- Fix subprocess timeouts and upgrade release workflow to v1.1.6 by @Copilot in #20
Full Changelog: v1.1.5...v1.1.6
v1.1.5
Media Downloader v1.1.5 - 2025-12-06
🐛 Bug Fixes
- Fixed async_timeout deprecation warning: Added Python 3.11+ compatibility with automatic fallback to
async_timeoutfor older versions, ensuring compatibility across different Home Assistant installations - Fixed UnboundLocalError in normalize_video_aspect(): Resolved potential crash where
tmp_filevariable could be referenced before assignment in the exception handler - Fixed UnboundLocalError in embed_thumbnail(): Improved exception handling to properly define temporary file paths before cleanup operations
- Enhanced error handling: All video processing functions now have robust cleanup mechanisms that prevent resource leaks
⚡ Optimizations
- Removed unused
asyncioimport to clean up the codebase - Improved exception handling with proper resource cleanup in all video utility functions
- Streamlined imports and improved overall code structure
- Updated Python version target to 3.11 in mypy configuration for better type checking
🔧 Infrastructure Updates
- Replaced CI/CD workflows: Removed old workflows (
ci.yaml,validate_manifest_hacs.yaml) and validation script - Added Video_Normalizer workflows:
validate.ymlwith support for manual fixes via workflow dispatchrelease.ymlfor automatic release creation when manifest version changes
- Added requirements.txt: Easier dependency management for development tools (Ruff, Mypy, Pytest, Voluptuous)
- Updated mypy.ini: Now matches Video_Normalizer configuration standards with Python 3.11 target
📚 Documentation
- Updated README.md badges: Enhanced styling to match Video_Normalizer with proper links to:
- HACS repository
- Ruff linter
- Mypy type checker
- Added footer: "Proudly developed with GitHub Copilot" 🚀
- Updated translations: Added missing configuration options (
delete_file_path,delete_directory_path) in:strings.jsonen.json(English)es.json(Spanish)
✅ Validation
All changes have been validated with:
- ✅ Ruff linter (all checks passed)
- ✅ Mypy type checker (no issues found)
- ✅ JSON validation (all configuration files valid)
- ✅ Hassfest compatibility
v1.1.4
Media Downloader v1.1.4 - 2025-11-20
Added
- None (patch release focused on reliability and correctness).
Improved
- All blocking post-processing (normalization, thumbnail embedding, resize and dimension detection) now runs in an executor via
hass.async_add_executor_jobto avoid blocking the Home Assistant event loop. - Sensor lifecycle hardened:
- The status sensor now properly subscribes and unsubscribes to bus events and is guaranteed to be registered in
hass.databefore services are used. async_will_remove_from_hassremoves bus listeners to avoid callback leaks.
- The status sensor now properly subscribes and unsubscribes to bus events and is guaranteed to be registered in
- Emitted both
job_interruptedand a namespacedmedia_downloader_job_interruptedevent for compatibility and clearer automations.
Fixed
- Critical thread-safety bug where
async_write_ha_state()could be called from a worker thread (risking crashes or data corruption) — now all state writes occur on the event loop thread. - Event delivery issues: interruption and completion events are now reliably emitted and consumed by the sensor and automations.
- Temporary file cleanup improved to reduce leftover
.partfiles after timeouts or failures. - Resizing/thumbnail/normalization routines that were blocking now execute without preventing timeouts from taking effect.
Result
- Reliable timeout enforcement across the entire download + post-processing workflow without risking Home Assistant stability.
sensor.media_downloader_status.attributes.last_jobreliably reflects the last job outcome ("done"or"interrupted").- Automations listening for interruption events will consistently receive either
job_interruptedormedia_downloader_job_interrupted.
Notes
- For custom CPU-bound post-processing hooks, prefer running them in an executor (or converting to async-friendly implementations) to preserve timeout semantics.
- If you prefer only a single, namespaced interruption event, we can remove the short alias in a future non-breaking release; for now both are emitted to preserve compatibility.