OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import mimetypes | 5 import mimetypes |
6 import posixpath | 6 import os |
7 | 7 |
8 from compiled_file_system import SingleFile | 8 from compiled_file_system import SingleFile |
9 from directory_zipper import DirectoryZipper | 9 from directory_zipper import DirectoryZipper |
10 from docs_server_utils import ToUnicode | 10 from docs_server_utils import ToUnicode |
11 from file_system import FileNotFoundError | |
12 from future import Gettable, Future | 11 from future import Gettable, Future |
13 from third_party.handlebar import Handlebar | 12 from third_party.handlebar import Handlebar |
14 from third_party.markdown import markdown | |
15 | 13 |
16 | 14 |
17 class ContentAndType(object): | 15 class ContentAndType(object): |
18 '''Return value from ContentProvider.GetContentAndType. | 16 '''Return value from ContentProvider.GetContentAndType. |
19 ''' | 17 ''' |
20 | 18 |
21 def __init__(self, content, content_type): | 19 def __init__(self, content, content_type): |
22 self.content = content | 20 self.content = content |
23 self.content_type = content_type | 21 self.content_type = content_type |
24 | 22 |
(...skipping 25 matching lines...) Expand all Loading... |
50 self._supports_templates = supports_templates | 48 self._supports_templates = supports_templates |
51 if supports_zip: | 49 if supports_zip: |
52 self._directory_zipper = DirectoryZipper(compiled_fs_factory, file_system) | 50 self._directory_zipper = DirectoryZipper(compiled_fs_factory, file_system) |
53 else: | 51 else: |
54 self._directory_zipper = None | 52 self._directory_zipper = None |
55 | 53 |
56 @SingleFile | 54 @SingleFile |
57 def _CompileContent(self, path, text): | 55 def _CompileContent(self, path, text): |
58 assert text is not None, path | 56 assert text is not None, path |
59 mimetype = mimetypes.guess_type(path)[0] | 57 mimetype = mimetypes.guess_type(path)[0] |
60 if posixpath.splitext(path)[1] == '.md': | 58 if mimetype is None: |
61 # See http://pythonhosted.org/Markdown/extensions | |
62 # for details on "extensions=". | |
63 content = markdown(ToUnicode(text), | |
64 extensions=('extra', 'headerid', 'sane_lists')) | |
65 if self._supports_templates: | |
66 content = Handlebar(content, name=path) | |
67 mimetype = 'text/html' | |
68 elif mimetype is None: | |
69 content = text | 59 content = text |
70 mimetype = 'text/plain' | 60 mimetype = 'text/plain' |
71 elif mimetype == 'text/html': | 61 elif mimetype == 'text/html': |
72 content = ToUnicode(text) | 62 content = ToUnicode(text) |
73 if self._supports_templates: | 63 if self._supports_templates: |
74 content = Handlebar(content, name=path) | 64 content = Handlebar(content, name=path) |
75 elif (mimetype.startswith('text/') or | 65 elif (mimetype.startswith('text/') or |
76 mimetype in ('application/javascript', 'application/json')): | 66 mimetype in ('application/javascript', 'application/json')): |
77 content = ToUnicode(text) | 67 content = ToUnicode(text) |
78 else: | 68 else: |
79 content = text | 69 content = text |
80 return ContentAndType(content, mimetype) | 70 return ContentAndType(content, mimetype) |
81 | 71 |
82 def _MaybeMarkdown(self, path): | |
83 if posixpath.splitext(path)[1] != '.html': | |
84 return path | |
85 | |
86 dirname, file_name = posixpath.split(path) | |
87 if dirname != '': | |
88 dirname = dirname + '/' | |
89 file_list = self.file_system.ReadSingle(dirname).Get() | |
90 if file_name in file_list: | |
91 return path | |
92 | |
93 if posixpath.splitext(file_name)[0] + '.md' in file_list: | |
94 return posixpath.splitext(path)[0] + '.md' | |
95 return path | |
96 | |
97 def GetContentAndType(self, path): | 72 def GetContentAndType(self, path): |
98 path = path.lstrip('/') | 73 path = path.lstrip('/') |
99 base, ext = posixpath.splitext(path) | 74 base, ext = os.path.splitext(path) |
100 | 75 |
101 # Check for a zip file first, if zip is enabled. | 76 # Check for a zip file first, if zip is enabled. |
102 if self._directory_zipper and ext == '.zip': | 77 if self._directory_zipper and ext == '.zip': |
103 zip_future = self._directory_zipper.Zip(base) | 78 zip_future = self._directory_zipper.Zip(base) |
104 return Future(delegate=Gettable( | 79 return Future(delegate=Gettable( |
105 lambda: ContentAndType(zip_future.Get(), 'application/zip'))) | 80 lambda: ContentAndType(zip_future.Get(), 'application/zip'))) |
106 | 81 |
107 return self._content_cache.GetFromFile(self._MaybeMarkdown(path)) | 82 return self._content_cache.GetFromFile(path) |
108 | 83 |
109 def Cron(self): | 84 def Cron(self): |
110 # Running Refresh() on the file system is enough to pull GitHub content, | 85 # Running Refresh() on the file system is enough to pull GitHub content, |
111 # which is all we need for now while the full render-every-page cron step | 86 # which is all we need for now while the full render-every-page cron step |
112 # is in effect. | 87 # is in effect. |
113 # TODO(kalman): Walk over the whole filesystem and compile the content. | 88 # TODO(kalman): Walk over the whole filesystem and compile the content. |
114 return self.file_system.Refresh() | 89 return self.file_system.Refresh() |
115 | 90 |
116 def __repr__(self): | 91 def __repr__(self): |
117 return 'ContentProvider of <%s>' % repr(self.file_system) | 92 return 'ContentProvider of <%s>' % repr(self.file_system) |
OLD | NEW |