OLD | NEW |
---|---|
1 # Copyright 2016 The LUCI Authors. All rights reserved. | 1 # Copyright 2016 The LUCI Authors. All rights reserved. |
2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
4 | 4 |
5 import collections | |
5 import re | 6 import re |
6 import string | 7 import string |
7 import types | 8 import types |
9 import urllib | |
10 import urlparse | |
8 | 11 |
9 _ALNUM_CHARS = string.ascii_letters + string.digits | 12 _ALNUM_CHARS = string.ascii_letters + string.digits |
10 _SEGMENT_RE_BASE = r'[a-zA-Z0-9][a-zA-Z0-9:_\-.]*' | 13 _SEGMENT_RE_BASE = r'[a-zA-Z0-9][a-zA-Z0-9:_\-.]*' |
11 _STREAM_NAME_RE = re.compile('^(' + _SEGMENT_RE_BASE + ')(/' + | 14 _STREAM_NAME_RE = re.compile('^(' + _SEGMENT_RE_BASE + ')(/' + |
12 _SEGMENT_RE_BASE + ')*$') | 15 _SEGMENT_RE_BASE + ')*$') |
13 _MAX_STREAM_NAME_LENGTH = 4096 | 16 _MAX_STREAM_NAME_LENGTH = 4096 |
14 | 17 |
15 _MAX_TAG_KEY_LENGTH = 64 | 18 _MAX_TAG_KEY_LENGTH = 64 |
16 _MAX_TAG_VALUE_LENGTH = 4096 | 19 _MAX_TAG_VALUE_LENGTH = 4096 |
17 | 20 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
98 """ | 101 """ |
99 # Alphanumeric check. | 102 # Alphanumeric check. |
100 if ch in _ALNUM_CHARS: | 103 if ch in _ALNUM_CHARS: |
101 return True | 104 return True |
102 if first: | 105 if first: |
103 # The first character must be alphanumeric. | 106 # The first character must be alphanumeric. |
104 return False | 107 return False |
105 | 108 |
106 # Check additional middle-name characters: | 109 # Check additional middle-name characters: |
107 return ch in ':_-./' | 110 return ch in ':_-./' |
111 | |
112 | |
113 class StreamPath(collections.namedtuple('_StreamPath', ('prefix', 'name'))): | |
114 """StreamPath is a full stream path. | |
115 | |
116 This consists of both a stream prefix and a stream name. | |
117 | |
118 When constructed with parse or make, the stream path must be completely valid. | |
119 However, invalid stream paths may be constructed by manually instantiation. | |
120 This can be useful for wildcard query values (e.g., "prefix='foo/*/bar/**'"). | |
121 """ | |
122 | |
123 @classmethod | |
124 def make(cls, prefix, name): | |
125 """Returns (StreamPath): The validated StreamPath instance. | |
126 | |
127 Args: | |
128 prefix (str): the prefix component | |
129 name (str): the name component | |
130 | |
131 Raises: | |
132 ValueError: If path is not a full, valid stream path string. | |
133 """ | |
134 inst = cls(prefix=prefix, name=name) | |
135 inst.validate() | |
136 return inst | |
137 | |
138 @classmethod | |
139 def parse(cls, path): | |
140 """Returns (StreamPath): The parsed StreamPath instance. | |
141 | |
jbudorick
2016/10/27 13:24:06
nit: missing Args
dnj
2016/10/27 22:42:45
Done.
| |
142 Raises: | |
143 ValueError: If path is not a full, valid stream path string. | |
144 """ | |
145 parts = path.split('/+/', 1) | |
146 if len(parts) != 2: | |
147 raise ValueError('Not a full stream path: [%s]' % (path,)) | |
148 return cls.make(*parts) | |
149 | |
150 def validate(self): | |
151 """Raises: ValueError if this is not a valid stream name.""" | |
152 try: | |
153 validate_stream_name(self.prefix) | |
154 except ValueError as e: | |
155 raise ValueError('Invalid prefix component [%s]: %s' % ( | |
156 self.prefix, e.message,)) | |
157 | |
158 try: | |
159 validate_stream_name(self.name) | |
160 except ValueError as e: | |
161 raise ValueError('Invalid name component [%s]: %s' % ( | |
162 self.name, e.message,)) | |
163 | |
164 def __str__(self): | |
165 return '%s/+/%s' % (self.prefix, self.name) | |
166 | |
167 def urlquote(self): | |
168 return urllib.quote(str(self), safe='') | |
169 | |
170 | |
171 def get_logdog_viewer_url(host, *stream_paths): | |
172 """Returns (str): The LogDog viewer URL for the named stream(s). | |
173 | |
174 Args: | |
175 host (str): The name of the Coordiantor host. | |
176 stream_paths: A set of StreamPath instances for the stream paths to | |
177 generate the URL for. | |
178 """ | |
179 if len(stream_paths) == 0: | |
180 raise ValueError('At least one stream name must be supplied.') | |
181 | |
182 return urlparse.urlunparse(( | |
183 'https', # Scheme | |
184 host, # netloc | |
185 'v/', # path | |
186 '', # params | |
187 '&'.join(('s=%s' % (path.urlquote(),) for path in stream_paths)), # query | |
188 '', # fragment | |
189 )) | |
OLD | NEW |