Package pathaddition :: Module relative |
[hide private]
[frames] | no frames]

# Source Code for Module pathaddition.relative

      1  #============================================================================
      2  #Name        : relative.py
      3  #Part of     : Helium
      4
      5  #Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
      6  #All rights reserved.
      7  #This component and the accompanying materials are made available
      8  #under the terms of the License "Eclipse Public License v1.0"
      9  #which accompanies this distribution, and is available
     10  #at the URL "http://www.eclipse.org/legal/epl-v10.html".
     11  #
     12  #Initial Contributors:
     13  #Nokia Corporation - initial contribution.
     14  #
     15  #Contributors:
     16  #
     17  #Description:
     18  #===============================================================================
     19
     20  """
     21      Additional path functionnality.
     22      abs2rel
     23      rel2abs
     24  """
     25  import os
     26  import os.path
     27  import re
     28
     29  # matches http:// and ftp:// and mailto://
     30  protocolPattern = re.compile(r'^\w+://')
     31
     32 -def isabs(string):
     33      """
     34
     35      @return true if string is an absolute path or protocoladdress
     36      for addresses beginning in http:// or ftp:// or ldap:// -
     37      they are considered "absolute" paths.
     38      """
     39      if protocolPattern.match(string):
     40          return True
     41      return os.path.isabs(string)
     42
     43 -def rel2abs(path, base = None):
     44      """ converts a relative path to an absolute path.
     45
     46      @param path the path to convert - if already absolute, is returned
     47      without conversion.
     48      @param base - optional. Defaults to the current directory.
     49      The base is intelligently concatenated to the given relative path.
     50      @return the relative path of path from base
     51      """
     52      if isabs(path):
     53          return path
     54      if base is None:
     55          base = os.curdir
     56      retval = os.path.join(base, path)
     57      return os.path.abspath(retval)
     58
     59
     60 -def pathsplit(p, rest=None):
     61      """ Split path to pieces """
     62      if rest is None:
     63          rest = []
     64      (h, t) = os.path.split(p)
     65      if len(h) < 1:
     66          return [t]+rest
     67      if len(t) < 1:
     68          return [h]+rest
     69      return pathsplit(h, [t]+rest)
     70
     71 -def commonpath(l1, l2, common=None):
     72      """ return the common path"""
     73      if common is None:
     74          common = []
     75      if len(l1) < 1:
     76          return (common, l1, l2)
     77      if len(l2) < 1:
     78          return (common, l1, l2)
     79      if l1[0] != l2[0]:
     80          return (common, l1, l2)
     81      return commonpath(l1[1:], l2[1:], common+[l1[0]])
     82
     83
     84 -def relpath(p1, p2):
     85      (common, l1, l2) = commonpath(pathsplit(p1), pathsplit(p2))
     86      p = []
     87      if len(l1) > 0:
     88          p = [ '../' * len(l1) ]
     89      p = p + l2
     90      if len(p) is 0:
     91          return "."
     92      return os.path.join( *p )
     93
     94
     95 -def abs2rel(path, base = None):
     96      """ @return a relative path from base to path.
     97
     98      base can be absolute, or relative to curdir, or defaults
     99      to curdir.
    100      """
    101      if protocolPattern.match(path):
    102          return path
    103      if base is None:
    104          base = os.curdir
    105      base = rel2abs(base)
    106      path = rel2abs(path) # redundant - should already be absolute
    107      return relpath(base, path)
    108
    109
    110 -def commonprefix(paths):
    111      """
    112      Returns the common prefix base on the path components.
    113      """
    114      if len(paths) == 0:
    115          return ''
    116      if len(paths) == 1:
    117          return paths[0]
    118
    119      def _commonprefix_internal(p1, p2):
    120          c = commonpath(pathsplit(p1), pathsplit(p2))[0]
    121          if len(c) == 0:
    122              return ''
    123          return os.path.join(*c)
    124      common = _commonprefix_internal(paths[0], paths[1])
    125      for p in paths[2:]:
    126          common = _commonprefix_internal(common, p)
    127      return common
    128