Allow renaming of backup files in Synology DSM (#138652)

* get backup base file name from meta file

* use BackupNotFound
This commit is contained in:
Michael 2025-02-16 20:00:17 +01:00 committed by GitHub
parent e0b50ee1e2
commit ccd0e27e84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -14,6 +14,7 @@ from homeassistant.components.backup import (
AgentBackup, AgentBackup,
BackupAgent, BackupAgent,
BackupAgentError, BackupAgentError,
BackupNotFound,
suggested_filename, suggested_filename,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -101,6 +102,7 @@ class SynologyDSMBackupAgent(BackupAgent):
) )
syno_data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id] syno_data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
self.api = syno_data.api self.api = syno_data.api
self.backup_base_names: dict[str, str] = {}
@property @property
def _file_station(self) -> SynoFileStation: def _file_station(self) -> SynoFileStation:
@ -109,18 +111,19 @@ class SynologyDSMBackupAgent(BackupAgent):
assert self.api.file_station assert self.api.file_station
return self.api.file_station return self.api.file_station
async def _async_suggested_filenames( async def _async_backup_filenames(
self, self,
backup_id: str, backup_id: str,
) -> tuple[str, str]: ) -> tuple[str, str]:
"""Suggest filenames for the backup. """Return the actual backup filenames.
:param backup_id: The ID of the backup that was returned in async_list_backups. :param backup_id: The ID of the backup that was returned in async_list_backups.
:return: A tuple of tar_filename and meta_filename :return: A tuple of tar_filename and meta_filename
""" """
if (backup := await self.async_get_backup(backup_id)) is None: if await self.async_get_backup(backup_id) is None:
raise BackupAgentError("Backup not found") raise BackupNotFound
return suggested_filenames(backup) base_name = self.backup_base_names[backup_id]
return (f"{base_name}.tar", f"{base_name}_meta.json")
async def async_download_backup( async def async_download_backup(
self, self,
@ -132,7 +135,7 @@ class SynologyDSMBackupAgent(BackupAgent):
:param backup_id: The ID of the backup that was returned in async_list_backups. :param backup_id: The ID of the backup that was returned in async_list_backups.
:return: An async iterator that yields bytes. :return: An async iterator that yields bytes.
""" """
(filename_tar, _) = await self._async_suggested_filenames(backup_id) (filename_tar, _) = await self._async_backup_filenames(backup_id)
try: try:
resp = await self._file_station.download_file( resp = await self._file_station.download_file(
@ -193,7 +196,7 @@ class SynologyDSMBackupAgent(BackupAgent):
:param backup_id: The ID of the backup that was returned in async_list_backups. :param backup_id: The ID of the backup that was returned in async_list_backups.
""" """
try: try:
(filename_tar, filename_meta) = await self._async_suggested_filenames( (filename_tar, filename_meta) = await self._async_backup_filenames(
backup_id backup_id
) )
except BackupAgentError: except BackupAgentError:
@ -247,6 +250,7 @@ class SynologyDSMBackupAgent(BackupAgent):
assert files assert files
backups: dict[str, AgentBackup] = {} backups: dict[str, AgentBackup] = {}
backup_base_names: dict[str, str] = {}
for file in files: for file in files:
if file.name.endswith("_meta.json"): if file.name.endswith("_meta.json"):
try: try:
@ -255,7 +259,10 @@ class SynologyDSMBackupAgent(BackupAgent):
LOGGER.error("Failed to download meta data: %s", err) LOGGER.error("Failed to download meta data: %s", err)
continue continue
agent_backup = AgentBackup.from_dict(meta_data) agent_backup = AgentBackup.from_dict(meta_data)
backups[agent_backup.backup_id] = agent_backup backup_id = agent_backup.backup_id
backups[backup_id] = agent_backup
backup_base_names[backup_id] = file.name.replace("_meta.json", "")
self.backup_base_names = backup_base_names
return backups return backups
async def async_get_backup( async def async_get_backup(