Add smart combined album asset redistribution + fix locale string
Some checks failed
Validate / Hassfest (push) Has been cancelled

Core library:
- New combine_album_assets() in asset_utils.py: smart redistribution
  of unused quota when albums return fewer assets than their share.
  Two-pass algorithm: even split then redistribute remainder.
- 6 new tests (56 total passing).

Frontend:
- Fix "leave empty to keep current" not localized in server edit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 17:15:26 +03:00
parent b708b14f32
commit 5192483fff
5 changed files with 121 additions and 1 deletions

View File

@@ -2,6 +2,7 @@
from immich_watcher_core.asset_utils import (
build_asset_detail,
combine_album_assets,
filter_assets,
get_any_url,
get_public_url,
@@ -183,3 +184,54 @@ class TestBuildAssetDetail:
assert "url" not in detail
assert "download_url" not in detail
assert "thumbnail_url" in detail # always present
class TestCombineAlbumAssets:
def test_even_distribution(self):
"""Both albums have plenty, split evenly."""
a = [_make_asset(f"a{i}") for i in range(10)]
b = [_make_asset(f"b{i}") for i in range(10)]
result = combine_album_assets({"A": a, "B": b}, total_limit=6, order_by="name")
assert len(result) == 6
def test_smart_redistribution(self):
"""Album A has 1 photo, Album B has 20. Limit=10 should get 10 total."""
a = [_make_asset("a1", created_at="2023-03-19T10:00:00Z")]
b = [_make_asset(f"b{i}", created_at=f"2023-03-19T{10+i}:00:00Z") for i in range(20)]
result = combine_album_assets({"A": a, "B": b}, total_limit=10, order_by="name")
assert len(result) == 10
# a1 should be in result
ids = {r.id for r in result}
assert "a1" in ids
def test_redistribution_with_3_albums(self):
"""3 albums: A has 1, B has 2, C has 20. Limit=12."""
a = [_make_asset("a1")]
b = [_make_asset("b1"), _make_asset("b2")]
c = [_make_asset(f"c{i}") for i in range(20)]
result = combine_album_assets({"A": a, "B": b, "C": c}, total_limit=12, order_by="name")
assert len(result) == 12
# All of A and B should be included
ids = {r.id for r in result}
assert "a1" in ids
assert "b1" in ids
assert "b2" in ids
# C fills the remaining 9
c_count = sum(1 for r in result if r.id.startswith("c"))
assert c_count == 9
def test_all_albums_empty(self):
result = combine_album_assets({"A": [], "B": []}, total_limit=10)
assert result == []
def test_single_album(self):
a = [_make_asset(f"a{i}") for i in range(5)]
result = combine_album_assets({"A": a}, total_limit=3, order_by="name")
assert len(result) == 3
def test_total_less_than_limit(self):
"""Both albums together have fewer than limit."""
a = [_make_asset("a1")]
b = [_make_asset("b1"), _make_asset("b2")]
result = combine_album_assets({"A": a, "B": b}, total_limit=10, order_by="name")
assert len(result) == 3