Commit Graph

43 Commits

Author SHA1 Message Date
381de98c40 Comprehensive review fixes: security, performance, code quality, and UI polish
Some checks failed
Validate / Hassfest (push) Has been cancelled
Backend: Fix CORS wildcard+credentials, add secret key warning, remove raw
API keys from sync endpoint, fix N+1 queries in watcher/sync, fix
AttributeError on event_types, delete dead scheduled.py/templates.py,
add limit cap on history, re-validate server on URL/key update, apply
tracking/template config IDs in update_target.

HA Integration: Replace datetime.now() with dt_util.now(), fix notification
queue to only remove successfully sent items, use album UUID for entity
unique IDs, add shared links dirty flag and users cache hourly refresh,
deduplicate _is_quiet_hours, add HTTP timeouts, cache albums in config
flow, change iot_class to local_polling.

Frontend: Make i18n reactive via $state (remove window.location.reload),
add Modal transitions/a11y/Escape key, create ConfirmModal replacing all
confirm() calls, add error handling to all pages, replace Unicode nav
icons with MDI SVGs, add card hover effects, dashboard stat icons, global
focus-visible styles, form slide transitions, mobile responsive bottom
nav, fix password error color, add ~20 i18n keys (EN/RU).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 18:34:31 +03:00
43f83acda9 Fix Phase 5 review issues: SSTI, FK violation, sync rebuild
Some checks failed
Validate / Hassfest (push) Has been cancelled
Fixes 5 issues identified by code-reviewer agent:

1. (Critical) EventLog.tracker_id now nullable - use None instead
   of 0 when tracker name doesn't match, avoiding FK constraint
   violations on PostgreSQL
2. (Critical) Replace jinja2.Environment with SandboxedEnvironment
   in all 3 server template rendering locations to prevent SSTI
3. (Important) Rebuild sync_client in _async_update_listener when
   server URL/key options change, propagate to all coordinators
4. (Important) Validate partial server config - require both URL
   and API key or neither, with clear error message
5. (Important) Name fire-and-forget sync task for debugging

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 14:17:59 +03:00
ab1c7ac0db Add HAOS-Server sync for optional centralized management (Phase 5)
Some checks failed
Validate / Hassfest (push) Has been cancelled
Enable the HAOS integration to optionally connect to the standalone
Immich Watcher server for config sync and event reporting.

Server-side:
- New /api/sync/* endpoints: GET trackers, POST template render,
  POST event report
- API key auth via X-API-Key header (accepts JWT access tokens)

Integration-side:
- New sync.py: ServerSyncClient with graceful error handling
  (all methods return defaults on connection failure)
- Options flow: optional server_url and server_api_key fields
  with connection validation
- Coordinator: fire-and-forget event reporting to server when
  album changes are detected
- Translations: en.json and ru.json updated with new fields

The connection is fully additive -- the integration works identically
without a server URL configured. Server failures never break HA.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 14:10:29 +03:00
b107cfe67f Refactor HAOS integration to use shared core library (Phase 2)
Some checks failed
Validate / Hassfest (push) Has been cancelled
Wire the integration to delegate all HA-independent logic to
immich-watcher-core, eliminating ~2300 lines of duplicated code.

Changes:
- const.py: Import shared constants from core, keep HA-specific ones
- storage.py: Create HAStorageBackend adapter wrapping HA's Store,
  use core TelegramFileCache and NotificationQueue via adapter
- coordinator.py: Delegate to core ImmichClient for API calls,
  detect_album_changes() for change detection, and asset_utils
  for filtering/sorting/URL building. Keep HA-specific event firing.
- sensor.py: Replace ~1300 lines of Telegram code with 15-line
  delegation to core TelegramClient. Keep entity classes unchanged.
- __init__.py: Use factory functions for creating core instances
  with HA storage backends
- manifest.json: Add immich-watcher-core dependency

Integration line count: 3600 -> 1295 lines (-64%)
Zero behavior changes for end users.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:47:18 +03:00
71b79cd919 Move quiet hours from hub config to per-call service params
All checks were successful
Validate / Hassfest (push) Successful in 1m19s
Quiet hours are now specified per send_telegram_notification call via
quiet_hours_start/quiet_hours_end params instead of being a hub-wide
integration option. This allows different automations to use different
quiet hours windows (or none at all).

- Remove quiet_hours_start/end from config options UI and const.py
- Add quiet_hours_start/end as optional HH:MM params on the service
- Remove ignore_quiet_hours param (omit quiet hours params to send immediately)
- Queue stores quiet_hours_end per item; each unique end time gets its
  own async_track_time_change timer for replay
- On startup, items whose quiet hours have passed are sent immediately
- Add async_remove_indices() to NotificationQueue for selective removal
- Timers are cleaned up when no more items need them

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:04:20 +03:00
678e8a6e62 Add quiet hours, fix Telegram bugs, and improve cache performance
All checks were successful
Validate / Hassfest (push) Successful in 5s
- Add quiet hours support to queue notifications during configured time windows
- Fix UnboundLocalError when single-item document chunk exceeds max_asset_data_size
- Fix document-only multi-item chunks being silently dropped (missing skip guard)
- Fix notification queue entity lookup by storing entity_id in queued params
- Fix quiet hours using OS timezone instead of HA-configured timezone (dt_util.now)
- Fix chat_action schema rejecting empty string from "Disabled" selector
- Fix stale thumbhash cache entries not being removed on mismatch
- Fix translation descriptions for send_large_photos_as_documents
- Add batch async_set_many() to TelegramFileCache to reduce disk writes
- Add max-entries eviction (2000) for thumbhash cache to prevent unbounded growth
- Eliminate redundant _is_asset_id/get_asset_thumbhash lookups in media group loop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:45:34 +03:00
dd7032b411 Replace TTL with thumbhash-based cache validation and add Telegram video size limits
Some checks failed
Validate / Hassfest (push) Has been cancelled
- Asset cache now validates entries by comparing stored thumbhash with current
  Immich thumbhash instead of using TTL expiration. This makes cache invalidation
  precise (only when content actually changes) and eliminates unnecessary re-uploads.
  URL-based cache retains TTL for non-Immich URLs.
- Add TELEGRAM_MAX_VIDEO_SIZE (50 MB) check to skip oversized videos in both
  single-video and media-group paths, preventing entire groups from failing.
- Split media groups into sub-groups by cumulative upload size to ensure each
  sendMediaGroup request stays under Telegram's 50 MB upload limit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:28:33 +03:00
3ba33a36cf Minor refactoring to use common const for telegram API url
All checks were successful
Validate / Hassfest (push) Successful in 4s
2026-02-04 17:46:14 +03:00
6ca3cae5df Add document type and content_type support for send_telegram_notification
All checks were successful
Validate / Hassfest (push) Successful in 3s
- Add type: document as default media type (instead of photo)
- Add optional content_type field for explicit MIME type specification
- Documents are sent separately (Telegram API limitation for media groups)
- Default content types: image/jpeg (photo), video/mp4 (video), auto-detect (document)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:35:57 +03:00
fde2d0ae31 Bump version to 2.7.1
All checks were successful
Validate / Hassfest (push) Successful in 4s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 02:51:22 +03:00
5cee3ccc79 Add chat_action parameter to send_telegram_notification service
All checks were successful
Validate / Hassfest (push) Successful in 4s
Shows typing/upload indicator while processing media. Supports:
typing, upload_photo, upload_video, upload_document actions.
Set to empty string to disable. Default: typing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 02:48:25 +03:00
3b133dc4bb Exclude archived assets from processing status check
All checks were successful
Validate / Hassfest (push) Successful in 4s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 15:02:25 +03:00
a8ea9ab46a Rename on_this_day to memory_date with exclude-same-year behavior
All checks were successful
Validate / Hassfest (push) Successful in 2s
Renamed the date filter parameter and changed default behavior to match
Google Photos memories - now excludes assets from the same year as the
reference date, returning only photos from previous years on that day.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:24:08 +03:00
e88fd0fa3a Add get_assets filtering: offset, on_this_day, city, state, country
All checks were successful
Validate / Hassfest (push) Successful in 3s
- Add offset parameter for pagination support
- Add on_this_day parameter for memories filtering (match month and day)
- Add city, state, country parameters for geolocation filtering
- Update README with new parameters and examples

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 12:25:35 +03:00
3cf916dc77 Rename last_updated attribute to last_updated_at
All checks were successful
Validate / Hassfest (push) Successful in 3s
Renamed for consistency with created_at attribute naming.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:30:39 +03:00
df446390f2 Add album metadata attributes to Album ID sensor
All checks were successful
Validate / Hassfest (push) Successful in 4s
Add asset_count, last_updated, and created_at attributes to the
Album ID sensor for convenient access to album metadata.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 00:20:38 +03:00
1d61f05552 Track pending assets for delayed processing events
All checks were successful
Validate / Hassfest (push) Successful in 3s
- Add _pending_asset_ids to track assets detected but not yet processed
- Fire events when pending assets become processed (thumbhash available)
- Fixes issue where videos added during transcoding never triggered events
- Add debug logging for change detection and pending asset tracking
- Document external domain feature in README

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 22:23:32 +03:00
38a2a6ad7a Add external domain support for URLs
All checks were successful
Validate / Hassfest (push) Successful in 4s
- Fetch externalDomain from Immich server config on startup
- Use external domain for user-facing URLs (share links, asset URLs)
- Keep internal connection URL for API calls
- Add get_internal_download_url() to convert external URLs back to
  internal for faster local network downloads (Telegram notifications)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 21:53:02 +03:00
0bb7e71a1e Fix video asset processing detection
All checks were successful
Validate / Hassfest (push) Successful in 3s
- Use thumbhash for all assets instead of encodedVideoPath for videos
  (encodedVideoPath is not exposed in Immich API response)
- Add isTrashed check to exclude trashed assets from events
- Simplify processing status logic for both photos and videos

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 21:36:21 +03:00
c29fc2fbcf Add Telegram file ID caching and reverse geocoding fields
All checks were successful
Validate / Hassfest (push) Successful in 3s
Implement caching for Telegram file_ids to avoid re-uploading the same media.
Cached IDs are reused for subsequent sends, improving performance significantly.
Added configurable cache TTL option (1-168 hours, default 48).

Also added city, state, and country fields from Immich reverse geocoding
to asset data in events and get_assets service.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 03:12:05 +03:00
011f105823 Add geolocation (latitude/longitude) to asset data
All checks were successful
Validate / Hassfest (push) Successful in 3s
Expose GPS coordinates from EXIF data in asset responses. The latitude
and longitude fields are included in get_assets service responses and
event data when available.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 02:29:56 +03:00
ee45fdc177 Fix the services API
All checks were successful
Validate / Hassfest (push) Successful in 3s
2026-02-01 02:22:52 +03:00
4b0f3b8b12 Enhance get_assets service with flexible filtering and sorting
All checks were successful
Validate / Hassfest (push) Successful in 5s
- Replace filter parameter with independent favorite_only boolean
- Add order_by parameter supporting date, rating, and name sorting
- Rename count to limit for clarity
- Add date range filtering with min_date and max_date parameters
- Add asset_type filtering for photos and videos
- Update README with language support section and fixed sensor list
- Add translations for all new parameters

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 01:39:04 +03:00
e5e45f0fbf Add asset preprocessing filter and enhance asset data
All checks were successful
Validate / Hassfest (push) Successful in 3s
Features:
- Filter unprocessed assets from events and get_assets service
  - Videos require completed transcoding (encodedVideoPath)
  - Photos require generated thumbnails (thumbhash)
- Add photo_url field for images (preview-sized thumbnail)
- Simplify asset attribute names (remove asset_ prefix)
- Prioritize user-added descriptions over EXIF descriptions

Documentation:
- Update README with new asset fields and preprocessing note
- Update services.yaml parameter descriptions

Version: 2.1.0

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 01:14:21 +03:00
8714685d5e Improve Telegram error handling and unify asset data structure
All checks were successful
Validate / Hassfest (push) Successful in 3s
- Remove photo downscaling logic in favor of cleaner error handling
- Add intelligent Telegram API error logging with diagnostics and suggestions
- Define Telegram photo limits as global constants (TELEGRAM_MAX_PHOTO_SIZE, TELEGRAM_MAX_DIMENSION_SUM)
- Add photo_url support for image assets (matching video_url for videos)
- Unify asset detail building with shared _build_asset_detail() helper method
- Enhance get_assets service to return complete asset data matching events
- Simplify attribute naming by removing redundant asset_ prefix from values

BREAKING CHANGE: Asset attribute keys changed from "asset_type", "asset_filename"
to simpler "type", "filename" for consistency and cleaner JSON responses

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 23:40:19 +03:00
bbcd97e1ac Expose favorite and asset rating to asset data
All checks were successful
Validate / Hassfest (push) Successful in 3s
2026-01-31 18:14:33 +03:00
04dd63825c Add intelligent handling for oversized photos in Telegram service
All checks were successful
Validate / Hassfest (push) Successful in 3s
Implements send_large_photos_as_documents parameter to handle photos
exceeding Telegram's limits (10MB file size or 10000px dimension sum).

Features:
- Automatic detection of oversized photos using file size and PIL-based
  dimension checking
- Two handling modes:
  * send_large_photos_as_documents=false (default): Intelligently
    downsizes photos using Lanczos resampling and progressive JPEG
    quality reduction to fit within Telegram limits
  * send_large_photos_as_documents=true: Sends oversized photos as
    documents to preserve original quality
- For media groups: separates oversized photos and sends them as
  documents after the main group, or downsizes them inline
- Maintains backward compatibility with existing max_asset_data_size
  parameter for hard size limits

This resolves PHOTO_INVALID_DIMENSIONS errors for large images like
26MP photos while giving users control over quality vs. file size.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 18:03:50 +03:00
71d3714f6a Add max_asset_data_size parameter to Telegram service
All checks were successful
Validate / Hassfest (push) Successful in 3s
Introduces optional max_asset_data_size parameter (in bytes) to filter
out oversized photos and videos from Telegram notifications. Assets
exceeding the limit are skipped with a warning, preventing
PHOTO_INVALID_DIMENSIONS errors for large images (e.g., 26MP photos).

Changes:
- Add max_asset_data_size parameter to service signature
- Implement size checking for single photos/videos
- Filter oversized assets in media groups
- Update services.yaml, translations, and documentation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 17:31:14 +03:00
459f5ef1e5 Bump version to 2.0.0 (major release)
All checks were successful
Validate / Hassfest (push) Successful in 3s
2026-01-31 17:07:40 +03:00
42b2d912c9 Add non-blocking mode support to Telegram notification service
All checks were successful
Validate / Hassfest (push) Successful in 3s
- Add `wait_for_response` parameter (default: true) for fire-and-forget operation
- Change supports_response to OPTIONAL to allow both modes
- Refactor execution logic into `_execute_telegram_notification` method
- Background tasks created with `hass.async_create_task` when wait_for_response=false
- Update documentation with non-blocking mode example and response behavior

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 15:53:35 +03:00
2007b020ba Add parse_mode to service call API
All checks were successful
Validate / Hassfest (push) Successful in 3s
2026-01-31 15:32:20 +03:00
2ae706d700 Enhance Telegram service with multi-format support and chunking
All checks were successful
Validate / Hassfest (push) Successful in 2s
Renamed send_telegram_media_group to send_telegram_notification with expanded capabilities:
- Text messages (when urls is empty)
- Single photo/video (uses sendPhoto/sendVideo APIs)
- Media groups (uses sendMediaGroup API)
- Automatic chunking for unlimited media URLs
- Smart optimization: single-item chunks use appropriate single-item APIs

New parameters:
- max_group_size (2-10, default 10): control items per media group
- chunk_delay (0-60000ms, default 0): delay between chunks for rate limiting
- disable_web_page_preview: disable link previews in text messages

The service now intelligently selects the most efficient Telegram API endpoint based on content type and chunk size, with comprehensive error handling and logging.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-31 14:33:18 +03:00
1cc5d7cc7d Remove album name from entity names
All checks were successful
Validate / Hassfest (push) Successful in 3s
2026-01-31 04:49:53 +03:00
5d878cfbd0 Add translation for telegram service
All checks were successful
Validate / Hassfest (push) Successful in 3s
2026-01-31 04:44:50 +03:00
02c0535f50 Add telegram media sender as service. Also fixed the via_device warnings that would break in HA 2025.12.0.
All checks were successful
Validate / Hassfest (push) Successful in 3s
2026-01-31 04:07:13 +03:00
6f39a8175d Update root README.md 2026-01-30 23:41:52 +03:00
e6619cb1c5 Album ID sensor now also exposes album name 2026-01-30 15:48:16 +03:00
eedc7792c8 Add album id sensor that has primary share link url attribute 2026-01-30 15:41:58 +03:00
3a0573e432 Add persistent storage 2026-01-30 15:30:05 +03:00
847c39eaa8 Add a note about handy blueprint 2026-01-30 14:42:17 +03:00
9013c5e0c3 Update README to use github remote url 2026-01-30 14:40:50 +03:00
557ec91f05 Update remote url for HACS config and README 2026-01-30 14:12:46 +03:00
436139ede9 Prepare the integration for HACS installation 2026-01-30 14:11:28 +03:00