##// END OF EJS Templates
cached-commits: don't update cache on summary page....
dan -
r4161:e6cf946d default
parent child Browse files
Show More
@@ -1,319 +1,314 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2011-2019 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 import logging
22 22 import string
23 23 import time
24 24
25 25 import rhodecode
26 26
27 27 from pyramid.view import view_config
28 28
29 29 from rhodecode.lib.view_utils import get_format_ref_id
30 30 from rhodecode.apps._base import RepoAppView
31 31 from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP)
32 32 from rhodecode.lib import helpers as h, rc_cache
33 33 from rhodecode.lib.utils2 import safe_str, safe_int
34 34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
35 35 from rhodecode.lib.ext_json import json
36 36 from rhodecode.lib.vcs.backends.base import EmptyCommit
37 37 from rhodecode.lib.vcs.exceptions import (
38 38 CommitError, EmptyRepositoryError, CommitDoesNotExistError)
39 39 from rhodecode.model.db import Statistics, CacheKey, User
40 40 from rhodecode.model.meta import Session
41 41 from rhodecode.model.scm import ScmModel
42 42
43 43 log = logging.getLogger(__name__)
44 44
45 45
46 46 class RepoSummaryView(RepoAppView):
47 47
48 48 def load_default_context(self):
49 49 c = self._get_local_tmpl_context(include_app_defaults=True)
50 50 c.rhodecode_repo = None
51 51 if not c.repository_requirements_missing:
52 52 c.rhodecode_repo = self.rhodecode_vcs_repo
53 53 return c
54 54
55 55 def _load_commits_context(self, c):
56 56 p = safe_int(self.request.GET.get('page'), 1)
57 57 size = safe_int(self.request.GET.get('size'), 10)
58 58
59 59 def url_generator(page_num):
60 60 query_params = {
61 61 'page': page_num,
62 62 'size': size
63 63 }
64 64 return h.route_path(
65 65 'repo_summary_commits',
66 66 repo_name=c.rhodecode_db_repo.repo_name, _query=query_params)
67 67
68 68 pre_load = ['author', 'branch', 'date', 'message']
69 69 try:
70 70 collection = self.rhodecode_vcs_repo.get_commits(
71 71 pre_load=pre_load, translate_tags=False)
72 72 except EmptyRepositoryError:
73 73 collection = self.rhodecode_vcs_repo
74 74
75 75 c.repo_commits = h.RepoPage(
76 76 collection, page=p, items_per_page=size, url_maker=url_generator)
77 77 page_ids = [x.raw_id for x in c.repo_commits]
78 78 c.comments = self.db_repo.get_comments(page_ids)
79 79 c.statuses = self.db_repo.statuses(page_ids)
80 80
81 81 def _prepare_and_set_clone_url(self, c):
82 82 username = ''
83 83 if self._rhodecode_user.username != User.DEFAULT_USER:
84 84 username = safe_str(self._rhodecode_user.username)
85 85
86 86 _def_clone_uri = _def_clone_uri_id = c.clone_uri_tmpl
87 87 _def_clone_uri_ssh = c.clone_uri_ssh_tmpl
88 88
89 89 if '{repo}' in _def_clone_uri:
90 90 _def_clone_uri_id = _def_clone_uri.replace('{repo}', '_{repoid}')
91 91 elif '{repoid}' in _def_clone_uri:
92 92 _def_clone_uri_id = _def_clone_uri.replace('_{repoid}', '{repo}')
93 93
94 94 c.clone_repo_url = self.db_repo.clone_url(
95 95 user=username, uri_tmpl=_def_clone_uri)
96 96 c.clone_repo_url_id = self.db_repo.clone_url(
97 97 user=username, uri_tmpl=_def_clone_uri_id)
98 98 c.clone_repo_url_ssh = self.db_repo.clone_url(
99 99 uri_tmpl=_def_clone_uri_ssh, ssh=True)
100 100
101 101 @LoginRequired()
102 102 @HasRepoPermissionAnyDecorator(
103 103 'repository.read', 'repository.write', 'repository.admin')
104 104 @view_config(
105 105 route_name='repo_summary_commits', request_method='GET',
106 106 renderer='rhodecode:templates/summary/summary_commits.mako')
107 107 def summary_commits(self):
108 108 c = self.load_default_context()
109 109 self._prepare_and_set_clone_url(c)
110 110 self._load_commits_context(c)
111 111 return self._get_template_context(c)
112 112
113 113 @LoginRequired()
114 114 @HasRepoPermissionAnyDecorator(
115 115 'repository.read', 'repository.write', 'repository.admin')
116 116 @view_config(
117 117 route_name='repo_summary', request_method='GET',
118 118 renderer='rhodecode:templates/summary/summary.mako')
119 119 @view_config(
120 120 route_name='repo_summary_slash', request_method='GET',
121 121 renderer='rhodecode:templates/summary/summary.mako')
122 122 @view_config(
123 123 route_name='repo_summary_explicit', request_method='GET',
124 124 renderer='rhodecode:templates/summary/summary.mako')
125 125 def summary(self):
126 126 c = self.load_default_context()
127 127
128 128 # Prepare the clone URL
129 129 self._prepare_and_set_clone_url(c)
130 130
131 # update every 5 min
132 if self.db_repo.last_commit_cache_update_diff > 60 * 5:
133 self.db_repo.update_commit_cache()
134
135 131 # If enabled, get statistics data
136
137 132 c.show_stats = bool(self.db_repo.enable_statistics)
138 133
139 134 stats = Session().query(Statistics) \
140 135 .filter(Statistics.repository == self.db_repo) \
141 136 .scalar()
142 137
143 138 c.stats_percentage = 0
144 139
145 140 if stats and stats.languages:
146 141 c.no_data = False is self.db_repo.enable_statistics
147 142 lang_stats_d = json.loads(stats.languages)
148 143
149 144 # Sort first by decreasing count and second by the file extension,
150 145 # so we have a consistent output.
151 146 lang_stats_items = sorted(lang_stats_d.iteritems(),
152 147 key=lambda k: (-k[1], k[0]))[:10]
153 148 lang_stats = [(x, {"count": y,
154 149 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
155 150 for x, y in lang_stats_items]
156 151
157 152 c.trending_languages = json.dumps(lang_stats)
158 153 else:
159 154 c.no_data = True
160 155 c.trending_languages = json.dumps({})
161 156
162 157 scm_model = ScmModel()
163 158 c.enable_downloads = self.db_repo.enable_downloads
164 159 c.repository_followers = scm_model.get_followers(self.db_repo)
165 160 c.repository_forks = scm_model.get_forks(self.db_repo)
166 161
167 162 # first interaction with the VCS instance after here...
168 163 if c.repository_requirements_missing:
169 164 self.request.override_renderer = \
170 165 'rhodecode:templates/summary/missing_requirements.mako'
171 166 return self._get_template_context(c)
172 167
173 168 c.readme_data, c.readme_file = \
174 169 self._get_readme_data(self.db_repo, c.visual.default_renderer)
175 170
176 171 # loads the summary commits template context
177 172 self._load_commits_context(c)
178 173
179 174 return self._get_template_context(c)
180 175
181 176 @LoginRequired()
182 177 @HasRepoPermissionAnyDecorator(
183 178 'repository.read', 'repository.write', 'repository.admin')
184 179 @view_config(
185 180 route_name='repo_stats', request_method='GET',
186 181 renderer='json_ext')
187 182 def repo_stats(self):
188 183 show_stats = bool(self.db_repo.enable_statistics)
189 184 repo_id = self.db_repo.repo_id
190 185
191 186 landing_commit = self.db_repo.get_landing_commit()
192 187 if isinstance(landing_commit, EmptyCommit):
193 188 return {'size': 0, 'code_stats': {}}
194 189
195 190 cache_seconds = safe_int(rhodecode.CONFIG.get('rc_cache.cache_repo.expiration_time'))
196 191 cache_on = cache_seconds > 0
197 192
198 193 log.debug(
199 194 'Computing REPO STATS for repo_id %s commit_id `%s` '
200 195 'with caching: %s[TTL: %ss]' % (
201 196 repo_id, landing_commit, cache_on, cache_seconds or 0))
202 197
203 198 cache_namespace_uid = 'cache_repo.{}'.format(repo_id)
204 199 region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid)
205 200
206 201 @region.conditional_cache_on_arguments(namespace=cache_namespace_uid,
207 202 condition=cache_on)
208 203 def compute_stats(repo_id, commit_id, _show_stats):
209 204 code_stats = {}
210 205 size = 0
211 206 try:
212 207 commit = self.db_repo.get_commit(commit_id)
213 208
214 209 for node in commit.get_filenodes_generator():
215 210 size += node.size
216 211 if not _show_stats:
217 212 continue
218 213 ext = string.lower(node.extension)
219 214 ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext)
220 215 if ext_info:
221 216 if ext in code_stats:
222 217 code_stats[ext]['count'] += 1
223 218 else:
224 219 code_stats[ext] = {"count": 1, "desc": ext_info}
225 220 except (EmptyRepositoryError, CommitDoesNotExistError):
226 221 pass
227 222 return {'size': h.format_byte_size_binary(size),
228 223 'code_stats': code_stats}
229 224
230 225 stats = compute_stats(self.db_repo.repo_id, landing_commit.raw_id, show_stats)
231 226 return stats
232 227
233 228 @LoginRequired()
234 229 @HasRepoPermissionAnyDecorator(
235 230 'repository.read', 'repository.write', 'repository.admin')
236 231 @view_config(
237 232 route_name='repo_refs_data', request_method='GET',
238 233 renderer='json_ext')
239 234 def repo_refs_data(self):
240 235 _ = self.request.translate
241 236 self.load_default_context()
242 237
243 238 repo = self.rhodecode_vcs_repo
244 239 refs_to_create = [
245 240 (_("Branch"), repo.branches, 'branch'),
246 241 (_("Tag"), repo.tags, 'tag'),
247 242 (_("Bookmark"), repo.bookmarks, 'book'),
248 243 ]
249 244 res = self._create_reference_data(repo, self.db_repo_name, refs_to_create)
250 245 data = {
251 246 'more': False,
252 247 'results': res
253 248 }
254 249 return data
255 250
256 251 @LoginRequired()
257 252 @HasRepoPermissionAnyDecorator(
258 253 'repository.read', 'repository.write', 'repository.admin')
259 254 @view_config(
260 255 route_name='repo_refs_changelog_data', request_method='GET',
261 256 renderer='json_ext')
262 257 def repo_refs_changelog_data(self):
263 258 _ = self.request.translate
264 259 self.load_default_context()
265 260
266 261 repo = self.rhodecode_vcs_repo
267 262
268 263 refs_to_create = [
269 264 (_("Branches"), repo.branches, 'branch'),
270 265 (_("Closed branches"), repo.branches_closed, 'branch_closed'),
271 266 # TODO: enable when vcs can handle bookmarks filters
272 267 # (_("Bookmarks"), repo.bookmarks, "book"),
273 268 ]
274 269 res = self._create_reference_data(
275 270 repo, self.db_repo_name, refs_to_create)
276 271 data = {
277 272 'more': False,
278 273 'results': res
279 274 }
280 275 return data
281 276
282 277 def _create_reference_data(self, repo, full_repo_name, refs_to_create):
283 278 format_ref_id = get_format_ref_id(repo)
284 279
285 280 result = []
286 281 for title, refs, ref_type in refs_to_create:
287 282 if refs:
288 283 result.append({
289 284 'text': title,
290 285 'children': self._create_reference_items(
291 286 repo, full_repo_name, refs, ref_type,
292 287 format_ref_id),
293 288 })
294 289 return result
295 290
296 291 def _create_reference_items(self, repo, full_repo_name, refs, ref_type, format_ref_id):
297 292 result = []
298 293 is_svn = h.is_svn(repo)
299 294 for ref_name, raw_id in refs.iteritems():
300 295 files_url = self._create_files_url(
301 296 repo, full_repo_name, ref_name, raw_id, is_svn)
302 297 result.append({
303 298 'text': ref_name,
304 299 'id': format_ref_id(ref_name, raw_id),
305 300 'raw_id': raw_id,
306 301 'type': ref_type,
307 302 'files_url': files_url,
308 303 'idx': 0,
309 304 })
310 305 return result
311 306
312 307 def _create_files_url(self, repo, full_repo_name, ref_name, raw_id, is_svn):
313 308 use_commit_id = '/' in ref_name or is_svn
314 309 return h.route_path(
315 310 'repo_files',
316 311 repo_name=full_repo_name,
317 312 f_path=ref_name if is_svn else '',
318 313 commit_id=raw_id if use_commit_id else ref_name,
319 314 _query=dict(at=ref_name))
General Comments 0
You need to be logged in to leave comments. Login now