1 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 import posixpath 6 7 8 # TODO(kalman): Write a Path class and use that everywhere rather than a 9 # utility class. 10 11 12 def IsDirectory(path): 13 '''Returns whether |path| should be considered a directory. 14 ''' 15 # This assertion is sprinkled throughout the code base. 16 AssertIsValid(path) 17 return path in ('', '.', '..') or path.endswith('/') or path.endswith('/..') 18 19 20 def IsValid(path): 21 '''Returns whether |path| is a valid path for the purposes of the docserver. 22 Paths may not start with /, must be posix paths, and for sanity shouldn't 23 repeat the path separator //. 24 ''' 25 return not path.startswith('/') and not '\\' in path and not '//' in path 26 27 28 def AssertIsValid(path): 29 assert IsValid(path), 'Path "%s" is invalid' % path 30 31 32 def Join(*paths): 33 assert all(IsValid(path) for path in paths), paths 34 return posixpath.join(*paths) 35 36 37 def SplitParent(path): 38 '''Returns the parent directory and base name of |path| in a tuple. 39 Any trailing slash of |path| is preserved, such that the parent of 40 '/hello/world/' is '/hello' and the base is 'world/'. 41 ''' 42 parent, base = posixpath.split(path.rstrip('/')) 43 if path.endswith('/'): 44 base += '/' 45 return parent, base 46 47 48 def Split(path): 49 '''Returns a list of the directories and filename in a path. 'p1/p2/p3' 50 will return ['p1/', 'p2/', 'p3']. 51 ''' 52 AssertIsValid(path) 53 names = [name + '/' for name in path.rstrip('/').split('/')] 54 if names and not path.endswith('/'): 55 names[-1] = names[-1][:-1] 56 return names 57 58 59 def ToDirectory(path): 60 '''Returns a string representing |path| as a directory, that is, 61 IsDirectory(result) is True (and does not fail assertions). If |path| is 62 already a directory then this is a no-op. 63 ''' 64 return path if IsDirectory(path) else (path + '/') 65 66 67 def AssertIsDirectory(path): 68 assert IsDirectory(path), '"%s" is not a directory' % path 69 70 71 def AssertIsFile(path): 72 assert not IsDirectory(path), '"%s" is not a file' % path 73 74 def Segment(path): 75 '''Yields a tuple (url, file) for directory split pairs. 76 For example, if we split the path 'foo/bar/baz', it will yield: 77 ('', 'foo/bar/baz'), ('foo', "bar/baz'), ('foo/bar', 'baz'), 78 ('foo/bar/baz', '') 79 ''' 80 AssertIsValid(path) 81 82 last_path = '' 83 yield (last_path, path) 84 85 for segment in (segment for segment in path.split('/') if segment != ''): 86 last_path = posixpath.join(last_path, segment) 87 rel_path = posixpath.relpath(path, last_path) 88 89 # Don't let relpath say the filename is '.' 90 if rel_path == '.': 91 rel_path = '' 92 else: 93 last_path = ToDirectory(last_path) 94 95 yield (last_path, rel_path) 96