1616from .info import Info
1717from .iotools import RawWrapper
1818from .opener import open_fs
19- from .path import dirname , normpath , relpath , basename
19+ from .path import dirname , relpath , basename , isbase , parts , frombase
2020from .wrapfs import WrapFS
2121from .permissions import Permissions
2222
@@ -256,9 +256,14 @@ def getinfo(self, path, namespaces=None):
256256
257257 else :
258258 try :
259+ implicit = False
259260 member = self ._tar .getmember (self ._encode (_path ))
260261 except KeyError :
261- raise errors .ResourceNotFound (path )
262+ if not self .isdir (_path ):
263+ raise errors .ResourceNotFound (path )
264+ implicit = True
265+ member = tarfile .TarInfo (_path )
266+ member .type = tarfile .DIRTYPE
262267
263268 raw_info ["basic" ] = {
264269 "name" : basename (self ._decode (member .name )),
@@ -268,18 +273,19 @@ def getinfo(self, path, namespaces=None):
268273 if "details" in namespaces :
269274 raw_info ["details" ] = {
270275 "size" : member .size ,
271- "type" : int (self .type_map [member .type ]),
272- "modified" : member .mtime ,
276+ "type" : int (self .type_map [member .type ])
273277 }
274- if "access" in namespaces :
278+ if not implicit :
279+ raw_info ["details" ]["modified" ] = member .mtime
280+ if "access" in namespaces and not implicit :
275281 raw_info ["access" ] = {
276282 "gid" : member .gid ,
277283 "group" : member .gname ,
278284 "permissions" : Permissions (mode = member .mode ).dump (),
279285 "uid" : member .uid ,
280286 "user" : member .uname ,
281287 }
282- if "tar" in namespaces :
288+ if "tar" in namespaces and not implicit :
283289 raw_info ["tar" ] = _get_member_info (member , self .encoding )
284290 raw_info ["tar" ].update ({
285291 k .replace ('is' , 'is_' ):getattr (member , k )()
@@ -289,39 +295,46 @@ def getinfo(self, path, namespaces=None):
289295
290296 return Info (raw_info )
291297
298+ def isdir (self , path ):
299+ _path = relpath (self .validatepath (path ))
300+ try :
301+ return self ._directory [_path ].isdir ()
302+ except KeyError :
303+ return any (isbase (_path , name ) for name in self ._directory )
304+
305+ def isfile (self , path ):
306+ _path = relpath (self .validatepath (path ))
307+ try :
308+ return self ._directory [_path ].isfile ()
309+ except KeyError :
310+ return False
311+
292312 def setinfo (self , path , info ):
293313 self .check ()
294314 raise errors .ResourceReadOnly (path )
295315
296316 def listdir (self , path ):
297- self .check ()
298- _path = relpath (path )
299- info = self ._directory .get (_path )
300- if _path :
301- if info is None :
302- raise errors .ResourceNotFound (path )
303- if not info .isdir ():
304- raise errors .DirectoryExpected (path )
305- dir_list = [
306- basename (name )
307- for name in self ._directory .keys ()
308- if dirname (name ) == _path
309- ]
310- return dir_list
317+ _path = relpath (self .validatepath (path ))
318+
319+ if not self .gettype (path ) is ResourceType .directory :
320+ raise errors .DirectoryExpected (path )
321+
322+ children = (frombase (_path , n ) for n in self ._directory if isbase (_path , n ))
323+ content = (parts (child )[1 ] for child in children if relpath (child ))
324+ return list (OrderedDict .fromkeys (content ))
311325
312326 def makedir (self , path , permissions = None , recreate = False ):
313327 self .check ()
314328 raise errors .ResourceReadOnly (path )
315329
316330 def openbin (self , path , mode = "r" , buffering = - 1 , ** options ):
317- self .check ()
318- path = relpath (normpath (path ))
331+ _path = relpath (self .validatepath (path ))
319332
320333 if 'w' in mode or '+' in mode or 'a' in mode :
321334 raise errors .ResourceReadOnly (path )
322335
323336 try :
324- member = self ._tar .getmember (self ._encode (path ))
337+ member = self ._tar .getmember (self ._encode (_path ))
325338 except KeyError :
326339 six .raise_from (errors .ResourceNotFound (path ), None )
327340
0 commit comments