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

Unified Diff: chrome/common/extensions/docs/server2/path_canonicalizer.py

Issue 148293018: Docserver: Make the .html extension unnecessary for content pages, for example, (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/docs/server2/path_canonicalizer.py
diff --git a/chrome/common/extensions/docs/server2/path_canonicalizer.py b/chrome/common/extensions/docs/server2/path_canonicalizer.py
index 1d7d7bf4671f5967fb6c1a3f35499ec86d60da2e..f2b0da7853a62154624cfe5e9560d3390ae7bedb 100644
--- a/chrome/common/extensions/docs/server2/path_canonicalizer.py
+++ b/chrome/common/extensions/docs/server2/path_canonicalizer.py
@@ -6,6 +6,7 @@ from collections import defaultdict
import posixpath
from path_util import SplitParent
+from special_paths import WEBMASTER_PROOF
def _SimplifyFileName(file_name):
@@ -17,49 +18,86 @@ def _SimplifyFileName(file_name):
class PathCanonicalizer(object):
- '''Transforms paths into their canonical forms. Since the dev server has had
+ '''Transforms paths into their canonical forms. Since the docserver has had
many incarnations - e.g. there didn't use to be apps/ - there may be old
paths lying around the webs. We try to redirect those to where they are now.
'''
- def __init__(self, compiled_fs_factory, file_system):
+ def __init__(self,
+ file_system,
+ object_store_creator,
+ strip_extensions):
+ # |strip_extensions| is a list of file extensions (e.g. .html) that should
+ # be stripped for a path's canonical form.
+ self._cache = object_store_creator.Create(
+ PathCanonicalizer, category=file_system.GetIdentity())
self._file_system = file_system
- # A lazily populated mapping of file names to a list of full paths that
- # contain them. For example,
- # - browserAction.html: [extensions/browserAction.html]
- # - storage.html: [apps/storage.html, extensions/storage.html]
- self._files_to_paths = None
-
- def _GetPotentialPaths(self, filename):
- '''Returns the paths to any file called |filename|.
- '''
- if self._files_to_paths is None:
- self._files_to_paths = defaultdict(list)
+ self._strip_extensions = strip_extensions
+
+ def _LoadCache(self):
+ cached = self._cache.GetMulti(('canonical_paths',
+ 'simplified_to_paths')).Get()
+
+ # |canonical_paths| is the pre-calculated set of canonical paths.
+ # |simplified_to_paths| is a lazily populated mapping of simplified file
Yoyo Zhou 2014/02/12 22:14:05 simplified_paths_map?
not at google - send to devlin 2014/02/13 03:34:34 Done.
+ # names to a list of full paths that contain them. For example,
+ # - browseraction: [extensions/browserAction.html]
+ # - storage: [apps/storage.html, extensions/storage.html]
+ canonical_paths, simplified_to_paths = (
+ cached.get('canonical_paths'), cached.get('simplified_to_paths'))
+
+ if canonical_paths is None:
+ assert simplified_to_paths is None
+ canonical_paths = set()
+ simplified_to_paths = {}
for base, dirs, files in self._file_system.Walk(''):
- for f in dirs + files:
- self._files_to_paths[_SimplifyFileName(f)].append(
- posixpath.join(base, f))
- return self._files_to_paths.get(_SimplifyFileName(filename))
+ for path in dirs + files:
Yoyo Zhou 2014/02/12 22:14:05 Be consistent: path_without_ext + ext = path here,
not at google - send to devlin 2014/02/13 03:34:34 Done.
+ # Update |canonical_paths|.
+ path_without_ext, ext = posixpath.splitext(path)
+ canonical_path = posixpath.join(
+ base,
+ path_without_ext if ext in self._strip_extensions else path)
+ canonical_paths.add(canonical_path)
+ # Update |simplified_to_paths|.
+ simplified = _SimplifyFileName(path)
+ if simplified not in simplified_to_paths:
Yoyo Zhou 2014/02/12 22:14:05 Why not use defaultdict for simplified_to_paths?
not at google - send to devlin 2014/02/13 03:34:34 Ooh, it pickles.
+ simplified_to_paths[simplified] = [canonical_path]
+ simplified_to_paths[simplified].append(canonical_path)
+ # Store |simplified_to_paths| sorted. Ties in length are broken by taking
+ # the shortest, lexicographically smallest path.
+ for path_list in simplified_to_paths.itervalues():
+ path_list.sort(key=lambda p: (len(p), p))
+ self._cache.SetMulti({
+ 'canonical_paths': canonical_paths,
+ 'simplified_to_paths': simplified_to_paths,
+ })
+ else:
+ assert simplified_to_paths is not None
+
+ return canonical_paths, simplified_to_paths
def Canonicalize(self, path):
'''Returns the canonical path for |path|.
'''
+ if path == WEBMASTER_PROOF:
Yoyo Zhou 2014/02/12 22:14:05 Are there tests that cover this path?
not at google - send to devlin 2014/02/13 03:34:34 There are now. And I decided the current behaviour
+ return path
+
+ canonical_paths, simplified_to_paths = self._LoadCache()
+
# Path may already be the canonical path.
- if self._file_system.Exists(path).Get():
+ if path in canonical_paths:
return path
- # Path not found. Our single heuristic: find |basename| in the directory
+ # Path not found. Our single heuristic: find |base| in the directory
# structure with the longest common prefix of |path|.
_, base = SplitParent(path)
- potential_paths = self._GetPotentialPaths(base)
+ potential_paths = simplified_to_paths.get(_SimplifyFileName(base))
if not potential_paths:
- # There is no file with that name.
+ # There is no file with anything close to that name.
return path
- # The most likely canonical file is the one with the longest common prefix.
- # This is slightly weaker than it could be; |path| is compared, not the
- # simplified form of |path|, which may matter. Ties in length are broken by
- # taking the shortest, lexicographically smallest path.
- potential_paths.sort(key=lambda p: (len(p), p))
+ # The most likely canonical file is the one with the longest common prefix
+ # with |path|. This is slightly weaker than it could be; |path| is
+ # compared, not the simplified form of |path|, which may matter.
max_prefix = potential_paths[0]
max_prefix_length = len(posixpath.commonprefix((max_prefix, path)))
for path_for_file in potential_paths[1:]:

Powered by Google App Engine
This is Rietveld 408576698