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
|
|
|
|
from time import sleep
|
2022-09-05 23:53:53 +00:00
|
|
|
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
|
|
|
|
|
|
|
from .async_helpers import run_in_executor
|
|
|
|
from .settings import SETTINGS
|
|
|
|
|
2022-09-04 22:41:46 +00:00
|
|
|
_WEBDAV_CLIENT = WebDAVclient({
|
2022-09-09 02:56:22 +00:00
|
|
|
"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__)
|
|
|
|
|
|
|
|
|
2022-09-18 21:36:52 +00:00
|
|
|
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),
|
|
|
|
)
|
2022-09-18 21:36:52 +00:00
|
|
|
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),
|
|
|
|
)
|
2022-09-18 21:36:52 +00:00
|
|
|
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-08 14:02:50 +00:00
|
|
|
def webdav_ensure_path(remote_path: str) -> None:
|
|
|
|
remote_path = f"{SETTINGS.webdav_prefix}/{remote_path}"
|
|
|
|
|
|
|
|
if _WEBDAV_CLIENT.check(remote_path):
|
|
|
|
_logger.debug(
|
|
|
|
"WebDAV path %s found.",
|
|
|
|
repr(remote_path),
|
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
_logger.info(
|
|
|
|
"WebDAV path %s not found, creating ...",
|
|
|
|
repr(remote_path),
|
|
|
|
)
|
|
|
|
_WEBDAV_CLIENT.mkdir(remote_path)
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
"""
|
|
|
|
|
2022-09-05 20:17:27 +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
|
|
|
"""
|
|
|
|
|
2022-09-05 20:17:27 +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()
|
2022-09-05 23:53:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
@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.
|
2022-09-05 23:53:53 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
return (
|
2022-09-08 00:24:36 +00:00
|
|
|
str(cal.name)
|
2022-09-05 23:53:53 +00:00
|
|
|
for cal in caldav_principal().calendars()
|
|
|
|
)
|