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 import logging | 5 import logging |
6 import os | 6 import os |
7 import sys | 7 import sys |
8 | 8 |
9 from appengine_wrappers import webapp | 9 from appengine_wrappers import webapp |
10 from appengine_wrappers import memcache | 10 from appengine_wrappers import memcache |
(...skipping 21 matching lines...) Expand all Loading... |
32 DEFAULT_BRANCH = 'local' | 32 DEFAULT_BRANCH = 'local' |
33 | 33 |
34 SVN_URL = 'http://src.chromium.org/chrome' | 34 SVN_URL = 'http://src.chromium.org/chrome' |
35 TRUNK_URL = SVN_URL + '/trunk' | 35 TRUNK_URL = SVN_URL + '/trunk' |
36 BRANCH_URL = SVN_URL + '/branches' | 36 BRANCH_URL = SVN_URL + '/branches' |
37 | 37 |
38 OMAHA_PROXY_URL = 'http://omahaproxy.appspot.com/json' | 38 OMAHA_PROXY_URL = 'http://omahaproxy.appspot.com/json' |
39 BRANCH_UTILITY_MEMCACHE = AppEngineMemcache('branch_utility') | 39 BRANCH_UTILITY_MEMCACHE = AppEngineMemcache('branch_utility') |
40 BRANCH_UTILITY = BranchUtility(OMAHA_PROXY_URL, | 40 BRANCH_UTILITY = BranchUtility(OMAHA_PROXY_URL, |
41 DEFAULT_BRANCH, | 41 DEFAULT_BRANCH, |
42 AppEngineUrlFetcher(''), | 42 AppEngineUrlFetcher(None), |
43 BRANCH_UTILITY_MEMCACHE) | 43 BRANCH_UTILITY_MEMCACHE) |
44 | 44 |
45 STATIC_DIR_PREFIX = 'docs/server2' | 45 STATIC_DIR_PREFIX = 'docs/server2' |
46 EXTENSIONS_PATH = 'chrome/common/extensions' | 46 EXTENSIONS_PATH = 'chrome/common/extensions' |
47 DOCS_PATH = 'docs' | 47 DOCS_PATH = 'docs' |
48 API_PATH = 'api' | 48 API_PATH = 'api' |
49 INTRO_PATH = DOCS_PATH + '/server2/templates/intros' | 49 INTRO_PATH = DOCS_PATH + '/server2/templates/intros' |
50 ARTICLE_PATH = DOCS_PATH + '/server2/templates/articles' | 50 ARTICLE_PATH = DOCS_PATH + '/server2/templates/articles' |
51 PUBLIC_TEMPLATE_PATH = DOCS_PATH + '/server2/templates/public' | 51 PUBLIC_TEMPLATE_PATH = DOCS_PATH + '/server2/templates/public' |
52 PRIVATE_TEMPLATE_PATH = DOCS_PATH + '/server2/templates/private' | 52 PRIVATE_TEMPLATE_PATH = DOCS_PATH + '/server2/templates/private' |
53 EXAMPLES_PATH = DOCS_PATH + '/examples' | 53 EXAMPLES_PATH = DOCS_PATH + '/examples' |
54 FULL_EXAMPLES_PATH = DOCS_PATH + '/' + EXAMPLES_PATH | 54 FULL_EXAMPLES_PATH = DOCS_PATH + '/' + EXAMPLES_PATH |
55 | 55 |
56 # Global cache of instances because Handler is recreated for every request. | 56 # Global cache of instances because Handler is recreated for every request. |
57 SERVER_INSTANCES = {} | 57 SERVER_INSTANCES = {} |
58 | 58 |
59 def _GetInstanceForBranch(branch, local_path): | 59 def _GetInstanceForBranch(channel_name, local_path): |
| 60 branch = BRANCH_UTILITY.GetBranchNumberForChannelName(channel_name) |
60 if branch in SERVER_INSTANCES: | 61 if branch in SERVER_INSTANCES: |
61 return SERVER_INSTANCES[branch] | 62 return SERVER_INSTANCES[branch] |
62 if branch == 'local': | 63 if branch == 'local': |
63 file_system = LocalFileSystem(local_path) | 64 file_system = LocalFileSystem(local_path) |
64 else: | 65 else: |
65 fetcher = AppEngineUrlFetcher( | 66 fetcher = AppEngineUrlFetcher( |
66 _GetURLFromBranch(branch) + '/' + EXTENSIONS_PATH) | 67 _GetURLFromBranch(branch) + '/' + EXTENSIONS_PATH) |
67 file_system = MemcacheFileSystem(SubversionFileSystem(fetcher), | 68 file_system = MemcacheFileSystem(SubversionFileSystem(fetcher), |
68 AppEngineMemcache(branch)) | 69 AppEngineMemcache(branch)) |
69 | 70 |
70 cache_builder = FileSystemCache.Builder(file_system) | 71 cache_builder = FileSystemCache.Builder(file_system) |
71 api_list_data_source = APIListDataSource(cache_builder, | 72 api_list_data_source = APIListDataSource(cache_builder, |
72 file_system, | 73 file_system, |
73 API_PATH, | 74 API_PATH, |
74 PUBLIC_TEMPLATE_PATH) | 75 PUBLIC_TEMPLATE_PATH) |
75 intro_data_source = IntroDataSource(cache_builder, | 76 intro_data_source = IntroDataSource(cache_builder, |
76 [INTRO_PATH, ARTICLE_PATH]) | 77 [INTRO_PATH, ARTICLE_PATH]) |
77 samples_data_source_factory = SamplesDataSource.Factory(branch, | 78 samples_data_source_factory = SamplesDataSource.Factory(branch, |
78 file_system, | 79 file_system, |
79 cache_builder, | 80 cache_builder, |
80 EXAMPLES_PATH) | 81 EXAMPLES_PATH) |
81 api_data_source_factory = APIDataSource.Factory(cache_builder, | 82 api_data_source_factory = APIDataSource.Factory(cache_builder, |
82 API_PATH, | 83 API_PATH, |
83 samples_data_source_factory) | 84 samples_data_source_factory) |
84 template_data_source_factory = TemplateDataSource.Factory( | 85 template_data_source_factory = TemplateDataSource.Factory( |
85 branch, | 86 channel_name, |
86 api_data_source_factory, | 87 api_data_source_factory, |
87 api_list_data_source, | 88 api_list_data_source, |
88 intro_data_source, | 89 intro_data_source, |
89 samples_data_source_factory, | 90 samples_data_source_factory, |
90 cache_builder, | 91 cache_builder, |
91 PUBLIC_TEMPLATE_PATH, | 92 PUBLIC_TEMPLATE_PATH, |
92 PRIVATE_TEMPLATE_PATH) | 93 PRIVATE_TEMPLATE_PATH) |
93 example_zipper = ExampleZipper(file_system, | 94 example_zipper = ExampleZipper(file_system, |
94 cache_builder, | 95 cache_builder, |
95 DOCS_PATH, | 96 DOCS_PATH, |
96 EXAMPLES_PATH) | 97 EXAMPLES_PATH) |
97 SERVER_INSTANCES[branch] = ServerInstance( | 98 SERVER_INSTANCES[branch] = ServerInstance( |
98 template_data_source_factory, | 99 template_data_source_factory, |
99 example_zipper, | 100 example_zipper, |
100 cache_builder) | 101 cache_builder) |
101 return SERVER_INSTANCES[branch] | 102 return SERVER_INSTANCES[branch] |
102 | 103 |
103 def _GetURLFromBranch(branch): | 104 def _GetURLFromBranch(branch): |
104 if branch == 'trunk': | 105 if branch == 'trunk': |
105 return TRUNK_URL + '/src' | 106 return TRUNK_URL + '/src' |
106 return BRANCH_URL + '/' + branch + '/src' | 107 return BRANCH_URL + '/' + branch + '/src' |
107 | 108 |
| 109 def _CleanBranches(): |
| 110 numbers = BRANCH_UTILITY.GetAllBranchNumbers() |
| 111 for key in SERVER_INSTANCES.keys(): |
| 112 if key not in numbers: |
| 113 SERVER_INSTANCES.pop(key) |
| 114 |
108 class Handler(webapp.RequestHandler): | 115 class Handler(webapp.RequestHandler): |
109 def __init__(self, request, response, local_path=EXTENSIONS_PATH): | 116 def __init__(self, request, response, local_path=EXTENSIONS_PATH): |
110 self._local_path = local_path | 117 self._local_path = local_path |
111 super(Handler, self).__init__(request, response) | 118 super(Handler, self).__init__(request, response) |
112 | 119 |
113 def _NavigateToPath(self, path): | 120 def _NavigateToPath(self, path): |
114 channel_name, real_path = BRANCH_UTILITY.SplitChannelNameFromPath(path) | 121 channel_name, real_path = BRANCH_UTILITY.SplitChannelNameFromPath(path) |
115 branch = BRANCH_UTILITY.GetBranchNumberForChannelName(channel_name) | |
116 # TODO: Detect that these are directories and serve index.html out of them. | 122 # TODO: Detect that these are directories and serve index.html out of them. |
117 if real_path.strip('/') == 'apps': | 123 if real_path.strip('/') == 'apps': |
118 real_path = 'apps/index.html' | 124 real_path = 'apps/index.html' |
119 if real_path.strip('/') == 'extensions': | 125 if real_path.strip('/') == 'extensions': |
120 real_path = 'extensions/index.html' | 126 real_path = 'extensions/index.html' |
121 # TODO: This leaks Server instances when branch bumps. | 127 _CleanBranches() |
122 _GetInstanceForBranch(branch, self._local_path).Get(real_path, | 128 _GetInstanceForBranch(channel_name, self._local_path).Get(real_path, |
123 self.request, | 129 self.request, |
124 self.response) | 130 self.response) |
125 | 131 |
126 def get(self): | 132 def get(self): |
127 path = self.request.path | 133 path = self.request.path |
128 if '_ah/warmup' in path: | 134 if '_ah/warmup' in path: |
129 logging.info('Warmup request.') | 135 logging.info('Warmup request.') |
130 if DEFAULT_BRANCH != 'local': | 136 self._NavigateToPath('trunk/extensions/samples.html') |
131 self._NavigateToPath('trunk/extensions/samples.html') | |
132 self._NavigateToPath('dev/extensions/samples.html') | 137 self._NavigateToPath('dev/extensions/samples.html') |
133 self._NavigateToPath('beta/extensions/samples.html') | 138 self._NavigateToPath('beta/extensions/samples.html') |
134 self._NavigateToPath('stable/extensions/samples.html') | 139 self._NavigateToPath('stable/extensions/samples.html') |
135 return | 140 return |
136 | 141 |
137 # Redirect paths like "directory" to "directory/". This is so relative file | 142 # Redirect paths like "directory" to "directory/". This is so relative file |
138 # paths will know to treat this as a directory. | 143 # paths will know to treat this as a directory. |
139 if os.path.splitext(path)[1] == '' and path[-1] != '/': | 144 if os.path.splitext(path)[1] == '' and path[-1] != '/': |
140 self.redirect(path + '/') | 145 self.redirect(path + '/') |
141 path = path.replace('/chrome/', '') | 146 path = path.replace('/chrome/', '') |
142 path = path.strip('/') | 147 path = path.strip('/') |
143 self._NavigateToPath(path) | 148 self._NavigateToPath(path) |
OLD | NEW |