Added method for settings of WebDAV resource property values in batch.
Prepared for release 0.5
This commit is contained in:
		
							parent
							
								
									354cf64d22
								
							
						
					
					
						commit
						743f8b96bb
					
				
					 6 changed files with 99 additions and 21 deletions
				
			
		| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
python setup.py register -r pypitestCOPYRIGHT AND PERMISSION NOTICE
 | 
					COPYRIGHT AND PERMISSION NOTICE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Copyright (c) 2016, The WDC Project, and many
 | 
					Copyright (c) 2016, The WDC Project, and many
 | 
				
			||||||
contributors, see the THANKS file.
 | 
					contributors, see the THANKS file.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,10 +7,14 @@ But uses `requests` instead of `PyCURL`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Release Notes
 | 
					Release Notes
 | 
				
			||||||
=============
 | 
					=============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Version 0.5 – 03.12.2017
 | 
				
			||||||
 | 
					* Added method for setting of WebDAV resource property values in batch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Version 0.4 - 27.11.2017
 | 
					Version 0.4 - 27.11.2017
 | 
				
			||||||
* Refactoring of WebDAV client and making it works in following methods:
 | 
					* Refactoring of WebDAV client and making it works in following methods:
 | 
				
			||||||
    - Checking is remote resource directory
 | 
					    - Checking is remote resource directory
 | 
				
			||||||
    - Fixed problem when connection lost during request executing and nothing was happened, now it raises an exception.
 | 
					    - Fixed problem when connection lost during request executing and nothing was happened, now it raises an exception
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Version 0.3 - 18.10.2017
 | 
					Version 0.3 - 18.10.2017
 | 
				
			||||||
* Refactoring of WebDAV client and making it works in following methods:
 | 
					* Refactoring of WebDAV client and making it works in following methods:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								setup.py
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								setup.py
									
										
									
									
									
								
							| 
						 | 
					@ -6,7 +6,7 @@ from setuptools import setup, find_packages
 | 
				
			||||||
from setuptools.command.install import install as InstallCommand
 | 
					from setuptools.command.install import install as InstallCommand
 | 
				
			||||||
from setuptools.command.test import test as TestCommand
 | 
					from setuptools.command.test import test as TestCommand
 | 
				
			||||||
 | 
					
 | 
				
			||||||
version = "0.4"
 | 
					version = "0.5"
 | 
				
			||||||
requirements = "libxml2-dev libxslt-dev python-dev"
 | 
					requirements = "libxml2-dev libxslt-dev python-dev"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,10 +160,18 @@ class ClientTestCase(TestCase):
 | 
				
			||||||
        self.assertTrue('created' in result)
 | 
					        self.assertTrue('created' in result)
 | 
				
			||||||
        self.assertTrue('modified' in result)
 | 
					        self.assertTrue('modified' in result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_property(self):
 | 
					    def test_directory_is_dir(self):
 | 
				
			||||||
 | 
					        self._prepare_for_downloading()
 | 
				
			||||||
 | 
					        self.assertTrue(self.client.is_dir(self.remote_path_dir), 'Should return True for directory')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_file_is_not_dir(self):
 | 
				
			||||||
 | 
					        self._prepare_for_downloading()
 | 
				
			||||||
 | 
					        self.assertFalse(self.client.is_dir(self.remote_path_file), 'Should return False for file')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_get_property_of_non_exist(self):
 | 
				
			||||||
        self._prepare_for_downloading()
 | 
					        self._prepare_for_downloading()
 | 
				
			||||||
        result = self.client.get_property(remote_path=self.remote_path_file, option={'name': 'aProperty'})
 | 
					        result = self.client.get_property(remote_path=self.remote_path_file, option={'name': 'aProperty'})
 | 
				
			||||||
        self.assertEquals(result, None)
 | 
					        self.assertEquals(result, None, 'For not found property should return value as None')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_set_property(self):
 | 
					    def test_set_property(self):
 | 
				
			||||||
        self._prepare_for_downloading()
 | 
					        self._prepare_for_downloading()
 | 
				
			||||||
| 
						 | 
					@ -174,7 +182,28 @@ class ClientTestCase(TestCase):
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        result = self.client.get_property(remote_path=self.remote_path_file,
 | 
					        result = self.client.get_property(remote_path=self.remote_path_file,
 | 
				
			||||||
                                          option={'namespace': 'test', 'name': 'aProperty'})
 | 
					                                          option={'namespace': 'test', 'name': 'aProperty'})
 | 
				
			||||||
        self.assertEquals(result, "aValue")
 | 
					        self.assertEquals(result, 'aValue', 'Property value should be set')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_set_property_batch(self):
 | 
				
			||||||
 | 
					        self._prepare_for_downloading()
 | 
				
			||||||
 | 
					        self.client.set_property_batch(remote_path=self.remote_path_file, option=[
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'namespace': 'test',
 | 
				
			||||||
 | 
					                'name': 'aProperty',
 | 
				
			||||||
 | 
					                'value': 'aValue'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'namespace': 'test',
 | 
				
			||||||
 | 
					                'name': 'aProperty2',
 | 
				
			||||||
 | 
					                'value': 'aValue2'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ])
 | 
				
			||||||
 | 
					        result = self.client.get_property(remote_path=self.remote_path_file,
 | 
				
			||||||
 | 
					                                          option={'namespace': 'test', 'name': 'aProperty'})
 | 
				
			||||||
 | 
					        self.assertEquals(result, 'aValue', 'First property value should be set')
 | 
				
			||||||
 | 
					        result = self.client.get_property(remote_path=self.remote_path_file,
 | 
				
			||||||
 | 
					                                          option={'namespace': 'test', 'name': 'aProperty2'})
 | 
				
			||||||
 | 
					        self.assertEquals(result, 'aValue2', 'Second property value should be set')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _prepare_for_downloading(self):
 | 
					    def _prepare_for_downloading(self):
 | 
				
			||||||
        if not self.client.check(remote_path=self.remote_path_dir):
 | 
					        if not self.client.check(remote_path=self.remote_path_dir):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,24 +72,56 @@ class ClientTestCase(TestCase):
 | 
				
			||||||
        result = utils.parse_get_property_response(content=content, name='aProperty')
 | 
					        result = utils.parse_get_property_response(content=content, name='aProperty')
 | 
				
			||||||
        self.assertEquals(result, 'aValue')
 | 
					        self.assertEquals(result, 'aValue')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_set_property_request_content(self):
 | 
					    def test_create_set_one_property_request_content(self):
 | 
				
			||||||
        option = {
 | 
					        option = {
 | 
				
			||||||
            'namespace': 'test',
 | 
					            'namespace': 'test',
 | 
				
			||||||
            'name': 'aProperty',
 | 
					            'name': 'aProperty',
 | 
				
			||||||
            'value': 'aValue'
 | 
					            'value': 'aValue'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        result = utils.create_set_property_request_content(option=option)
 | 
					        result = utils.create_set_property_batch_request_content(options=[option])
 | 
				
			||||||
        self.assertEquals(result, '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<propertyupdate xmlns="DAV:"><set><prop>'
 | 
					        self.assertEquals(result, '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<propertyupdate xmlns="DAV:"><set><prop>'
 | 
				
			||||||
                                  '<aProperty xmlns="test">aValue</aProperty></prop></set></propertyupdate>')
 | 
					                                  '<aProperty xmlns="test">aValue</aProperty></prop></set></propertyupdate>')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_set_property_request_content_name_only(self):
 | 
					    def test_create_set_one_property_request_content_name_only(self):
 | 
				
			||||||
        option = {
 | 
					        option = {
 | 
				
			||||||
            'name': 'aProperty'
 | 
					            'name': 'aProperty'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        result = utils.create_set_property_request_content(option=option)
 | 
					        result = utils.create_set_property_batch_request_content(options=[option])
 | 
				
			||||||
        self.assertEquals(result, '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<propertyupdate xmlns="DAV:"><set><prop>'
 | 
					        self.assertEquals(result, '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<propertyupdate xmlns="DAV:"><set><prop>'
 | 
				
			||||||
                                  '<aProperty xmlns=""></aProperty></prop></set></propertyupdate>')
 | 
					                                  '<aProperty xmlns=""></aProperty></prop></set></propertyupdate>')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_create_set_property_batch_request_content(self):
 | 
				
			||||||
 | 
					        options = [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'namespace': 'test',
 | 
				
			||||||
 | 
					                'name': 'aProperty',
 | 
				
			||||||
 | 
					                'value': 'aValue'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'namespace': 'test2',
 | 
				
			||||||
 | 
					                'name': 'aProperty2',
 | 
				
			||||||
 | 
					                'value': 'aValue2'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        result = utils.create_set_property_batch_request_content(options=options)
 | 
				
			||||||
 | 
					        self.assertEquals(result, '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<propertyupdate xmlns="DAV:"><set><prop>'
 | 
				
			||||||
 | 
					                                  '<aProperty xmlns="test">aValue</aProperty><aProperty2 xmlns="test2">aValue2'
 | 
				
			||||||
 | 
					                                  '</aProperty2></prop></set></propertyupdate>')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_create_set_property_batch_request_content_name_only(self):
 | 
				
			||||||
 | 
					        options = [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'name': 'aProperty'
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'name': 'aProperty2'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        result = utils.create_set_property_batch_request_content(options=options)
 | 
				
			||||||
 | 
					        self.assertEquals(result, '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<propertyupdate xmlns="DAV:"><set><prop>'
 | 
				
			||||||
 | 
					                                  '<aProperty xmlns=""></aProperty><aProperty2 xmlns=""></aProperty2></prop></set>'
 | 
				
			||||||
 | 
					                                  '</propertyupdate>')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_etree_to_string(self):
 | 
					    def test_etree_to_string(self):
 | 
				
			||||||
        tree = ElementTree(Element('test'))
 | 
					        tree = ElementTree(Element('test'))
 | 
				
			||||||
        result = utils.etree_to_string(tree)
 | 
					        result = utils.etree_to_string(tree)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -575,7 +575,6 @@ class Client(object):
 | 
				
			||||||
        path = self.get_full_path(urn)
 | 
					        path = self.get_full_path(urn)
 | 
				
			||||||
        return WebDavXmlUtils.parse_info_response(content=response.content, path=path, hostname=self.webdav.hostname)
 | 
					        return WebDavXmlUtils.parse_info_response(content=response.content, path=path, hostname=self.webdav.hostname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # TODO refactor code below and write tests for it.
 | 
					 | 
				
			||||||
    @wrap_connection_error
 | 
					    @wrap_connection_error
 | 
				
			||||||
    def is_dir(self, remote_path):
 | 
					    def is_dir(self, remote_path):
 | 
				
			||||||
        """Checks is the remote resource directory.
 | 
					        """Checks is the remote resource directory.
 | 
				
			||||||
| 
						 | 
					@ -623,11 +622,24 @@ class Client(object):
 | 
				
			||||||
                       `name`: the name of property which will be set,
 | 
					                       `name`: the name of property which will be set,
 | 
				
			||||||
                       `value`: (optional) the value of property which will be set. Defaults is empty string.
 | 
					                       `value`: (optional) the value of property which will be set. Defaults is empty string.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        self.set_property_batch(remote_path=remote_path, option=[option])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @wrap_connection_error
 | 
				
			||||||
 | 
					    def set_property_batch(self, remote_path, option):
 | 
				
			||||||
 | 
					        """Sets batch metadata properties of remote resource on WebDAV server in batch.
 | 
				
			||||||
 | 
					        More information you can find by link http://webdav.org/specs/rfc4918.html#METHOD_PROPPATCH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param remote_path: the path to remote resource.
 | 
				
			||||||
 | 
					        :param option: the property attributes as list of dictionaries with following keys:
 | 
				
			||||||
 | 
					                       `namespace`: (optional) the namespace for XML property which will be set,
 | 
				
			||||||
 | 
					                       `name`: the name of property which will be set,
 | 
				
			||||||
 | 
					                       `value`: (optional) the value of property which will be set. Defaults is empty string.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
        urn = Urn(remote_path)
 | 
					        urn = Urn(remote_path)
 | 
				
			||||||
        if not self.check(urn.path()):
 | 
					        if not self.check(urn.path()):
 | 
				
			||||||
            raise RemoteResourceNotFound(urn.path())
 | 
					            raise RemoteResourceNotFound(urn.path())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        data = WebDavXmlUtils.create_set_property_request_content(option)
 | 
					        data = WebDavXmlUtils.create_set_property_batch_request_content(option)
 | 
				
			||||||
        self.execute_request(action='set_property', path=urn.quote(), data=data)
 | 
					        self.execute_request(action='set_property', path=urn.quote(), data=data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resource(self, remote_path):
 | 
					    def resource(self, remote_path):
 | 
				
			||||||
| 
						 | 
					@ -874,10 +886,10 @@ class WebDavXmlUtils:
 | 
				
			||||||
        :return: True in case the remote resource is directory and False otherwise.
 | 
					        :return: True in case the remote resource is directory and False otherwise.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        response = WebDavXmlUtils.extract_response_for_path(content=content, path=path, hostname=hostname)
 | 
					        response = WebDavXmlUtils.extract_response_for_path(content=content, path=path, hostname=hostname)
 | 
				
			||||||
        type = response.find(".//{DAV:}resourcetype")
 | 
					        resource_type = response.find(".//{DAV:}resourcetype")
 | 
				
			||||||
        if type is None:
 | 
					        if resource_type is None:
 | 
				
			||||||
            raise MethodNotSupported(name="is_dir", server=self.webdav.hostname)
 | 
					            raise MethodNotSupported(name="is_dir", server=hostname)
 | 
				
			||||||
        dir_type = type.find("{DAV:}collection")
 | 
					        dir_type = resource_type.find("{DAV:}collection")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return True if dir_type is not None else False
 | 
					        return True if dir_type is not None else False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -908,10 +920,10 @@ class WebDavXmlUtils:
 | 
				
			||||||
        return tree.xpath('//*[local-name() = $name]', name=name)[0].text
 | 
					        return tree.xpath('//*[local-name() = $name]', name=name)[0].text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def create_set_property_request_content(option):
 | 
					    def create_set_property_batch_request_content(options):
 | 
				
			||||||
        """Creates an XML for requesting of setting a property value for remote WebDAV resource.
 | 
					        """Creates an XML for requesting of setting a property values for remote WebDAV resource in batch.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param option: the property attributes as dictionary with following keys:
 | 
					        :param options: the property attributes as list of dictionaries with following keys:
 | 
				
			||||||
                       `namespace`: (optional) the namespace for XML property which will be set,
 | 
					                       `namespace`: (optional) the namespace for XML property which will be set,
 | 
				
			||||||
                       `name`: the name of property which will be set,
 | 
					                       `name`: the name of property which will be set,
 | 
				
			||||||
                       `value`: (optional) the value of property which will be set. Defaults is empty string.
 | 
					                       `value`: (optional) the value of property which will be set. Defaults is empty string.
 | 
				
			||||||
| 
						 | 
					@ -920,6 +932,7 @@ class WebDavXmlUtils:
 | 
				
			||||||
        root_node = etree.Element('propertyupdate', xmlns='DAV:')
 | 
					        root_node = etree.Element('propertyupdate', xmlns='DAV:')
 | 
				
			||||||
        set_node = etree.SubElement(root_node, 'set')
 | 
					        set_node = etree.SubElement(root_node, 'set')
 | 
				
			||||||
        prop_node = etree.SubElement(set_node, 'prop')
 | 
					        prop_node = etree.SubElement(set_node, 'prop')
 | 
				
			||||||
 | 
					        for option in options:
 | 
				
			||||||
            opt_node = etree.SubElement(prop_node, option['name'], xmlns=option.get('namespace', ''))
 | 
					            opt_node = etree.SubElement(prop_node, option['name'], xmlns=option.get('namespace', ''))
 | 
				
			||||||
            opt_node.text = option.get('value', '')
 | 
					            opt_node.text = option.get('value', '')
 | 
				
			||||||
        tree = etree.ElementTree(root_node)
 | 
					        tree = etree.ElementTree(root_node)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue