VRoot:
usr/
share/
lib
...etc...
And app have to access files under relative paths in VRoot (sandbox).
VRoot(mount_point) create virtual (sandbox) root with methods:
- hpath(virtual_path) returns path on host
- vpath(host_path, keep_host=False) returns virtual path, if not possible and keep_host, returns original host_path (None otherwise)
- path2uri(path, base=None) returns URI, like a/b/c to be inserted to 'file:///HERE'
from os import path
class VRoot:
"""Use always unicode in path!
"""
_mp = None
def __init__(self, mp):
"mp is the mount-point: abs. path on host"
self.mount(mp)
def hpath(self, vp):
"""Returns host path from virtual path:
>>> vr = VRoot(u'/a/b')
>>> vr.hpath(u'c///') == VRoot._fixed_abspath(u'/a/b/c')
True
>>> vr.hpath(u'/c///') == VRoot._fixed_abspath(u'/a/b/c')
True
>>> vr.hpath(u"../../../c/") == VRoot._fixed_abspath(u'/a/b/c')
True
>>> vr.hpath(u"/../c/") == VRoot._fixed_abspath(u'/a/b/c')
True
"""
vp = vp.replace(u"\\", u"/").split(u'/')
vp = u'/'.join(x for x in vp if x and x!=u"..")
return VRoot._fixed_abspath(path.join(self._mp, vp))
def vpath(self, hp, keep_host=False):
"""Returns virtual path, relative to _mp. If keep_host, then
returns original hp when hp is not in _mp, otherwise returns None:
>>> vr = VRoot(u'/a/b/')
>>> vr.vpath(u'/a/b/') == path.sep
True
>>> vr.vpath(u'/a/b/', True) == path.sep
True
>>> vr.vpath(u"/x///")
>>> vr.vpath(u"/x/", True) == path.sep + u'x'
True
>>> vr = VRoot(u'/')
>>> vr.vpath(u'/a/b/') == path.normpath(u"a/b")
True
"""
ap = VRoot._fixed_abspath(hp)
ap = VRoot._fixed_relpath(ap, self._mp)
if u".." in ap:
if keep_host:
return path.normpath(hp)
else:
return None
elif ap == u".":
return path.sep
else:
return ap
@staticmethod
def _pathroot(p):
"""Returns absolute path of root of path p:
>>> VRoot._pathroot("/a/") == VRoot._fixed_abspath("/")
True
>>> VRoot._pathroot(r"d:\\x\\y\\\\")
'd:\\\\'
"""
p_drive = path.splitdrive(p)[0]
if p_drive:
# if there is the drive, absroot will be ''
absroot = p_drive + path.sep
else:
# else will be default system root
absroot = VRoot._fixed_abspath(u"/")
return absroot
@staticmethod
def _fixed_abspath(p):
"""Issue: not normalized case"""
return path.normcase(path.abspath(p))
@staticmethod
def _fixed_relpath(p, base):
"""Issue: when base is root, p is prefixed by '..':
>>> VRoot._fixed_relpath('/a/b/c/', '/') == r'a\\b\\c'
True
>>> VRoot._fixed_relpath(r'd:\\x\\y', r'd:\\\\') == path.normpath("x/y")
True
"""
base_drive = path.splitdrive(base)[0]
if base_drive:
# if there is the drive, absroot will be ''
absroot = base_drive + path.sep
else:
# else will be default system root
absroot = VRoot._fixed_abspath(u"/")
if VRoot._fixed_abspath(base) == absroot:
# if base is root
return path.normpath(p).lstrip(u".." + absroot)
else:
return path.relpath(p, base)
def mount(self, mp):
self._mp = VRoot._fixed_abspath(mp)
def path2uri(p, base=None):
"""Path to uri, but without 'file:///'! See:
>>> path2uri('/a/b/c///')
u'a/b/c'
>>> path2uri(r'd:\\x\\y')
u'x/y'
>>> path2uri(u'/x/y/z', '/x')
u'y/z'
"""
return VRoot(base or VRoot._pathroot(p)).vpath(p).replace('\\', '/')
if __name__ == "__main__":
import doctest
doctest.testmod()
#print VRoot._pathroot(r'd:\\\\x\y')
Комментариев нет:
Отправить комментарий
Thanks for your posting!