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

Side by Side Diff: appengine/chrome_infra_packages/cipd/impl.py

Issue 1194803002: Add a package listing API to cipd. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 5 years, 6 months 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
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Implementation of package repository service. 5 """Implementation of package repository service.
6 6
7 Package and PackageInstance 7 Package and PackageInstance
8 --------------------------- 8 ---------------------------
9 9
10 Definitions: 10 Definitions:
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 """Returns Package entity if it exists. 172 """Returns Package entity if it exists.
173 173
174 Args: 174 Args:
175 package_name: name of the package, e.g. 'infra/tools/cipd'. 175 package_name: name of the package, e.g. 'infra/tools/cipd'.
176 176
177 Returns: 177 Returns:
178 Package or None. 178 Package or None.
179 """ 179 """
180 return package_key(package_name).get() 180 return package_key(package_name).get()
181 181
182 @staticmethod
183 def _is_in_directory(directory, path, recursive):
184 """Tests if the path is under the given directory.
185
186 This assumes directory is a prefix of path.
187
188 Args:
189 directory: string, directory the path should fall under.
190 path: string, full path to test.
191 recursive: whether the path can be in a subdirectory.
192
193 Returns:
194 True if the path is under the directory.
195 """
196 start = len(directory)
197
198 # The directory itself or anything shorter is not a match.
199 if len(path) <= start:
200 return False
201
202 # The root doesn't begin with slash so only check non-root searches.
203 if start:
204 if path[start] != '/':
205 return False
206 start += 1
207
208 # A subdirectory was found and we're not looking for recursive matches.
209 if not recursive and '/' in path[start:]:
210 return False
211 return True
212
213 def list_packages(self, dir_path, recursive):
214 """Returns lists of package names and directory names with the given prefix.
215
216 Args:
217 dir_path: string directory from which to list packages.
218 recursive: boolean whether to list contents of subdirectories.
219
220 Returns:
221 [package name, ...], [directory name, ...]
222 """
223 query = Package.query()
224
225 # Normalize directory to simplify matching logic later.
226 dir_path = dir_path.rstrip('/')
227
228 # Only apply the filtering if a prefix was given. The empty string isn't a
229 # valid key and will result in an exception.
230 if dir_path:
231 query = query.filter(
232 # Prefix match using the operators available to us. Packages can only
233 # contain lowercase ascii, numbers, and '/' so '\uffff' will always
234 # be larger.
235 ndb.AND(Package.key >= ndb.Key(Package, dir_path),
236 Package.key <= ndb.Key(Package, dir_path + u'\uffff')))
237 pkgs = []
238 dirs = set()
239 for key in query.iter(keys_only=True):
240 pkg = key.string_id()
241
242 # In case the index is stale since this is an eventual consistent query.
243 if not pkg.startswith(dir_path): # pragma: no cover
244 continue
245 pkgs.append(pkg)
246
247 # Add in directories derived from full package path.
248 if '/' in pkg:
249 parts = pkg.split('/')
250 dirs.update('/'.join(parts[:n]) for n in xrange(1, len(parts)))
251
252 dirs = [d for d in dirs if self._is_in_directory(dir_path, d, recursive)]
253 pkgs = [p for p in pkgs if self._is_in_directory(dir_path, p, recursive)
254 or len(dir_path) == len(p)]
255 return pkgs, dirs
256
182 def get_processing_result(self, package_name, instance_id, processor_name): 257 def get_processing_result(self, package_name, instance_id, processor_name):
183 """Returns results of some asynchronous processor or None if not ready. 258 """Returns results of some asynchronous processor or None if not ready.
184 259
185 Args: 260 Args:
186 package_name: name of the package, e.g. 'infra/tools/cipd'. 261 package_name: name of the package, e.g. 'infra/tools/cipd'.
187 instance_id: identifier of the package instance (SHA1 of package file). 262 instance_id: identifier of the package instance (SHA1 of package file).
188 processor_name: name of the processor to retrieve results of. 263 processor_name: name of the processor to retrieve results of.
189 264
190 Returns: 265 Returns:
191 ProcessingResult entity or None. 266 ProcessingResult entity or None.
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 processors=payload['processors']) 959 processors=payload['processors'])
885 960
886 961
887 def get_backend_routes(): # pragma: no cover 962 def get_backend_routes(): # pragma: no cover
888 """Returns a list of webapp2.Route to add to backend WSGI app.""" 963 """Returns a list of webapp2.Route to add to backend WSGI app."""
889 return [ 964 return [
890 webapp2.Route( 965 webapp2.Route(
891 r'/internal/taskqueue/cipd-process/<instance_id:.+>', 966 r'/internal/taskqueue/cipd-process/<instance_id:.+>',
892 ProcessTaskQueueHandler), 967 ProcessTaskQueueHandler),
893 ] 968 ]
OLDNEW
« no previous file with comments | « appengine/chrome_infra_packages/cipd/api.py ('k') | appengine/chrome_infra_packages/cipd/test/api_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698