Merge branch 'develop' into master
This commit is contained in:
commit
c606ae3875
11 changed files with 161 additions and 104 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -6,6 +6,6 @@
|
||||||
.project
|
.project
|
||||||
.pydevproject
|
.pydevproject
|
||||||
/.settings/
|
/.settings/
|
||||||
venv
|
.idea/
|
||||||
.idea
|
venv/
|
||||||
build
|
build
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
language: python
|
language: python
|
||||||
python:
|
python:
|
||||||
- "2.7"
|
- "3.7"
|
||||||
install:
|
install:
|
||||||
- python setup.py develop
|
- python setup.py develop
|
||||||
script:
|
script:
|
||||||
|
|
|
@ -27,6 +27,8 @@ ____________
|
||||||
|
|
||||||
Release Notes
|
Release Notes
|
||||||
=============
|
=============
|
||||||
|
**Version 0.13 – TBD**
|
||||||
|
* Main version of Python is updated up to 3.7
|
||||||
|
|
||||||
**Version 0.12 - 21.06.2019**
|
**Version 0.12 - 21.06.2019**
|
||||||
* Added depth argument in copy method in client.py by https://github.com/JesperHakansson
|
* Added depth argument in copy method in client.py by https://github.com/JesperHakansson
|
||||||
|
|
6
setup.py
6
setup.py
|
@ -49,7 +49,8 @@ setup(
|
||||||
requires=['python (>= 2.7.6)'],
|
requires=['python (>= 2.7.6)'],
|
||||||
install_requires=['requests', 'lxml', 'argcomplete'],
|
install_requires=['requests', 'lxml', 'argcomplete'],
|
||||||
scripts=['wdc'],
|
scripts=['wdc'],
|
||||||
tests_require=['pytest', 'pyhamcrest', 'junit-xml', 'pytest-allure-adaptor'],
|
test_suite='tests',
|
||||||
|
tests_require=['pytest'],
|
||||||
cmdclass={'install': Install, 'test': Test},
|
cmdclass={'install': Install, 'test': Test},
|
||||||
description='WebDAV client, based on original package https://github.com/designerror/webdav-client-python but '
|
description='WebDAV client, based on original package https://github.com/designerror/webdav-client-python but '
|
||||||
'uses requests instead of PyCURL',
|
'uses requests instead of PyCURL',
|
||||||
|
@ -73,6 +74,9 @@ setup(
|
||||||
'Programming Language :: Python :: 3.2',
|
'Programming Language :: Python :: 3.2',
|
||||||
'Programming Language :: Python :: 3.3',
|
'Programming Language :: Python :: 3.3',
|
||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
|
'Programming Language :: Python :: 3.5',
|
||||||
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet',
|
'Topic :: Internet',
|
||||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
__author__ = 'designerror'
|
|
||||||
|
|
||||||
from hamcrest.core.base_matcher import BaseMatcher
|
|
||||||
from hamcrest.core.helpers.hasmethod import hasmethod
|
|
||||||
|
|
||||||
class Valid(BaseMatcher):
|
|
||||||
def _matches(self, item):
|
|
||||||
return False if not hasmethod(item, 'valid') else item.valid()
|
|
||||||
|
|
||||||
class NotValid(BaseMatcher):
|
|
||||||
def _matches(self, item):
|
|
||||||
return False if not hasmethod(item, 'valid') else not item.valid()
|
|
||||||
|
|
||||||
class Success(BaseMatcher):
|
|
||||||
def _matches(self, item):
|
|
||||||
return item
|
|
||||||
|
|
||||||
class NotSuccess(BaseMatcher):
|
|
||||||
def _matches(self, item):
|
|
||||||
return not item
|
|
||||||
|
|
||||||
def valid():
|
|
||||||
return Valid()
|
|
||||||
|
|
||||||
def not_valid():
|
|
||||||
return NotValid()
|
|
||||||
|
|
||||||
def success():
|
|
||||||
return Success()
|
|
||||||
|
|
||||||
def not_success():
|
|
||||||
return NotSuccess()
|
|
136
tests/response_dir.xml
Normal file
136
tests/response_dir.xml
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<d:multistatus xmlns:d="DAV:">
|
||||||
|
<d:response>
|
||||||
|
<d:href>/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
<d:prop>
|
||||||
|
<d:creationdate>2012-04-04T20:00:00Z</d:creationdate>
|
||||||
|
<d:displayname>disk</d:displayname>
|
||||||
|
<d:getlastmodified>Wed, 04 Apr 2012 20:00:00 GMT</d:getlastmodified>
|
||||||
|
<d:resourcetype>
|
||||||
|
<d:collection/>
|
||||||
|
</d:resourcetype>
|
||||||
|
</d:prop>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/test_dir/</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
<d:prop>
|
||||||
|
<d:creationdate>2018-05-10T07:31:13Z</d:creationdate>
|
||||||
|
<d:displayname>test_dir</d:displayname>
|
||||||
|
<d:getlastmodified>Thu, 10 May 2018 07:31:13 GMT</d:getlastmodified>
|
||||||
|
<d:resourcetype>
|
||||||
|
<d:collection/>
|
||||||
|
</d:resourcetype>
|
||||||
|
</d:prop>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/%D0%93%D0%BE%D1%80%D1%8B.jpg</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>1392851f0668017168ee4b5a59d66e7b</d:getetag>
|
||||||
|
<d:creationdate>2018-05-09T14:44:28Z</d:creationdate>
|
||||||
|
<d:displayname>Горы.jpg</d:displayname>
|
||||||
|
<d:getlastmodified>Wed, 09 May 2018 14:44:28 GMT</d:getlastmodified>
|
||||||
|
<d:getcontenttype>image/jpeg</d:getcontenttype>
|
||||||
|
<d:getcontentlength>1762478</d:getcontentlength>
|
||||||
|
<d:resourcetype/>
|
||||||
|
</d:prop>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/%D0%97%D0%B8%D0%BC%D0%B0.jpg</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>a64146fee5e15b3b94c204e544426d43</d:getetag>
|
||||||
|
<d:creationdate>2018-05-09T14:44:28Z</d:creationdate>
|
||||||
|
<d:displayname>Зима.jpg</d:displayname>
|
||||||
|
<d:getlastmodified>Wed, 09 May 2018 14:44:28 GMT</d:getlastmodified>
|
||||||
|
<d:getcontenttype>image/jpeg</d:getcontenttype>
|
||||||
|
<d:getcontentlength>1394575</d:getcontentlength>
|
||||||
|
<d:resourcetype/>
|
||||||
|
</d:prop>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/%D0%9C%D0%B8%D1%88%D0%BA%D0%B8.jpg</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>569a1c98696050439b5b2a1ecfa52d19</d:getetag>
|
||||||
|
<d:creationdate>2018-05-09T14:44:27Z</d:creationdate>
|
||||||
|
<d:displayname>Мишки.jpg</d:displayname>
|
||||||
|
<d:getlastmodified>Wed, 09 May 2018 14:44:27 GMT</d:getlastmodified>
|
||||||
|
<d:getcontenttype>image/jpeg</d:getcontenttype>
|
||||||
|
<d:getcontentlength>1555830</d:getcontentlength>
|
||||||
|
<d:resourcetype/>
|
||||||
|
</d:prop>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/%D0%9C%D0%BE%D1%80%D0%B5.jpg</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>ab903d9cab031eca2a8f12f37bbc9d37</d:getetag>
|
||||||
|
<d:creationdate>2018-05-09T14:44:27Z</d:creationdate>
|
||||||
|
<d:displayname>Море.jpg</d:displayname>
|
||||||
|
<d:getlastmodified>Wed, 09 May 2018 14:44:27 GMT</d:getlastmodified>
|
||||||
|
<d:getcontenttype>image/jpeg</d:getcontenttype>
|
||||||
|
<d:getcontentlength>1080301</d:getcontentlength>
|
||||||
|
<d:resourcetype/>
|
||||||
|
</d:prop>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0.jpg</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>d27d72a3059ad5ebed7a5470459d2670</d:getetag>
|
||||||
|
<d:creationdate>2018-05-09T14:44:27Z</d:creationdate>
|
||||||
|
<d:displayname>Москва.jpg</d:displayname>
|
||||||
|
<d:getlastmodified>Wed, 09 May 2018 14:44:27 GMT</d:getlastmodified>
|
||||||
|
<d:getcontenttype>image/jpeg</d:getcontenttype>
|
||||||
|
<d:getcontentlength>1454228</d:getcontentlength>
|
||||||
|
<d:resourcetype/>
|
||||||
|
</d:prop>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3.jpg</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>f1abe3b27b410128623fd1ca00a45c29</d:getetag>
|
||||||
|
<d:creationdate>2018-05-09T14:44:27Z</d:creationdate>
|
||||||
|
<d:displayname>Санкт-Петербург.jpg</d:displayname>
|
||||||
|
<d:getlastmodified>Wed, 09 May 2018 14:44:27 GMT</d:getlastmodified>
|
||||||
|
<d:getcontenttype>image/jpeg</d:getcontenttype>
|
||||||
|
<d:getcontentlength>2573704</d:getcontentlength>
|
||||||
|
<d:resourcetype/>
|
||||||
|
</d:prop>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
<d:response>
|
||||||
|
<d:href>/%D0%A5%D0%BB%D0%B5%D0%B1%D0%BD%D1%8B%D0%B5%20%D0%BA%D1%80%D0%BE%D1%88%D0%BA%D0%B8.mp4</d:href>
|
||||||
|
<d:propstat>
|
||||||
|
<d:status>HTTP/1.1 200 OK</d:status>
|
||||||
|
<d:prop>
|
||||||
|
<d:getetag>ea977f513074d5524bee3638798183b9</d:getetag>
|
||||||
|
<d:creationdate>2018-05-09T14:44:28Z</d:creationdate>
|
||||||
|
<d:displayname>Хлебные крошки.mp4</d:displayname>
|
||||||
|
<d:getlastmodified>Wed, 09 May 2018 14:44:28 GMT</d:getlastmodified>
|
||||||
|
<d:getcontenttype>video/mp4</d:getcontenttype>
|
||||||
|
<d:getcontentlength>31000079</d:getcontentlength>
|
||||||
|
<d:resourcetype/>
|
||||||
|
</d:prop>
|
||||||
|
</d:propstat>
|
||||||
|
</d:response>
|
||||||
|
</d:multistatus>
|
|
@ -129,56 +129,14 @@ class ClientTestCase(TestCase):
|
||||||
self.assertEqual(result, b'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<test/>')
|
self.assertEqual(result, b'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<test/>')
|
||||||
|
|
||||||
def test_parse_is_dir_response_directory(self):
|
def test_parse_is_dir_response_directory(self):
|
||||||
content = '<?xml version=\'1.0\' encoding=\'UTF-8\'?><d:multistatus xmlns:d="DAV:"><d:response><d:href>/</d:h' \
|
f = open('./tests/response_dir.xml')
|
||||||
'ref><d:propstat><d:status>HTTP/1.1 200 OK</d:status><d:prop><d:creationdate>2012-04-04T20:00:00Z</' \
|
content = f.read()
|
||||||
'd:creationdate><d:displayname>disk</d:displayname><d:getlastmodified>Wed, 04 Apr 2012 20:00:00 GMT' \
|
|
||||||
'</d:getlastmodified><d:resourcetype><d:collection/></d:resourcetype></d:prop></d:propstat></d:resp' \
|
|
||||||
'onse><d:response><d:href>/test_dir/</d:href><d:propstat><d:status>HTTP/1.1 200 OK</d:status><d:pro' \
|
|
||||||
'p><d:creationdate>2018-05-10T07:31:13Z</d:creationdate><d:displayname>test_dir</d:displayname><d:g' \
|
|
||||||
'etlastmodified>Thu, 10 May 2018 07:31:13 GMT</d:getlastmodified><d:resourcetype><d:collection/></d' \
|
|
||||||
':resourcetype></d:prop></d:propstat></d:response><d:response><d:href>/%D0%93%D0%BE%D1%80%D1%8B.jpg' \
|
|
||||||
'</d:href><d:propstat><d:status>HTTP/1.1 200 OK</d:status><d:prop><d:getetag>1392851f0668017168ee4b' \
|
|
||||||
'5a59d66e7b</d:getetag><d:creationdate>2018-05-09T14:44:28Z</d:creationdate><d:displayname>Горы.jpg' \
|
|
||||||
'</d:displayname><d:getlastmodified>Wed, 09 May 2018 14:44:28 GMT</d:getlastmodified><d:getcontentt' \
|
|
||||||
'ype>image/jpeg</d:getcontenttype><d:getcontentlength>1762478</d:getcontentlength><d:resourcetype/>' \
|
|
||||||
'</d:prop></d:propstat></d:response><d:response><d:href>/%D0%97%D0%B8%D0%BC%D0%B0.jpg</d:href><d:pr' \
|
|
||||||
'opstat><d:status>HTTP/1.1 200 OK</d:status><d:prop><d:getetag>a64146fee5e15b3b94c204e544426d43</d:' \
|
|
||||||
'getetag><d:creationdate>2018-05-09T14:44:28Z</d:creationdate><d:displayname>Зима.jpg</d:displaynam' \
|
|
||||||
'e><d:getlastmodified>Wed, 09 May 2018 14:44:28 GMT</d:getlastmodified><d:getcontenttype>image/jpeg' \
|
|
||||||
'</d:getcontenttype><d:getcontentlength>1394575</d:getcontentlength><d:resourcetype/></d:prop></d:p' \
|
|
||||||
'ropstat></d:response><d:response><d:href>/%D0%9C%D0%B8%D1%88%D0%BA%D0%B8.jpg</d:href><d:propstat><' \
|
|
||||||
'd:status>HTTP/1.1 200 OK</d:status><d:prop><d:getetag>569a1c98696050439b5b2a1ecfa52d19</d:getetag>' \
|
|
||||||
'<d:creationdate>2018-05-09T14:44:27Z</d:creationdate><d:displayname>Мишки.jpg</d:displayname><d:ge' \
|
|
||||||
'tlastmodified>Wed, 09 May 2018 14:44:27 GMT</d:getlastmodified><d:getcontenttype>image/jpeg</d:get' \
|
|
||||||
'contenttype><d:getcontentlength>1555830</d:getcontentlength><d:resourcetype/></d:prop></d:propstat' \
|
|
||||||
'></d:response><d:response><d:href>/%D0%9C%D0%BE%D1%80%D0%B5.jpg</d:href><d:propstat><d:status>HTTP' \
|
|
||||||
'/1.1 200 OK</d:status><d:prop><d:getetag>ab903d9cab031eca2a8f12f37bbc9d37</d:getetag><d:creationda' \
|
|
||||||
'te>2018-05-09T14:44:27Z</d:creationdate><d:displayname>Море.jpg</d:displayname><d:getlastmodified>' \
|
|
||||||
'Wed, 09 May 2018 14:44:27 GMT</d:getlastmodified><d:getcontenttype>image/jpeg</d:getcontenttype><d' \
|
|
||||||
':getcontentlength>1080301</d:getcontentlength><d:resourcetype/></d:prop></d:propstat></d:response>' \
|
|
||||||
'<d:response><d:href>/%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0.jpg</d:href><d:propstat><d:status>HTTP/1' \
|
|
||||||
'.1 200 OK</d:status><d:prop><d:getetag>d27d72a3059ad5ebed7a5470459d2670</d:getetag><d:creationdate' \
|
|
||||||
'>2018-05-09T14:44:27Z</d:creationdate><d:displayname>Москва.jpg</d:displayname><d:getlastmodified>' \
|
|
||||||
'Wed, 09 May 2018 14:44:27 GMT</d:getlastmodified><d:getcontenttype>image/jpeg</d:getcontenttype><d' \
|
|
||||||
':getcontentlength>1454228</d:getcontentlength><d:resourcetype/></d:prop></d:propstat></d:response>' \
|
|
||||||
'<d:response><d:href>/%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%' \
|
|
||||||
'80%D0%B3.jpg</d:href><d:propstat><d:status>HTTP/1.1 200 OK</d:status><d:prop><d:getetag>f1abe3b27b' \
|
|
||||||
'410128623fd1ca00a45c29</d:getetag><d:creationdate>2018-05-09T14:44:27Z</d:creationdate><d:displayn' \
|
|
||||||
'ame>Санкт-Петербург.jpg</d:displayname><d:getlastmodified>Wed, 09 May 2018 14:44:27 GMT</d:getlast' \
|
|
||||||
'modified><d:getcontenttype>image/jpeg</d:getcontenttype><d:getcontentlength>2573704</d:getcontentl' \
|
|
||||||
'ength><d:resourcetype/></d:prop></d:propstat></d:response><d:response><d:href>/%D0%A5%D0%BB%D0%B5%' \
|
|
||||||
'D0%B1%D0%BD%D1%8B%D0%B5%20%D0%BA%D1%80%D0%BE%D1%88%D0%BA%D0%B8.mp4</d:href><d:propstat><d:status>H' \
|
|
||||||
'TTP/1.1 200 OK</d:status><d:prop><d:getetag>ea977f513074d5524bee3638798183b9</d:getetag><d:creatio' \
|
|
||||||
'ndate>2018-05-09T14:44:28Z</d:creationdate><d:displayname>Хлебные крошки.mp4</d:displayname><d:get' \
|
|
||||||
'lastmodified>Wed, 09 May 2018 14:44:28 GMT</d:getlastmodified><d:getcontenttype>video/mp4</d:getco' \
|
|
||||||
'ntenttype><d:getcontentlength>31000079</d:getcontentlength><d:resourcetype/></d:prop></d:propstat>' \
|
|
||||||
'</d:response></d:multistatus>'
|
|
||||||
path = '/test_dir'
|
path = '/test_dir'
|
||||||
hostname = 'https://webdav.yandex.ru'
|
hostname = 'https://webdav.yandex.ru'
|
||||||
result = utils.parse_is_dir_response(content.encode('utf-8'), path, hostname)
|
result = utils.parse_is_dir_response(content, path, hostname)
|
||||||
self.assertTrue(result, 'It should be directory')
|
self.assertTrue(result, 'It should be directory')
|
||||||
|
|
||||||
def test_parse_is_dir_response_directory(self):
|
def test_parse_is_dir_response_file(self):
|
||||||
content = '<?xml version=\'1.0\' encoding=\'UTF-8\'?><d:multistatus xmlns:d="DAV:"><d:response><d:href>/test_' \
|
content = '<?xml version=\'1.0\' encoding=\'UTF-8\'?><d:multistatus xmlns:d="DAV:"><d:response><d:href>/test_' \
|
||||||
'dir/</d:href><d:propstat><d:status>HTTP/1.1 200 OK</d:status><d:prop><d:creationdate>2018-05-10T07' \
|
'dir/</d:href><d:propstat><d:status>HTTP/1.1 200 OK</d:status><d:prop><d:creationdate>2018-05-10T07' \
|
||||||
':40:11Z</d:creationdate><d:displayname>test_dir</d:displayname><d:getlastmodified>Thu, 10 May 2018' \
|
':40:11Z</d:creationdate><d:displayname>test_dir</d:displayname><d:getlastmodified>Thu, 10 May 2018' \
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
__author__ = 'designerror'
|
|
|
@ -1,11 +0,0 @@
|
||||||
__author__ = 'designerror'
|
|
||||||
|
|
||||||
import allure
|
|
||||||
#from hamcrest import *
|
|
||||||
|
|
||||||
class TestRequiredOptions:
|
|
||||||
|
|
||||||
def test_without_webdav_hostname(self):
|
|
||||||
options = { 'webdav_server': "https://webdav.yandex.ru"}
|
|
||||||
allure.attach('options', options.__str__())
|
|
||||||
assert 1
|
|
|
@ -1 +0,0 @@
|
||||||
__author__ = 'designerror'
|
|
|
@ -959,6 +959,8 @@ class WebDavXmlUtils:
|
||||||
:return: XML object of response for the remote resource defined by path.
|
:return: XML object of response for the remote resource defined by path.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
if isinstance(content, str):
|
||||||
|
content = content.encode('utf-8')
|
||||||
tree = etree.fromstring(content)
|
tree = etree.fromstring(content)
|
||||||
responses = tree.findall("{DAV:}response")
|
responses = tree.findall("{DAV:}response")
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue