Fix issues and tests
This commit is contained in:
parent
85b10d53c9
commit
8c7ee2e372
3 changed files with 111 additions and 56 deletions
|
@ -35,29 +35,39 @@ class BaseClientTestCase(unittest.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
self.client = Client(self.options)
|
||||
if path.exists(path=self.local_path_dir):
|
||||
shutil.rmtree(path=self.local_path_dir)
|
||||
self.clean_local_dir(self.local_path_dir)
|
||||
|
||||
def tearDown(self):
|
||||
if path.exists(path=self.local_path_dir):
|
||||
shutil.rmtree(path=self.local_path_dir)
|
||||
if self.client.check(remote_path=self.remote_path_dir):
|
||||
self.client.clean(remote_path=self.remote_path_dir)
|
||||
if self.client.check(remote_path=self.remote_path_dir2):
|
||||
self.client.clean(remote_path=self.remote_path_dir2)
|
||||
self.clean_local_dir(self.local_path_dir)
|
||||
self.clean_remote_dir(self.remote_path_dir)
|
||||
self.clean_remote_dir(self.remote_path_dir2)
|
||||
|
||||
def _prepare_for_downloading(self, inner_dir=False):
|
||||
if not self.client.check(remote_path=self.remote_path_dir):
|
||||
self.client.mkdir(remote_path=self.remote_path_dir)
|
||||
if not self.client.check(remote_path=self.remote_path_file):
|
||||
self.client.upload_file(remote_path=self.remote_path_file, local_path=self.local_file_path)
|
||||
def clean_remote_dir(self, remote_path_dir):
|
||||
if self.client.check(remote_path=remote_path_dir):
|
||||
self.client.clean(remote_path=remote_path_dir)
|
||||
|
||||
@staticmethod
|
||||
def clean_local_dir(local_path_dir):
|
||||
if path.exists(path=local_path_dir):
|
||||
shutil.rmtree(path=local_path_dir)
|
||||
|
||||
def _prepare_for_downloading(self, inner_dir=False, base_path=''):
|
||||
if base_path:
|
||||
self._create_remote_dir_if_needed(base_path)
|
||||
self._prepare_dir_for_downloading(base_path + self.remote_path_dir, base_path + self.remote_path_file, self.local_file_path)
|
||||
if not path.exists(self.local_path_dir):
|
||||
os.makedirs(self.local_path_dir)
|
||||
if inner_dir:
|
||||
if not self.client.check(remote_path=self.remote_inner_path_dir):
|
||||
self.client.mkdir(remote_path=self.remote_inner_path_dir)
|
||||
if not self.client.check(remote_path=self.remote_inner_path_file):
|
||||
self.client.upload_file(remote_path=self.remote_inner_path_file, local_path=self.local_file_path)
|
||||
self._prepare_dir_for_downloading(base_path + self.remote_inner_path_dir, base_path + self.remote_inner_path_file, self.local_file_path)
|
||||
|
||||
def _prepare_dir_for_downloading(self, remote_path_dir, remote_path_file, local_file_path):
|
||||
self._create_remote_dir_if_needed(remote_path_dir)
|
||||
if not self.client.check(remote_path=remote_path_file):
|
||||
self.client.upload_file(remote_path=remote_path_file, local_path=local_file_path)
|
||||
|
||||
def _create_remote_dir_if_needed(self, remote_dir):
|
||||
if not self.client.check(remote_path=remote_dir):
|
||||
self.client.mkdir(remote_path=remote_dir)
|
||||
|
||||
def _prepare_for_uploading(self):
|
||||
if not self.client.check(remote_path=self.remote_path_dir):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import os.path
|
||||
import shutil
|
||||
import unittest
|
||||
from io import BytesIO, StringIO
|
||||
from os import path
|
||||
|
@ -9,6 +10,7 @@ from webdav3.exceptions import MethodNotSupported, OptionNotValid, RemoteResourc
|
|||
|
||||
|
||||
class ClientTestCase(BaseClientTestCase):
|
||||
pulled_file = BaseClientTestCase.local_path_dir + os.sep + BaseClientTestCase.local_file
|
||||
|
||||
def test_list(self):
|
||||
self._prepare_for_downloading()
|
||||
|
@ -227,6 +229,55 @@ class ClientTestCase(BaseClientTestCase):
|
|||
def test_check_is_overridden(self):
|
||||
self.assertEqual('GET', self.client.requests['check'])
|
||||
|
||||
def test_pull_newer(self):
|
||||
init_modification_time = int(self._prepare_local_test_file_and_get_modification_time())
|
||||
sleep(1)
|
||||
self._prepare_for_downloading(base_path='time/')
|
||||
result = self.client.pull('time/' + self.remote_path_dir, self.local_path_dir)
|
||||
update_modification_time = int(os.path.getmtime(self.pulled_file))
|
||||
self.assertTrue(result)
|
||||
self.assertGreater(update_modification_time, init_modification_time)
|
||||
self.client.clean(remote_path='time/' + self.remote_path_dir)
|
||||
|
||||
def test_pull_older(self):
|
||||
self._prepare_for_downloading(base_path='time/')
|
||||
sleep(1)
|
||||
init_modification_time = int(self._prepare_local_test_file_and_get_modification_time())
|
||||
result = self.client.pull('time/' + self.remote_path_dir, self.local_path_dir)
|
||||
update_modification_time = int(os.path.getmtime(self.pulled_file))
|
||||
self.assertFalse(result)
|
||||
self.assertEqual(update_modification_time, init_modification_time)
|
||||
self.client.clean(remote_path='time/' + self.remote_path_dir)
|
||||
|
||||
def test_push_newer(self):
|
||||
self._prepare_for_downloading(base_path='time/')
|
||||
sleep(1)
|
||||
self._prepare_for_uploading()
|
||||
init_modification_time = self.client.info('time/' + self.remote_path_file)['modified']
|
||||
result = self.client.push('time/' + self.remote_path_dir, self.local_path_dir)
|
||||
update_modification_time = self.client.info('time/' + self.remote_path_file)['modified']
|
||||
self.assertTrue(result)
|
||||
self.assertNotEqual(init_modification_time, update_modification_time)
|
||||
self.client.clean(remote_path='time/' + self.remote_path_dir)
|
||||
|
||||
def test_push_older(self):
|
||||
self._prepare_for_uploading()
|
||||
sleep(1)
|
||||
self._prepare_for_downloading(base_path='time/')
|
||||
init_modification_time = self.client.info('time/' + self.remote_path_file)['modified']
|
||||
result = self.client.push('time/' + self.remote_path_dir, self.local_path_dir)
|
||||
update_modification_time = self.client.info('time/' + self.remote_path_file)['modified']
|
||||
self.assertFalse(result)
|
||||
self.assertEqual(init_modification_time, update_modification_time)
|
||||
self.client.clean(remote_path='time/' + self.remote_path_dir)
|
||||
|
||||
def _prepare_local_test_file_and_get_modification_time(self):
|
||||
if not path.exists(path=self.local_path_dir):
|
||||
os.mkdir(self.local_path_dir)
|
||||
if not path.exists(path=self.local_path_dir + os.sep + self.local_file):
|
||||
shutil.copy(src=self.local_file_path, dst=self.pulled_file)
|
||||
return os.path.getmtime(self.pulled_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -671,51 +671,39 @@ class Client(object):
|
|||
def prune(src, exp):
|
||||
return [sub(exp, "", item) for item in src]
|
||||
|
||||
updated = False
|
||||
urn = Urn(remote_directory, directory=True)
|
||||
|
||||
if not self.is_dir(urn.path()):
|
||||
raise OptionNotValid(name="remote_path", value=remote_directory)
|
||||
|
||||
if not os.path.isdir(local_directory):
|
||||
raise OptionNotValid(name="local_path", value=local_directory)
|
||||
|
||||
if not os.path.exists(local_directory):
|
||||
raise LocalResourceNotFound(local_directory)
|
||||
self._validate_remote_directory(urn)
|
||||
self._validate_local_directory(local_directory)
|
||||
|
||||
paths = self.list(urn.path())
|
||||
expression = "{begin}{end}".format(begin="^", end=urn.path())
|
||||
remote_resource_names = prune(paths, expression)
|
||||
|
||||
for local_resource_name in listdir(local_directory):
|
||||
|
||||
local_path = os.path.join(local_directory, local_resource_name)
|
||||
remote_path = "{remote_directory}{resource_name}".format(remote_directory=urn.path(),
|
||||
resource_name=local_resource_name)
|
||||
remote_path = "{remote_directory}{resource_name}".format(remote_directory=urn.path(), resource_name=local_resource_name)
|
||||
|
||||
if os.path.isdir(local_path):
|
||||
if not self.check(remote_path=remote_path):
|
||||
self.mkdir(remote_path=remote_path)
|
||||
self.push(remote_directory=remote_path, local_directory=local_path)
|
||||
result = self.push(remote_directory=remote_path, local_directory=local_path)
|
||||
updated = updated or result
|
||||
else:
|
||||
if local_resource_name in remote_resource_names:
|
||||
if self.is_local_more_recent(local_path, remote_path):
|
||||
continue
|
||||
if local_resource_name in remote_resource_names and not self.is_local_more_recent(local_path, remote_path):
|
||||
continue
|
||||
self.upload_file(remote_path=remote_path, local_path=local_path)
|
||||
|
||||
updated = True
|
||||
return updated
|
||||
|
||||
def pull(self, remote_directory, local_directory):
|
||||
def prune(src, exp):
|
||||
return [sub(exp, "", item) for item in src]
|
||||
|
||||
updated = False
|
||||
|
||||
urn = Urn(remote_directory, directory=True)
|
||||
|
||||
if not self.is_dir(urn.path()):
|
||||
raise OptionNotValid(name="remote_path", value=remote_directory)
|
||||
|
||||
if not os.path.exists(local_directory):
|
||||
raise LocalResourceNotFound(local_directory)
|
||||
self._validate_remote_directory(urn)
|
||||
self._validate_local_directory(local_directory)
|
||||
|
||||
local_resource_names = listdir(local_directory)
|
||||
|
||||
|
@ -724,23 +712,19 @@ class Client(object):
|
|||
remote_resource_names = prune(paths, expression)
|
||||
|
||||
for remote_resource_name in remote_resource_names:
|
||||
|
||||
local_path = os.path.join(local_directory, remote_resource_name)
|
||||
remote_path = "{remote_directory}{resource_name}".format(remote_directory=urn.path(),
|
||||
resource_name=remote_resource_name)
|
||||
|
||||
remote_path = "{remote_directory}{resource_name}".format(remote_directory=urn.path(), resource_name=remote_resource_name)
|
||||
remote_urn = Urn(remote_path)
|
||||
|
||||
if remote_urn.path().endswith("/"):
|
||||
if not os.path.exists(local_path):
|
||||
updated = True
|
||||
os.mkdir(local_path)
|
||||
self.pull(remote_directory=remote_path, local_directory=local_path)
|
||||
result = self.pull(remote_directory=remote_path, local_directory=local_path)
|
||||
updated = updated or result
|
||||
else:
|
||||
if remote_resource_name in local_resource_names:
|
||||
# Skip pull if local resource is more recent of we can't tell
|
||||
if self.is_local_more_recent(local_path, remote_path) in (True, None):
|
||||
continue
|
||||
if remote_resource_name in local_resource_names and self.is_local_more_recent(local_path, remote_path):
|
||||
continue
|
||||
|
||||
self.download_file(remote_path=remote_path, local_path=local_path)
|
||||
updated = True
|
||||
|
@ -757,15 +741,13 @@ class Client(object):
|
|||
"""
|
||||
try:
|
||||
remote_info = self.info(remote_path)
|
||||
# Try to compare modification dates if our server
|
||||
# offers that information
|
||||
remote_last_mod_date = remote_info['modified']
|
||||
remote_last_mod_date = dateutil_parser.parse(remote_last_mod_date)
|
||||
remote_last_mod_date_unix_ts = int(remote_last_mod_date.strftime("%s"))
|
||||
local_last_mod_date_unix_ts = os.stat(local_path).st_mtime
|
||||
remote_last_mod_date_unix_ts = int(remote_last_mod_date.timestamp())
|
||||
local_last_mod_date_unix_ts = int(os.stat(local_path).st_mtime)
|
||||
|
||||
return (local_last_mod_date_unix_ts > remote_last_mod_date_unix_ts)
|
||||
except:
|
||||
return remote_last_mod_date_unix_ts < local_last_mod_date_unix_ts
|
||||
except ValueError or RuntimeWarning or KeyError:
|
||||
# If there is problem when parsing dates, or cannot get
|
||||
# last modified information, return None
|
||||
return None
|
||||
|
@ -774,6 +756,18 @@ class Client(object):
|
|||
self.pull(remote_directory=remote_directory, local_directory=local_directory)
|
||||
self.push(remote_directory=remote_directory, local_directory=local_directory)
|
||||
|
||||
def _validate_remote_directory(self, urn):
|
||||
if not self.is_dir(urn.path()):
|
||||
raise OptionNotValid(name="remote_path", value=urn.path())
|
||||
|
||||
@staticmethod
|
||||
def _validate_local_directory(local_directory):
|
||||
if not os.path.isdir(local_directory):
|
||||
raise OptionNotValid(name="local_path", value=local_directory)
|
||||
|
||||
if not os.path.exists(local_directory):
|
||||
raise LocalResourceNotFound(local_directory)
|
||||
|
||||
|
||||
class Resource(object):
|
||||
def __init__(self, client, urn):
|
||||
|
|
Loading…
Add table
Reference in a new issue