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 |
new file mode 100644 |
index 0000000000000000000000000000000000000000..df84c8ef68ab4d4e82fc2d7ca0824766d696e84a |
--- /dev/null |
+++ b/chrome/common/extensions/docs/server2/content_provider.py |
@@ -0,0 +1,88 @@ |
+# Copyright 2013 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+from HTMLParser import HTMLParser |
+import mimetypes |
+import logging |
+import os |
+ |
+from compiled_file_system import SingleFile |
+from directory_zipper import DirectoryZipper |
+from file_system import ToUnicode |
+from future import Gettable, Future |
+from third_party.handlebar import Handlebar |
+ |
+ |
+class ContentAndType(object): |
+ '''Return value from ContentProvider.GetContentAndType. |
+ ''' |
+ |
+ def __init__(self, content, content_type): |
+ self.content = content |
+ self.content_type = content_type |
+ |
+ |
+class ContentProvider(object): |
+ '''Returns file contents correctly typed for their content-types (in the HTTP |
+ sense). Content-type is determined from Python's mimetype library which |
+ guesses based on the file extension. |
+ |
+ 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. |
+ ''' |
+ |
+ def __init__(self, |
+ name, |
+ compiled_fs_factory, |
+ file_system, |
+ supports_templates=False, |
+ supports_zip=False): |
+ # Public. |
+ self.name = name |
+ self.file_system = file_system |
+ # Private. |
+ self._content_cache = compiled_fs_factory.Create(file_system, |
+ self._CompileContent, |
+ ContentProvider) |
+ self._supports_templates = supports_templates |
+ if supports_zip: |
+ self._directory_zipper = DirectoryZipper(compiled_fs_factory, file_system) |
+ else: |
+ self._directory_zipper = None |
+ |
+ @SingleFile |
+ def _CompileContent(self, path, text): |
+ assert text is not None, path |
+ mimetype = mimetypes.guess_type(path)[0] |
+ if mimetype is None: |
+ content = text |
+ mimetype = 'text/plain' |
+ elif mimetype == 'text/html': |
+ content = ToUnicode(text) |
+ if self._supports_templates: |
+ content = Handlebar(content) |
+ elif (mimetype.startswith('text/') or |
+ mimetype in ('application/javascript', 'application/json')): |
+ content = ToUnicode(text) |
+ else: |
+ content = text |
+ return ContentAndType(content, mimetype) |
+ |
+ def GetContentAndType(self, host, path): |
+ path = path.lstrip('/') |
+ base, ext = os.path.splitext(path) |
+ |
+ # Check for a zip file first, if zip is enabled. |
+ if self._directory_zipper and ext == '.zip': |
+ zip_future = self._directory_zipper.Zip(base) |
+ return Future(delegate=Gettable( |
+ lambda: ContentAndType(zip_future.Get(), 'application/zip'))) |
+ |
+ return self._content_cache.GetFromFile(path, binary=True) |
+ |
+ def Cron(self): |
+ # TODO(kalman): Implement. |
+ pass |