import logging from dataclasses import dataclass from io import BytesIO from typing import Any from webdav3.client import Resource from .async_helpers import get_ttl_hash, run_in_executor, timed_alru_cache from .dav_common import webdav_resource from .settings import SETTINGS _logger = logging.getLogger(__name__) @timed_alru_cache(maxsize=20) async def _get_buffer( remote_path: Any, ) -> BytesIO: @run_in_executor def _inner(resource: Resource) -> BytesIO: _logger.info(f"updating {resource.urn.filename()!r} ...") buffer = BytesIO() resource.write_to(buffer) return buffer resource = webdav_resource(remote_path) return await _inner(resource) @dataclass(frozen=True) class DavFile: remote_path: str @property async def __buffer(self) -> BytesIO: return await _get_buffer( ttl_hash=get_ttl_hash(SETTINGS.cache_seconds), remote_path=self.remote_path, ) @property def resource(self) -> Resource: return webdav_resource(self.remote_path) @property async def bytes(self) -> bytes: buffer = await self.__buffer buffer.seek(0) return buffer.read() @property async def string(self) -> str: bytes = await self.bytes return bytes.decode(encoding="utf-8") async def dump(self, content: bytes) -> None: @run_in_executor def _inner() -> None: buffer = BytesIO(content) self.resource.read_from(buffer) await _inner()