| 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 traceback | 7 import traceback |
| 8 | 8 |
| 9 from branch_utility import BranchUtility | |
| 10 import compiled_file_system as compiled_fs | 9 import compiled_file_system as compiled_fs |
| 11 from docs_server_utils import FormatKey | 10 from docs_server_utils import FormatKey |
| 12 from file_system import FileNotFoundError | 11 from file_system import FileNotFoundError |
| 13 from third_party.handlebar import Handlebar | 12 from third_party.handlebar import Handlebar |
| 14 import url_constants | 13 import url_constants |
| 15 | 14 |
| 16 EXTENSIONS_URL = '/chrome/extensions' | 15 EXTENSIONS_URL = '/chrome/extensions' |
| 17 | 16 |
| 18 def _MakeChannelDict(channel_name): | |
| 19 channel_dict = { | |
| 20 'channels': [{'name': name} for name in BranchUtility.GetAllChannelNames()], | |
| 21 'current': channel_name | |
| 22 } | |
| 23 for channel in channel_dict['channels']: | |
| 24 if channel['name'] == channel_name: | |
| 25 channel['isCurrent'] = True | |
| 26 return channel_dict | |
| 27 | |
| 28 class TemplateDataSource(object): | 17 class TemplateDataSource(object): |
| 29 """Renders Handlebar templates, providing them with the context in which to | 18 """Renders Handlebar templates, providing them with the context in which to |
| 30 render. | 19 render. |
| 31 | 20 |
| 32 Also acts as a data source itself, providing partial Handlebar templates to | 21 Also acts as a data source itself, providing partial Handlebar templates to |
| 33 those it renders. | 22 those it renders. |
| 34 | 23 |
| 35 Each instance of TemplateDataSource is bound to a Request so that it can | 24 Each instance of TemplateDataSource is bound to a Request so that it can |
| 36 render templates with request-specific data (such as Accept-Language); use | 25 render templates with request-specific data (such as Accept-Language); use |
| 37 a Factory to cheaply construct these. | 26 a Factory to cheaply construct these. |
| 38 """ | 27 """ |
| 39 | 28 |
| 40 class Factory(object): | 29 class Factory(object): |
| 41 """A factory to create lightweight TemplateDataSource instances bound to | 30 """A factory to create lightweight TemplateDataSource instances bound to |
| 42 individual Requests. | 31 individual Requests. |
| 43 """ | 32 """ |
| 44 def __init__(self, | 33 def __init__(self, |
| 45 channel_name, | |
| 46 api_data_source_factory, | 34 api_data_source_factory, |
| 47 api_list_data_source_factory, | 35 api_list_data_source_factory, |
| 48 intro_data_source_factory, | 36 intro_data_source_factory, |
| 49 samples_data_source_factory, | 37 samples_data_source_factory, |
| 50 sidenav_data_source_factory, | 38 sidenav_data_source_factory, |
| 51 compiled_fs_factory, | 39 compiled_fs_factory, |
| 52 ref_resolver_factory, | 40 ref_resolver_factory, |
| 53 public_template_path, | 41 public_template_path, |
| 54 private_template_path, | 42 private_template_path, |
| 55 static_path): | 43 static_path): |
| 56 self._branch_info = _MakeChannelDict(channel_name) | |
| 57 self._api_data_source_factory = api_data_source_factory | 44 self._api_data_source_factory = api_data_source_factory |
| 58 self._api_list_data_source_factory = api_list_data_source_factory | 45 self._api_list_data_source_factory = api_list_data_source_factory |
| 59 self._intro_data_source_factory = intro_data_source_factory | 46 self._intro_data_source_factory = intro_data_source_factory |
| 60 self._samples_data_source_factory = samples_data_source_factory | 47 self._samples_data_source_factory = samples_data_source_factory |
| 61 self._sidenav_data_source_factory = sidenav_data_source_factory | 48 self._sidenav_data_source_factory = sidenav_data_source_factory |
| 62 self._cache = compiled_fs_factory.Create(self._CreateTemplate, | 49 self._cache = compiled_fs_factory.Create(self._CreateTemplate, |
| 63 TemplateDataSource) | 50 TemplateDataSource) |
| 64 self._ref_resolver = ref_resolver_factory.Create() | 51 self._ref_resolver = ref_resolver_factory.Create() |
| 65 self._public_template_path = public_template_path | 52 self._public_template_path = public_template_path |
| 66 self._private_template_path = private_template_path | 53 self._private_template_path = private_template_path |
| 67 self._static_resources = static_path | 54 self._static_path = static_path |
| 68 | 55 |
| 69 def _CreateTemplate(self, template_name, text): | 56 def _CreateTemplate(self, template_name, text): |
| 70 return Handlebar(self._ref_resolver.ResolveAllLinks(text)) | 57 return Handlebar(self._ref_resolver.ResolveAllLinks(text)) |
| 71 | 58 |
| 72 def Create(self, request, path): | 59 def Create(self, request, path): |
| 73 """Returns a new TemplateDataSource bound to |request|. | 60 """Returns a new TemplateDataSource bound to |request|. |
| 74 """ | 61 """ |
| 75 return TemplateDataSource( | 62 return TemplateDataSource( |
| 76 self._branch_info, | |
| 77 self._api_data_source_factory.Create(request), | 63 self._api_data_source_factory.Create(request), |
| 78 self._api_list_data_source_factory.Create(), | 64 self._api_list_data_source_factory.Create(), |
| 79 self._intro_data_source_factory.Create(), | 65 self._intro_data_source_factory.Create(), |
| 80 self._samples_data_source_factory.Create(request), | 66 self._samples_data_source_factory.Create(request), |
| 81 self._sidenav_data_source_factory.Create(path), | 67 self._sidenav_data_source_factory.Create(path), |
| 82 self._cache, | 68 self._cache, |
| 83 self._public_template_path, | 69 self._public_template_path, |
| 84 self._private_template_path, | 70 self._private_template_path, |
| 85 self._static_resources) | 71 self._static_path) |
| 86 | 72 |
| 87 def __init__(self, | 73 def __init__(self, |
| 88 branch_info, | |
| 89 api_data_source, | 74 api_data_source, |
| 90 api_list_data_source, | 75 api_list_data_source, |
| 91 intro_data_source, | 76 intro_data_source, |
| 92 samples_data_source, | 77 samples_data_source, |
| 93 sidenav_data_source, | 78 sidenav_data_source, |
| 94 cache, | 79 cache, |
| 95 public_template_path, | 80 public_template_path, |
| 96 private_template_path, | 81 private_template_path, |
| 97 static_resources): | 82 static_path): |
| 98 self._branch_info = branch_info | |
| 99 self._api_list_data_source = api_list_data_source | 83 self._api_list_data_source = api_list_data_source |
| 100 self._intro_data_source = intro_data_source | 84 self._intro_data_source = intro_data_source |
| 101 self._samples_data_source = samples_data_source | 85 self._samples_data_source = samples_data_source |
| 102 self._api_data_source = api_data_source | 86 self._api_data_source = api_data_source |
| 103 self._sidenav_data_source = sidenav_data_source | 87 self._sidenav_data_source = sidenav_data_source |
| 104 self._cache = cache | 88 self._cache = cache |
| 105 self._public_template_path = public_template_path | 89 self._public_template_path = public_template_path |
| 106 self._private_template_path = private_template_path | 90 self._private_template_path = private_template_path |
| 107 self._static_resources = static_resources | 91 self._static_path = static_path |
| 108 | 92 |
| 109 def Render(self, template_name): | 93 def Render(self, template_name): |
| 110 """This method will render a template named |template_name|, fetching all | 94 """This method will render a template named |template_name|, fetching all |
| 111 the partial templates needed from |self._cache|. Partials are retrieved | 95 the partial templates needed from |self._cache|. Partials are retrieved |
| 112 from the TemplateDataSource with the |get| method. | 96 from the TemplateDataSource with the |get| method. |
| 113 """ | 97 """ |
| 114 template = self.GetTemplate(self._public_template_path, template_name) | 98 template = self.GetTemplate(self._public_template_path, template_name) |
| 115 if not template: | 99 if not template: |
| 116 return None | 100 return None |
| 117 # TODO error handling | 101 # TODO error handling |
| 118 render_data = template.render({ | 102 render_data = template.render({ |
| 119 'api_list': self._api_list_data_source, | 103 'api_list': self._api_list_data_source, |
| 120 'apis': self._api_data_source, | 104 'apis': self._api_data_source, |
| 121 'branchInfo': self._branch_info, | |
| 122 'intros': self._intro_data_source, | 105 'intros': self._intro_data_source, |
| 123 'sidenavs': self._sidenav_data_source, | 106 'sidenavs': self._sidenav_data_source, |
| 124 'partials': self, | 107 'partials': self, |
| 125 'samples': self._samples_data_source, | 108 'samples': self._samples_data_source, |
| 126 'static': self._static_resources, | 109 'static': self._static_path, |
| 127 'app': 'app', | 110 'app': 'app', |
| 128 'extension': 'extension', | 111 'extension': 'extension', |
| 129 'apps_title': 'Apps', | 112 'apps_title': 'Apps', |
| 130 'extensions_title': 'Extensions', | 113 'extensions_title': 'Extensions', |
| 131 'apps_samples_url': url_constants.GITHUB_BASE, | 114 'apps_samples_url': url_constants.GITHUB_BASE, |
| 132 # TODO(kalman): this is wrong, it's always getting from trunk, but meh | 115 # TODO(kalman): this is wrong, it's always getting from trunk, but meh |
| 133 # it hardly ever shows up (only in the "cannot fetch samples" message). | 116 # it hardly ever shows up (only in the "cannot fetch samples" message). |
| 134 # In fact I don't even know if it can show up anymore due the samples data | 117 # In fact I don't even know if it can show up anymore due the samples data |
| 135 # being persisent. In any case, when the channel distinctions are gone | 118 # being persisent. In any case, when the channel distinctions are gone |
| 136 # this can go away, so, double meh. | 119 # this can go away, so, double meh. |
| 137 'extensions_samples_url': url_constants.EXTENSIONS_SAMPLES, | 120 'extensions_samples_url': url_constants.EXTENSIONS_SAMPLES, |
| 138 'true': True, | 121 'true': True, |
| 139 'false': False | 122 'false': False |
| 140 }) | 123 }) |
| 141 if render_data.errors: | 124 if render_data.errors: |
| 142 logging.error('Handlebar error(s) rendering %s:\n%s' % | 125 logging.error('Handlebar error(s) rendering %s:\n%s' % |
| 143 (template_name, ' \n'.join(render_data.errors))) | 126 (template_name, ' \n'.join(render_data.errors))) |
| 144 return render_data.text | 127 return render_data.text |
| 145 | 128 |
| 146 def get(self, key): | 129 def get(self, key): |
| 147 return self.GetTemplate(self._private_template_path, key) | 130 return self.GetTemplate(self._private_template_path, key) |
| 148 | 131 |
| 149 def GetTemplate(self, base_path, template_name): | 132 def GetTemplate(self, base_path, template_name): |
| 150 try: | 133 try: |
| 151 return self._cache.GetFromFile( | 134 return self._cache.GetFromFile( |
| 152 '/'.join((base_path, FormatKey(template_name)))) | 135 '/'.join((base_path, FormatKey(template_name)))) |
| 153 except FileNotFoundError as e: | 136 except FileNotFoundError as e: |
| 154 logging.warning(traceback.format_exc()) | 137 logging.warning(traceback.format_exc()) |
| 155 return None | 138 return None |
| OLD | NEW |