Exemplo n.º 1
0
class WebDavServiceBase:
    def __init__(self, conf: WebDavConfig):
        url = f"http{'s' if conf.use_https else ''}://{conf.host}:{conf.port}{conf.path}{conf.root_dir}"
        options = {
            'webdav_hostname': url,
            'webdav_login': conf.username,
            'webdav_password': conf.password,
            'webdav_timeout': 600
        }
        self.client = Client(options)
        if conf.force_direct:
            self.client.session.proxies = {}
        self.sem = threading.Semaphore(5)

    def dir_exists(self, path: str):
        try:
            # rclone doesn't allow you check an existing dir
            return self.client.check(path)
        except webdav3.exceptions.MethodNotSupported as e:
            print(e)
            return True

    def ensure_dir(self, tag: str, path: str):
        service_name = f"{SERVICE_NAME}:{tag}"
        if ServiceKVStore.exists(service_name, path):
            return
        if self.dir_exists(path):
            ServiceKVStore.put(service_name, path, {})
            return
        self.client.mkdir(path)
        ServiceKVStore.put(service_name, path, {})

    def write_file(self, tag: str, service: ServiceType, dir_name: str,
                   filename: str, buffer: IO):
        with self.sem:
            self.ensure_dir(tag, service.value)
            self.ensure_dir(tag, f"{service.value}/{dir_name}")
            fp = f"{service.value}/{dir_name}/{filename}"
            with NamedTemporaryFile() as f:
                f.write(buffer.read())
                f.flush()
                try:
                    self.client.upload(fp, f.name)
                except webdav3.exceptions.RemoteParentNotFound as err:
                    print(err)
                    pp = f"{service.value}/{dir_name}"
                    # assert not ServiceKVStore.exists(SERVICE_NAME, pp)
                    # self.client.mkdir(pp)
                    from webdav3.urn import Urn
                    directory_urn = Urn(pp, directory=True)
                    response = self.client.execute_request(
                        action='mkdir', path=directory_urn.quote())
                    assert response in (200, 201), response

                    ServiceKVStore.put(SERVICE_NAME, pp, {})
                    self.client.upload(fp, f.name)
            return fp
 def test_auth_invoked(self, mock_session):
     client = Client(self.options)
     client.session.auth.return_value = True
     client.session.request.return_value.status_code = 200
     client.execute_request(action='list', path='')
     client.session.request.assert_any_call(method="GET",
                                            url='http://localhost:8585',
                                            verify=True,
                                            timeout=30)
     client.session.request.assert_any_call(auth=None,
                                            cert=None,
                                            data=None,
                                            headers={
                                                'Accept': '*/*',
                                                'Depth': '1'
                                            },
                                            method='PROPFIND',
                                            stream=True,
                                            timeout=30,
                                            url='http://localhost:8585',
                                            verify=True)