12 # distributed under the License is distributed on an "AS IS" BASIS, |
12 # distributed under the License is distributed on an "AS IS" BASIS, |
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 # See the License for the specific language governing permissions and |
14 # See the License for the specific language governing permissions and |
15 # limitations under the License. |
15 # limitations under the License. |
16 |
16 |
17 """Path and link name manipulation functions. |
17 """Path and link ID manipulation functions. |
18 """ |
18 """ |
19 |
19 |
20 __authors__ = [ |
20 __authors__ = [ |
21 '"Todd Larsen" <tlarsen@google.com>', |
21 '"Todd Larsen" <tlarsen@google.com>', |
22 '"Lennard de Rijk" <ljvderijk@gmail.com>', |
22 '"Lennard de Rijk" <ljvderijk@gmail.com>', |
29 # start with ASCII digit or lowercase |
29 # start with ASCII digit or lowercase |
30 # (additional ASCII digit or lowercase |
30 # (additional ASCII digit or lowercase |
31 # -OR- |
31 # -OR- |
32 # underscore and ASCII digit or lowercase) |
32 # underscore and ASCII digit or lowercase) |
33 # zero or more of OR group |
33 # zero or more of OR group |
34 LINKNAME_PATTERN_CORE = r'[0-9a-z](?:[0-9a-z]|_[0-9a-z])*' |
34 LINK_ID_PATTERN_CORE = r'[0-9a-z](?:[0-9a-z]|_[0-9a-z])*' |
35 LINKNAME_ARG_PATTERN = r'(?P<link_name>%s)' % LINKNAME_PATTERN_CORE |
35 LINK_ID_ARG_PATTERN = r'(?P<link_id>%s)' % LINK_ID_PATTERN_CORE |
36 LINKNAME_PATTERN = r'^%s$' % LINKNAME_PATTERN_CORE |
36 LINK_ID_PATTERN = r'^%s$' % LINK_ID_PATTERN_CORE |
37 LINKNAME_REGEX = re.compile(LINKNAME_PATTERN) |
37 LINK_ID_REGEX = re.compile(LINK_ID_PATTERN) |
38 |
38 |
39 # partial path is multiple link_name chunks, |
39 # partial path is multiple link_id chunks, |
40 # each separated by a trailing / |
40 # each separated by a trailing / |
41 # (at least 1) |
41 # (at least 1) |
42 PARTIAL_PATH_ARG_PATTERN = (r'(?P<partial_path>%(link_name)s' |
42 PARTIAL_PATH_ARG_PATTERN = (r'(?P<partial_path>%(link_id)s' |
43 '(?:/%(link_name)s)*)' % { |
43 '(?:/%(link_id)s)*)' % { |
44 'link_name': LINKNAME_PATTERN_CORE}) |
44 'link_id': LINK_ID_PATTERN_CORE}) |
45 PARTIAL_PATH_PATTERN = r'^%s$' % PARTIAL_PATH_ARG_PATTERN |
45 PARTIAL_PATH_PATTERN = r'^%s$' % PARTIAL_PATH_ARG_PATTERN |
46 PARTIAL_PATH_REGEX = re.compile(PARTIAL_PATH_PATTERN) |
46 PARTIAL_PATH_REGEX = re.compile(PARTIAL_PATH_PATTERN) |
47 |
47 |
48 # path is multiple link_name chunks, |
48 # path is multiple link_id chunks, |
49 # each separated by a trailing / |
49 # each separated by a trailing / |
50 # (at least 1) |
50 # (at least 1) |
51 # followed by a single link_name with no trailing / |
51 # followed by a single link_id with no trailing / |
52 PATH_LINKNAME_ARGS_PATTERN = ( |
52 PATH_LINK_ID_ARGS_PATTERN = ( |
53 r'%(partial_path)s/' |
53 r'%(partial_path)s/' |
54 '(?P<link_name>%(link_name)s)' % { |
54 '(?P<link_id>%(link_id)s)' % { |
55 'partial_path' : PARTIAL_PATH_ARG_PATTERN, |
55 'partial_path' : PARTIAL_PATH_ARG_PATTERN, |
56 'link_name': LINKNAME_PATTERN_CORE}) |
56 'link_id': LINK_ID_PATTERN_CORE}) |
57 PATH_LINKNAME_PATTERN = r'^%s$' % PATH_LINKNAME_ARGS_PATTERN |
57 PATH_LINK_ID_PATTERN = r'^%s$' % PATH_LINK_ID_ARGS_PATTERN |
58 PATH_LINKNAME_REGEX = re.compile(PATH_LINKNAME_PATTERN) |
58 PATH_LINK_ID_REGEX = re.compile(PATH_LINK_ID_PATTERN) |
59 |
59 |
60 |
60 |
61 def getPartsFromPath(path): |
61 def getPartsFromPath(path): |
62 """Splits path string into partial_path and link_name. |
62 """Splits path string into partial_path and link_id. |
63 |
63 |
64 Returns: |
64 Returns: |
65 {'partial_path': 'everything/but', |
65 {'partial_path': 'everything/but', |
66 'link_name': 'link_name'} |
66 'link_id': 'link_id'} |
67 or {} (empty dict) if string did not match PATH_LINKNAME_PATTERN. |
67 or {} (empty dict) if string did not match PATH_LINK_ID_PATTERN. |
68 """ |
68 """ |
69 path_link_name_match = PATH_LINKNAME_REGEX.match(path) |
69 path_link_name_match = PATH_LINK_ID_REGEX.match(path) |
70 |
70 |
71 if not path_link_name_match: |
71 if not path_link_name_match: |
72 return {} |
72 return {} |
73 |
73 |
74 return path_link_name_match.groupdict() |
74 return path_link_name_match.groupdict() |
81 path_parts: a single path string, or a list of path part strings, |
81 path_parts: a single path string, or a list of path part strings, |
82 or a nested list of path part strings (where the zeroeth element in |
82 or a nested list of path part strings (where the zeroeth element in |
83 the list is itself a list); for example: |
83 the list is itself a list); for example: |
84 'a/complete/path/in/one/string' |
84 'a/complete/path/in/one/string' |
85 ['some', 'path', 'parts'] |
85 ['some', 'path', 'parts'] |
86 [['path', 'parts', 'and', 'a'], 'link name'] |
86 [['path', 'parts', 'and', 'a'], 'link ID'] |
87 |
87 |
88 Returns: |
88 Returns: |
89 None if path_parts is False (None, empty string, etc.) or if |
89 None if path_parts is False (None, empty string, etc.) or if |
90 any list elements are False (an empty list, empty string, etc.); |
90 any list elements are False (an empty list, empty string, etc.); |
91 otherwise, the combined string with the necessary separators. |
91 otherwise, the combined string with the necessary separators. |