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

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

Issue 15087006: Docserver: there is only one. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: epic rebase Created 7 years, 5 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 8b5f77c03d09f82ef7bcecdcd179fc279f25f948..b4498a7f611cd02c5c965a9467252143863ab287 100644
--- a/chrome/common/extensions/docs/server2/path_canonicalizer.py
+++ b/chrome/common/extensions/docs/server2/path_canonicalizer.py
@@ -2,48 +2,106 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import logging
import os
+import posixpath
+import traceback
+
+from branch_utility import BranchUtility
+from file_system import FileNotFoundError
from third_party.json_schema_compiler.model import UnixName
import svn_constants
+def _SimplifyFileName(file_name):
+ return (posixpath.splitext(file_name)[0]
+ .lower()
+ .replace('.', '')
+ .replace('-', '')
+ .replace('_', ''))
+
class PathCanonicalizer(object):
'''Transforms paths into their canonical forms. Since the dev server 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, channel, compiled_fs_factory):
- self._channel = channel
- self._identity_fs = compiled_fs_factory.CreateIdentity(PathCanonicalizer)
+ def __init__(self, compiled_fs_factory):
+ # Map of simplified API names (for typo detection) to their real paths.
+ def make_public_apis(_, file_names):
+ return dict((_SimplifyFileName(name), name) for name in file_names)
+ self._public_apis = compiled_fs_factory.Create(make_public_apis,
+ PathCanonicalizer)
def Canonicalize(self, path):
- starts_with_channel, path_without_channel = (False, path)
- if path.startswith('%s/' % self._channel):
- starts_with_channel, path_without_channel = (
- True, path[len(self._channel) + 1:])
-
- if any(path.startswith(prefix)
- for prefix in ('extensions/', 'apps/', 'static/')):
- return path
-
- if '/' in path_without_channel or path_without_channel == '404.html':
- return path
-
- apps_templates = self._identity_fs.GetFromFileListing(
- '/'.join((svn_constants.PUBLIC_TEMPLATE_PATH, 'apps')))
- extensions_templates = self._identity_fs.GetFromFileListing(
- '/'.join((svn_constants.PUBLIC_TEMPLATE_PATH, 'extensions')))
-
- if self._channel is None or not starts_with_channel:
- apps_path = 'apps/%s' % path_without_channel
- extensions_path = 'extensions/%s' % path_without_channel
+ '''Returns the canonical path for |path|, and whether that path is a
+ permanent canonicalisation (e.g. when we redirect from a channel to a
+ channel-less URL) or temporary (e.g. when we redirect from an apps-only API
+ to an extensions one - we may at some point enable it for extensions).
+ '''
+ class ReturnType(object):
+ def __init__(self, path, permanent):
+ self.path = path
+ self.permanent = permanent
+
+ # Catch incorrect comparisons by disabling ==/!=.
+ def __eq__(self, _): raise NotImplementedError()
+ def __ne__(self, _): raise NotImplementedError()
+
+ # Strip any channel info off it. There are no channels anymore.
+ for channel_name in BranchUtility.GetAllChannelNames():
+ channel_prefix = channel_name + '/'
+ if path.startswith(channel_prefix):
+ # Redirect now so that we can set the permanent-redirect bit. Channel
+ # redirects are the only things that should be permanent redirects;
+ # anything else *could* change, so is temporary.
+ return ReturnType(path[len(channel_prefix):], True)
+
+ # No further work needed for static.
+ if path.startswith('static/'):
+ return ReturnType(path, False)
+
+ # People go to just "extensions" or "apps". Redirect to the directory.
+ if path in ('extensions', 'apps'):
+ return ReturnType(path + '/', False)
+
+ # The rest of this function deals with trying to figure out what API page
+ # for extensions/apps to redirect to, if any. We see a few different cases
+ # here:
+ # - Unqualified names ("browserAction.html"). These are easy to resolve;
+ # figure out whether it's an extension or app API and redirect.
+ # - but what if it's both? Well, assume extensions. Maybe later we can
+ # check analytics and see which is more popular.
+ # - Wrong names ("apps/browserAction.html"). This really does happen,
+ # damn it, so do the above logic but record which is the default.
+ if path.startswith(('extensions/', 'apps/')):
+ default_platform, reference_path = path.split('/', 1)
+ else:
+ default_platform, reference_path = ('extensions', path)
+
+ try:
+ apps_public = self._public_apis.GetFromFileListing(
+ '/'.join((svn_constants.PUBLIC_TEMPLATE_PATH, 'apps')))
+ extensions_public = self._public_apis.GetFromFileListing(
+ '/'.join((svn_constants.PUBLIC_TEMPLATE_PATH, 'extensions')))
+ except FileNotFoundError:
+ # Probably offline.
+ logging.warning(traceback.format_exc())
+ return ReturnType(path, False)
+
+ simple_reference_path = _SimplifyFileName(reference_path)
+ apps_path = apps_public.get(simple_reference_path)
+ extensions_path = extensions_public.get(simple_reference_path)
+
+ if apps_path is None:
+ if extensions_path is None:
+ # No idea. Just return the original path. It'll probably 404.
+ pass
+ else:
+ path = 'extensions/%s' % extensions_path
else:
- apps_path = '%s/apps/%s' % (self._channel, path_without_channel)
- extensions_path = '%s/extensions/%s' % (self._channel,
- path_without_channel)
-
- unix_path = UnixName(os.path.splitext(path_without_channel)[0])
- if unix_path in extensions_templates:
- return extensions_path
- if unix_path in apps_templates:
- return apps_path
- return extensions_path
+ if extensions_path is None:
+ path = 'apps/%s' % apps_path
+ else:
+ assert apps_path == extensions_path
+ path = '%s/%s' % (default_platform, apps_path)
+
+ return ReturnType(path, False)
« no previous file with comments | « chrome/common/extensions/docs/server2/patcher.py ('k') | chrome/common/extensions/docs/server2/path_canonicalizer_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698