Skip to content

Commit 4139d39

Browse files
authored
Merge pull request #28 from joequant/dev/add-cache
Dev/add cache
2 parents 3f9f6a7 + 12eaaca commit 4139d39

File tree

2 files changed

+53
-13
lines changed

2 files changed

+53
-13
lines changed

setup.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@
2424

2525
REQUIREMENTS = [
2626
"fs>2.0",
27+
"webdavclient2",
28+
"cachetools"
2729
"webdavclient3",
2830
"python-dateutil"
31+
2932
]
3033

3134
setup(

webdavfs/webdavfs.py

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from fs.iotools import line_iterator
2121
from fs.mode import Mode
2222
from fs.path import dirname
23+
from cachetools import TTLCache
2324

2425

2526
log = logging.getLogger(__name__)
@@ -156,7 +157,8 @@ class WebDAVFS(FS):
156157
'virtual': False,
157158
}
158159

159-
def __init__(self, url, login=None, password=None, root=None):
160+
def __init__(self, url, login=None, password=None, root=None,
161+
cache_maxsize=10000, cache_ttl=60):
160162
self.url = url
161163
self.root = root
162164
super(WebDAVFS, self).__init__()
@@ -167,6 +169,8 @@ def __init__(self, url, login=None, password=None, root=None):
167169
'webdav_password': password,
168170
'root': self.root
169171
}
172+
self.info_cache = TTLCache(maxsize=cache_maxsize,
173+
ttl=cache_ttl)
170174
self.client = wc.Client(options)
171175

172176
def _create_resource(self, path):
@@ -182,7 +186,8 @@ def _create_info_dict(info):
182186
info_dict = {
183187
'basic': {"is_dir": False},
184188
'details': {'type': int(ResourceType.file)},
185-
'access': {}
189+
'access': {},
190+
'other': {}
186191
}
187192

188193
if six.PY2:
@@ -230,9 +235,8 @@ def exists(self, path):
230235

231236
def getinfo(self, path, namespaces=None):
232237
_path = self.validatepath(path)
233-
namespaces = namespaces or ()
234-
235238
if _path in '/':
239+
<<<<<<< Updated upstream
236240
info_dict = {
237241
"basic": {
238242
"name": "",
@@ -257,18 +261,51 @@ def getinfo(self, path, namespaces=None):
257261
raise errors.ResourceNotFound(path, exc=exc)
258262

259263
return Info(info_dict)
264+
=======
265+
self.info_cache.clear()
266+
try:
267+
_path = self.validatepath(path)
268+
namespaces = namespaces or ()
269+
urn =wu.Urn(_path.encode('utf-8'))
270+
path = self.client.get_full_path(urn);
271+
if path in self.info_cache:
272+
info = self.info_cache[path]
273+
response = None
274+
else:
275+
response = self.client.execute_request(action='info',
276+
path=urn.quote())
277+
info = wc.WebDavXmlUtils.parse_info_response(content=response.content, path=path, hostname=self.client.webdav.hostname)
278+
if info['name'] is None:
279+
info['name'] = _path.split("/")[-1]
280+
if wc.WebDavXmlUtils.parse_is_dir_response(content=response.content, path=path, hostname=self.client.webdav.hostname):
281+
info['isdir'] = True
282+
info['files'] = []
283+
for i in wc.WebDavXmlUtils.parse_get_list_info_response(response.content):
284+
if i['path'].rstrip('/') != path.rstrip('/'):
285+
self.info_cache[i['path']] = i
286+
filename = wu.Urn(i['path'], i['isdir']).filename()
287+
if six.PY2:
288+
filename = filename.decode('utf-8')
289+
filename = filename.rstrip('/')
290+
info['files'].append(filename)
291+
self.info_cache[path] = info
292+
info_dict = self._create_info_dict(info)
293+
if info.get('isdir', False):
294+
info_dict['basic']['is_dir'] = True
295+
info_dict['details']['type'] = ResourceType.directory
296+
except we.RemoteResourceNotFound as exc:
297+
raise errors.ResourceNotFound(path, exc=exc)
298+
retval = Info(info_dict)
299+
return retval
300+
>>>>>>> Stashed changes
260301

261302
def listdir(self, path):
262-
_path = self.validatepath(path)
263-
264-
if not self.getinfo(_path).is_dir:
303+
info = self.getinfo(path)
304+
if not info.is_dir:
265305
raise errors.DirectoryExpected(path)
266-
267-
dir_list = self.client.list(_path.encode('utf-8'))
268-
if six.PY2:
269-
dir_list = map(operator.methodcaller('decode', 'utf-8'), dir_list)
270-
271-
return list(map(operator.methodcaller('rstrip', '/'), dir_list))
306+
for i in info.raw['other']['files']:
307+
yield i
308+
return
272309

273310
def makedir(self, path, permissions=None, recreate=False):
274311
_path = self.validatepath(path)

0 commit comments

Comments
 (0)