Skip to content
This repository has been archived by the owner on Nov 7, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
maxim committed Feb 7, 2023
2 parents 0ffa08c + 2bed16a commit ab9c5af
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 12 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

Для работы компонента необходимо создать приложение Яндекс в своём Яндекс аккаунте и дать ему права на доступ к ЯндексДиску.

> :warning:
**Внимание: Интеграция не работает без ручного вмешательства в конфигурацию контейнера с homeassistant**
>
> Необходимо вручную добавить маппирование каталога backup, вот такая особенность выяснилась в последний момент :(
>
> HACS интеграции работают внутри контейнера homeassistant, в который не смаппирован этот каталог.
## Установка

Expand Down
5 changes: 3 additions & 2 deletions custom_components/yabackup/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from homeassistant.core import HomeAssistant

from .constants import DOMAIN
from .yad import YaDsk
from .yad import YaDsk, BackupObserver

#
_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -35,7 +35,8 @@ async def update_yad_option(option: dict):
# add options handler
entry.add_update_listener(async_update_options)

ya_dsk = YaDsk(hass, entry.options, entry.entry_id)
backup_observer = BackupObserver(hass, "/backup")
ya_dsk = YaDsk(hass, backup_observer, entry.options, entry.entry_id)
_LOGGER.info("Create YaDisk " + ya_dsk.get_info())

ya_dsk.add_update_listener(update_yad_option)
Expand Down
4 changes: 2 additions & 2 deletions custom_components/yabackup/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"issue_tracker": "https://github.com/maxifly/YaBackup/issues",
"codeowners": ["@maxi_fly"],
"dependencies": [],
"after_dependencies": ["backup"],
"after_dependencies": [],
"requirements": ["yadisk==1.2.17"],
"version": "1.0.0",
"version": "1.0.1",
"iot_class": "local_polling"
}
76 changes: 68 additions & 8 deletions custom_components/yabackup/yad.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
""" Core integration objects"""
import base64
import datetime
import json
import logging
import tarfile
from dataclasses import dataclass
from pathlib import Path
from typing import Generator

import requests
import yadisk as yadisk
from homeassistant.components.backup import BackupManager
from homeassistant.components.backup.const import DOMAIN as BACKUP_DOMAIN
from homeassistant.core import HomeAssistant
from yadisk.objects import ResourceObject
from yadisk.objects import TokenObject
Expand Down Expand Up @@ -78,10 +80,68 @@ def _get_auth_string(client_id, client_secret):
return base64.b64encode(bytes(client_id + ':' + client_secret, 'utf-8')).decode('utf-8')


@dataclass
class Backup:
"""Backup class."""

slug: str
name: str
date: str
path: Path
size: float


class BackupObserver:
"""Backup observer.
Base on core BackupManager
"""

def __init__(self, hass: HomeAssistant, backup_dir: str) -> None:
""" Initialize the backup observer."""
self.hass = hass
self.backup_dir = Path(hass.config.path("backups")) if backup_dir is None else Path(backup_dir)

async def get_backups(self) -> dict[str, Backup]:
""" Get data of stored backup files."""
backups = await self.hass.async_add_executor_job(self._read_backups)

_LOGGER.debug("Loaded %s backups", len(backups))

return backups

def _read_backups(self) -> dict[str, Backup]:
"""Read backups from disk."""
_LOGGER.debug("Check %s path", self.backup_dir)

_LOGGER.debug("Size %s", len(list(self.backup_dir.glob("*"))))

for backup_path in self.backup_dir.glob("*"):
_LOGGER.debug("backup_path %s", backup_path)

backups: dict[str, Backup] = {}
for backup_path in self.backup_dir.glob("*.tar"):
try:
with tarfile.open(backup_path, "r:") as backup_file:
if data_file := backup_file.extractfile("./backup.json"):
data = json.loads(data_file.read())
backup = Backup(
slug=data["slug"],
name=data["name"],
date=data["date"],
path=backup_path,
size=round(backup_path.stat().st_size / 1_048_576, 2),
)
backups[backup.slug] = backup
except (OSError, tarfile.TarError, json.JSONDecodeError, KeyError) as err:
_LOGGER.warning("Unable to read backup %s: %s", backup_path, err)
return backups


class YaDsk:
""" Core integration class.
Contains all method for YandexDisk communication.
"""
_backup_observer = None
_token = None
_path = None
_upload_without_suffix = True
Expand All @@ -98,10 +158,10 @@ def file_amount(self):

@property
def file_markdown_list(self):
""" File list in markdown format """
""" File list in Markdown format """
return self._file_markdown_list

def __init__(self, hass: HomeAssistant, config: dict, unique_id=None):
def __init__(self, hass: HomeAssistant, backup_observer: BackupObserver, config: dict, unique_id=None):
self._options = {}
self._options.update(config)
self._token = config[CONF_TOKEN]
Expand All @@ -112,6 +172,7 @@ def __init__(self, hass: HomeAssistant, config: dict, unique_id=None):
self._client_id = config[CONF_CLIENT_ID]
self._client_s = config[CONF_CLIENT_SECRET]
self._hass = hass
self._backup_observer = backup_observer

def get_info(self):
""" Get class info """
Expand Down Expand Up @@ -144,7 +205,7 @@ async def list_yandex_disk(self):
def _list_yandex_disk(self):
""" List yandex disk directory.
Fill file amount< file markdown list and file simple list.
Fill file amount< file Markdown list and file simple list.
"""
try:
Expand Down Expand Up @@ -199,12 +260,11 @@ async def upload_files(self):
async def get_local_files_list(self):
""" Get list of home assistant backups """

manager: BackupManager = self._hass.data[BACKUP_DOMAIN]
backups = await manager.get_backups()
backups = await self._backup_observer.get_backups()

result = {}
for backup in backups.values():
key = backup.name + '_' + backup.slug
key = (backup.name + '_' + backup.slug).replace(" ","-").replace(":","_")
if not self._upload_without_suffix:
key += '.tar'
result[key] = backup.path
Expand Down

0 comments on commit ab9c5af

Please sign in to comment.