##// END OF EJS Templates
mover verbose logging in readme search function
marcink -
r2633:bc272fd6 beta
parent child Browse files
Show More
@@ -1,244 +1,245 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.summary
3 rhodecode.controllers.summary
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Summary controller for Rhodecode
6 Summary controller for Rhodecode
7
7
8 :created_on: Apr 18, 2010
8 :created_on: Apr 18, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import traceback
26 import traceback
27 import calendar
27 import calendar
28 import logging
28 import logging
29 import urllib
29 import urllib
30 from time import mktime
30 from time import mktime
31 from datetime import timedelta, date
31 from datetime import timedelta, date
32 from urlparse import urlparse
32 from urlparse import urlparse
33 from rhodecode.lib.compat import product
33 from rhodecode.lib.compat import product
34
34
35 from rhodecode.lib.vcs.exceptions import ChangesetError, EmptyRepositoryError, \
35 from rhodecode.lib.vcs.exceptions import ChangesetError, EmptyRepositoryError, \
36 NodeDoesNotExistError
36 NodeDoesNotExistError
37
37
38 from pylons import tmpl_context as c, request, url, config
38 from pylons import tmpl_context as c, request, url, config
39 from pylons.i18n.translation import _
39 from pylons.i18n.translation import _
40
40
41 from beaker.cache import cache_region, region_invalidate
41 from beaker.cache import cache_region, region_invalidate
42
42
43 from rhodecode.config.conf import ALL_READMES, ALL_EXTS, LANGUAGES_EXTENSIONS_MAP
43 from rhodecode.config.conf import ALL_READMES, ALL_EXTS, LANGUAGES_EXTENSIONS_MAP
44 from rhodecode.model.db import Statistics, CacheInvalidation
44 from rhodecode.model.db import Statistics, CacheInvalidation
45 from rhodecode.lib.utils2 import safe_unicode
45 from rhodecode.lib.utils2 import safe_unicode
46 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
46 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
47 from rhodecode.lib.base import BaseRepoController, render
47 from rhodecode.lib.base import BaseRepoController, render
48 from rhodecode.lib.utils import EmptyChangeset
48 from rhodecode.lib.utils import EmptyChangeset
49 from rhodecode.lib.markup_renderer import MarkupRenderer
49 from rhodecode.lib.markup_renderer import MarkupRenderer
50 from rhodecode.lib.celerylib import run_task
50 from rhodecode.lib.celerylib import run_task
51 from rhodecode.lib.celerylib.tasks import get_commits_stats
51 from rhodecode.lib.celerylib.tasks import get_commits_stats
52 from rhodecode.lib.helpers import RepoPage
52 from rhodecode.lib.helpers import RepoPage
53 from rhodecode.lib.compat import json, OrderedDict
53 from rhodecode.lib.compat import json, OrderedDict
54 from rhodecode.lib.vcs.nodes import FileNode
54 from rhodecode.lib.vcs.nodes import FileNode
55
55
56 log = logging.getLogger(__name__)
56 log = logging.getLogger(__name__)
57
57
58 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
58 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
59 sorted(list(product(ALL_READMES, ALL_EXTS)),
59 sorted(list(product(ALL_READMES, ALL_EXTS)),
60 key=lambda y:y[0][1] + y[1][1])]
60 key=lambda y:y[0][1] + y[1][1])]
61
61
62
62
63 class SummaryController(BaseRepoController):
63 class SummaryController(BaseRepoController):
64
64
65 @LoginRequired()
65 @LoginRequired()
66 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
66 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
67 'repository.admin')
67 'repository.admin')
68 def __before__(self):
68 def __before__(self):
69 super(SummaryController, self).__before__()
69 super(SummaryController, self).__before__()
70
70
71 def index(self, repo_name):
71 def index(self, repo_name):
72 c.dbrepo = dbrepo = c.rhodecode_db_repo
72 c.dbrepo = dbrepo = c.rhodecode_db_repo
73 c.following = self.scm_model.is_following_repo(repo_name,
73 c.following = self.scm_model.is_following_repo(repo_name,
74 self.rhodecode_user.user_id)
74 self.rhodecode_user.user_id)
75
75
76 def url_generator(**kw):
76 def url_generator(**kw):
77 return url('shortlog_home', repo_name=repo_name, size=10, **kw)
77 return url('shortlog_home', repo_name=repo_name, size=10, **kw)
78
78
79 c.repo_changesets = RepoPage(c.rhodecode_repo, page=1,
79 c.repo_changesets = RepoPage(c.rhodecode_repo, page=1,
80 items_per_page=10, url=url_generator)
80 items_per_page=10, url=url_generator)
81
81
82 if self.rhodecode_user.username == 'default':
82 if self.rhodecode_user.username == 'default':
83 # for default(anonymous) user we don't need to pass credentials
83 # for default(anonymous) user we don't need to pass credentials
84 username = ''
84 username = ''
85 password = ''
85 password = ''
86 else:
86 else:
87 username = str(self.rhodecode_user.username)
87 username = str(self.rhodecode_user.username)
88 password = '@'
88 password = '@'
89
89
90 parsed_url = urlparse(url.current(qualified=True))
90 parsed_url = urlparse(url.current(qualified=True))
91
91
92 default_clone_uri = '{scheme}://{user}{pass}{netloc}{path}'
92 default_clone_uri = '{scheme}://{user}{pass}{netloc}{path}'
93
93
94 uri_tmpl = config.get('clone_uri', default_clone_uri)
94 uri_tmpl = config.get('clone_uri', default_clone_uri)
95 uri_tmpl = uri_tmpl.replace('{', '%(').replace('}', ')s')
95 uri_tmpl = uri_tmpl.replace('{', '%(').replace('}', ')s')
96 decoded_path = safe_unicode(urllib.unquote(parsed_url.path))
96 decoded_path = safe_unicode(urllib.unquote(parsed_url.path))
97 uri_dict = {
97 uri_dict = {
98 'user': username,
98 'user': username,
99 'pass': password,
99 'pass': password,
100 'scheme': parsed_url.scheme,
100 'scheme': parsed_url.scheme,
101 'netloc': parsed_url.netloc,
101 'netloc': parsed_url.netloc,
102 'path': decoded_path
102 'path': decoded_path
103 }
103 }
104
104
105 uri = uri_tmpl % uri_dict
105 uri = uri_tmpl % uri_dict
106 # generate another clone url by id
106 # generate another clone url by id
107 uri_dict.update(
107 uri_dict.update(
108 {'path': decoded_path.replace(repo_name, '_%s' % c.dbrepo.repo_id)}
108 {'path': decoded_path.replace(repo_name, '_%s' % c.dbrepo.repo_id)}
109 )
109 )
110 uri_id = uri_tmpl % uri_dict
110 uri_id = uri_tmpl % uri_dict
111
111
112 c.clone_repo_url = uri
112 c.clone_repo_url = uri
113 c.clone_repo_url_id = uri_id
113 c.clone_repo_url_id = uri_id
114 c.repo_tags = OrderedDict()
114 c.repo_tags = OrderedDict()
115 for name, hash_ in c.rhodecode_repo.tags.items()[:10]:
115 for name, hash_ in c.rhodecode_repo.tags.items()[:10]:
116 try:
116 try:
117 c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash_)
117 c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash_)
118 except ChangesetError:
118 except ChangesetError:
119 c.repo_tags[name] = EmptyChangeset(hash_)
119 c.repo_tags[name] = EmptyChangeset(hash_)
120
120
121 c.repo_branches = OrderedDict()
121 c.repo_branches = OrderedDict()
122 for name, hash_ in c.rhodecode_repo.branches.items()[:10]:
122 for name, hash_ in c.rhodecode_repo.branches.items()[:10]:
123 try:
123 try:
124 c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash_)
124 c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash_)
125 except ChangesetError:
125 except ChangesetError:
126 c.repo_branches[name] = EmptyChangeset(hash_)
126 c.repo_branches[name] = EmptyChangeset(hash_)
127
127
128 td = date.today() + timedelta(days=1)
128 td = date.today() + timedelta(days=1)
129 td_1m = td - timedelta(days=calendar.mdays[td.month])
129 td_1m = td - timedelta(days=calendar.mdays[td.month])
130 td_1y = td - timedelta(days=365)
130 td_1y = td - timedelta(days=365)
131
131
132 ts_min_m = mktime(td_1m.timetuple())
132 ts_min_m = mktime(td_1m.timetuple())
133 ts_min_y = mktime(td_1y.timetuple())
133 ts_min_y = mktime(td_1y.timetuple())
134 ts_max_y = mktime(td.timetuple())
134 ts_max_y = mktime(td.timetuple())
135
135
136 if dbrepo.enable_statistics:
136 if dbrepo.enable_statistics:
137 c.show_stats = True
137 c.show_stats = True
138 c.no_data_msg = _('No data loaded yet')
138 c.no_data_msg = _('No data loaded yet')
139 run_task(get_commits_stats, c.dbrepo.repo_name, ts_min_y, ts_max_y)
139 run_task(get_commits_stats, c.dbrepo.repo_name, ts_min_y, ts_max_y)
140 else:
140 else:
141 c.show_stats = False
141 c.show_stats = False
142 c.no_data_msg = _('Statistics are disabled for this repository')
142 c.no_data_msg = _('Statistics are disabled for this repository')
143 c.ts_min = ts_min_m
143 c.ts_min = ts_min_m
144 c.ts_max = ts_max_y
144 c.ts_max = ts_max_y
145
145
146 stats = self.sa.query(Statistics)\
146 stats = self.sa.query(Statistics)\
147 .filter(Statistics.repository == dbrepo)\
147 .filter(Statistics.repository == dbrepo)\
148 .scalar()
148 .scalar()
149
149
150 c.stats_percentage = 0
150 c.stats_percentage = 0
151
151
152 if stats and stats.languages:
152 if stats and stats.languages:
153 c.no_data = False is dbrepo.enable_statistics
153 c.no_data = False is dbrepo.enable_statistics
154 lang_stats_d = json.loads(stats.languages)
154 lang_stats_d = json.loads(stats.languages)
155 c.commit_data = stats.commit_activity
155 c.commit_data = stats.commit_activity
156 c.overview_data = stats.commit_activity_combined
156 c.overview_data = stats.commit_activity_combined
157
157
158 lang_stats = ((x, {"count": y,
158 lang_stats = ((x, {"count": y,
159 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
159 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
160 for x, y in lang_stats_d.items())
160 for x, y in lang_stats_d.items())
161
161
162 c.trending_languages = json.dumps(
162 c.trending_languages = json.dumps(
163 sorted(lang_stats, reverse=True, key=lambda k: k[1])[:10]
163 sorted(lang_stats, reverse=True, key=lambda k: k[1])[:10]
164 )
164 )
165 last_rev = stats.stat_on_revision + 1
165 last_rev = stats.stat_on_revision + 1
166 c.repo_last_rev = c.rhodecode_repo.count()\
166 c.repo_last_rev = c.rhodecode_repo.count()\
167 if c.rhodecode_repo.revisions else 0
167 if c.rhodecode_repo.revisions else 0
168 if last_rev == 0 or c.repo_last_rev == 0:
168 if last_rev == 0 or c.repo_last_rev == 0:
169 pass
169 pass
170 else:
170 else:
171 c.stats_percentage = '%.2f' % ((float((last_rev)) /
171 c.stats_percentage = '%.2f' % ((float((last_rev)) /
172 c.repo_last_rev) * 100)
172 c.repo_last_rev) * 100)
173 else:
173 else:
174 c.commit_data = json.dumps({})
174 c.commit_data = json.dumps({})
175 c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]])
175 c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]])
176 c.trending_languages = json.dumps({})
176 c.trending_languages = json.dumps({})
177 c.no_data = True
177 c.no_data = True
178
178
179 c.enable_downloads = dbrepo.enable_downloads
179 c.enable_downloads = dbrepo.enable_downloads
180 if c.enable_downloads:
180 if c.enable_downloads:
181 c.download_options = self._get_download_links(c.rhodecode_repo)
181 c.download_options = self._get_download_links(c.rhodecode_repo)
182
182
183 c.readme_data, c.readme_file = \
183 c.readme_data, c.readme_file = \
184 self.__get_readme_data(c.rhodecode_db_repo)
184 self.__get_readme_data(c.rhodecode_db_repo)
185 return render('summary/summary.html')
185 return render('summary/summary.html')
186
186
187 def __get_readme_data(self, db_repo):
187 def __get_readme_data(self, db_repo):
188 repo_name = db_repo.repo_name
188 repo_name = db_repo.repo_name
189
189
190 @cache_region('long_term')
190 @cache_region('long_term')
191 def _get_readme_from_cache(key):
191 def _get_readme_from_cache(key):
192 readme_data = None
192 readme_data = None
193 readme_file = None
193 readme_file = None
194 log.debug('Fetching readme file')
194 log.debug('Looking for README file')
195 try:
195 try:
196 # get's the landing revision! or tip if fails
196 # get's the landing revision! or tip if fails
197 cs = db_repo.get_landing_changeset()
197 cs = db_repo.get_landing_changeset()
198 renderer = MarkupRenderer()
198 renderer = MarkupRenderer()
199 for f in README_FILES:
199 for f in README_FILES:
200 try:
200 try:
201 readme = cs.get_node(f)
201 readme = cs.get_node(f)
202 if not isinstance(readme, FileNode):
202 if not isinstance(readme, FileNode):
203 continue
203 continue
204 readme_file = f
204 readme_file = f
205 log.debug('Found README file `%s` rendering...' %
206 readme_file)
205 readme_data = renderer.render(readme.content, f)
207 readme_data = renderer.render(readme.content, f)
206 log.debug('Found readme %s' % readme_file)
207 break
208 break
208 except NodeDoesNotExistError:
209 except NodeDoesNotExistError:
209 continue
210 continue
210 except ChangesetError:
211 except ChangesetError:
211 log.error(traceback.format_exc())
212 log.error(traceback.format_exc())
212 pass
213 pass
213 except EmptyRepositoryError:
214 except EmptyRepositoryError:
214 pass
215 pass
215 except Exception:
216 except Exception:
216 log.error(traceback.format_exc())
217 log.error(traceback.format_exc())
217
218
218 return readme_data, readme_file
219 return readme_data, readme_file
219
220
220 key = repo_name + '_README'
221 key = repo_name + '_README'
221 inv = CacheInvalidation.invalidate(key)
222 inv = CacheInvalidation.invalidate(key)
222 if inv is not None:
223 if inv is not None:
223 region_invalidate(_get_readme_from_cache, None, key)
224 region_invalidate(_get_readme_from_cache, None, key)
224 CacheInvalidation.set_valid(inv.cache_key)
225 CacheInvalidation.set_valid(inv.cache_key)
225 return _get_readme_from_cache(key)
226 return _get_readme_from_cache(key)
226
227
227 def _get_download_links(self, repo):
228 def _get_download_links(self, repo):
228
229
229 download_l = []
230 download_l = []
230
231
231 branches_group = ([], _("Branches"))
232 branches_group = ([], _("Branches"))
232 tags_group = ([], _("Tags"))
233 tags_group = ([], _("Tags"))
233
234
234 for name, chs in c.rhodecode_repo.branches.items():
235 for name, chs in c.rhodecode_repo.branches.items():
235 #chs = chs.split(':')[-1]
236 #chs = chs.split(':')[-1]
236 branches_group[0].append((chs, name),)
237 branches_group[0].append((chs, name),)
237 download_l.append(branches_group)
238 download_l.append(branches_group)
238
239
239 for name, chs in c.rhodecode_repo.tags.items():
240 for name, chs in c.rhodecode_repo.tags.items():
240 #chs = chs.split(':')[-1]
241 #chs = chs.split(':')[-1]
241 tags_group[0].append((chs, name),)
242 tags_group[0].append((chs, name),)
242 download_l.append(tags_group)
243 download_l.append(tags_group)
243
244
244 return download_l
245 return download_l
General Comments 0
You need to be logged in to leave comments. Login now