From 8ec5472b79c67710f8ded30270c9208a4e351e46 Mon Sep 17 00:00:00 2001 From: Lode Smets <31108717+lodesmets@users.noreply.github.com> Date: Tue, 20 May 2025 21:17:43 +0200 Subject: [PATCH] Added support for shared spaces in Synology DSM (Photo Station) (#144044) * Added shared space to the list of all the albums * Added tests * added more tests * Apply suggestions from code review --------- Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com> --- .../components/synology_dsm/media_source.py | 34 ++++++++++++--- .../synology_dsm/test_media_source.py | 41 +++++++++++++++++-- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/synology_dsm/media_source.py b/homeassistant/components/synology_dsm/media_source.py index 6234f5e8dd0..7fafe1fecb3 100644 --- a/homeassistant/components/synology_dsm/media_source.py +++ b/homeassistant/components/synology_dsm/media_source.py @@ -145,6 +145,17 @@ class SynologyPhotosMediaSource(MediaSource): can_expand=True, ) ] + ret += [ + BrowseMediaSource( + domain=DOMAIN, + identifier=f"{item.identifier}/shared", + media_class=MediaClass.DIRECTORY, + media_content_type=MediaClass.IMAGE, + title="Shared space", + can_play=False, + can_expand=True, + ) + ] ret.extend( BrowseMediaSource( domain=DOMAIN, @@ -162,13 +173,24 @@ class SynologyPhotosMediaSource(MediaSource): # Request items of album # Get Items - album = SynoPhotosAlbum(int(identifier.album_id), "", 0, identifier.passphrase) - try: - album_items = await diskstation.api.photos.get_items_from_album( - album, 0, 1000 + if identifier.album_id == "shared": + # Get items from shared space + try: + album_items = await diskstation.api.photos.get_items_from_shared_space( + 0, 1000 + ) + except SynologyDSMException: + return [] + else: + album = SynoPhotosAlbum( + int(identifier.album_id), "", 0, identifier.passphrase ) - except SynologyDSMException: - return [] + try: + album_items = await diskstation.api.photos.get_items_from_album( + album, 0, 1000 + ) + except SynologyDSMException: + return [] assert album_items is not None ret = [] diff --git a/tests/components/synology_dsm/test_media_source.py b/tests/components/synology_dsm/test_media_source.py index dd454f92137..d66688575bc 100644 --- a/tests/components/synology_dsm/test_media_source.py +++ b/tests/components/synology_dsm/test_media_source.py @@ -61,6 +61,11 @@ def dsm_with_photos() -> MagicMock: SynoPhotosItem(10, "", "filename.jpg", 12345, "10_1298753", "sm", True, ""), ] ) + dsm.photos.get_items_from_shared_space = AsyncMock( + return_value=[ + SynoPhotosItem(10, "", "filename.jpg", 12345, "10_1298753", "sm", True, ""), + ] + ) dsm.photos.get_item_thumbnail_url = AsyncMock( return_value="http://my.thumbnail.url" ) @@ -257,13 +262,16 @@ async def test_browse_media_get_albums( result = await source.async_browse_media(item) assert result - assert len(result.children) == 2 + assert len(result.children) == 3 assert isinstance(result.children[0], BrowseMedia) assert result.children[0].identifier == "mocked_syno_dsm_entry/0" assert result.children[0].title == "All images" assert isinstance(result.children[1], BrowseMedia) - assert result.children[1].identifier == "mocked_syno_dsm_entry/1_" - assert result.children[1].title == "Album 1" + assert result.children[1].identifier == "mocked_syno_dsm_entry/shared" + assert result.children[1].title == "Shared space" + assert isinstance(result.children[2], BrowseMedia) + assert result.children[2].identifier == "mocked_syno_dsm_entry/1_" + assert result.children[2].title == "Album 1" @pytest.mark.usefixtures("setup_media_source") @@ -315,6 +323,17 @@ async def test_browse_media_get_items_error( assert result.identifier is None assert len(result.children) == 0 + # exception in get_items_from_shared_space() + dsm_with_photos.photos.get_items_from_shared_space = AsyncMock( + side_effect=SynologyDSMException("", None) + ) + item = MediaSourceItem(hass, DOMAIN, "mocked_syno_dsm_entry/shared", None) + result = await source.async_browse_media(item) + + assert result + assert result.identifier is None + assert len(result.children) == 0 + @pytest.mark.usefixtures("setup_media_source") async def test_browse_media_get_items_thumbnail_error( @@ -411,6 +430,22 @@ async def test_browse_media_get_items( assert not item.can_expand assert item.thumbnail == "http://my.thumbnail.url" + item = MediaSourceItem(hass, DOMAIN, "mocked_syno_dsm_entry/shared", None) + result = await source.async_browse_media(item) + assert result + assert len(result.children) == 1 + item = result.children[0] + assert ( + item.identifier + == "mocked_syno_dsm_entry/shared_/10_1298753/filename.jpg_shared" + ) + assert item.title == "filename.jpg" + assert item.media_class == MediaClass.IMAGE + assert item.media_content_type == "image/jpeg" + assert item.can_play + assert not item.can_expand + assert item.thumbnail == "http://my.thumbnail.url" + @pytest.mark.usefixtures("setup_media_source") async def test_media_view(