This commit is contained in:
Yuriy Khomyakov 2017-04-17 00:10:58 +03:00
commit e80fe6c108
18 changed files with 3633 additions and 0 deletions

0
webdav2/__init__.py Normal file
View file

1096
webdav2/client.py Normal file

File diff suppressed because it is too large Load diff

81
webdav2/connection.py Normal file
View file

@ -0,0 +1,81 @@
from webdav2.exceptions import *
from webdav2.urn import Urn
from os.path import exists
class ConnectionSettings:
def is_valid(self):
pass
def valid(self):
try:
self.is_valid()
except OptionNotValid:
return False
else:
return True
class WebDAVSettings(ConnectionSettings):
ns = "webdav:"
prefix = "webdav_"
keys = {'hostname', 'login', 'password', 'token', 'root', 'cert_path', 'key_path', 'recv_speed', 'send_speed', 'verbose'}
def __init__(self, options):
self.options = dict()
for key in self.keys:
value = options.get(key, '')
self.options[key] = value
self.__dict__[key] = value
self.root = Urn(self.root).quote() if self.root else ''
self.root = self.root.rstrip(Urn.separate)
def is_valid(self):
if not self.hostname:
raise OptionNotValid(name="hostname", value=self.hostname, ns=self.ns)
if self.cert_path and not exists(self.cert_path):
raise OptionNotValid(name="cert_path", value=self.cert_path, ns=self.ns)
if self.key_path and not exists(self.key_path):
raise OptionNotValid(name="key_path", value=self.key_path, ns=self.ns)
if self.key_path and not self.cert_path:
raise OptionNotValid(name="cert_path", value=self.cert_path, ns=self.ns)
if self.password and not self.login:
raise OptionNotValid(name="login", value=self.login, ns=self.ns)
if not self.token and not self.login:
raise OptionNotValid(name="login", value=self.login, ns=self.ns)
class ProxySettings(ConnectionSettings):
ns = "proxy:"
prefix = "proxy_"
keys = {'hostname', 'login', 'password'}
def __init__(self, options):
self.options = dict()
for key in self.keys:
value = options.get(key, '')
self.options[key] = value
self.__dict__[key] = value
def is_valid(self):
if self.password and not self.login:
raise OptionNotValid(name="login", value=self.login, ns=self.ns)
if self.login or self.password:
if not self.hostname:
raise OptionNotValid(name="hostname", value=self.hostname, ns=self.ns)

73
webdav2/exceptions.py Normal file
View file

@ -0,0 +1,73 @@
class WebDavException(Exception):
pass
class NotValid(WebDavException):
pass
class OptionNotValid(NotValid):
def __init__(self, name, value, ns=""):
self.name = name
self.value = value
self.ns = ns
def __str__(self):
return "Option ({ns}{name}={value}) have invalid name or value".format(ns=self.ns, name=self.name, value=self.value)
class CertificateNotValid(NotValid):
pass
class NotFound(WebDavException):
pass
class LocalResourceNotFound(NotFound):
def __init__(self, path):
self.path = path
def __str__(self):
return "Local file: {path} not found".format(path=self.path)
class RemoteResourceNotFound(NotFound):
def __init__(self, path):
self.path = path
def __str__(self):
return "Remote resource: {path} not found".format(path=self.path)
class RemoteParentNotFound(NotFound):
def __init__(self, path):
self.path = path
def __str__(self):
return "Remote parent for: {path} not found".format(path=self.path)
class MethodNotSupported(WebDavException):
def __init__(self, name, server):
self.name = name
self.server = server
def __str__(self):
return "Method {name} not supported for {server}".format(name=self.name, server=self.server)
class NotConnection(WebDavException):
def __init__(self, hostname):
self.hostname = hostname
def __str__(self):
return "Not connection with {hostname}".format(hostname=self.hostname)
class NotEnoughSpace(WebDavException):
def __init__(self):
pass
def __str__(self):
return "Not enough space on the server"

56
webdav2/urn.py Normal file
View file

@ -0,0 +1,56 @@
try:
from urllib.parse import unquote, quote
except ImportError:
from urllib import unquote, quote
from re import sub
class Urn(object):
separate = "/"
def __init__(self, path, directory=False):
self._path = quote(path)
expressions = "/\.+/", "/+"
for expression in expressions:
self._path = sub(expression, Urn.separate, self._path)
if not self._path.startswith(Urn.separate):
self._path = "{begin}{end}".format(begin=Urn.separate, end=self._path)
if directory and not self._path.endswith(Urn.separate):
self._path = "{begin}{end}".format(begin=self._path, end=Urn.separate)
def __str__(self):
return self.path()
def path(self):
return unquote(self._path)
def quote(self):
return self._path
def filename(self):
path_split = self._path.split(Urn.separate)
name = path_split[-2] + Urn.separate if path_split[-1] == '' else path_split[-1]
return unquote(name)
def parent(self):
path_split = self._path.split(Urn.separate)
nesting_level = self.nesting_level()
parent_path_split = path_split[:nesting_level]
parent = self.separate.join(parent_path_split) if nesting_level != 1 else Urn.separate
if not parent.endswith(Urn.separate):
return unquote(parent + Urn.separate)
else:
return unquote(parent)
def nesting_level(self):
return self._path.count(Urn.separate, 0, -1)
def is_dir(self):
return self._path[-1] == Urn.separate