OLD | NEW |
(Empty) | |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 from HTMLParser import HTMLParser |
| 6 import mimetypes |
| 7 import logging |
| 8 import os |
| 9 |
| 10 from compiled_file_system import SingleFile |
| 11 from directory_zipper import DirectoryZipper |
| 12 from file_system import ToUnicode |
| 13 from future import Gettable, Future |
| 14 from third_party.handlebar import Handlebar |
| 15 |
| 16 |
| 17 class ContentAndType(object): |
| 18 '''Return value from ContentProvider.GetContentAndType. |
| 19 ''' |
| 20 |
| 21 def __init__(self, content, content_type): |
| 22 self.content = content |
| 23 self.content_type = content_type |
| 24 |
| 25 |
| 26 class ContentProvider(object): |
| 27 '''Returns file contents correctly typed for their content-types (in the HTTP |
| 28 sense). Content-type is determined from Python's mimetype library which |
| 29 guesses based on the file extension. |
| 30 |
| 31 Typically the file contents will be either str (for binary content) or |
| 32 unicode (for text content). However, HTML files *may* be returned as |
| 33 Handlebar templates (if supports_templates is True on construction), in which |
| 34 case the caller will presumably want to Render them. |
| 35 ''' |
| 36 |
| 37 def __init__(self, |
| 38 name, |
| 39 compiled_fs_factory, |
| 40 file_system, |
| 41 supports_templates=False, |
| 42 supports_zip=False): |
| 43 # Public. |
| 44 self.name = name |
| 45 self.file_system = file_system |
| 46 # Private. |
| 47 self._content_cache = compiled_fs_factory.Create(file_system, |
| 48 self._CompileContent, |
| 49 ContentProvider) |
| 50 self._supports_templates = supports_templates |
| 51 if supports_zip: |
| 52 self._directory_zipper = DirectoryZipper(compiled_fs_factory, file_system) |
| 53 else: |
| 54 self._directory_zipper = None |
| 55 |
| 56 @SingleFile |
| 57 def _CompileContent(self, path, text): |
| 58 assert text is not None, path |
| 59 mimetype = mimetypes.guess_type(path)[0] |
| 60 if mimetype is None: |
| 61 content = text |
| 62 mimetype = 'text/plain' |
| 63 elif mimetype == 'text/html': |
| 64 content = ToUnicode(text) |
| 65 if self._supports_templates: |
| 66 content = Handlebar(content) |
| 67 elif (mimetype.startswith('text/') or |
| 68 mimetype in ('application/javascript', 'application/json')): |
| 69 content = ToUnicode(text) |
| 70 else: |
| 71 content = text |
| 72 return ContentAndType(content, mimetype) |
| 73 |
| 74 def GetContentAndType(self, host, path): |
| 75 path = path.lstrip('/') |
| 76 base, ext = os.path.splitext(path) |
| 77 |
| 78 # Check for a zip file first, if zip is enabled. |
| 79 if self._directory_zipper and ext == '.zip': |
| 80 zip_future = self._directory_zipper.Zip(base) |
| 81 return Future(delegate=Gettable( |
| 82 lambda: ContentAndType(zip_future.Get(), 'application/zip'))) |
| 83 |
| 84 return self._content_cache.GetFromFile(path, binary=True) |
| 85 |
| 86 def Cron(self): |
| 87 # TODO(kalman): Implement. |
| 88 pass |
OLD | NEW |