##// END OF EJS Templates
repo-summary: protect against wrong commits in repo summary.
marcink -
r2148:de03feb2 default
parent child Browse files
Show More
@@ -1,370 +1,371 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2017 RhodeCode GmbH
3 # Copyright (C) 2011-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22 import string
22 import string
23
23
24 from pyramid.view import view_config
24 from pyramid.view import view_config
25 from beaker.cache import cache_region
25 from beaker.cache import cache_region
26
26
27 from rhodecode.controllers import utils
27 from rhodecode.controllers import utils
28 from rhodecode.apps._base import RepoAppView
28 from rhodecode.apps._base import RepoAppView
29 from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP)
29 from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP)
30 from rhodecode.lib import caches, helpers as h
30 from rhodecode.lib import caches, helpers as h
31 from rhodecode.lib.helpers import RepoPage
31 from rhodecode.lib.helpers import RepoPage
32 from rhodecode.lib.utils2 import safe_str, safe_int
32 from rhodecode.lib.utils2 import safe_str, safe_int
33 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
33 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
34 from rhodecode.lib.markup_renderer import MarkupRenderer, relative_links
34 from rhodecode.lib.markup_renderer import MarkupRenderer, relative_links
35 from rhodecode.lib.ext_json import json
35 from rhodecode.lib.ext_json import json
36 from rhodecode.lib.vcs.backends.base import EmptyCommit
36 from rhodecode.lib.vcs.backends.base import EmptyCommit
37 from rhodecode.lib.vcs.exceptions import CommitError, EmptyRepositoryError
37 from rhodecode.lib.vcs.exceptions import CommitError, EmptyRepositoryError, \
38 CommitDoesNotExistError
38 from rhodecode.model.db import Statistics, CacheKey, User
39 from rhodecode.model.db import Statistics, CacheKey, User
39 from rhodecode.model.meta import Session
40 from rhodecode.model.meta import Session
40 from rhodecode.model.repo import ReadmeFinder
41 from rhodecode.model.repo import ReadmeFinder
41 from rhodecode.model.scm import ScmModel
42 from rhodecode.model.scm import ScmModel
42
43
43 log = logging.getLogger(__name__)
44 log = logging.getLogger(__name__)
44
45
45
46
46 class RepoSummaryView(RepoAppView):
47 class RepoSummaryView(RepoAppView):
47
48
48 def load_default_context(self):
49 def load_default_context(self):
49 c = self._get_local_tmpl_context(include_app_defaults=True)
50 c = self._get_local_tmpl_context(include_app_defaults=True)
50
51
51 c.rhodecode_repo = None
52 c.rhodecode_repo = None
52 if not c.repository_requirements_missing:
53 if not c.repository_requirements_missing:
53 c.rhodecode_repo = self.rhodecode_vcs_repo
54 c.rhodecode_repo = self.rhodecode_vcs_repo
54
55
55 self._register_global_c(c)
56 self._register_global_c(c)
56 return c
57 return c
57
58
58 def _get_readme_data(self, db_repo, default_renderer):
59 def _get_readme_data(self, db_repo, default_renderer):
59 repo_name = db_repo.repo_name
60 repo_name = db_repo.repo_name
60 log.debug('Looking for README file')
61 log.debug('Looking for README file')
61
62
62 @cache_region('long_term')
63 @cache_region('long_term')
63 def _generate_readme(cache_key):
64 def _generate_readme(cache_key):
64 readme_data = None
65 readme_data = None
65 readme_node = None
66 readme_node = None
66 readme_filename = None
67 readme_filename = None
67 commit = self._get_landing_commit_or_none(db_repo)
68 commit = self._get_landing_commit_or_none(db_repo)
68 if commit:
69 if commit:
69 log.debug("Searching for a README file.")
70 log.debug("Searching for a README file.")
70 readme_node = ReadmeFinder(default_renderer).search(commit)
71 readme_node = ReadmeFinder(default_renderer).search(commit)
71 if readme_node:
72 if readme_node:
72 relative_urls = {
73 relative_urls = {
73 'raw': h.route_path(
74 'raw': h.route_path(
74 'repo_file_raw', repo_name=repo_name,
75 'repo_file_raw', repo_name=repo_name,
75 commit_id=commit.raw_id, f_path=readme_node.path),
76 commit_id=commit.raw_id, f_path=readme_node.path),
76 'standard': h.route_path(
77 'standard': h.route_path(
77 'repo_files', repo_name=repo_name,
78 'repo_files', repo_name=repo_name,
78 commit_id=commit.raw_id, f_path=readme_node.path),
79 commit_id=commit.raw_id, f_path=readme_node.path),
79 }
80 }
80 readme_data = self._render_readme_or_none(
81 readme_data = self._render_readme_or_none(
81 commit, readme_node, relative_urls)
82 commit, readme_node, relative_urls)
82 readme_filename = readme_node.path
83 readme_filename = readme_node.path
83 return readme_data, readme_filename
84 return readme_data, readme_filename
84
85
85 invalidator_context = CacheKey.repo_context_cache(
86 invalidator_context = CacheKey.repo_context_cache(
86 _generate_readme, repo_name, CacheKey.CACHE_TYPE_README)
87 _generate_readme, repo_name, CacheKey.CACHE_TYPE_README)
87
88
88 with invalidator_context as context:
89 with invalidator_context as context:
89 context.invalidate()
90 context.invalidate()
90 computed = context.compute()
91 computed = context.compute()
91
92
92 return computed
93 return computed
93
94
94 def _get_landing_commit_or_none(self, db_repo):
95 def _get_landing_commit_or_none(self, db_repo):
95 log.debug("Getting the landing commit.")
96 log.debug("Getting the landing commit.")
96 try:
97 try:
97 commit = db_repo.get_landing_commit()
98 commit = db_repo.get_landing_commit()
98 if not isinstance(commit, EmptyCommit):
99 if not isinstance(commit, EmptyCommit):
99 return commit
100 return commit
100 else:
101 else:
101 log.debug("Repository is empty, no README to render.")
102 log.debug("Repository is empty, no README to render.")
102 except CommitError:
103 except CommitError:
103 log.exception(
104 log.exception(
104 "Problem getting commit when trying to render the README.")
105 "Problem getting commit when trying to render the README.")
105
106
106 def _render_readme_or_none(self, commit, readme_node, relative_urls):
107 def _render_readme_or_none(self, commit, readme_node, relative_urls):
107 log.debug(
108 log.debug(
108 'Found README file `%s` rendering...', readme_node.path)
109 'Found README file `%s` rendering...', readme_node.path)
109 renderer = MarkupRenderer()
110 renderer = MarkupRenderer()
110 try:
111 try:
111 html_source = renderer.render(
112 html_source = renderer.render(
112 readme_node.content, filename=readme_node.path)
113 readme_node.content, filename=readme_node.path)
113 if relative_urls:
114 if relative_urls:
114 return relative_links(html_source, relative_urls)
115 return relative_links(html_source, relative_urls)
115 return html_source
116 return html_source
116 except Exception:
117 except Exception:
117 log.exception(
118 log.exception(
118 "Exception while trying to render the README")
119 "Exception while trying to render the README")
119
120
120 def _load_commits_context(self, c):
121 def _load_commits_context(self, c):
121 p = safe_int(self.request.GET.get('page'), 1)
122 p = safe_int(self.request.GET.get('page'), 1)
122 size = safe_int(self.request.GET.get('size'), 10)
123 size = safe_int(self.request.GET.get('size'), 10)
123
124
124 def url_generator(**kw):
125 def url_generator(**kw):
125 query_params = {
126 query_params = {
126 'size': size
127 'size': size
127 }
128 }
128 query_params.update(kw)
129 query_params.update(kw)
129 return h.route_path(
130 return h.route_path(
130 'repo_summary_commits',
131 'repo_summary_commits',
131 repo_name=c.rhodecode_db_repo.repo_name, _query=query_params)
132 repo_name=c.rhodecode_db_repo.repo_name, _query=query_params)
132
133
133 pre_load = ['author', 'branch', 'date', 'message']
134 pre_load = ['author', 'branch', 'date', 'message']
134 try:
135 try:
135 collection = self.rhodecode_vcs_repo.get_commits(pre_load=pre_load)
136 collection = self.rhodecode_vcs_repo.get_commits(pre_load=pre_load)
136 except EmptyRepositoryError:
137 except EmptyRepositoryError:
137 collection = self.rhodecode_vcs_repo
138 collection = self.rhodecode_vcs_repo
138
139
139 c.repo_commits = RepoPage(
140 c.repo_commits = RepoPage(
140 collection, page=p, items_per_page=size, url=url_generator)
141 collection, page=p, items_per_page=size, url=url_generator)
141 page_ids = [x.raw_id for x in c.repo_commits]
142 page_ids = [x.raw_id for x in c.repo_commits]
142 c.comments = self.db_repo.get_comments(page_ids)
143 c.comments = self.db_repo.get_comments(page_ids)
143 c.statuses = self.db_repo.statuses(page_ids)
144 c.statuses = self.db_repo.statuses(page_ids)
144
145
145 @LoginRequired()
146 @LoginRequired()
146 @HasRepoPermissionAnyDecorator(
147 @HasRepoPermissionAnyDecorator(
147 'repository.read', 'repository.write', 'repository.admin')
148 'repository.read', 'repository.write', 'repository.admin')
148 @view_config(
149 @view_config(
149 route_name='repo_summary_commits', request_method='GET',
150 route_name='repo_summary_commits', request_method='GET',
150 renderer='rhodecode:templates/summary/summary_commits.mako')
151 renderer='rhodecode:templates/summary/summary_commits.mako')
151 def summary_commits(self):
152 def summary_commits(self):
152 c = self.load_default_context()
153 c = self.load_default_context()
153 self._load_commits_context(c)
154 self._load_commits_context(c)
154 return self._get_template_context(c)
155 return self._get_template_context(c)
155
156
156 @LoginRequired()
157 @LoginRequired()
157 @HasRepoPermissionAnyDecorator(
158 @HasRepoPermissionAnyDecorator(
158 'repository.read', 'repository.write', 'repository.admin')
159 'repository.read', 'repository.write', 'repository.admin')
159 @view_config(
160 @view_config(
160 route_name='repo_summary', request_method='GET',
161 route_name='repo_summary', request_method='GET',
161 renderer='rhodecode:templates/summary/summary.mako')
162 renderer='rhodecode:templates/summary/summary.mako')
162 @view_config(
163 @view_config(
163 route_name='repo_summary_slash', request_method='GET',
164 route_name='repo_summary_slash', request_method='GET',
164 renderer='rhodecode:templates/summary/summary.mako')
165 renderer='rhodecode:templates/summary/summary.mako')
165 @view_config(
166 @view_config(
166 route_name='repo_summary_explicit', request_method='GET',
167 route_name='repo_summary_explicit', request_method='GET',
167 renderer='rhodecode:templates/summary/summary.mako')
168 renderer='rhodecode:templates/summary/summary.mako')
168 def summary(self):
169 def summary(self):
169 c = self.load_default_context()
170 c = self.load_default_context()
170
171
171 # Prepare the clone URL
172 # Prepare the clone URL
172 username = ''
173 username = ''
173 if self._rhodecode_user.username != User.DEFAULT_USER:
174 if self._rhodecode_user.username != User.DEFAULT_USER:
174 username = safe_str(self._rhodecode_user.username)
175 username = safe_str(self._rhodecode_user.username)
175
176
176 _def_clone_uri = _def_clone_uri_by_id = c.clone_uri_tmpl
177 _def_clone_uri = _def_clone_uri_by_id = c.clone_uri_tmpl
177 if '{repo}' in _def_clone_uri:
178 if '{repo}' in _def_clone_uri:
178 _def_clone_uri_by_id = _def_clone_uri.replace(
179 _def_clone_uri_by_id = _def_clone_uri.replace(
179 '{repo}', '_{repoid}')
180 '{repo}', '_{repoid}')
180 elif '{repoid}' in _def_clone_uri:
181 elif '{repoid}' in _def_clone_uri:
181 _def_clone_uri_by_id = _def_clone_uri.replace(
182 _def_clone_uri_by_id = _def_clone_uri.replace(
182 '_{repoid}', '{repo}')
183 '_{repoid}', '{repo}')
183
184
184 c.clone_repo_url = self.db_repo.clone_url(
185 c.clone_repo_url = self.db_repo.clone_url(
185 user=username, uri_tmpl=_def_clone_uri)
186 user=username, uri_tmpl=_def_clone_uri)
186 c.clone_repo_url_id = self.db_repo.clone_url(
187 c.clone_repo_url_id = self.db_repo.clone_url(
187 user=username, uri_tmpl=_def_clone_uri_by_id)
188 user=username, uri_tmpl=_def_clone_uri_by_id)
188
189
189 # If enabled, get statistics data
190 # If enabled, get statistics data
190
191
191 c.show_stats = bool(self.db_repo.enable_statistics)
192 c.show_stats = bool(self.db_repo.enable_statistics)
192
193
193 stats = Session().query(Statistics) \
194 stats = Session().query(Statistics) \
194 .filter(Statistics.repository == self.db_repo) \
195 .filter(Statistics.repository == self.db_repo) \
195 .scalar()
196 .scalar()
196
197
197 c.stats_percentage = 0
198 c.stats_percentage = 0
198
199
199 if stats and stats.languages:
200 if stats and stats.languages:
200 c.no_data = False is self.db_repo.enable_statistics
201 c.no_data = False is self.db_repo.enable_statistics
201 lang_stats_d = json.loads(stats.languages)
202 lang_stats_d = json.loads(stats.languages)
202
203
203 # Sort first by decreasing count and second by the file extension,
204 # Sort first by decreasing count and second by the file extension,
204 # so we have a consistent output.
205 # so we have a consistent output.
205 lang_stats_items = sorted(lang_stats_d.iteritems(),
206 lang_stats_items = sorted(lang_stats_d.iteritems(),
206 key=lambda k: (-k[1], k[0]))[:10]
207 key=lambda k: (-k[1], k[0]))[:10]
207 lang_stats = [(x, {"count": y,
208 lang_stats = [(x, {"count": y,
208 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
209 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
209 for x, y in lang_stats_items]
210 for x, y in lang_stats_items]
210
211
211 c.trending_languages = json.dumps(lang_stats)
212 c.trending_languages = json.dumps(lang_stats)
212 else:
213 else:
213 c.no_data = True
214 c.no_data = True
214 c.trending_languages = json.dumps({})
215 c.trending_languages = json.dumps({})
215
216
216 scm_model = ScmModel()
217 scm_model = ScmModel()
217 c.enable_downloads = self.db_repo.enable_downloads
218 c.enable_downloads = self.db_repo.enable_downloads
218 c.repository_followers = scm_model.get_followers(self.db_repo)
219 c.repository_followers = scm_model.get_followers(self.db_repo)
219 c.repository_forks = scm_model.get_forks(self.db_repo)
220 c.repository_forks = scm_model.get_forks(self.db_repo)
220 c.repository_is_user_following = scm_model.is_following_repo(
221 c.repository_is_user_following = scm_model.is_following_repo(
221 self.db_repo_name, self._rhodecode_user.user_id)
222 self.db_repo_name, self._rhodecode_user.user_id)
222
223
223 # first interaction with the VCS instance after here...
224 # first interaction with the VCS instance after here...
224 if c.repository_requirements_missing:
225 if c.repository_requirements_missing:
225 self.request.override_renderer = \
226 self.request.override_renderer = \
226 'rhodecode:templates/summary/missing_requirements.mako'
227 'rhodecode:templates/summary/missing_requirements.mako'
227 return self._get_template_context(c)
228 return self._get_template_context(c)
228
229
229 c.readme_data, c.readme_file = \
230 c.readme_data, c.readme_file = \
230 self._get_readme_data(self.db_repo, c.visual.default_renderer)
231 self._get_readme_data(self.db_repo, c.visual.default_renderer)
231
232
232 # loads the summary commits template context
233 # loads the summary commits template context
233 self._load_commits_context(c)
234 self._load_commits_context(c)
234
235
235 return self._get_template_context(c)
236 return self._get_template_context(c)
236
237
237 def get_request_commit_id(self):
238 def get_request_commit_id(self):
238 return self.request.matchdict['commit_id']
239 return self.request.matchdict['commit_id']
239
240
240 @LoginRequired()
241 @LoginRequired()
241 @HasRepoPermissionAnyDecorator(
242 @HasRepoPermissionAnyDecorator(
242 'repository.read', 'repository.write', 'repository.admin')
243 'repository.read', 'repository.write', 'repository.admin')
243 @view_config(
244 @view_config(
244 route_name='repo_stats', request_method='GET',
245 route_name='repo_stats', request_method='GET',
245 renderer='json_ext')
246 renderer='json_ext')
246 def repo_stats(self):
247 def repo_stats(self):
247 commit_id = self.get_request_commit_id()
248 commit_id = self.get_request_commit_id()
248
249
249 _namespace = caches.get_repo_namespace_key(
250 _namespace = caches.get_repo_namespace_key(
250 caches.SUMMARY_STATS, self.db_repo_name)
251 caches.SUMMARY_STATS, self.db_repo_name)
251 show_stats = bool(self.db_repo.enable_statistics)
252 show_stats = bool(self.db_repo.enable_statistics)
252 cache_manager = caches.get_cache_manager(
253 cache_manager = caches.get_cache_manager(
253 'repo_cache_long', _namespace)
254 'repo_cache_long', _namespace)
254 _cache_key = caches.compute_key_from_params(
255 _cache_key = caches.compute_key_from_params(
255 self.db_repo_name, commit_id, show_stats)
256 self.db_repo_name, commit_id, show_stats)
256
257
257 def compute_stats():
258 def compute_stats():
258 code_stats = {}
259 code_stats = {}
259 size = 0
260 size = 0
260 try:
261 try:
261 scm_instance = self.db_repo.scm_instance()
262 scm_instance = self.db_repo.scm_instance()
262 commit = scm_instance.get_commit(commit_id)
263 commit = scm_instance.get_commit(commit_id)
263
264
264 for node in commit.get_filenodes_generator():
265 for node in commit.get_filenodes_generator():
265 size += node.size
266 size += node.size
266 if not show_stats:
267 if not show_stats:
267 continue
268 continue
268 ext = string.lower(node.extension)
269 ext = string.lower(node.extension)
269 ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext)
270 ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext)
270 if ext_info:
271 if ext_info:
271 if ext in code_stats:
272 if ext in code_stats:
272 code_stats[ext]['count'] += 1
273 code_stats[ext]['count'] += 1
273 else:
274 else:
274 code_stats[ext] = {"count": 1, "desc": ext_info}
275 code_stats[ext] = {"count": 1, "desc": ext_info}
275 except EmptyRepositoryError:
276 except (EmptyRepositoryError, CommitDoesNotExistError):
276 pass
277 pass
277 return {'size': h.format_byte_size_binary(size),
278 return {'size': h.format_byte_size_binary(size),
278 'code_stats': code_stats}
279 'code_stats': code_stats}
279
280
280 stats = cache_manager.get(_cache_key, createfunc=compute_stats)
281 stats = cache_manager.get(_cache_key, createfunc=compute_stats)
281 return stats
282 return stats
282
283
283 @LoginRequired()
284 @LoginRequired()
284 @HasRepoPermissionAnyDecorator(
285 @HasRepoPermissionAnyDecorator(
285 'repository.read', 'repository.write', 'repository.admin')
286 'repository.read', 'repository.write', 'repository.admin')
286 @view_config(
287 @view_config(
287 route_name='repo_refs_data', request_method='GET',
288 route_name='repo_refs_data', request_method='GET',
288 renderer='json_ext')
289 renderer='json_ext')
289 def repo_refs_data(self):
290 def repo_refs_data(self):
290 _ = self.request.translate
291 _ = self.request.translate
291 self.load_default_context()
292 self.load_default_context()
292
293
293 repo = self.rhodecode_vcs_repo
294 repo = self.rhodecode_vcs_repo
294 refs_to_create = [
295 refs_to_create = [
295 (_("Branch"), repo.branches, 'branch'),
296 (_("Branch"), repo.branches, 'branch'),
296 (_("Tag"), repo.tags, 'tag'),
297 (_("Tag"), repo.tags, 'tag'),
297 (_("Bookmark"), repo.bookmarks, 'book'),
298 (_("Bookmark"), repo.bookmarks, 'book'),
298 ]
299 ]
299 res = self._create_reference_data(
300 res = self._create_reference_data(
300 repo, self.db_repo_name, refs_to_create)
301 repo, self.db_repo_name, refs_to_create)
301 data = {
302 data = {
302 'more': False,
303 'more': False,
303 'results': res
304 'results': res
304 }
305 }
305 return data
306 return data
306
307
307 @LoginRequired()
308 @LoginRequired()
308 @HasRepoPermissionAnyDecorator(
309 @HasRepoPermissionAnyDecorator(
309 'repository.read', 'repository.write', 'repository.admin')
310 'repository.read', 'repository.write', 'repository.admin')
310 @view_config(
311 @view_config(
311 route_name='repo_refs_changelog_data', request_method='GET',
312 route_name='repo_refs_changelog_data', request_method='GET',
312 renderer='json_ext')
313 renderer='json_ext')
313 def repo_refs_changelog_data(self):
314 def repo_refs_changelog_data(self):
314 _ = self.request.translate
315 _ = self.request.translate
315 self.load_default_context()
316 self.load_default_context()
316
317
317 repo = self.rhodecode_vcs_repo
318 repo = self.rhodecode_vcs_repo
318
319
319 refs_to_create = [
320 refs_to_create = [
320 (_("Branches"), repo.branches, 'branch'),
321 (_("Branches"), repo.branches, 'branch'),
321 (_("Closed branches"), repo.branches_closed, 'branch_closed'),
322 (_("Closed branches"), repo.branches_closed, 'branch_closed'),
322 # TODO: enable when vcs can handle bookmarks filters
323 # TODO: enable when vcs can handle bookmarks filters
323 # (_("Bookmarks"), repo.bookmarks, "book"),
324 # (_("Bookmarks"), repo.bookmarks, "book"),
324 ]
325 ]
325 res = self._create_reference_data(
326 res = self._create_reference_data(
326 repo, self.db_repo_name, refs_to_create)
327 repo, self.db_repo_name, refs_to_create)
327 data = {
328 data = {
328 'more': False,
329 'more': False,
329 'results': res
330 'results': res
330 }
331 }
331 return data
332 return data
332
333
333 def _create_reference_data(self, repo, full_repo_name, refs_to_create):
334 def _create_reference_data(self, repo, full_repo_name, refs_to_create):
334 format_ref_id = utils.get_format_ref_id(repo)
335 format_ref_id = utils.get_format_ref_id(repo)
335
336
336 result = []
337 result = []
337 for title, refs, ref_type in refs_to_create:
338 for title, refs, ref_type in refs_to_create:
338 if refs:
339 if refs:
339 result.append({
340 result.append({
340 'text': title,
341 'text': title,
341 'children': self._create_reference_items(
342 'children': self._create_reference_items(
342 repo, full_repo_name, refs, ref_type,
343 repo, full_repo_name, refs, ref_type,
343 format_ref_id),
344 format_ref_id),
344 })
345 })
345 return result
346 return result
346
347
347 def _create_reference_items(self, repo, full_repo_name, refs, ref_type,
348 def _create_reference_items(self, repo, full_repo_name, refs, ref_type,
348 format_ref_id):
349 format_ref_id):
349 result = []
350 result = []
350 is_svn = h.is_svn(repo)
351 is_svn = h.is_svn(repo)
351 for ref_name, raw_id in refs.iteritems():
352 for ref_name, raw_id in refs.iteritems():
352 files_url = self._create_files_url(
353 files_url = self._create_files_url(
353 repo, full_repo_name, ref_name, raw_id, is_svn)
354 repo, full_repo_name, ref_name, raw_id, is_svn)
354 result.append({
355 result.append({
355 'text': ref_name,
356 'text': ref_name,
356 'id': format_ref_id(ref_name, raw_id),
357 'id': format_ref_id(ref_name, raw_id),
357 'raw_id': raw_id,
358 'raw_id': raw_id,
358 'type': ref_type,
359 'type': ref_type,
359 'files_url': files_url,
360 'files_url': files_url,
360 })
361 })
361 return result
362 return result
362
363
363 def _create_files_url(self, repo, full_repo_name, ref_name, raw_id, is_svn):
364 def _create_files_url(self, repo, full_repo_name, ref_name, raw_id, is_svn):
364 use_commit_id = '/' in ref_name or is_svn
365 use_commit_id = '/' in ref_name or is_svn
365 return h.route_path(
366 return h.route_path(
366 'repo_files',
367 'repo_files',
367 repo_name=full_repo_name,
368 repo_name=full_repo_name,
368 f_path=ref_name if is_svn else '',
369 f_path=ref_name if is_svn else '',
369 commit_id=raw_id if use_commit_id else ref_name,
370 commit_id=raw_id if use_commit_id else ref_name,
370 _query=dict(at=ref_name))
371 _query=dict(at=ref_name))
General Comments 0
You need to be logged in to leave comments. Login now