##// END OF EJS Templates
files: Include the repository groups when computing files url, fixes #4104.
Martin Bornhold -
r458:d58b1643 default
parent child Browse files
Show More
@@ -1,296 +1,300 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 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 """
21 """
22 Summary controller for RhodeCode Enterprise
22 Summary controller for RhodeCode Enterprise
23 """
23 """
24
24
25 import logging
25 import logging
26 from string import lower
26 from string import lower
27
27
28 from pylons import tmpl_context as c, request
28 from pylons import tmpl_context as c, request
29 from pylons.i18n.translation import _
29 from pylons.i18n.translation import _
30 from beaker.cache import cache_region, region_invalidate
30 from beaker.cache import cache_region, region_invalidate
31
31
32 from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP)
32 from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP)
33 from rhodecode.controllers import utils
33 from rhodecode.controllers import utils
34 from rhodecode.controllers.changelog import _load_changelog_summary
34 from rhodecode.controllers.changelog import _load_changelog_summary
35 from rhodecode.lib import caches, helpers as h
35 from rhodecode.lib import caches, helpers as h
36 from rhodecode.lib.utils import jsonify
36 from rhodecode.lib.utils import jsonify
37 from rhodecode.lib.utils2 import safe_str
37 from rhodecode.lib.utils2 import safe_str
38 from rhodecode.lib.auth import (
38 from rhodecode.lib.auth import (
39 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, XHRRequired)
39 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, XHRRequired)
40 from rhodecode.lib.base import BaseRepoController, render
40 from rhodecode.lib.base import BaseRepoController, render
41 from rhodecode.lib.markup_renderer import MarkupRenderer
41 from rhodecode.lib.markup_renderer import MarkupRenderer
42 from rhodecode.lib.ext_json import json
42 from rhodecode.lib.ext_json import json
43 from rhodecode.lib.vcs.backends.base import EmptyCommit
43 from rhodecode.lib.vcs.backends.base import EmptyCommit
44 from rhodecode.lib.vcs.exceptions import (
44 from rhodecode.lib.vcs.exceptions import (
45 CommitError, EmptyRepositoryError, NodeDoesNotExistError)
45 CommitError, EmptyRepositoryError, NodeDoesNotExistError)
46 from rhodecode.model.db import Statistics, CacheKey, User
46 from rhodecode.model.db import Statistics, CacheKey, User
47
47
48 log = logging.getLogger(__name__)
48 log = logging.getLogger(__name__)
49
49
50
50
51 class SummaryController(BaseRepoController):
51 class SummaryController(BaseRepoController):
52
52
53 def __before__(self):
53 def __before__(self):
54 super(SummaryController, self).__before__()
54 super(SummaryController, self).__before__()
55
55
56 def __get_readme_data(self, db_repo):
56 def __get_readme_data(self, db_repo):
57 repo_name = db_repo.repo_name
57 repo_name = db_repo.repo_name
58 log.debug('Looking for README file')
58 log.debug('Looking for README file')
59 default_renderer = c.visual.default_renderer
59 default_renderer = c.visual.default_renderer
60
60
61 @cache_region('long_term')
61 @cache_region('long_term')
62 def _generate_readme(cache_key):
62 def _generate_readme(cache_key):
63 readme_data = None
63 readme_data = None
64 readme_file = None
64 readme_file = None
65 try:
65 try:
66 # gets the landing revision or tip if fails
66 # gets the landing revision or tip if fails
67 commit = db_repo.get_landing_commit()
67 commit = db_repo.get_landing_commit()
68 if isinstance(commit, EmptyCommit):
68 if isinstance(commit, EmptyCommit):
69 raise EmptyRepositoryError()
69 raise EmptyRepositoryError()
70 renderer = MarkupRenderer()
70 renderer = MarkupRenderer()
71 for f in renderer.pick_readme_order(default_renderer):
71 for f in renderer.pick_readme_order(default_renderer):
72 try:
72 try:
73 node = commit.get_node(f)
73 node = commit.get_node(f)
74 except NodeDoesNotExistError:
74 except NodeDoesNotExistError:
75 continue
75 continue
76
76
77 if not node.is_file():
77 if not node.is_file():
78 continue
78 continue
79
79
80 readme_file = f
80 readme_file = f
81 log.debug('Found README file `%s` rendering...',
81 log.debug('Found README file `%s` rendering...',
82 readme_file)
82 readme_file)
83 readme_data = renderer.render(node.content,
83 readme_data = renderer.render(node.content,
84 filename=f)
84 filename=f)
85 break
85 break
86 except CommitError:
86 except CommitError:
87 log.exception("Problem getting commit")
87 log.exception("Problem getting commit")
88 pass
88 pass
89 except EmptyRepositoryError:
89 except EmptyRepositoryError:
90 pass
90 pass
91 except Exception:
91 except Exception:
92 log.exception("General failure")
92 log.exception("General failure")
93
93
94 return readme_data, readme_file
94 return readme_data, readme_file
95
95
96 invalidator_context = CacheKey.repo_context_cache(
96 invalidator_context = CacheKey.repo_context_cache(
97 _generate_readme, repo_name, CacheKey.CACHE_TYPE_README)
97 _generate_readme, repo_name, CacheKey.CACHE_TYPE_README)
98
98
99 with invalidator_context as context:
99 with invalidator_context as context:
100 context.invalidate()
100 context.invalidate()
101 computed = context.compute()
101 computed = context.compute()
102
102
103 return computed
103 return computed
104
104
105
105
106 @LoginRequired()
106 @LoginRequired()
107 @HasRepoPermissionAnyDecorator(
107 @HasRepoPermissionAnyDecorator(
108 'repository.read', 'repository.write', 'repository.admin')
108 'repository.read', 'repository.write', 'repository.admin')
109 def index(self, repo_name):
109 def index(self, repo_name):
110 username = ''
110 username = ''
111 if c.rhodecode_user.username != User.DEFAULT_USER:
111 if c.rhodecode_user.username != User.DEFAULT_USER:
112 username = safe_str(c.rhodecode_user.username)
112 username = safe_str(c.rhodecode_user.username)
113
113
114 _def_clone_uri = _def_clone_uri_by_id = c.clone_uri_tmpl
114 _def_clone_uri = _def_clone_uri_by_id = c.clone_uri_tmpl
115 if '{repo}' in _def_clone_uri:
115 if '{repo}' in _def_clone_uri:
116 _def_clone_uri_by_id = _def_clone_uri.replace(
116 _def_clone_uri_by_id = _def_clone_uri.replace(
117 '{repo}', '_{repoid}')
117 '{repo}', '_{repoid}')
118 elif '{repoid}' in _def_clone_uri:
118 elif '{repoid}' in _def_clone_uri:
119 _def_clone_uri_by_id = _def_clone_uri.replace(
119 _def_clone_uri_by_id = _def_clone_uri.replace(
120 '_{repoid}', '{repo}')
120 '_{repoid}', '{repo}')
121
121
122 c.clone_repo_url = c.rhodecode_db_repo.clone_url(
122 c.clone_repo_url = c.rhodecode_db_repo.clone_url(
123 user=username, uri_tmpl=_def_clone_uri)
123 user=username, uri_tmpl=_def_clone_uri)
124 c.clone_repo_url_id = c.rhodecode_db_repo.clone_url(
124 c.clone_repo_url_id = c.rhodecode_db_repo.clone_url(
125 user=username, uri_tmpl=_def_clone_uri_by_id)
125 user=username, uri_tmpl=_def_clone_uri_by_id)
126
126
127 c.show_stats = bool(c.rhodecode_db_repo.enable_statistics)
127 c.show_stats = bool(c.rhodecode_db_repo.enable_statistics)
128
128
129 stats = self.sa.query(Statistics)\
129 stats = self.sa.query(Statistics)\
130 .filter(Statistics.repository == c.rhodecode_db_repo)\
130 .filter(Statistics.repository == c.rhodecode_db_repo)\
131 .scalar()
131 .scalar()
132
132
133 c.stats_percentage = 0
133 c.stats_percentage = 0
134
134
135 if stats and stats.languages:
135 if stats and stats.languages:
136 c.no_data = False is c.rhodecode_db_repo.enable_statistics
136 c.no_data = False is c.rhodecode_db_repo.enable_statistics
137 lang_stats_d = json.loads(stats.languages)
137 lang_stats_d = json.loads(stats.languages)
138
138
139 # Sort first by decreasing count and second by the file extension,
139 # Sort first by decreasing count and second by the file extension,
140 # so we have a consistent output.
140 # so we have a consistent output.
141 lang_stats_items = sorted(lang_stats_d.iteritems(),
141 lang_stats_items = sorted(lang_stats_d.iteritems(),
142 key=lambda k: (-k[1], k[0]))[:10]
142 key=lambda k: (-k[1], k[0]))[:10]
143 lang_stats = [(x, {"count": y,
143 lang_stats = [(x, {"count": y,
144 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
144 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
145 for x, y in lang_stats_items]
145 for x, y in lang_stats_items]
146
146
147 c.trending_languages = json.dumps(lang_stats)
147 c.trending_languages = json.dumps(lang_stats)
148 else:
148 else:
149 c.no_data = True
149 c.no_data = True
150 c.trending_languages = json.dumps({})
150 c.trending_languages = json.dumps({})
151
151
152 c.enable_downloads = c.rhodecode_db_repo.enable_downloads
152 c.enable_downloads = c.rhodecode_db_repo.enable_downloads
153 c.repository_followers = self.scm_model.get_followers(
153 c.repository_followers = self.scm_model.get_followers(
154 c.rhodecode_db_repo)
154 c.rhodecode_db_repo)
155 c.repository_forks = self.scm_model.get_forks(c.rhodecode_db_repo)
155 c.repository_forks = self.scm_model.get_forks(c.rhodecode_db_repo)
156 c.repository_is_user_following = self.scm_model.is_following_repo(
156 c.repository_is_user_following = self.scm_model.is_following_repo(
157 c.repo_name, c.rhodecode_user.user_id)
157 c.repo_name, c.rhodecode_user.user_id)
158
158
159 if c.repository_requirements_missing:
159 if c.repository_requirements_missing:
160 return render('summary/missing_requirements.html')
160 return render('summary/missing_requirements.html')
161
161
162 c.readme_data, c.readme_file = \
162 c.readme_data, c.readme_file = \
163 self.__get_readme_data(c.rhodecode_db_repo)
163 self.__get_readme_data(c.rhodecode_db_repo)
164
164
165 _load_changelog_summary()
165 _load_changelog_summary()
166
166
167 if request.is_xhr:
167 if request.is_xhr:
168 return render('changelog/changelog_summary_data.html')
168 return render('changelog/changelog_summary_data.html')
169
169
170 return render('summary/summary.html')
170 return render('summary/summary.html')
171
171
172 @LoginRequired()
172 @LoginRequired()
173 @XHRRequired()
173 @XHRRequired()
174 @HasRepoPermissionAnyDecorator(
174 @HasRepoPermissionAnyDecorator(
175 'repository.read', 'repository.write', 'repository.admin')
175 'repository.read', 'repository.write', 'repository.admin')
176 @jsonify
176 @jsonify
177 def repo_stats(self, repo_name, commit_id):
177 def repo_stats(self, repo_name, commit_id):
178 _namespace = caches.get_repo_namespace_key(
178 _namespace = caches.get_repo_namespace_key(
179 caches.SUMMARY_STATS, repo_name)
179 caches.SUMMARY_STATS, repo_name)
180 show_stats = bool(c.rhodecode_db_repo.enable_statistics)
180 show_stats = bool(c.rhodecode_db_repo.enable_statistics)
181 cache_manager = caches.get_cache_manager('repo_cache_long', _namespace)
181 cache_manager = caches.get_cache_manager('repo_cache_long', _namespace)
182 _cache_key = caches.compute_key_from_params(
182 _cache_key = caches.compute_key_from_params(
183 repo_name, commit_id, show_stats)
183 repo_name, commit_id, show_stats)
184
184
185 def compute_stats():
185 def compute_stats():
186 code_stats = {}
186 code_stats = {}
187 size = 0
187 size = 0
188 try:
188 try:
189 scm_instance = c.rhodecode_db_repo.scm_instance()
189 scm_instance = c.rhodecode_db_repo.scm_instance()
190 commit = scm_instance.get_commit(commit_id)
190 commit = scm_instance.get_commit(commit_id)
191
191
192 for node in commit.get_filenodes_generator():
192 for node in commit.get_filenodes_generator():
193 size += node.size
193 size += node.size
194 if not show_stats:
194 if not show_stats:
195 continue
195 continue
196 ext = lower(node.extension)
196 ext = lower(node.extension)
197 ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext)
197 ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext)
198 if ext_info:
198 if ext_info:
199 if ext in code_stats:
199 if ext in code_stats:
200 code_stats[ext]['count'] += 1
200 code_stats[ext]['count'] += 1
201 else:
201 else:
202 code_stats[ext] = {"count": 1, "desc": ext_info}
202 code_stats[ext] = {"count": 1, "desc": ext_info}
203 except EmptyRepositoryError:
203 except EmptyRepositoryError:
204 pass
204 pass
205 return {'size': h.format_byte_size_binary(size),
205 return {'size': h.format_byte_size_binary(size),
206 'code_stats': code_stats}
206 'code_stats': code_stats}
207
207
208 stats = cache_manager.get(_cache_key, createfunc=compute_stats)
208 stats = cache_manager.get(_cache_key, createfunc=compute_stats)
209 return stats
209 return stats
210
210
211 def _switcher_reference_data(self, repo_name, references, is_svn):
211 def _switcher_reference_data(self, repo_name, references, is_svn):
212 """Prepare reference data for given `references`"""
212 """Prepare reference data for given `references`"""
213 items = []
213 items = []
214 for name, commit_id in references.items():
214 for name, commit_id in references.items():
215 use_commit_id = '/' in name or is_svn
215 use_commit_id = '/' in name or is_svn
216 items.append({
216 items.append({
217 'name': name,
217 'name': name,
218 'commit_id': commit_id,
218 'commit_id': commit_id,
219 'files_url': h.url(
219 'files_url': h.url(
220 'files_home',
220 'files_home',
221 repo_name=repo_name,
221 repo_name=repo_name,
222 f_path=name if is_svn else '',
222 f_path=name if is_svn else '',
223 revision=commit_id if use_commit_id else name,
223 revision=commit_id if use_commit_id else name,
224 at=name)
224 at=name)
225 })
225 })
226 return items
226 return items
227
227
228 @LoginRequired()
228 @LoginRequired()
229 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
229 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
230 'repository.admin')
230 'repository.admin')
231 @jsonify
231 @jsonify
232 def repo_refs_data(self, repo_name):
232 def repo_refs_data(self, repo_name):
233 repo = c.rhodecode_repo
233 repo = c.rhodecode_repo
234 refs_to_create = [
234 refs_to_create = [
235 (_("Branch"), repo.branches, 'branch'),
235 (_("Branch"), repo.branches, 'branch'),
236 (_("Tag"), repo.tags, 'tag'),
236 (_("Tag"), repo.tags, 'tag'),
237 (_("Bookmark"), repo.bookmarks, 'book'),
237 (_("Bookmark"), repo.bookmarks, 'book'),
238 ]
238 ]
239 res = self._create_reference_data(repo, refs_to_create)
239 res = self._create_reference_data(repo, repo_name, refs_to_create)
240 data = {
240 data = {
241 'more': False,
241 'more': False,
242 'results': res
242 'results': res
243 }
243 }
244 return data
244 return data
245
245
246 @jsonify
246 @jsonify
247 def repo_refs_changelog_data(self, repo_name):
247 def repo_refs_changelog_data(self, repo_name):
248 repo = c.rhodecode_repo
248 repo = c.rhodecode_repo
249
249
250 refs_to_create = [
250 refs_to_create = [
251 (_("Branches"), repo.branches, 'branch'),
251 (_("Branches"), repo.branches, 'branch'),
252 (_("Closed branches"), repo.branches_closed, 'branch_closed'),
252 (_("Closed branches"), repo.branches_closed, 'branch_closed'),
253 # TODO: enable when vcs can handle bookmarks filters
253 # TODO: enable when vcs can handle bookmarks filters
254 # (_("Bookmarks"), repo.bookmarks, "book"),
254 # (_("Bookmarks"), repo.bookmarks, "book"),
255 ]
255 ]
256 res = self._create_reference_data(repo, refs_to_create)
256 res = self._create_reference_data(repo, repo_name, refs_to_create)
257 data = {
257 data = {
258 'more': False,
258 'more': False,
259 'results': res
259 'results': res
260 }
260 }
261 return data
261 return data
262
262
263 def _create_reference_data(self, repo, refs_to_create):
263 def _create_reference_data(self, repo, full_repo_name, refs_to_create):
264 format_ref_id = utils.get_format_ref_id(repo)
264 format_ref_id = utils.get_format_ref_id(repo)
265
265
266 result = []
266 result = []
267 for title, refs, ref_type in refs_to_create:
267 for title, refs, ref_type in refs_to_create:
268 if refs:
268 if refs:
269 result.append({
269 result.append({
270 'text': title,
270 'text': title,
271 'children': self._create_reference_items(
271 'children': self._create_reference_items(
272 repo, refs, ref_type, format_ref_id),
272 repo, full_repo_name, refs, ref_type, format_ref_id),
273 })
273 })
274 return result
274 return result
275
275
276 def _create_reference_items(self, repo, refs, ref_type, format_ref_id):
276 def _create_reference_items(self, repo, full_repo_name, refs, ref_type,
277 format_ref_id):
277 result = []
278 result = []
278 is_svn = h.is_svn(repo)
279 is_svn = h.is_svn(repo)
279 for name, raw_id in refs.iteritems():
280 for ref_name, raw_id in refs.iteritems():
281 files_url = self._create_files_url(
282 repo, full_repo_name, ref_name, raw_id, is_svn)
280 result.append({
283 result.append({
281 'text': name,
284 'text': ref_name,
282 'id': format_ref_id(name, raw_id),
285 'id': format_ref_id(ref_name, raw_id),
283 'raw_id': raw_id,
286 'raw_id': raw_id,
284 'type': ref_type,
287 'type': ref_type,
285 'files_url': self._create_files_url(repo, name, raw_id, is_svn)
288 'files_url': files_url,
286 })
289 })
287 return result
290 return result
288
291
289 def _create_files_url(self, repo, name, raw_id, is_svn):
292 def _create_files_url(self, repo, full_repo_name, ref_name, raw_id,
290 use_commit_id = '/' in name or is_svn
293 is_svn):
294 use_commit_id = '/' in ref_name or is_svn
291 return h.url(
295 return h.url(
292 'files_home',
296 'files_home',
293 repo_name=repo.name,
297 repo_name=full_repo_name,
294 f_path=name if is_svn else '',
298 f_path=ref_name if is_svn else '',
295 revision=raw_id if use_commit_id else name,
299 revision=raw_id if use_commit_id else ref_name,
296 at=name)
300 at=ref_name)
General Comments 0
You need to be logged in to leave comments. Login now