1 """Display models and utility functions"""
5 def shorten_paths(source_paths
):
6 """Shorten a sequence of paths into unique strings for display"""
8 # Start by assuming that all paths are in conflict.
9 # On each iteration we will collect all the path suffixes, move the newly
10 # unique entries to the result, and repeat until no conflicts remain.
12 conflicts
= list(source_paths
)
16 # Gather the suffixes for the current paths in conflict
17 suffixes
= collections
.defaultdict(list)
18 for path
in conflicts
:
19 suffix
= path_suffix(path
, count
)
20 suffixes
[suffix
].append(path
)
22 # Loop over the suffixes to gather new conflicts and unique entries.
26 for suffix
, paths
in suffixes
.items():
27 # If only a single path exists for the suffix then no conflict
28 # exists, and the suffix is valid.
30 result
[paths
[0]] = suffix
31 # If this loop runs too long then bail out by using the full path.
35 # If multiple paths map to the same suffix then the paths are
36 # considered in conflict, and will be reprocessed.
38 conflicts
.extend(paths
)
44 def path_suffix(path
, count
):
45 """Return `count` number of trailing path components"""
46 path
= normalize_path(path
)
47 components
= path
.split('/')[-count
:]
48 return '/'.join(components
)
51 def normalize_path(path
):
52 """Normalize a path so that only "/" is used as a separator"""
53 return path
.replace('\\', '/')