Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Side by Side Diff: client/libs/logdog/streamname.py

Issue 2453273002: Update LogDog client library to generate URLs. (Closed)
Patch Set: Forgot project, oops. Addressed nits. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « client/libs/logdog/stream.py ('k') | client/libs/logdog/tests/bootstrap_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
142 Args:
143 path (str): the full stream path to parse.
144
145 Raises:
146 ValueError: If path is not a full, valid stream path string.
147 """
148 parts = path.split('/+/', 1)
149 if len(parts) != 2:
150 raise ValueError('Not a full stream path: [%s]' % (path,))
151 return cls.make(*parts)
152
153 def validate(self):
154 """Raises: ValueError if this is not a valid stream name."""
155 try:
156 validate_stream_name(self.prefix)
157 except ValueError as e:
158 raise ValueError('Invalid prefix component [%s]: %s' % (
159 self.prefix, e.message,))
160
161 try:
162 validate_stream_name(self.name)
163 except ValueError as e:
164 raise ValueError('Invalid name component [%s]: %s' % (
165 self.name, e.message,))
166
167 def __str__(self):
168 return '%s/+/%s' % (self.prefix, self.name)
169
170
171 def get_logdog_viewer_url(host, project, *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 project (str): The project name.
177 stream_paths: A set of StreamPath instances for the stream paths to
178 generate the URL for.
179 """
180 return urlparse.urlunparse((
181 'https', # Scheme
182 host, # netloc
183 'v/', # path
184 '', # params
185 '&'.join(('s=%s' % (urllib.quote('%s/%s' % (project, path), safe=''))
186 for path in stream_paths)), # query
187 '', # fragment
188 ))
OLDNEW
« no previous file with comments | « client/libs/logdog/stream.py ('k') | client/libs/logdog/tests/bootstrap_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698