From a37eb460033b60d2632273a435de886357c01e54 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Sat, 28 Feb 2026 12:10:55 +0300 Subject: [PATCH] Codebase audit fixes: stability and performance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Safe int conversion for position/duration (catch ValueError/TypeError) - Hoist get_media_folders() out of browse loop (N+1 → 1 API call) - Fix path separator detection alongside folder metadata fetch - Increase browse pagination limit from 1000 to 5000 Co-Authored-By: Claude Opus 4.6 --- .../remote_media_player/media_player.py | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/custom_components/remote_media_player/media_player.py b/custom_components/remote_media_player/media_player.py index f8722f2..50323bd 100644 --- a/custom_components/remote_media_player/media_player.py +++ b/custom_components/remote_media_player/media_player.py @@ -385,7 +385,12 @@ class RemoteMediaPlayerEntity(CoordinatorEntity[MediaPlayerCoordinator], MediaPl if self.coordinator.data is None: return None duration = self.coordinator.data.get("duration") - return int(duration) if duration is not None else None + if duration is None: + return None + try: + return int(duration) + except (ValueError, TypeError): + return None @property def media_position(self) -> int | None: @@ -393,7 +398,12 @@ class RemoteMediaPlayerEntity(CoordinatorEntity[MediaPlayerCoordinator], MediaPl if self.coordinator.data is None: return None position = self.coordinator.data.get("position") - return int(position) if position is not None else None + if position is None: + return None + try: + return int(position) + except (ValueError, TypeError): + return None @property def media_position_updated_at(self) -> datetime | None: @@ -575,7 +585,14 @@ class RemoteMediaPlayerEntity(CoordinatorEntity[MediaPlayerCoordinator], MediaPl raise ValueError("Invalid media_content_id format") # Get folder contents from API - browse_data = await self.coordinator.client.browse_folder(folder_id, path, offset=0, limit=1000) + browse_data = await self.coordinator.client.browse_folder(folder_id, path, offset=0, limit=5000) + + # Fetch folder metadata once (not per-item) for building absolute paths + folders = await self.coordinator.client.get_media_folders() + base_path = folders.get(folder_id, {}).get("path", "") + # Detect path separator from server's base_path (Unix vs Windows) + separator = '\\' if '\\' in base_path else '/' + base_path_clean = base_path.rstrip('/\\') children = [] for item in browse_data.get("items", []): @@ -593,15 +610,8 @@ class RemoteMediaPlayerEntity(CoordinatorEntity[MediaPlayerCoordinator], MediaPl ) ) elif item.get("is_media", False): - # Media file - # Build absolute path for playback - folders = await self.coordinator.client.get_media_folders() - base_path = folders[folder_id]["path"] + # Media file - build absolute path for playback file_path_in_folder = f"{path}/{item['name']}" if path else item['name'] - # Handle platform path separators - separator = '\\' if '\\' in base_path else '/' - # Ensure base_path doesn't end with separator to avoid double separators - base_path_clean = base_path.rstrip('/\\') absolute_path = f"{base_path_clean}{separator}{file_path_in_folder.replace('/', separator)}" children.append(