from webdav3.exceptions import WebDavException, ResponseErrorCode from webdav3.client import Client import storage.exceptions as StorageException from storage.utils import human_filesize from storage.storage import BaseStorage import logging logger = logging.getLogger(__name__) # WebDAV Support - https://pypi.org/project/webdavclient3/ class WebDAVStorage(BaseStorage): TYPE = 'webdav' def __connect(self): # Connect to the external storage. This function can be run multiple times. It will check if it has already a connection to re-use try: # When this fails with an Attribute error, that means that the 'client' variable is not set and we need to make a new connection assert(self.client) except AttributeError: # Because the 'client' variable is not known, the WebDAV connections is not created yet. So do it now! self.client = Client({ 'webdav_hostname': self.url, 'webdav_login': self.username, 'webdav_password': self.password, }) try: # Here we abuse the .free check to see if the login credentials do work free_space = self.client.free() logger.info(f'Created WebDAV connection to url: \'{self.url}\', with space left: {human_filesize(free_space)}') except ResponseErrorCode as ex: # Login went wrong, so delete the client variable for next run/try del(self.client) # If there was an authentication error, raise exception and quit. if 401 == ex.code: raise StorageException.InvalidAuthentication(self.username) # TODO: More errors..... def _file_exists_action(self, path): self.__connect() return self.client.check(path) def _directory_exists_action(self, path): self.__connect() return self.client.check(path) def _make_folder_action(self, path): self.__connect() self.client.mkdir(path) return True def _upload_file_action(self, source, destination): self.__connect() self.client.upload(local_path=source, remote_path=destination) return True def _download_file_action(self, source, destination): self.__connect() self.client.download(source, destination) return True