Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 from fnmatch import fnmatch | 5 from fnmatch import fnmatch |
| 6 import logging | 6 import logging |
| 7 import mimetypes | 7 import mimetypes |
| 8 import traceback | 8 import traceback |
| 9 import os | 9 import os |
| 10 | 10 |
| 11 from api_data_source import APIDataSource | 11 from api_data_source import APIDataSource |
| 12 from api_list_data_source import APIListDataSource | 12 from api_list_data_source import APIListDataSource |
| 13 from appengine_blobstore import AppEngineBlobstore | 13 from appengine_blobstore import AppEngineBlobstore |
| 14 from appengine_url_fetcher import AppEngineUrlFetcher | 14 from appengine_url_fetcher import AppEngineUrlFetcher |
| 15 from appengine_wrappers import GetAppVersion, IsDevServer | 15 from appengine_wrappers import GetAppVersion, IsDevServer |
| 16 from branch_utility import BranchUtility | 16 from branch_utility import BranchUtility |
| 17 from caching_file_system import CachingFileSystem | 17 from caching_file_system import CachingFileSystem |
| 18 from compiled_file_system import CompiledFileSystem | 18 from compiled_file_system import CompiledFileSystem |
| 19 from empty_dir_file_system import EmptyDirFileSystem | 19 from empty_dir_file_system import EmptyDirFileSystem |
| 20 from example_zipper import ExampleZipper | 20 from example_zipper import ExampleZipper |
| 21 from file_system import FileNotFoundError | 21 from file_system import FileNotFoundError |
| 22 from github_file_system import GithubFileSystem | 22 from github_file_system import GithubFileSystem |
| 23 from intro_data_source import IntroDataSource | 23 from intro_data_source import IntroDataSource |
| 24 from local_file_system import LocalFileSystem | 24 from local_file_system import LocalFileSystem |
| 25 from object_store_creator import ObjectStoreCreator | 25 from object_store_creator import ObjectStoreCreator |
| 26 from offline_file_system import OfflineFileSystem | 26 from offline_file_system import OfflineFileSystem |
| 27 from patched_file_system import PatchedFileSystem | |
| 27 from path_canonicalizer import PathCanonicalizer | 28 from path_canonicalizer import PathCanonicalizer |
| 28 from reference_resolver import ReferenceResolver | 29 from reference_resolver import ReferenceResolver |
| 30 from rietveld_file_system import RietveldFileSystem | |
| 31 from rietveld_utility import RietveldUtility | |
| 29 from samples_data_source import SamplesDataSource | 32 from samples_data_source import SamplesDataSource |
| 30 from sidenav_data_source import SidenavDataSource | 33 from sidenav_data_source import SidenavDataSource |
| 31 from subversion_file_system import SubversionFileSystem | 34 from subversion_file_system import SubversionFileSystem |
| 32 import svn_constants | 35 import svn_constants |
| 33 from template_data_source import TemplateDataSource | 36 from template_data_source import TemplateDataSource |
| 34 from third_party.json_schema_compiler.memoize import memoize | 37 from third_party.json_schema_compiler.memoize import memoize |
| 35 from third_party.json_schema_compiler.model import UnixName | 38 from third_party.json_schema_compiler.model import UnixName |
| 36 import url_constants | 39 import url_constants |
| 37 | 40 |
| 38 def _IsBinaryMimetype(mimetype): | 41 def _IsBinaryMimetype(mimetype): |
| 39 return any(mimetype.startswith(prefix) | 42 return any(mimetype.startswith(prefix) |
| 40 for prefix in ['audio', 'image', 'video']) | 43 for prefix in ['audio', 'image', 'video']) |
| 41 | 44 |
| 42 def _IsSamplesDisabled(): | 45 def _IsSamplesDisabled(): |
| 43 return IsDevServer() | 46 return IsDevServer() |
| 44 | 47 |
| 45 class ServerInstance(object): | 48 class ServerInstance(object): |
| 46 # Lazily create so we don't create github file systems unnecessarily in | 49 # Lazily create so we don't create github file systems unnecessarily in |
| 47 # tests. | 50 # tests. |
| 48 branch_utility = None | 51 branch_utility = None |
| 52 rietveld_utility = None | |
| 49 github_file_system = None | 53 github_file_system = None |
| 50 | 54 |
| 51 @staticmethod | 55 @staticmethod |
| 52 @memoize | 56 @memoize |
| 53 def GetOrCreateOffline(channel): | 57 def GetOrCreateOffline(channel): |
| 54 '''Gets/creates a local ServerInstance, meaning that only resources local to | 58 '''Gets/creates a local ServerInstance, meaning that only resources local to |
| 55 the server - memcache, object store, etc, are queried. This amounts to not | 59 the server - memcache, object store, etc, are queried. This amounts to not |
| 56 setting up the subversion nor github file systems. | 60 setting up the subversion nor github file systems. |
| 57 ''' | 61 ''' |
| 58 branch_utility = ServerInstance._GetOrCreateBranchUtility() | 62 branch_utility = ServerInstance._GetOrCreateBranchUtility() |
| 59 branch = branch_utility.GetBranchNumberForChannelName(channel) | 63 branch = branch_utility.GetBranchNumberForChannelName(channel) |
| 60 object_store_creator_factory = ObjectStoreCreator.Factory(GetAppVersion(), | 64 object_store_creator_factory = ObjectStoreCreator.Factory(GetAppVersion(), |
| 61 branch) | 65 branch) |
| 62 # No svn nor github file systems. Rely on the crons to fill the caches, and | 66 # No svn nor github file systems. Rely on the crons to fill the caches, and |
| 63 # for the caches to exist. | 67 # for the caches to exist. |
| 64 return ServerInstance( | 68 return ServerInstance( |
| 65 channel, | 69 channel, |
| 66 object_store_creator_factory, | 70 object_store_creator_factory, |
| 67 CachingFileSystem(OfflineFileSystem(SubversionFileSystem), | 71 CachingFileSystem(OfflineFileSystem(SubversionFileSystem), |
| 68 object_store_creator_factory), | 72 object_store_creator_factory), |
| 69 # TODO(kalman): convert GithubFileSystem to be wrappable in a | 73 # TODO(kalman): convert GithubFileSystem to be wrappable in a |
| 70 # CachingFileSystem so that it can be replaced with an | 74 # CachingFileSystem so that it can be replaced with an |
| 71 # OfflineFileSystem. Currently GFS doesn't set the child versions of | 75 # OfflineFileSystem. Currently GFS doesn't set the child versions of |
| 72 # stat requests so it doesn't. | 76 # stat requests so it doesn't. |
| 73 ServerInstance._GetOrCreateGithubFileSystem()) | 77 ServerInstance._GetOrCreateGithubFileSystem()) |
| 74 | 78 |
| 75 @staticmethod | 79 @staticmethod |
| 76 def CreateOnline(channel): | 80 def CreateOnline(channel, issue=None): |
| 77 '''Creates/creates an online server instance, meaning that both local and | 81 '''Creates/creates an online server instance, meaning that both local and |
| 78 subversion/github resources are queried. | 82 subversion/github resources are queried. |
| 79 ''' | 83 ''' |
| 80 branch_utility = ServerInstance._GetOrCreateBranchUtility() | 84 branch_utility = ServerInstance._GetOrCreateBranchUtility() |
| 81 branch = branch_utility.GetBranchNumberForChannelName(channel) | 85 branch = branch_utility.GetBranchNumberForChannelName(channel) |
| 82 | 86 |
| 83 if branch == 'trunk': | 87 if branch == 'trunk': |
| 84 svn_url = '/'.join((url_constants.SVN_TRUNK_URL, | 88 svn_url = '/'.join((url_constants.SVN_TRUNK_URL, |
| 85 'src', | 89 'src', |
| 86 svn_constants.EXTENSIONS_PATH)) | 90 svn_constants.EXTENSIONS_PATH)) |
| 87 else: | 91 else: |
| 88 svn_url = '/'.join((url_constants.SVN_BRANCH_URL, | 92 svn_url = '/'.join((url_constants.SVN_BRANCH_URL, |
| 89 branch, | 93 branch, |
| 90 'src', | 94 'src', |
| 91 svn_constants.EXTENSIONS_PATH)) | 95 svn_constants.EXTENSIONS_PATH)) |
| 92 | 96 |
| 93 viewvc_url = svn_url.replace(url_constants.SVN_URL, | 97 viewvc_url = svn_url.replace(url_constants.SVN_URL, |
| 94 url_constants.VIEWVC_URL) | 98 url_constants.VIEWVC_URL) |
| 95 | 99 |
| 100 if issue is not None: | |
| 101 rietveld_utility = ServerInstance._GetOrCreateRietveldUtility() | |
| 102 patchset = rietveld_utility.GetPatchsetFromIssue(issue) | |
| 103 if patchset is None: | |
| 104 issue is None | |
|
not at google - send to devlin
2013/04/26 23:53:53
I don't think "issue is None" means anything as a
| |
| 105 | |
| 96 object_store_creator_factory = ObjectStoreCreator.Factory(GetAppVersion(), | 106 object_store_creator_factory = ObjectStoreCreator.Factory(GetAppVersion(), |
| 97 branch, | 107 branch, |
| 98 start_empty=True) | 108 start_empty=True) |
| 99 | 109 |
| 100 svn_file_system = CachingFileSystem( | 110 svn_file_system = CachingFileSystem( |
| 101 SubversionFileSystem(AppEngineUrlFetcher(svn_url), | 111 SubversionFileSystem(AppEngineUrlFetcher(svn_url), |
| 102 AppEngineUrlFetcher(viewvc_url)), | 112 AppEngineUrlFetcher(viewvc_url)), |
| 103 object_store_creator_factory) | 113 object_store_creator_factory) |
| 114 if issue is not None: | |
| 115 (patched_files, changes) = rietveld_utility.GetPatchsetDetails( | |
| 116 issue, patchset) | |
|
not at google - send to devlin
2013/04/26 23:53:53
patched files... changes... everything should be p
| |
| 117 patched_object_store_creator_factory = ObjectStoreCreator.Factory( | |
| 118 GetAppVersion(), | |
| 119 branch, | |
| 120 True, # start_empty | |
|
not at google - send to devlin
2013/04/26 23:53:53
use start_empty=True
方觉(Fang Jue)
2013/04/29 12:46:23
Done.
| |
| 121 issue, | |
| 122 patchset) | |
|
not at google - send to devlin
2013/04/26 23:53:53
it's nice to spell out optional arguments explicit
方觉(Fang Jue)
2013/04/29 12:46:23
Done.
| |
| 123 rietveld_file_system = CachingFileSystem( | |
| 124 RietveldFileSystem(issue, | |
| 125 patchset, | |
| 126 patched_files, | |
| 127 AppEngineUrlFetcher( | |
| 128 url_constants.CODEREVIEW_SERVER)), | |
| 129 patched_object_store_creator_factory) | |
| 130 patched_file_system = PatchedFileSystem(patched_files, | |
| 131 svn_file_system, | |
| 132 rietveld_file_system) | |
| 133 else: | |
| 134 patched_object_store_creator_factory = None | |
| 135 patched_file_system = None | |
| 136 changes = None | |
| 104 | 137 |
| 105 return ServerInstance(channel, | 138 return ServerInstance(channel, |
| 106 object_store_creator_factory, | 139 object_store_creator_factory, |
| 107 svn_file_system, | 140 svn_file_system, |
|
not at google - send to devlin
2013/04/26 23:53:53
I hope that it's possible to inject patched_file_s
方觉(Fang Jue)
2013/04/27 00:24:34
I was trying to reuse existing cached content for
not at google - send to devlin
2013/04/27 00:45:30
patched_file_system delegates to svn_file_system,
方觉(Fang Jue)
2013/04/27 01:02:48
SubversionFileSystem will get all the caching but
not at google - send to devlin
2013/04/27 01:07:48
Ah I see what you mean. Eh, re-compiling all that
方觉(Fang Jue)
2013/04/29 12:46:23
Then complicated and messy changes below are no lo
| |
| 108 ServerInstance._GetOrCreateGithubFileSystem()) | 141 ServerInstance._GetOrCreateGithubFileSystem(), |
| 142 patched_object_store_creator_factory, | |
| 143 patched_file_system, | |
| 144 changes) | |
| 109 | 145 |
| 110 @staticmethod | 146 @staticmethod |
| 111 def CreateForTest(file_system): | 147 def CreateForTest(file_system): |
| 112 return ServerInstance('test', | 148 return ServerInstance('test', |
| 113 ObjectStoreCreator.TestFactory(), | 149 ObjectStoreCreator.TestFactory(), |
| 114 file_system, | 150 file_system, |
| 115 None) | 151 None) |
| 116 | 152 |
| 117 @staticmethod | 153 @staticmethod |
| 118 def _GetOrCreateBranchUtility(): | 154 def _GetOrCreateBranchUtility(): |
| 119 if ServerInstance.branch_utility is None: | 155 if ServerInstance.branch_utility is None: |
| 120 ServerInstance.branch_utility = BranchUtility( | 156 ServerInstance.branch_utility = BranchUtility( |
| 121 url_constants.OMAHA_PROXY_URL, | 157 url_constants.OMAHA_PROXY_URL, |
| 122 AppEngineUrlFetcher()) | 158 AppEngineUrlFetcher()) |
| 123 return ServerInstance.branch_utility | 159 return ServerInstance.branch_utility |
| 124 | 160 |
| 125 @staticmethod | 161 @staticmethod |
| 162 def _GetOrCreateRietveldUtility(): | |
| 163 if ServerInstance.rietveld_utility is None: | |
| 164 ServerInstance.rietveld_utility = RietveldUtility( | |
| 165 AppEngineUrlFetcher(url_constants.CODEREVIEW_SERVER)) | |
| 166 return ServerInstance.rietveld_utility | |
|
not at google - send to devlin
2013/04/26 23:53:53
this would probably end up getting owned by PatchS
| |
| 167 | |
| 168 @staticmethod | |
| 126 def _GetOrCreateGithubFileSystem(): | 169 def _GetOrCreateGithubFileSystem(): |
| 127 # Initialising github is pointless if samples are disabled, since it's only | 170 # Initialising github is pointless if samples are disabled, since it's only |
| 128 # used for apps samples. | 171 # used for apps samples. |
| 129 if ServerInstance.github_file_system is None: | 172 if ServerInstance.github_file_system is None: |
| 130 if _IsSamplesDisabled(): | 173 if _IsSamplesDisabled(): |
| 131 ServerInstance.github_file_system = EmptyDirFileSystem() | 174 ServerInstance.github_file_system = EmptyDirFileSystem() |
| 132 else: | 175 else: |
| 133 ServerInstance.github_file_system = GithubFileSystem( | 176 ServerInstance.github_file_system = GithubFileSystem( |
| 134 AppEngineUrlFetcher(url_constants.GITHUB_URL), | 177 AppEngineUrlFetcher(url_constants.GITHUB_URL), |
| 135 AppEngineBlobstore()) | 178 AppEngineBlobstore()) |
| 136 return ServerInstance.github_file_system | 179 return ServerInstance.github_file_system |
| 137 | 180 |
| 181 def _GetCompiledFileSystemFactory(self, deps=[]): | |
| 182 for dep in deps: | |
| 183 if self.changes.get(dep): | |
| 184 return self.compiled_fs_factory | |
| 185 return self.unpatched_compiled_fs_factory | |
| 186 | |
| 138 def __init__(self, | 187 def __init__(self, |
|
not at google - send to devlin
2013/04/26 23:53:53
As above - I think most of __init__ can stay the s
方觉(Fang Jue)
2013/04/29 12:46:23
Done.
| |
| 139 channel, | 188 channel, |
| 140 object_store_creator_factory, | 189 unpatched_object_store_creator_factory, |
| 141 svn_file_system, | 190 svn_file_system, |
| 142 github_file_system): | 191 github_file_system, |
| 143 self.svn_file_system = svn_file_system | 192 patched_object_store_creator_factory=None, |
| 193 patched_file_system=None, | |
| 194 changes=None): | |
| 195 if changes is None: | |
| 196 changes = {} | |
| 197 self.changes = changes | |
| 198 logging.info(changes) | |
| 144 | 199 |
| 145 self.github_file_system = github_file_system | 200 self.github_file_system = github_file_system |
| 146 | 201 |
| 147 self.compiled_fs_factory = CompiledFileSystem.Factory( | 202 self.unpatched_compiled_fs_factory = CompiledFileSystem.Factory( |
| 148 svn_file_system, | 203 svn_file_system, |
| 149 object_store_creator_factory) | 204 unpatched_object_store_creator_factory) |
| 205 if patched_object_store_creator_factory is None: | |
| 206 patched_object_store_creator_factory = ( | |
| 207 unpatched_object_store_creator_factory) | |
| 208 self.compiled_fs_factory = self.unpatched_compiled_fs_factory | |
| 209 else: | |
| 210 self.compiled_fs_factory = CompiledFileSystem.Factory( | |
| 211 patched_file_system, | |
| 212 patched_object_store_creator_factory) | |
| 150 | 213 |
| 151 self.api_list_data_source_factory = APIListDataSource.Factory( | 214 self.api_list_data_source_factory = APIListDataSource.Factory( |
| 152 self.compiled_fs_factory, | 215 self._GetCompiledFileSystemFactory([ |
| 216 svn_constants.API_PATH, | |
| 217 svn_constants.PUBLIC_TEMPLATE_PATH]), | |
| 153 svn_constants.API_PATH, | 218 svn_constants.API_PATH, |
| 154 svn_constants.PUBLIC_TEMPLATE_PATH) | 219 svn_constants.PUBLIC_TEMPLATE_PATH) |
| 155 | 220 |
| 156 self.api_data_source_factory = APIDataSource.Factory( | 221 self.api_data_source_factory = APIDataSource.Factory( |
| 157 self.compiled_fs_factory, | 222 self._GetCompiledFileSystemFactory([svn_constants.API_PATH]), |
| 158 svn_constants.API_PATH) | 223 svn_constants.API_PATH) |
| 159 | 224 |
| 160 self.ref_resolver_factory = ReferenceResolver.Factory( | 225 self.unpatched_ref_resolver_factory = ReferenceResolver.Factory( |
| 226 APIDataSource.Factory( | |
| 227 self.compiled_fs_factory, | |
| 228 svn_constants.API_PATH), | |
| 229 APIListDataSource.Factory( | |
| 230 self.compiled_fs_factory, | |
| 231 svn_constants.API_PATH, | |
| 232 svn_constants.PUBLIC_TEMPLATE_PATH), | |
| 233 unpatched_object_store_creator_factory) | |
| 234 if (changes.get(svn_constants.API_PATH) or | |
| 235 changes.get(svn_constants.PUBLIC_TEMPLATE_PATH)): | |
| 236 self.ref_resolver_factory = ReferenceResolver.Factory( | |
| 161 self.api_data_source_factory, | 237 self.api_data_source_factory, |
| 162 self.api_list_data_source_factory, | 238 self.api_list_data_source_factory, |
| 163 object_store_creator_factory) | 239 patched_object_store_creator_factory) |
| 240 else: | |
| 241 self.ref_resolver_factory = self.unpatched_ref_resolver_factory | |
| 164 | 242 |
| 165 self.api_data_source_factory.SetReferenceResolverFactory( | 243 self.api_data_source_factory.SetReferenceResolverFactory( |
| 166 self.ref_resolver_factory) | 244 self.ref_resolver_factory) |
| 167 | 245 |
| 168 # Note: samples are super slow in the dev server because it doesn't support | 246 # Note: samples are super slow in the dev server because it doesn't support |
| 169 # async fetch, so disable them. If you actually want to test samples, then | 247 # async fetch, so disable them. If you actually want to test samples, then |
| 170 # good luck, and modify _IsSamplesDisabled at the top. | 248 # good luck, and modify _IsSamplesDisabled at the top. |
| 171 if _IsSamplesDisabled(): | 249 if _IsSamplesDisabled(): |
| 172 svn_fs_for_samples = EmptyDirFileSystem() | 250 svn_fs_for_samples = EmptyDirFileSystem() |
| 173 else: | 251 else: |
| 174 svn_fs_for_samples = self.svn_file_system | 252 svn_fs_for_samples = svn_file_system |
| 175 self.samples_data_source_factory = SamplesDataSource.Factory( | 253 self.samples_data_source_factory = SamplesDataSource.Factory( |
| 176 channel, | 254 channel, |
| 177 svn_fs_for_samples, | 255 svn_fs_for_samples, |
| 178 self.github_file_system, | 256 self.github_file_system, |
| 179 self.ref_resolver_factory, | 257 self.unpatched_ref_resolver_factory, |
| 180 object_store_creator_factory, | 258 unpatched_object_store_creator_factory, |
| 181 svn_constants.EXAMPLES_PATH) | 259 svn_constants.EXAMPLES_PATH) |
| 182 | 260 |
| 183 self.api_data_source_factory.SetSamplesDataSourceFactory( | 261 self.api_data_source_factory.SetSamplesDataSourceFactory( |
| 184 self.samples_data_source_factory) | 262 self.samples_data_source_factory) |
| 185 | 263 |
| 186 self.intro_data_source_factory = IntroDataSource.Factory( | 264 self.intro_data_source_factory = IntroDataSource.Factory( |
| 187 self.compiled_fs_factory, | 265 self._GetCompiledFileSystemFactory([ |
| 266 svn_constants.INTRO_PATH, | |
| 267 svn_constants.ARTICLE_PATH]), | |
| 188 self.ref_resolver_factory, | 268 self.ref_resolver_factory, |
| 189 [svn_constants.INTRO_PATH, svn_constants.ARTICLE_PATH]) | 269 [svn_constants.INTRO_PATH, svn_constants.ARTICLE_PATH]) |
| 190 | 270 |
| 191 self.sidenav_data_source_factory = SidenavDataSource.Factory( | 271 self.sidenav_data_source_factory = SidenavDataSource.Factory( |
| 192 self.compiled_fs_factory, | 272 self._GetCompiledFileSystemFactory([svn_constants.JSON_PATH]), |
| 193 svn_constants.JSON_PATH) | 273 svn_constants.JSON_PATH) |
| 194 | 274 |
| 195 self.template_data_source_factory = TemplateDataSource.Factory( | 275 self.template_data_source_factory = TemplateDataSource.Factory( |
| 196 channel, | 276 channel, |
| 197 self.api_data_source_factory, | 277 self.api_data_source_factory, |
| 198 self.api_list_data_source_factory, | 278 self.api_list_data_source_factory, |
| 199 self.intro_data_source_factory, | 279 self.intro_data_source_factory, |
| 200 self.samples_data_source_factory, | 280 self.samples_data_source_factory, |
| 201 self.sidenav_data_source_factory, | 281 self.sidenav_data_source_factory, |
| 202 self.compiled_fs_factory, | 282 self.compiled_fs_factory, |
| 203 self.ref_resolver_factory, | 283 self.ref_resolver_factory, |
| 204 svn_constants.PUBLIC_TEMPLATE_PATH, | 284 svn_constants.PUBLIC_TEMPLATE_PATH, |
| 205 svn_constants.PRIVATE_TEMPLATE_PATH) | 285 svn_constants.PRIVATE_TEMPLATE_PATH) |
| 206 | 286 |
| 207 self.example_zipper = ExampleZipper( | 287 self.example_zipper = ExampleZipper( |
| 208 self.compiled_fs_factory, | 288 self.unpatched_compiled_fs_factory, |
| 209 svn_constants.DOCS_PATH) | 289 svn_constants.DOCS_PATH) |
| 210 | 290 |
| 211 self.path_canonicalizer = PathCanonicalizer( | 291 self.path_canonicalizer = PathCanonicalizer( |
| 212 channel, | 292 channel, |
| 213 self.compiled_fs_factory) | 293 self.unpatched_compiled_fs_factory) |
| 214 | 294 |
| 215 self.content_cache = self.compiled_fs_factory.GetOrCreateIdentity() | 295 self.unpatched_content_cache = (self.unpatched_compiled_fs_factory. |
| 296 GetOrCreateIdentity()) | |
| 297 if changes.get(svn_constants.STATIC_PATH): | |
| 298 self.content_cache = (self.patched_compiled_fs_factory. | |
| 299 GetOrCreateIdentity()) | |
| 300 else: | |
| 301 self.content_cache = self.unpatched_content_cache | |
| 216 | 302 |
| 217 def _FetchStaticResource(self, path, response): | 303 def _FetchStaticResource(self, path, response): |
| 218 """Fetch a resource in the 'static' directory. | 304 """Fetch a resource in the 'static' directory. |
| 219 """ | 305 """ |
| 220 mimetype = mimetypes.guess_type(path)[0] or 'text/plain' | 306 mimetype = mimetypes.guess_type(path)[0] or 'text/plain' |
| 221 result = self.content_cache.GetFromFile( | 307 result = self.content_cache.GetFromFile( |
| 222 svn_constants.DOCS_PATH + '/' + path, | 308 svn_constants.DOCS_PATH + '/' + path, |
| 223 binary=_IsBinaryMimetype(mimetype)) | 309 binary=_IsBinaryMimetype(mimetype)) |
| 224 response.headers['content-type'] = mimetype | 310 response.headers['content-type'] = mimetype |
| 225 return result | 311 return result |
| 226 | 312 |
| 227 def Get(self, path, request, response): | 313 def Get(self, path, request, response): |
| 228 templates = self.template_data_source_factory.Create(request, path) | 314 templates = self.template_data_source_factory.Create(request, path) |
| 229 | 315 |
| 230 content = None | 316 content = None |
| 231 try: | 317 try: |
| 232 if fnmatch(path, 'extensions/examples/*.zip'): | 318 if fnmatch(path, 'extensions/examples/*.zip'): |
| 233 content = self.example_zipper.Create( | 319 content = self.example_zipper.Create( |
| 234 path[len('extensions/'):-len('.zip')]) | 320 path[len('extensions/'):-len('.zip')]) |
| 235 response.headers['content-type'] = 'application/zip' | 321 response.headers['content-type'] = 'application/zip' |
| 236 elif path.startswith('extensions/examples/'): | 322 elif path.startswith('extensions/examples/'): |
| 237 mimetype = mimetypes.guess_type(path)[0] or 'text/plain' | 323 mimetype = mimetypes.guess_type(path)[0] or 'text/plain' |
| 238 content = self.content_cache.GetFromFile( | 324 content = self.unpatched_content_cache.GetFromFile( |
| 239 '%s/%s' % (svn_constants.DOCS_PATH, path[len('extensions/'):]), | 325 '%s/%s' % (svn_constants.DOCS_PATH, path[len('extensions/'):]), |
| 240 binary=_IsBinaryMimetype(mimetype)) | 326 binary=_IsBinaryMimetype(mimetype)) |
| 241 response.headers['content-type'] = 'text/plain' | 327 response.headers['content-type'] = 'text/plain' |
| 242 elif path.startswith('static/'): | 328 elif path.startswith('static/'): |
| 243 content = self._FetchStaticResource(path, response) | 329 content = self._FetchStaticResource(path, response) |
| 244 elif path.endswith('.html'): | 330 elif path.endswith('.html'): |
| 245 content = templates.Render(path) | 331 content = templates.Render(path) |
| 246 except FileNotFoundError as e: | 332 except FileNotFoundError as e: |
| 247 logging.warning(traceback.format_exc()) | 333 logging.warning(traceback.format_exc()) |
| 248 | 334 |
| 249 response.headers['x-frame-options'] = 'sameorigin' | 335 response.headers['x-frame-options'] = 'sameorigin' |
| 250 if content is None: | 336 if content is None: |
| 251 response.set_status(404); | 337 response.set_status(404); |
| 252 response.out.write(templates.Render('404')) | 338 response.out.write(templates.Render('404')) |
| 253 else: | 339 else: |
| 254 if not content: | 340 if not content: |
| 255 logging.error('%s had empty content' % path) | 341 logging.error('%s had empty content' % path) |
| 256 response.headers['cache-control'] = 'max-age=300' | 342 response.headers['cache-control'] = 'max-age=300' |
| 257 response.out.write(content) | 343 response.out.write(content) |
| OLD | NEW |