| 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 patch_servlet import PatchData |
| 28 from patched_file_system import PatchedFileSystem |
| 27 from path_canonicalizer import PathCanonicalizer | 29 from path_canonicalizer import PathCanonicalizer |
| 28 from reference_resolver import ReferenceResolver | 30 from reference_resolver import ReferenceResolver |
| 31 from rietveld_file_system import RietveldFileSystem |
| 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 |
| 49 github_file_system = None | 52 github_file_system = None |
| 50 | 53 |
| 51 @staticmethod | 54 @staticmethod |
| 52 @memoize | 55 @memoize |
| 53 def GetOrCreateOffline(channel): | 56 def GetOrCreateOffline(channel, branch_path=None): |
| 54 '''Gets/creates a local ServerInstance, meaning that only resources local to | 57 '''Gets/creates a local ServerInstance, meaning that only resources local to |
| 55 the server - memcache, object store, etc, are queried. This amounts to not | 58 the server - memcache, object store, etc, are queried. This amounts to not |
| 56 setting up the subversion nor github file systems. | 59 setting up the subversion nor github file systems. |
| 57 ''' | 60 ''' |
| 58 branch_utility = ServerInstance._GetOrCreateBranchUtility() | 61 branch_utility = ServerInstance._GetOrCreateBranchUtility() |
| 59 branch = branch_utility.GetBranchNumberForChannelName(channel) | 62 branch = branch_utility.GetBranchNumberForChannelName(channel) |
| 60 object_store_creator_factory = ObjectStoreCreator.Factory(GetAppVersion(), | 63 object_store_creator_factory = ObjectStoreCreator.Factory(GetAppVersion(), |
| 61 branch) | 64 branch) |
| 62 # No svn nor github file systems. Rely on the crons to fill the caches, and | 65 # No svn nor github file systems. Rely on the crons to fill the caches, and |
| 63 # for the caches to exist. | 66 # for the caches to exist. |
| 64 return ServerInstance( | 67 return ServerInstance( |
| 65 channel, | 68 channel, |
| 69 branch_path, |
| 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, branch_path=None, patch_data=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 |
| 96 object_store_creator_factory = ObjectStoreCreator.Factory(GetAppVersion(), | 100 object_store_creator_factory = ObjectStoreCreator.Factory(GetAppVersion(), |
| 97 branch, | 101 branch, |
| 98 start_empty=True) | 102 start_empty=True) |
| 99 | 103 |
| 100 svn_file_system = CachingFileSystem( | 104 svn_file_system = CachingFileSystem( |
| 101 SubversionFileSystem(AppEngineUrlFetcher(svn_url), | 105 SubversionFileSystem(AppEngineUrlFetcher(svn_url), |
| 102 AppEngineUrlFetcher(viewvc_url)), | 106 AppEngineUrlFetcher(viewvc_url)), |
| 103 object_store_creator_factory) | 107 object_store_creator_factory) |
| 104 | 108 |
| 109 if patch_data is not None: |
| 110 object_store_creator_factory = ObjectStoreCreator.Factory( |
| 111 GetAppVersion(), |
| 112 branch, |
| 113 start_empty=True, |
| 114 persistent=False, |
| 115 more={'issue': patch_data.issue, 'patchset': patch_data.patchset}) |
| 116 rietveld_file_system = RietveldFileSystem( |
| 117 svn_constants.EXTENSIONS_PATH, |
| 118 patch_data, |
| 119 AppEngineUrlFetcher(url_constants.CODEREVIEW_SERVER), |
| 120 object_store_creator_factory) |
| 121 svn_file_system = PatchedFileSystem(patch_data.files, |
| 122 svn_file_system, |
| 123 rietveld_file_system) |
| 124 |
| 105 return ServerInstance(channel, | 125 return ServerInstance(channel, |
| 126 branch_path, |
| 106 object_store_creator_factory, | 127 object_store_creator_factory, |
| 107 svn_file_system, | 128 svn_file_system, |
| 108 ServerInstance._GetOrCreateGithubFileSystem()) | 129 ServerInstance._GetOrCreateGithubFileSystem()) |
| 109 | 130 |
| 110 @staticmethod | 131 @staticmethod |
| 111 def CreateForTest(file_system): | 132 def CreateForTest(file_system): |
| 112 return ServerInstance('test', | 133 return ServerInstance('test', |
| 134 None, |
| 113 ObjectStoreCreator.TestFactory(), | 135 ObjectStoreCreator.TestFactory(), |
| 114 file_system, | 136 file_system, |
| 115 None) | 137 None) |
| 116 | 138 |
| 117 @staticmethod | 139 @staticmethod |
| 118 def _GetOrCreateBranchUtility(): | 140 def _GetOrCreateBranchUtility(): |
| 119 if ServerInstance.branch_utility is None: | 141 if ServerInstance.branch_utility is None: |
| 120 ServerInstance.branch_utility = BranchUtility( | 142 ServerInstance.branch_utility = BranchUtility( |
| 121 url_constants.OMAHA_PROXY_URL, | 143 url_constants.OMAHA_PROXY_URL, |
| 122 AppEngineUrlFetcher()) | 144 AppEngineUrlFetcher()) |
| 123 return ServerInstance.branch_utility | 145 return ServerInstance.branch_utility |
| 124 | 146 |
| 125 @staticmethod | 147 @staticmethod |
| 126 def _GetOrCreateGithubFileSystem(): | 148 def _GetOrCreateGithubFileSystem(): |
| 127 # Initialising github is pointless if samples are disabled, since it's only | 149 # Initialising github is pointless if samples are disabled, since it's only |
| 128 # used for apps samples. | 150 # used for apps samples. |
| 129 if ServerInstance.github_file_system is None: | 151 if ServerInstance.github_file_system is None: |
| 130 if _IsSamplesDisabled(): | 152 if _IsSamplesDisabled(): |
| 131 ServerInstance.github_file_system = EmptyDirFileSystem() | 153 ServerInstance.github_file_system = EmptyDirFileSystem() |
| 132 else: | 154 else: |
| 133 ServerInstance.github_file_system = GithubFileSystem( | 155 ServerInstance.github_file_system = GithubFileSystem( |
| 134 AppEngineUrlFetcher(url_constants.GITHUB_URL), | 156 AppEngineUrlFetcher(url_constants.GITHUB_URL), |
| 135 AppEngineBlobstore()) | 157 AppEngineBlobstore()) |
| 136 return ServerInstance.github_file_system | 158 return ServerInstance.github_file_system |
| 137 | 159 |
| 138 def __init__(self, | 160 def __init__(self, |
| 139 channel, | 161 channel, |
| 162 branch_path, |
| 140 object_store_creator_factory, | 163 object_store_creator_factory, |
| 141 svn_file_system, | 164 svn_file_system, |
| 142 github_file_system): | 165 github_file_system): |
| 143 self.svn_file_system = svn_file_system | 166 self.svn_file_system = svn_file_system |
| 144 | 167 |
| 145 self.github_file_system = github_file_system | 168 self.github_file_system = github_file_system |
| 146 | 169 |
| 147 self.compiled_fs_factory = CompiledFileSystem.Factory( | 170 self.compiled_fs_factory = CompiledFileSystem.Factory( |
| 148 svn_file_system, | 171 svn_file_system, |
| 149 object_store_creator_factory) | 172 object_store_creator_factory) |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 self.template_data_source_factory = TemplateDataSource.Factory( | 218 self.template_data_source_factory = TemplateDataSource.Factory( |
| 196 channel, | 219 channel, |
| 197 self.api_data_source_factory, | 220 self.api_data_source_factory, |
| 198 self.api_list_data_source_factory, | 221 self.api_list_data_source_factory, |
| 199 self.intro_data_source_factory, | 222 self.intro_data_source_factory, |
| 200 self.samples_data_source_factory, | 223 self.samples_data_source_factory, |
| 201 self.sidenav_data_source_factory, | 224 self.sidenav_data_source_factory, |
| 202 self.compiled_fs_factory, | 225 self.compiled_fs_factory, |
| 203 self.ref_resolver_factory, | 226 self.ref_resolver_factory, |
| 204 svn_constants.PUBLIC_TEMPLATE_PATH, | 227 svn_constants.PUBLIC_TEMPLATE_PATH, |
| 205 svn_constants.PRIVATE_TEMPLATE_PATH) | 228 svn_constants.PRIVATE_TEMPLATE_PATH, |
| 229 branch_path) |
| 206 | 230 |
| 207 self.example_zipper = ExampleZipper( | 231 self.example_zipper = ExampleZipper( |
| 208 self.compiled_fs_factory, | 232 self.compiled_fs_factory, |
| 209 svn_constants.DOCS_PATH) | 233 svn_constants.DOCS_PATH) |
| 210 | 234 |
| 211 self.path_canonicalizer = PathCanonicalizer( | 235 self.path_canonicalizer = PathCanonicalizer( |
| 212 channel, | 236 channel, |
| 213 self.compiled_fs_factory) | 237 self.compiled_fs_factory) |
| 214 | 238 |
| 215 self.content_cache = self.compiled_fs_factory.GetOrCreateIdentity() | 239 self.content_cache = self.compiled_fs_factory.GetOrCreateIdentity() |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 | 272 |
| 249 response.headers['x-frame-options'] = 'sameorigin' | 273 response.headers['x-frame-options'] = 'sameorigin' |
| 250 if content is None: | 274 if content is None: |
| 251 response.set_status(404); | 275 response.set_status(404); |
| 252 response.out.write(templates.Render('404')) | 276 response.out.write(templates.Render('404')) |
| 253 else: | 277 else: |
| 254 if not content: | 278 if not content: |
| 255 logging.error('%s had empty content' % path) | 279 logging.error('%s had empty content' % path) |
| 256 response.headers['cache-control'] = 'max-age=300' | 280 response.headers['cache-control'] = 'max-age=300' |
| 257 response.out.write(content) | 281 response.out.write(content) |
| OLD | NEW |