Esempio n. 1
0
  def sys_to_ami_path(self, sys_path):
    """try to map an absolute system path back to an amiga path

       if multiple volumes overlap then take the shortest amiga path

       return ami_path or None if sys_path can't be mapped
    """
    if not os.path.isabs(sys_path):
      sys_path = resolve_sys_path(sys_path)
      log_path.debug("vol: sys_to_ami_path: resolved rel path: %s", sys_path)
    res_len = None
    result = None
    for volume in self.volumes:
      vol_sys_path = volume.get_path()
      cp = os.path.commonprefix([vol_sys_path, sys_path])
      if cp == vol_sys_path:
        remainder = sys_path[len(vol_sys_path):]
        n = len(remainder)
        if n > 0 and remainder[0] == '/':
          remainder = remainder[1:]
          n -= 1
        # get volume name and build amiga path
        vol_name = volume.get_name()
        ami_path = vol_name + ":" + remainder
        log_path.debug(
            "vol: sys_to_ami_path: sys='%s' -> ami='%s'", sys_path, ami_path)
        if result is None or n < res_len:
          result = ami_path
          res_len = n
    # return best result
    log_path.info(
        "vol: sys_to_ami_path: sys='%s' -> ami=%s", sys_path, result)
    return result
Esempio n. 2
0
  def abspath(self, ami_path, env=None):
    """return an absolute Amiga path

    If the path is already absolute then return path itself.
    Otherwise create a new AmiPath object with the absolute path
    by joining this path with the current directory of the path env.

    An AmiPathError is raised if the relative path cannot be joined
    to the current directory, e.g.:  "foo:".join("/")
    """
    if type(ami_path) is str:
      ami_path = AmiPath(ami_path)
    # already absolute?
    if ami_path.is_absolute():
      log_path.debug("abspath: is_absolute: '%s'", ami_path)
      return ami_path
    # get current directory and join cur dir with my path
    if env is None:
      env = self.default_env
      cwd = env.get_cwd()
    else:
      # make sure its a volume path
      cwd = env.get_cwd()
    res_path = cwd.join(ami_path)
    log_path.debug("abspath: relpath='%s' cwd='%s' -> join '%s'",
                   ami_path, cwd, res_path)
    return res_path
Esempio n. 3
0
 def shutdown(self):
   # shutdown all volumes
   log_path.debug("shutting down volumes")
   for volume in self.volumes:
     log_path.info("cleaning up volume: %s", volume)
     volume.shutdown()
     volume.is_setup = False
Esempio n. 4
0
 def shutdown(self):
     # shutdown all volumes
     log_path.debug("shutting down volumes")
     for volume in self.volumes:
         log_path.info("cleaning up volume: %s", volume)
         volume.shutdown()
         volume.is_setup = False
Esempio n. 5
0
 def create_rel_sys_path(self, rel_path):
     if type(rel_path) in (list, tuple):
         rel_path = os.path.join(*rel_path)
     dir_path = os.path.join(self.path, rel_path)
     if os.path.isdir(dir_path):
         log_path.debug(
             "rel sys path in volume already exists '%s' + %s -> %s",
             self.name,
             rel_path,
             dir_path,
         )
         return dir_path
     try:
         log_path.debug(
             "creating rel sys path in volume '%s' + %s -> %s",
             self.name,
             rel_path,
             dir_path,
         )
         os.makedirs(dir_path)
         return dir_path
     except OSError as e:
         log_path.error(
             "error creating rel sys path in volume '%s' + %s -> %s",
             self.name,
             rel_path,
             dir_path,
         )
         return None
Esempio n. 6
0
    def abspath(self, ami_path, env=None):
        """return an absolute Amiga path

    If the path is already absolute then return path itself.
    Otherwise create a new AmiPath object with the absolute path
    by joining this path with the current directory of the path env.

    An AmiPathError is raised if the relative path cannot be joined
    to the current directory, e.g.:  "foo:".join("/")
    """
        if type(ami_path) is str:
            ami_path = AmiPath(ami_path)
        # already absolute?
        if ami_path.is_absolute():
            log_path.debug("abspath: is_absolute: '%s'", ami_path)
            return ami_path
        # get current directory and join cur dir with my path
        if env is None:
            env = self.default_env
            cwd = env.get_cwd()
        else:
            # make sure its a volume path
            cwd = env.get_cwd()
        res_path = cwd.join(ami_path)
        log_path.debug("abspath: relpath='%s' cwd='%s' -> join '%s'", ami_path,
                       cwd, res_path)
        return res_path
Esempio n. 7
0
    def sys_to_ami_path(self, sys_path):
        """try to map an absolute system path back to an amiga path

       if multiple volumes overlap then take the shortest amiga path

       return ami_path or None if sys_path can't be mapped
    """
        if not os.path.isabs(sys_path):
            log_path.error("vol: sys_to_ami_path: no abs path: '%s'", sys_path)
            return None
        res_len = None
        result = None
        for vol_sys_path in self.sys2volume:
            cp = os.path.commonprefix([vol_sys_path, sys_path])
            if cp == vol_sys_path:
                remainder = sys_path[len(vol_sys_path):]
                n = len(remainder)
                if n > 0 and remainder[0] == '/':
                    remainder = remainder[1:]
                    n -= 1
                # get volume name and build amiga path
                vol_name = self.sys2volume[vol_sys_path]
                vol_name = self.orig_names[vol_name]
                ami_path = vol_name + ":" + remainder
                log_path.debug("vol: sys_to_ami_path: sys='%s' -> ami='%s'",
                               sys_path, ami_path)
                if result is None or n < res_len:
                    result = ami_path
                    res_len = n
        # return best result
        log_path.info("vol: sys_to_ami_path: sys='%s' -> ami=%s", sys_path,
                      result)
        return result
Esempio n. 8
0
 def setup(self):
     log_path.debug("setting up assigns")
     for a in self.assigns:
         if not a.setup(self):
             log_path.error("error setting up assign: %s", a)
             return False
         a.is_setup = True
     self.is_setup = True
     return True
Esempio n. 9
0
 def setup(self):
   log_path.debug("setting up assigns")
   for a in self.assigns:
     if not a.setup(self):
       log_path.error("error setting up assign: %s", a)
       return False
     a.is_setup = True
   self.is_setup = True
   return True
Esempio n. 10
0
 def setup(self):
     # setup all defined volumes
     log_path.debug("setting up volumes")
     for volume in self.volumes:
         if not volume.setup():
             log_path.error("Error settign up volume: %s", volume)
             return False
         volume.is_setup = True
     self.is_setup = True
     return True
Esempio n. 11
0
 def setup(self):
   # setup all defined volumes
   log_path.debug("setting up volumes")
   for volume in self.volumes:
     if not volume.setup():
       log_path.error("Error settign up volume: %s", volume)
       return False
     volume.is_setup = True
   self.is_setup = True
   return True
Esempio n. 12
0
 def _create_dir(self, volume, rel_dir):
   log_path.debug("%s: create assign dir: rel_dir='%s'", self.name, rel_dir)
   path = volume.create_rel_sys_path(rel_dir)
   if not path:
     log_path.error("assign '%s': can't create relative dir: %s",
                    self.name, rel_dir)
     return False
   else:
     log_path.debug("created sys path: %s", path)
     return True
Esempio n. 13
0
    def resolve_assigns(self, ami_path, recursive=True):
        """replace all assigns found in path until only a volume path exists.
       do not touch relative paths or abs paths without assign prefix.

        return: original path if path is not absolute
                or does not contain assign prefix
        or: string if no multi assigns are involved
        or: list of string if multi assigns were encountered
    """
        log_path.info("resolve_assign: ami_path='%s'", ami_path)
        split = self._split_volume_remainder(ami_path)
        if split is None:
            # relative path
            log_path.debug("resolve_assign: ami_path='%s' is rel_path!",
                           ami_path)
            return ami_path
        else:
            # is assign
            name = split[0].lower()
            if self.assigns.has_key(name):
                remainder = split[1]
                aname_list = self.assigns[name]
                # single assign
                if len(aname_list) == 1:
                    aname = aname_list[0]
                    new_path = self._concat_assign(aname, remainder)
                    log_path.info(
                        "resolve_assign: ami_path='%s' -> single assign: '%s'",
                        ami_path, new_path)
                    if recursive:
                        return self.resolve_assigns(new_path)
                    else:
                        return new_path
                # multi assign
                else:
                    result = []
                    for aname in aname_list:
                        new_path = self._concat_assign(aname, remainder)
                        log_path.info(
                            "resolve_assign: ami_path='%s' -> multi assign: '%s'",
                            ami_path, new_path)
                        if recursive:
                            new_path = self.resolve_assigns(new_path)
                            if new_path is None:
                                return None
                        if type(new_path) is str:
                            result.append(new_path)
                        else:
                            result += new_path
                    return result
            # prefix is not an assign
            else:
                log_path.debug("resolve_assign: ami_path='%s' has no assign!",
                               ami_path)
                return ami_path
Esempio n. 14
0
 def _create_dir(self, volume, rel_dir):
     log_path.debug("%s: create assign dir: rel_dir='%s'", self.name, rel_dir)
     path = volume.create_rel_sys_path(rel_dir)
     if not path:
         log_path.error(
             "assign '%s': can't create relative dir: %s", self.name, rel_dir
         )
         return False
     else:
         log_path.debug("created sys path: %s", path)
         return True
Esempio n. 15
0
 def _create_temp(self, path):
   if os.path.exists(path):
     log_path.error("temp volume volume path already exists: '%s'", path)
     return False
   # create temp dir
   try:
     log_path.debug("creating temp dir: %s", path)
     os.makedirs(path)
     return True
   except OSError:
     log_path.error("error creating temp dir: '%s'", path)
     return False
Esempio n. 16
0
    def ami_to_sys_path(self, ami_path, fast=False):
        """Map an Amiga path to a system path.

       An absolute Amiga path with volume prefix is expected.
       Any other path returns None.

       If volume does not exist also return None.

       It replaces the volume with the sys_path prefix.
       Furthermore, the remaining Amiga path is mapped to
       the system file system and case corrected if a
       corresponding entry is found.

       If 'fast' mode is enabled then the original case
       of the path elements is kept if the underlying FS
       is case insensitive.

       Return None on error or system path
    """
        # find volume
        pos = ami_path.find(':')
        if pos <= 0:
            log_path.debug("vol: ami_to_sys_path: empty volume: %s", ami_path)
            return None
        vol_name = ami_path[:pos].lower()
        # check volume name
        if vol_name in self.vols_by_name:
            volume = self.vols_by_name[vol_name]
            vol_sys_path = volume.get_path()
            remainder = ami_path[pos + 1:]

            # only volume name given
            if len(remainder) == 0:
                log_path.info("vol: direct volume: ami='%s' -> sys='%s'",
                              ami_path, vol_sys_path)
                return vol_sys_path

            # invalid volume:/... path
            if remainder[0] == '/':
                log_path.error("vol: ami_to_sys_path: invalid :/ path: %s",
                               ami_path)
                return None

            # follow ami path along in sys world
            dirs = remainder.split('/')
            sys_path = self._follow_path_no_case(vol_sys_path, dirs, fast)
            log_path.info("vol: ami_to_sys_path: ami='%s' -> sys='%s'",
                          ami_path, sys_path)
            return sys_path
        else:
            log_path.error("vol: ami_to_sys_path: volume='%s' not found: %s",
                           vol_name, ami_path)
            return None
Esempio n. 17
0
  def ami_to_sys_path(self, ami_path, fast=False):
    """Map an Amiga path to a system path.

       An absolute Amiga path with volume prefix is expected.
       Any other path returns None.

       If volume does not exist also return None.

       It replaces the volume with the sys_path prefix.
       Furthermore, the remaining Amiga path is mapped to
       the system file system and case corrected if a
       corresponding entry is found.

       If 'fast' mode is enabled then the original case
       of the path elements is kept if the underlying FS
       is case insensitive.

       Return None on error or system path
    """
    # find volume
    pos = ami_path.find(':')
    if pos <= 0:
      log_path.debug("vol: ami_to_sys_path: empty volume: %s", ami_path)
      return None
    vol_name = ami_path[:pos].lower()
    # check volume name
    if vol_name in self.vols_by_name:
      volume = self.vols_by_name[vol_name]
      vol_sys_path = volume.get_path()
      remainder = ami_path[pos+1:]

      # only volume name given
      if len(remainder) == 0:
        log_path.info("vol: direct volume: ami='%s' -> sys='%s'",
                      ami_path, vol_sys_path)
        return vol_sys_path

      # invalid volume:/... path
      if remainder[0] == '/':
        log_path.error("vol: ami_to_sys_path: invalid :/ path: %s", ami_path)
        return None

      # follow ami path along in sys world
      dirs = remainder.split('/')
      sys_path = self._follow_path_no_case(vol_sys_path, dirs, fast)
      log_path.info("vol: ami_to_sys_path: ami='%s' -> sys='%s'",
                    ami_path, sys_path)
      return sys_path
    else:
      log_path.error("vol: ami_to_sys_path: volume='%s' not found: %s",
                     vol_name, ami_path)
      return None
Esempio n. 18
0
 def _setup_base_dir(self):
     # ensure that vols_base_dir exists
     base_dir = self.vols_base_dir
     if not base_dir:
         raise ValueError("volume manager: no base dir given!")
     base_dir = resolve_sys_path(base_dir)
     if not os.path.isdir(base_dir):
         try:
             log_path.info("creating volume base dir: %s", base_dir)
             os.makedirs(base_dir)
         except OSError as e:
             log_path.error("error creating volume base dir: %s -> %s",
                            base_dir, e)
             return None
     else:
         log_path.debug("found base dir: %s", base_dir)
     return base_dir
Esempio n. 19
0
 def create_rel_sys_path(self, rel_path):
   if type(rel_path) in (list, tuple):
     rel_path = os.path.join(*rel_path)
   dir_path = os.path.join(self.path, rel_path)
   if os.path.isdir(dir_path):
     log_path.debug("rel sys path in volume already exists '%s' + %s -> %s",
                    self.name, rel_path, dir_path)
     return dir_path
   try:
     log_path.debug("creating rel sys path in volume '%s' + %s -> %s",
                    self.name, rel_path, dir_path)
     os.makedirs(dir_path)
     return dir_path
   except OSError as e:
     log_path.error("error creating rel sys path in volume '%s' + %s -> %s",
                    self.name, rel_path, dir_path)
     return None
Esempio n. 20
0
 def _setup_base_dir(self):
   # ensure that vols_base_dir exists
   base_dir = self.vols_base_dir
   if not base_dir:
     raise ValueError("volume manager: no base dir given!")
   base_dir = resolve_sys_path(base_dir)
   if not os.path.isdir(base_dir):
     try:
       log_path.info("creating volume base dir: %s", base_dir)
       os.makedirs(base_dir)
     except OSError as e:
       log_path.error("error creating volume base dir: %s -> %s",
                      base_dir, e)
       return None
   else:
     log_path.debug("found base dir: %s", base_dir)
   return base_dir
Esempio n. 21
0
 def parse_config(self, cfg):
     if cfg is None:
         return True
     path = cfg.path
     if path is None:
         return True
     if path.cwd:
         self.cwd.set(path.cwd)
     if path.command:
         self.cmd_paths.set(path.command)
     # enforce validation
     try:
         log_path.debug("env: parse_config: %s", cfg)
         self.cwd.resolve()
         self.cmd_paths.resolve()
         log_path.debug("env: done: %s", self)
     except AmiPathError as e:
         log_path.error("env: parse config error: %s", e)
         return False
     return True
Esempio n. 22
0
 def _parse_spec(self, spec):
     # auto parse string spec
     if type(spec) is str:
         try:
             spec = Spec.parse(spec)
         except ValueError as e:
             log_path.error("error parsing spec: %r -> %s", spec, e)
             return None
     # check spec
     name = spec.get_name()
     src_list = spec.get_src_list()
     cfg = spec.get_cfg()
     n = len(src_list)
     if n == 0:
         # local path
         path = self._get_local_vol_path(name)
         log_path.debug("local path='%s'", path)
         if path is None:
             return None
     elif n == 1:
         path = resolve_sys_path(src_list[0])
         log_path.debug("resolved path='%s'", path)
     if n > 1:
         log_path.error("only one source in volume spec allowed!")
         return None
     log_path.debug("name='%s', path='%s'", name, path)
     # create volume
     return Volume(name, path, cfg)
Esempio n. 23
0
 def _parse_spec(self, spec):
   # auto parse string spec
   if type(spec) is str:
     try:
       spec = Spec.parse(spec)
     except ValueError as e:
       log_path.error("error parsing spec: %r -> %s", spec, e)
       return None
   # check spec
   name = spec.get_name()
   src_list = spec.get_src_list()
   cfg = spec.get_cfg()
   n = len(src_list)
   if n == 0:
     # local path
     path = self._get_local_vol_path(name)
     log_path.debug("local path='%s'", path)
     if path is None:
       return None
   elif n == 1:
     path = resolve_sys_path(src_list[0])
     log_path.debug("resolved path='%s'", path)
   if n > 1:
     log_path.error("only one source in volume spec allowed!")
     return None
   log_path.debug("name='%s', path='%s'", name, path)
   # create volume
   return Volume(name, path, cfg)
Esempio n. 24
0
 def shutdown(self):
     log_path.debug("shutting down assigns")
     for a in self.assigns:
         log_path.info("cleaning up assign: %s", a)
         a.shutdown()
         a.is_setup = False
Esempio n. 25
0
 def shutdown(self):
   log_path.debug("shutting down assigns")
   for a in self.assigns:
     log_path.info("cleaning up assign: %s", a)
     a.shutdown()
     a.is_setup = False
Esempio n. 26
0
  def resolve_assigns(self, ami_path, recursive=True, as_list=False):
    """replace all assigns found in path until only a volume path exists.
       do not touch relative paths or abs paths without assign prefix.

        return: original path if path is not absolute
                or does not contain assign prefix
        or: string if no multi assigns are involved
        or: list of string if multi assigns were encountered
    """
    log_path.info("resolve_assign: ami_path='%s'", ami_path)
    split = self._split_volume_remainder(ami_path)
    if split is None:
      # relative path
      log_path.debug("resolve_assign: ami_path='%s' is rel_path!",
                     ami_path)
      if as_list:
        return [ami_path]
      else:
        return ami_path
    else:
      # is assign
      name = split[0].lower()
      if self.assigns_by_name.has_key(name):
        remainder = split[1]
        assign = self.assigns_by_name[name]
        aname_list = assign.get_assigns()
        # single assign
        if len(aname_list) == 1:
          aname = aname_list[0]
          new_path = self._concat_assign(aname, remainder)
          log_path.info("resolve_assign: ami_path='%s' -> single assign: '%s'",
                        ami_path, new_path)
          if recursive:
            return self.resolve_assigns(new_path, recursive, as_list)
          elif as_list:
            return [new_path]
          else:
            return new_path
        # multi assign
        else:
          result = []
          for aname in aname_list:
            new_path = self._concat_assign(aname, remainder)
            log_path.info(
                "resolve_assign: ami_path='%s' -> multi assign: '%s'",
                ami_path, new_path)
            if recursive:
              new_path = self.resolve_assigns(new_path, recursive, as_list)
              if new_path is None:
                return None
            if type(new_path) is str:
              result.append(new_path)
            else:
              result += new_path
          return result
      # prefix is not an assign
      else:
        log_path.debug("resolve_assign: ami_path='%s' has no assign!",
                       ami_path)
        if as_list:
          return [ami_path]
        else:
          return ami_path
Esempio n. 27
0
 def _delete_temp(self, path):
     try:
         log_path.debug("removing temp dir: %s", path)
         shutil.rmtree(path)
     except:
         log_path.error("error removing temp dir: '%s'", path)
Esempio n. 28
0
 def _delete_temp(self, path):
   try:
     log_path.debug("removing temp dir: %s", path)
     shutil.rmtree(path)
   except:
     log_path.error("error removing temp dir: '%s'", path)