ovdashboard/api/ovdashboard_api/dav_common.py

173 lines
4.2 KiB
Python
Raw Normal View History

2022-09-05 12:54:02 +00:00
"""
Definition of WebDAV and CalDAV clients.
"""
2022-09-04 22:30:40 +00:00
from functools import lru_cache
2022-09-07 00:23:31 +00:00
from logging import getLogger
2022-09-19 11:42:43 +00:00
from os import path
from pathlib import Path
2022-09-07 00:23:31 +00:00
from time import sleep
from typing import Any, Iterator
2022-09-04 22:30:40 +00:00
2022-09-04 22:41:46 +00:00
from caldav import DAVClient as CalDAVclient
from caldav import Principal as CalDAVPrincipal
from webdav3.client import Client as WebDAVclient
from webdav3.client import Resource as WebDAVResource
2022-09-04 22:30:40 +00:00
2022-09-19 11:42:43 +00:00
from . import __file__ as OVD_INIT
2022-09-04 22:30:40 +00:00
from .async_helpers import run_in_executor
from .settings import SETTINGS
2023-10-17 12:55:38 +00:00
_WEBDAV_CLIENT = WebDAVclient(
{
"webdav_hostname": SETTINGS.webdav.url,
"webdav_login": SETTINGS.webdav.username,
"webdav_password": SETTINGS.webdav.password,
"disable_check": SETTINGS.webdav_disable_check,
}
)
2022-09-04 22:30:40 +00:00
2022-09-07 00:23:31 +00:00
_logger = getLogger(__name__)
def webdav_check() -> None:
2022-09-07 00:23:31 +00:00
"""
Checks if base resources are available.
"""
_logger.info(
"Production mode is %s.",
"enabled" if SETTINGS.production_mode else "disabled",
)
if SETTINGS.production_mode:
for _ in range(SETTINGS.webdav_retries):
if _WEBDAV_CLIENT.check(""):
break
_logger.warning(
"Waiting for WebDAV connection to %s ...",
repr(SETTINGS.webdav.url),
)
sleep(30)
2022-09-07 12:57:38 +00:00
_logger.debug("WebDAV connection ok.")
2022-09-07 00:23:31 +00:00
2022-09-07 12:57:38 +00:00
elif not _WEBDAV_CLIENT.check(""):
2022-09-07 00:23:31 +00:00
_logger.error(
"WebDAV connection to %s FAILED!",
repr(SETTINGS.webdav.url),
)
raise ConnectionError(SETTINGS.webdav.url)
2022-09-07 00:23:31 +00:00
2022-09-07 12:57:38 +00:00
_logger.debug("WebDAV connection ok.")
2022-09-07 00:23:31 +00:00
2022-09-07 12:57:38 +00:00
if not _WEBDAV_CLIENT.check(SETTINGS.webdav_prefix):
2022-09-07 00:23:31 +00:00
_logger.error(
"WebDAV prefix directory %s NOT FOUND, please create it!",
repr(SETTINGS.webdav_prefix),
)
raise FileNotFoundError(SETTINGS.webdav_prefix)
2022-09-07 00:23:31 +00:00
2022-09-07 12:57:38 +00:00
_logger.debug("WebDAV prefix directory found.")
2022-09-04 22:30:40 +00:00
2022-09-19 11:42:43 +00:00
def webdav_ensure_path(remote_path: str) -> bool:
2022-09-08 14:02:50 +00:00
remote_path = f"{SETTINGS.webdav_prefix}/{remote_path}"
if _WEBDAV_CLIENT.check(remote_path):
_logger.debug(
"WebDAV path %s found.",
repr(remote_path),
)
2022-09-19 11:42:43 +00:00
return True
2022-09-08 14:02:50 +00:00
_logger.info(
"WebDAV path %s not found, creating ...",
repr(remote_path),
)
_WEBDAV_CLIENT.mkdir(remote_path)
2022-09-19 11:42:43 +00:00
return False
def get_skel_path(skel_file: str) -> Path:
skel_path = path.dirname(Path(OVD_INIT).absolute())
return Path(skel_path).joinpath("skel", skel_file)
def webdav_upload_skel(remote_path: str, *skel_files: str) -> None:
remote_path = f"{SETTINGS.webdav_prefix}/{remote_path}"
for skel_file in skel_files:
_logger.debug(
"Creating WebDAV file %s ...",
repr(skel_file),
)
_WEBDAV_CLIENT.upload_file(
f"{remote_path}/{skel_file}",
get_skel_path(skel_file),
)
def webdav_ensure_files(remote_path: str, *file_names: str) -> None:
missing_files = (
file_name
for file_name in file_names
2023-10-17 12:55:38 +00:00
if not _WEBDAV_CLIENT.check(
path.join(
SETTINGS.webdav_prefix,
remote_path,
file_name,
)
)
2022-09-19 11:42:43 +00:00
)
webdav_upload_skel(
remote_path,
*missing_files,
)
2022-09-08 14:02:50 +00:00
2022-09-06 07:54:44 +00:00
@lru_cache(maxsize=SETTINGS.cache_size)
2022-09-04 22:41:46 +00:00
def webdav_resource(remote_path: Any) -> WebDAVResource:
2022-09-05 12:54:02 +00:00
"""
Gets a resource using the main WebDAV client.
"""
2023-10-17 12:55:38 +00:00
return _WEBDAV_CLIENT.resource(f"{SETTINGS.webdav_prefix}/{remote_path}")
2022-09-04 22:30:40 +00:00
@run_in_executor
2022-09-05 12:54:02 +00:00
def webdav_list(remote_path: str) -> list[str]:
"""
2022-09-07 12:21:26 +00:00
Asynchronously lists a WebDAV path using the main WebDAV client.
2022-09-05 12:54:02 +00:00
"""
2023-10-17 12:55:38 +00:00
return _WEBDAV_CLIENT.list(f"{SETTINGS.webdav_prefix}/{remote_path}")
2022-09-04 22:30:40 +00:00
2022-09-04 22:41:46 +00:00
_CALDAV_CLIENT = CalDAVclient(
2022-09-05 14:39:34 +00:00
url=SETTINGS.caldav.url,
username=SETTINGS.caldav.username,
password=SETTINGS.caldav.password,
2022-09-04 22:30:40 +00:00
)
2022-09-04 22:41:46 +00:00
def caldav_principal() -> CalDAVPrincipal:
2022-09-05 12:54:02 +00:00
"""
Gets the `Principal` object of the main CalDAV client.
"""
2022-09-04 22:30:40 +00:00
return _CALDAV_CLIENT.principal()
@run_in_executor
def caldav_list() -> Iterator[str]:
"""
2022-09-07 12:21:26 +00:00
Asynchronously lists all calendars using the main WebDAV client.
"""
2023-10-17 12:55:38 +00:00
return (str(cal.name) for cal in caldav_principal().calendars())