summaryrefslogtreecommitdiff
path: root/summainlib.py
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2011-03-20 10:52:09 +0000
committerLars Wirzenius <liw@liw.fi>2011-03-20 10:52:09 +0000
commit97ac6cd06454dda91a3ad6131f578d3622678de7 (patch)
tree9c76e22b2c04d8762900a4d6a959bea74c243475 /summainlib.py
parentb74b5d783c718111cf9b346e0218a75735f4a791 (diff)
downloadsummain-97ac6cd06454dda91a3ad6131f578d3622678de7.tar.gz
Add a class for normalizing paths.
Diffstat (limited to 'summainlib.py')
-rw-r--r--summainlib.py65
1 files changed, 65 insertions, 0 deletions
diff --git a/summainlib.py b/summainlib.py
index e9d6c60..5dfd133 100644
--- a/summainlib.py
+++ b/summainlib.py
@@ -77,6 +77,71 @@ class NumberNormalizer(object):
self.next_dev = 1
+class PathNormalizer(object):
+
+ '''Normalize a filesystem path.
+
+ For every input path, a new output path is given. The same output
+ path is given every time the same input path is given. The output
+ path has the same number of elements as the input path, and if
+ /foo/bar results in /a/b, then /foo/yo results in /a/b, i.e., the
+ tree structure is the same.
+
+ '''
+
+ def __init__(self):
+ self._counter = 0
+ self._dict = dict()
+ self._dict[os.sep] = os.sep
+ self._dict['.'] = '.'
+ self._dict['..'] = '..'
+
+ def split(self, path):
+ if path == os.sep:
+ return [os.sep]
+ parts = path.split(os.sep)
+ if parts:
+ if parts[0] == '':
+ parts[0] = os.sep
+ if parts[-1] == '':
+ parts[-1] = os.sep
+ return parts
+
+ def _base26(self, n):
+ if n == 0:
+ digits = [0]
+ else:
+ digits = []
+ while n > 0:
+ digits.append(n % 26)
+ n /= 26
+
+ letters = 'abcdefghijklmnopqrstuvwxyz'
+ assert len(letters) == 26
+ return ''.join(letters[x] for x in reversed(digits))
+
+ def normalize_part(self, part):
+ if part not in self._dict:
+ self._dict[part] = self._base26(self._counter)
+ self._counter += 1
+ return self._dict[part]
+
+ def normalize(self, path):
+ parts = self.split(path)
+ normalized = [self.normalize_part(x) for x in parts]
+ result = ''
+ for x in normalized:
+ if not result:
+ result = x
+ elif x == os.sep:
+ result += x
+ elif result.endswith(os.sep):
+ result += x
+ else:
+ result += os.sep + x
+ return result
+
+
class FilesystemObject(object):
'''An object in the file system.