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

Side by Side Diff: chrome/common/extensions/docs/server2/content_provider.py

Issue 218363002: Docs: Use ETags. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 posixpath
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 11 from file_system import FileNotFoundError
12 from future import Future 12 from future import Future
13 from path_canonicalizer import PathCanonicalizer 13 from path_canonicalizer import PathCanonicalizer
14 from path_util import AssertIsValid, Join, ToDirectory 14 from path_util import AssertIsValid, Join, ToDirectory
15 from special_paths import SITE_VERIFICATION_FILE 15 from special_paths import SITE_VERIFICATION_FILE
16 from third_party.handlebar import Handlebar 16 from third_party.handlebar import Handlebar
17 from third_party.markdown import markdown 17 from third_party.markdown import markdown
18 18
19 19
20 _MIMETYPE_OVERRIDES = { 20 _MIMETYPE_OVERRIDES = {
21 # SVG is not supported by mimetypes.guess_type on AppEngine. 21 # SVG is not supported by mimetypes.guess_type on AppEngine.
22 '.svg': 'image/svg+xml', 22 '.svg': 'image/svg+xml',
23 } 23 }
24 24
25 25
26 class ContentAndType(object): 26 class ContentAndType(object):
27 '''Return value from ContentProvider.GetContentAndType. 27 '''Return value from ContentProvider.GetContentAndType.
28 ''' 28 '''
29 29
30 def __init__(self, content, content_type): 30 def __init__(self, content, content_type, version):
31 self.content = content 31 self.content = content
32 self.content_type = content_type 32 self.content_type = content_type
33 self.version = version
33 34
34 35
35 class ContentProvider(object): 36 class ContentProvider(object):
36 '''Returns file contents correctly typed for their content-types (in the HTTP 37 '''Returns file contents correctly typed for their content-types (in the HTTP
37 sense). Content-type is determined from Python's mimetype library which 38 sense). Content-type is determined from Python's mimetype library which
38 guesses based on the file extension. 39 guesses based on the file extension.
39 40
40 Typically the file contents will be either str (for binary content) or 41 Typically the file contents will be either str (for binary content) or
41 unicode (for text content). However, HTML files *may* be returned as 42 unicode (for text content). However, HTML files *may* be returned as
42 Handlebar templates (if |supports_templates| is True on construction), in 43 Handlebar templates (if |supports_templates| is True on construction), in
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 mimetype = 'text/plain' 94 mimetype = 'text/plain'
94 elif mimetype == 'text/html': 95 elif mimetype == 'text/html':
95 content = ToUnicode(text) 96 content = ToUnicode(text)
96 if self._supports_templates: 97 if self._supports_templates:
97 content = Handlebar(content, name=path) 98 content = Handlebar(content, name=path)
98 elif (mimetype.startswith('text/') or 99 elif (mimetype.startswith('text/') or
99 mimetype in ('application/javascript', 'application/json')): 100 mimetype in ('application/javascript', 'application/json')):
100 content = ToUnicode(text) 101 content = ToUnicode(text)
101 else: 102 else:
102 content = text 103 content = text
103 return ContentAndType(content, mimetype) 104 return ContentAndType(content,
105 mimetype,
106 self.file_system.Stat(path).version)
104 107
105 def GetCanonicalPath(self, path): 108 def GetCanonicalPath(self, path):
106 '''Gets the canonical location of |path|. This class is tolerant of 109 '''Gets the canonical location of |path|. This class is tolerant of
107 spelling errors and missing files that are in other directories, and this 110 spelling errors and missing files that are in other directories, and this
108 returns the correct/canonical path for those. 111 returns the correct/canonical path for those.
109 112
110 For example, the canonical path of "browseraction" is probably 113 For example, the canonical path of "browseraction" is probably
111 "extensions/browserAction.html". 114 "extensions/browserAction.html".
112 115
113 Note that the canonical path is relative to this content provider i.e. 116 Note that the canonical path is relative to this content provider i.e.
(...skipping 12 matching lines...) Expand all
126 def GetContentAndType(self, path): 129 def GetContentAndType(self, path):
127 '''Returns the ContentAndType of the file at |path|. 130 '''Returns the ContentAndType of the file at |path|.
128 ''' 131 '''
129 AssertIsValid(path) 132 AssertIsValid(path)
130 base, ext = posixpath.splitext(path) 133 base, ext = posixpath.splitext(path)
131 134
132 # Check for a zip file first, if zip is enabled. 135 # Check for a zip file first, if zip is enabled.
133 if self._directory_zipper and ext == '.zip': 136 if self._directory_zipper and ext == '.zip':
134 zip_future = self._directory_zipper.Zip(ToDirectory(base)) 137 zip_future = self._directory_zipper.Zip(ToDirectory(base))
135 return Future(callback= 138 return Future(callback=
136 lambda: ContentAndType(zip_future.Get(), 'application/zip')) 139 lambda: ContentAndType(zip_future.Get(), 'application/zip', None))
137 140
138 # If there is no file extension, look for a file with one of the default 141 # If there is no file extension, look for a file with one of the default
139 # extensions. 142 # extensions.
140 # 143 #
141 # Note that it would make sense to guard this on Exists(path), since a file 144 # Note that it would make sense to guard this on Exists(path), since a file
142 # without an extension may actually exist, but it's such an uncommon case 145 # without an extension may actually exist, but it's such an uncommon case
143 # it hardly seems worth the potential performance hit. 146 # it hardly seems worth the potential performance hit.
144 if not ext: 147 if not ext:
145 for default_ext in self._default_extensions: 148 for default_ext in self._default_extensions:
146 if self.file_system.Exists(path + default_ext).Get(): 149 if self.file_system.Exists(path + default_ext).Get():
147 path += default_ext 150 path += default_ext
148 break 151 break
149 152
150 return self._content_cache.GetFromFile(path) 153 return self._content_cache.GetFromFile(path)
151 154
152 def Cron(self): 155 def Cron(self):
153 futures = [self._path_canonicalizer.Cron()] 156 futures = [self._path_canonicalizer.Cron()]
154 for root, _, files in self.file_system.Walk(''): 157 for root, _, files in self.file_system.Walk(''):
155 for f in files: 158 for f in files:
156 futures.append(self.GetContentAndType(Join(root, f))) 159 futures.append(self.GetContentAndType(Join(root, f)))
157 # Also cache the extension-less version of the file if needed. 160 # Also cache the extension-less version of the file if needed.
158 base, ext = posixpath.splitext(f) 161 base, ext = posixpath.splitext(f)
159 if f != SITE_VERIFICATION_FILE and ext in self._default_extensions: 162 if f != SITE_VERIFICATION_FILE and ext in self._default_extensions:
160 futures.append(self.GetContentAndType(Join(root, base))) 163 futures.append(self.GetContentAndType(Join(root, base)))
161 # TODO(kalman): Cache .zip files for each directory (if supported). 164 # TODO(kalman): Cache .zip files for each directory (if supported).
162 return Future(callback=lambda: [f.Get() for f in futures]) 165 return Future(callback=lambda: [f.Get() for f in futures])
163 166
164 def __repr__(self): 167 def __repr__(self):
165 return 'ContentProvider of <%s>' % repr(self.file_system) 168 return 'ContentProvider of <%s>' % repr(self.file_system)
OLDNEW
« no previous file with comments | « chrome/common/extensions/docs/server2/app.yaml ('k') | chrome/common/extensions/docs/server2/cron.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698