Пример #1
0
    def download_file(self, remote_path, local_path):

        urn = Urn(remote_path)

        if self.is_dir(urn.path()):
            raise OptionNotValid(name="remote_path", value=remote_path)

        if os.path.isdir(local_path):
            raise OptionNotValid(name="local_path", value=local_path)

        if not self.check(urn.path()):
            raise RemoteResourceNotFound(urn.path())

        with open(local_path, 'wb') as local_file:

            url = {
                'hostname': self.webdav.hostname,
                'root': self.webdav.root,
                'path': urn.quote()
            }
            options = {
                'URL': "{hostname}{root}{path}".format(**url),
                'HTTPHEADER': self.get_header('download_file'),
                'WRITEDATA': local_file,
                'NOBODY': 0
            }

            response = requests.request(
                "GET",
                options["URL"],
                auth=(self.webdav.login, self.webdav.password),
                headers=self.get_header('download_file'))
            for block in response.iter_content(1024):
                local_file.write(block)
Пример #2
0
    def upload_from(self, buff, remote_path):

        urn = Urn(remote_path)

        if urn.is_dir():
            raise OptionNotValid(name="remote_path", value=remote_path)

        if not self.check(urn.parent()):
            raise RemoteParentNotFound(urn.path())

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
        }
        # import ipdb; ipdb.set_trace();
        #FIXME
        if buff.tell() == 0:
            data = buff.read()
        else:
            data = buff
        response = requests.request('PUT',
                                    options["URL"],
                                    auth=(self.webdav.login,
                                          self.webdav.password),
                                    headers=self.get_header('upload_from'),
                                    data=data)
        if response.status_code == 507:
            raise NotEnoughSpace()
        log.debug("Response: %s", response)
Пример #3
0
    def upload_file(self, remote_path, local_path, progress=None):

        if not os.path.exists(local_path):
            raise LocalResourceNotFound(local_path)

        urn = Urn(remote_path)

        if urn.is_dir():
            raise OptionNotValid(name="remote_path", value=remote_path)

        if os.path.isdir(local_path):
            raise OptionNotValid(name="local_path", value=local_path)

        if not self.check(urn.parent()):
            raise RemoteParentNotFound(urn.path())

        with open(local_path, "rb") as local_file:

            url = {
                'hostname': self.webdav.hostname,
                'root': self.webdav.root,
                'path': urn.quote()
            }
            options = {
                'URL': "{hostname}{root}{path}".format(**url),
                'HTTPHEADER': self.get_header('upload_file'),
                'UPLOAD': 1,
                'READFUNCTION': local_file.read,
                # 'NOPROGRESS': 0 if progress else 1
            }

            # if progress:
            #    options["PROGRESSFUNCTION"] = progress

            file_size = os.path.getsize(local_path)
            if file_size > self.large_size:
                options['INFILESIZE_LARGE'] = file_size
            else:
                options['INFILESIZE'] = file_size

            response = requests.request('PUT',
                                        options["URL"],
                                        auth=(self.webdav.login,
                                              self.webdav.password),
                                        headers=self.get_header('upload_file'),
                                        data=buff)
            if request.status_code == 507:
                raise NotEnoughSpace()
            if response.status_code == 409:
                raise Conflict()
Пример #4
0
    def get_property(self, remote_path, option):
        def parse(response, option):

            response_str = response.content
            tree = etree.fromstring(response_str)
            xpath = "{xpath_prefix}{xpath_exp}".format(
                xpath_prefix=".//", xpath_exp=option['name'])
            return tree.findtext(xpath)

        def data(option):

            root = etree.Element("propfind", xmlns="DAV:")
            prop = etree.SubElement(root, "prop")
            etree.SubElement(prop,
                             option.get('name', ""),
                             xmlns=option.get('namespace', ""))
            tree = etree.ElementTree(root)

            buff = BytesIO()

            tree.write(buff)
            return buff.getvalue()

        urn = Urn(remote_path)

        if not self.check(urn.path()):
            raise RemoteResourceNotFound(urn.path())

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
            'CUSTOMREQUEST': Client.requests['get_metadata'],
            'HTTPHEADER': self.get_header('get_metadata'),
            'POSTFIELDS': data(option),
            'NOBODY': 0
        }

        response = requests.request(options["CUSTOMREQUEST"],
                                    options["URL"],
                                    auth=(self.webdav.login,
                                          self.webdav.password),
                                    headers=self.get_header('get_metadata'),
                                    data=data(option))
        return parse(response, option)
Пример #5
0
    def list(self, remote_path=root):
        def parse(response):

            try:
                response_str = response.content
                tree = etree.fromstring(response_str)
                hrees = [
                    unquote(hree.text)
                    for hree in tree.findall(".//{DAV:}href")
                ]
                return [Urn(hree) for hree in hrees]
            except etree.XMLSyntaxError:
                return list()

        directory_urn = Urn(remote_path, directory=True)

        if directory_urn.path() != Client.root:
            if not self.check(directory_urn.path()):
                raise RemoteResourceNotFound(directory_urn.path())

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': directory_urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
            'CUSTOMREQUEST': Client.requests['list'],
            'HTTPHEADER': self.get_header('list'),
            'NOBODY': 0
        }

        response = requests.request(options["CUSTOMREQUEST"],
                                    options["URL"],
                                    auth=(self.webdav.login,
                                          self.webdav.password),
                                    headers=self.get_header('list'))

        urns = parse(response)

        path = "{root}{path}".format(root=self.webdav.root,
                                     path=directory_urn.path())
        return [
            urn.filename() for urn in urns
            if urn.path() != path and urn.path() != path[:-1]
        ]
Пример #6
0
    def set_property(self, remote_path, option):
        def data(option):

            root_node = etree.Element("propertyupdate", xmlns="DAV:")
            root_node.set('xmlns:u', option.get('namespace', ""))
            set_node = etree.SubElement(root_node, "set")
            prop_node = etree.SubElement(set_node, "prop")
            opt_node = etree.SubElement(
                prop_node, "{namespace}:{name}".format(namespace='u',
                                                       name=option['name']))
            opt_node.text = option.get('value', "")

            tree = etree.ElementTree(root_node)

            buff = BytesIO()
            tree.write(buff)

            return buff.getvalue()

        urn = Urn(remote_path)

        if not self.check(urn.path()):
            raise RemoteResourceNotFound(urn.path())

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
            'CUSTOMREQUEST': Client.requests['set_metadata'],
            'HTTPHEADER': self.get_header('get_metadata'),
            'POSTFIELDS': data(option)
        }

        response = requests.request(options["CUSTOMREQUEST"],
                                    options["URL"],
                                    auth=(self.webdav.login,
                                          self.webdav.password),
                                    headers=self.get_header('get_metadata'),
                                    data=data(option))
Пример #7
0
    def clean(self, remote_path):

        urn = Urn(remote_path)

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
            'CUSTOMREQUEST': Client.requests['clean'],
            'HTTPHEADER': self.get_header('clean')
        }

        response = requests.request(
            options["CUSTOMREQUEST"],
            options["URL"],
            auth=(self.webdav.login, self.webdav.password),
            headers=self.get_header('clean'),
        )
Пример #8
0
    def copy(self, remote_path_from, remote_path_to):
        def header(remote_path_to):

            path = Urn(remote_path_to).path()
            destination = "{root}{path}".format(root=self.webdav.root,
                                                path=path)
            header = self.get_header('copy')
            header["Destination"] = destination

            return header

        urn_from = Urn(remote_path_from)

        if not self.check(urn_from.path()):
            raise RemoteResourceNotFound(urn_from.path())

        urn_to = Urn(remote_path_to)

        if not self.check(urn_to.parent()):
            raise RemoteParentNotFound(urn_to.path())

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': urn_from.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
            'CUSTOMREQUEST': Client.requests['copy'],
            'HTTPHEADER': header(remote_path_to)
        }

        h = header(remote_path_to)
        response = requests.request(
            options["CUSTOMREQUEST"],
            options["URL"],
            auth=(self.webdav.login, self.webdav.password),
            headers=h,
        )
Пример #9
0
    def mkdir(self, remote_path):

        directory_urn = Urn(remote_path, directory=True)

        if not self.check(directory_urn.parent()):
            raise RemoteParentNotFound(directory_urn.path())

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': directory_urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
            'CUSTOMREQUEST': Client.requests['mkdir'],
        }

        response = requests.request(options["CUSTOMREQUEST"],
                                    options["URL"],
                                    auth=(self.webdav.login,
                                          self.webdav.password),
                                    headers=self.get_header('mkdir'))
Пример #10
0
    def check(self, remote_path=root):
        urn = Urn(remote_path)
        response = BytesIO()

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
            'CUSTOMREQUEST': Client.requests['check'],
        }

        response = requests.request(options["CUSTOMREQUEST"],
                                    options["URL"],
                                    auth=(self.webdav.login,
                                          self.webdav.password),
                                    headers=self.get_header('check'))

        if int(response.status_code) == 200:
            return True
        return False
Пример #11
0
    def download_to(self, buff, remote_path):
        urn = Urn(remote_path)

        if self.is_dir(urn.path()):
            raise OptionNotValid(name="remote_path", value=remote_path)

        if not self.check(urn.path()):
            raise RemoteResourceNotFound(urn.path())

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
        }

        response = requests.request("GET",
                                    options["URL"],
                                    auth=(self.webdav.login,
                                          self.webdav.password),
                                    headers=self.get_header('download_to'))
        buff.write(response.content)
Пример #12
0
    def is_dir(self, remote_path):
        def parse(response, path):

            try:
                response_str = response.content
                tree = etree.fromstring(response_str)

                resps = tree.findall("{DAV:}response")

                for resp in resps:
                    href = resp.findtext("{DAV:}href")
                    urn = unquote(href)

                    if path[-1] == Urn.separate:
                        if not path == urn:
                            continue
                    else:
                        path_with_sep = "{path}{sep}".format(path=path,
                                                             sep=Urn.separate)
                        if not path == urn and not path_with_sep == urn:
                            continue
                    type = resp.find(".//{DAV:}resourcetype")
                    if type is None:
                        raise MethodNotSupported(name="is_dir",
                                                 server=self.webdav.hostname)
                    dir_type = type.find("{DAV:}collection")

                    return True if dir_type is not None else False

                raise RemoteResourceNotFound(path)

            except etree.XMLSyntaxError:
                raise MethodNotSupported(name="is_dir",
                                         server=self.webdav.hostname)

        urn = Urn(remote_path)
        parent_urn = Urn(urn.parent())
        if not self.check(urn.path()) and not self.check(
                Urn(remote_path, directory=True).path()):
            raise RemoteResourceNotFound(remote_path)

        response = BytesIO()

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': parent_urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
            'CUSTOMREQUEST': Client.requests['info'],
        }

        response = requests.request(options["CUSTOMREQUEST"],
                                    options["URL"],
                                    auth=(self.webdav.login,
                                          self.webdav.password),
                                    headers=self.get_header('info'))

        path = "{root}{path}".format(root=self.webdav.root, path=urn.path())

        return parse(response, path)
Пример #13
0
    def info(self, remote_path):
        def parse(response, path):

            try:
                response_str = response.content
                tree = etree.fromstring(response_str)

                find_attributes = {
                    'created': ".//{DAV:}creationdate",
                    'name': ".//{DAV:}displayname",
                    'size': ".//{DAV:}getcontentlength",
                    'modified': ".//{DAV:}getlastmodified"
                }

                resps = tree.findall("{DAV:}response")

                for resp in resps:
                    href = resp.findtext("{DAV:}href")
                    urn = unquote(href)

                    if path[-1] == Urn.separate:
                        if not path == urn:
                            continue
                    else:
                        path_with_sep = "{path}{sep}".format(path=path,
                                                             sep=Urn.separate)
                        if not path == urn and not path_with_sep == urn:
                            continue

                    info = dict()
                    for (name, value) in find_attributes.items():
                        info[name] = resp.findtext(value)
                    return info

                raise RemoteResourceNotFound(path)
            except etree.XMLSyntaxError:
                raise MethodNotSupported(name="info",
                                         server=self.webdav.hostname)

        urn = Urn(remote_path)
        # response = BytesIO()

        if not self.check(urn.path()) and not self.check(
                Urn(remote_path, directory=True).path()):
            raise RemoteResourceNotFound(remote_path)

        url = {
            'hostname': self.webdav.hostname,
            'root': self.webdav.root,
            'path': urn.quote()
        }
        options = {
            'URL': "{hostname}{root}{path}".format(**url),
            'CUSTOMREQUEST': Client.requests['info'],
        }

        response = requests.request(options["CUSTOMREQUEST"],
                                    options["URL"],
                                    auth=(self.webdav.login,
                                          self.webdav.password),
                                    headers=self.get_header('info'))
        path = "{root}{path}".format(root=self.webdav.root, path=urn.path())
        return parse(response, path)