v0.4.0 - Reliability, performance & Android compatibility
This release addresses the review feedback from #1 and the Android-tablet blank-render bug.
Fixes
- HTTP response leak fixed - the aiohttp response is now released via
async with, preventing connection-pool exhaustion on long-running slideshows - PIL images explicitly closed on discard/consumption in all rendering paths (real impact on 4 GB devices like the HA Green)
- Android-friendly JPEGs - encoded as baseline (non-progressive) with 4:2:0 subsampling and no EXIF, maximising compatibility with Android WebView and older clients. Likely cause of the Android-tablet blank-render bug.
- DecompressionBomb protection - 80 MP image ceiling protects low-memory devices from a pathological album entry
- Download size cap (64 MB) with streaming read and
Content-Lengthpre-check Content-Typevalidation rejects HTML captive-portal / error pages served as HTTP 200
Performance
_DownloadCacherewritten oncollections.OrderedDict- O(1) get/put/evict (was O(n) per evicted entry under pressure)- Metadata-first orientation checks - when a
MediaItemhas width/height (Google Photos always does),is_portraitis resolved without downloading or decoding. Pairing and skip-mismatch loops no longer pay a decode cost per rejected candidate - PIL
draftmode -open_image(target_size=(w, h))lets libjpeg decode JPEGs at a reduced scale when the source is much larger than the render canvas
Correctness
- Peek vs commit advance -
_skip_mismatch_and_rendernow peek-advances for rejected candidates so the random cycle is not consumed, preventing premature repeats _wait_or_interrupt(timeout)helper encapsulates theclear()+wait_for()pattern- Last-frame cache in
SlideshowStore- a camera reload rehydrates the framebuffer instantly instead of returningNoneuntil the first render completes