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