| Index: chrome/common/extensions/docs/server2/content_provider.py
|
| diff --git a/chrome/common/extensions/docs/server2/content_provider.py b/chrome/common/extensions/docs/server2/content_provider.py
|
| index 62d29d550ca2924ebb07db3075db0282af209c15..db7bcb9d5a3b0999283777521ee023c82827ff56 100644
|
| --- a/chrome/common/extensions/docs/server2/content_provider.py
|
| +++ b/chrome/common/extensions/docs/server2/content_provider.py
|
| @@ -12,6 +12,7 @@ from file_system import FileNotFoundError
|
| from future import Gettable, Future
|
| from path_canonicalizer import PathCanonicalizer
|
| from path_util import AssertIsValid, ToDirectory
|
| +from special_paths import SITE_VERIFICATION_FILE
|
| from third_party.handlebar import Handlebar
|
| from third_party.markdown import markdown
|
|
|
| @@ -38,14 +39,23 @@ class ContentProvider(object):
|
|
|
| Typically the file contents will be either str (for binary content) or
|
| unicode (for text content). However, HTML files *may* be returned as
|
| - Handlebar templates (if supports_templates is True on construction), in which
|
| - case the caller will presumably want to Render them.
|
| + Handlebar templates (if |supports_templates| is True on construction), in
|
| + which case the caller will presumably want to Render them.
|
| +
|
| + Zip file are automatically created and returned for .zip file extensions if
|
| + |supports_zip| is True.
|
| +
|
| + |default_extensions| is a list of file extensions which are queried when no
|
| + file extension is given to GetCanonicalPath/GetContentAndType. Typically
|
| + this will include .html.
|
| '''
|
|
|
| def __init__(self,
|
| name,
|
| compiled_fs_factory,
|
| file_system,
|
| + object_store_creator,
|
| + default_extensions=(),
|
| supports_templates=False,
|
| supports_zip=False):
|
| # Public.
|
| @@ -55,8 +65,10 @@ class ContentProvider(object):
|
| self._content_cache = compiled_fs_factory.Create(file_system,
|
| self._CompileContent,
|
| ContentProvider)
|
| - self._path_canonicalizer = PathCanonicalizer(compiled_fs_factory,
|
| - file_system)
|
| + self._path_canonicalizer = PathCanonicalizer(file_system,
|
| + object_store_creator,
|
| + default_extensions)
|
| + self._default_extensions = default_extensions
|
| self._supports_templates = supports_templates
|
| if supports_zip:
|
| self._directory_zipper = DirectoryZipper(compiled_fs_factory, file_system)
|
| @@ -90,17 +102,6 @@ class ContentProvider(object):
|
| content = text
|
| return ContentAndType(content, mimetype)
|
|
|
| - def _MaybeMarkdown(self, path):
|
| - base, ext = posixpath.splitext(path)
|
| - if ext != '.html':
|
| - return path
|
| - if self.file_system.Exists(path).Get():
|
| - return path
|
| - as_md = base + '.md'
|
| - if self.file_system.Exists(as_md).Get():
|
| - return as_md
|
| - return path
|
| -
|
| def GetCanonicalPath(self, path):
|
| '''Gets the canonical location of |path|. This class is tolerant of
|
| spelling errors and missing files that are in other directories, and this
|
| @@ -108,12 +109,19 @@ class ContentProvider(object):
|
|
|
| For example, the canonical path of "browseraction" is probably
|
| "extensions/browserAction.html".
|
| +
|
| + Note that the canonical path is relative to this content provider i.e.
|
| + given relative to |path|. It does not add the "serveFrom" prefix which
|
| + would have been pulled out in ContentProviders, callers must do that
|
| + themselves.
|
| '''
|
| AssertIsValid(path)
|
| - _, ext = posixpath.splitext(path)
|
| - if not ext or ext == '.html':
|
| - return self._path_canonicalizer.Canonicalize(path)
|
| - return path
|
| + base, ext = posixpath.splitext(path)
|
| + if self._directory_zipper and ext == '.zip':
|
| + # The canonical location of zip files is the canonical location of the
|
| + # directory to zip + '.zip'.
|
| + return self._path_canonicalizer.Canonicalize(base + '/').rstrip('/') + ext
|
| + return self._path_canonicalizer.Canonicalize(path)
|
|
|
| def GetContentAndType(self, path):
|
| '''Returns the ContentAndType of the file at |path|.
|
| @@ -127,16 +135,30 @@ class ContentProvider(object):
|
| return Future(delegate=Gettable(
|
| lambda: ContentAndType(zip_future.Get(), 'application/zip')))
|
|
|
| - return self._content_cache.GetFromFile(self._MaybeMarkdown(path))
|
| + # If there is no file extension, look for a file with one of the default
|
| + # extensions.
|
| + #
|
| + # Note that it would make sense to guard this on Exists(path), since a file
|
| + # without an extension may actually exist, but it's such an uncommon case
|
| + # it hardly seems worth the potential performance hit.
|
| + if not ext:
|
| + for default_ext in self._default_extensions:
|
| + if self.file_system.Exists(path + default_ext).Get():
|
| + path += default_ext
|
| + break
|
| +
|
| + return self._content_cache.GetFromFile(path)
|
|
|
| def Cron(self):
|
| - # Running Refresh() on the file system is enough to pull GitHub content,
|
| - # which is all we need for now while the full render-every-page cron step
|
| - # is in effect.
|
| futures = []
|
| for root, _, files in self.file_system.Walk(''):
|
| - futures += [self.GetContentAndType(posixpath.join(root, filename))
|
| - for filename in files]
|
| + for f in files:
|
| + futures.append(self.GetContentAndType(posixpath.join(root, f)))
|
| + # Also cache the extension-less version of the file if needed.
|
| + base, ext = posixpath.splitext(f)
|
| + if f != SITE_VERIFICATION_FILE and ext in self._default_extensions:
|
| + futures.append(self.GetContentAndType(posixpath.join(root, base)))
|
| + # TODO(kalman): Cache .zip files for each directory (if supported).
|
| return Future(delegate=Gettable(lambda: [f.Get() for f in futures]))
|
|
|
| def __repr__(self):
|
|
|