##// END OF EJS Templates
fixes issue #385 clone by ID url was loosing proxy prefix in URL
marcink -
r2099:e829e844 beta
parent child Browse files
Show More
@@ -1,233 +1,237 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 from time import mktime
30 from time import mktime
30 from datetime import timedelta, date
31 from datetime import timedelta, date
31 from urlparse import urlparse
32 from urlparse import urlparse
32 from rhodecode.lib.compat import product
33 from rhodecode.lib.compat import product
33
34
34 from rhodecode.lib.vcs.exceptions import ChangesetError, EmptyRepositoryError, \
35 from rhodecode.lib.vcs.exceptions import ChangesetError, EmptyRepositoryError, \
35 NodeDoesNotExistError
36 NodeDoesNotExistError
36
37
37 from pylons import tmpl_context as c, request, url, config
38 from pylons import tmpl_context as c, request, url, config
38 from pylons.i18n.translation import _
39 from pylons.i18n.translation import _
39
40
40 from beaker.cache import cache_region, region_invalidate
41 from beaker.cache import cache_region, region_invalidate
41
42
42 from rhodecode.model.db import Statistics, CacheInvalidation
43 from rhodecode.model.db import Statistics, CacheInvalidation
43 from rhodecode.lib import ALL_READMES, ALL_EXTS
44 from rhodecode.lib import ALL_READMES, ALL_EXTS, safe_unicode
44 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
45 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
45 from rhodecode.lib.base import BaseRepoController, render
46 from rhodecode.lib.base import BaseRepoController, render
46 from rhodecode.lib.utils import EmptyChangeset
47 from rhodecode.lib.utils import EmptyChangeset
47 from rhodecode.lib.markup_renderer import MarkupRenderer
48 from rhodecode.lib.markup_renderer import MarkupRenderer
48 from rhodecode.lib.celerylib import run_task
49 from rhodecode.lib.celerylib import run_task
49 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
50 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
50 LANGUAGES_EXTENSIONS_MAP
51 LANGUAGES_EXTENSIONS_MAP
51 from rhodecode.lib.helpers import RepoPage
52 from rhodecode.lib.helpers import RepoPage
52 from rhodecode.lib.compat import json, OrderedDict
53 from rhodecode.lib.compat import json, OrderedDict
53
54
54 log = logging.getLogger(__name__)
55 log = logging.getLogger(__name__)
55
56
56 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
57 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
57 sorted(list(product(ALL_READMES, ALL_EXTS)),
58 sorted(list(product(ALL_READMES, ALL_EXTS)),
58 key=lambda y:y[0][1] + y[1][1])]
59 key=lambda y:y[0][1] + y[1][1])]
59
60
60
61
61 class SummaryController(BaseRepoController):
62 class SummaryController(BaseRepoController):
62
63
63 @LoginRequired()
64 @LoginRequired()
64 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
65 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
65 'repository.admin')
66 'repository.admin')
66 def __before__(self):
67 def __before__(self):
67 super(SummaryController, self).__before__()
68 super(SummaryController, self).__before__()
68
69
69 def index(self, repo_name):
70 def index(self, repo_name):
70 c.dbrepo = dbrepo = c.rhodecode_db_repo
71 c.dbrepo = dbrepo = c.rhodecode_db_repo
71 c.following = self.scm_model.is_following_repo(repo_name,
72 c.following = self.scm_model.is_following_repo(repo_name,
72 self.rhodecode_user.user_id)
73 self.rhodecode_user.user_id)
73
74
74 def url_generator(**kw):
75 def url_generator(**kw):
75 return url('shortlog_home', repo_name=repo_name, size=10, **kw)
76 return url('shortlog_home', repo_name=repo_name, size=10, **kw)
76
77
77 c.repo_changesets = RepoPage(c.rhodecode_repo, page=1,
78 c.repo_changesets = RepoPage(c.rhodecode_repo, page=1,
78 items_per_page=10, url=url_generator)
79 items_per_page=10, url=url_generator)
79
80
80 if self.rhodecode_user.username == 'default':
81 if self.rhodecode_user.username == 'default':
81 # for default(anonymous) user we don't need to pass credentials
82 # for default(anonymous) user we don't need to pass credentials
82 username = ''
83 username = ''
83 password = ''
84 password = ''
84 else:
85 else:
85 username = str(self.rhodecode_user.username)
86 username = str(self.rhodecode_user.username)
86 password = '@'
87 password = '@'
87
88
88 parsed_url = urlparse(url.current(qualified=True))
89 parsed_url = urlparse(url.current(qualified=True))
89
90
90 default_clone_uri = '{scheme}://{user}{pass}{netloc}{path}'
91 default_clone_uri = '{scheme}://{user}{pass}{netloc}{path}'
91
92
92 uri_tmpl = config.get('clone_uri', default_clone_uri)
93 uri_tmpl = config.get('clone_uri', default_clone_uri)
93 uri_tmpl = uri_tmpl.replace('{', '%(').replace('}', ')s')
94 uri_tmpl = uri_tmpl.replace('{', '%(').replace('}', ')s')
94
95 decoded_path = safe_unicode(urllib.unquote(parsed_url.path))
95 uri_dict = {
96 uri_dict = {
96 'user': username,
97 'user': username,
97 'pass': password,
98 'pass': password,
98 'scheme': parsed_url.scheme,
99 'scheme': parsed_url.scheme,
99 'netloc': parsed_url.netloc,
100 'netloc': parsed_url.netloc,
100 'path': parsed_url.path
101 'path': decoded_path
101 }
102 }
103
102 uri = uri_tmpl % uri_dict
104 uri = uri_tmpl % uri_dict
103 # generate another clone url by id
105 # generate another clone url by id
104 uri_dict.update({'path': '/_%s' % c.dbrepo.repo_id})
106 uri_dict.update(
107 {'path': decoded_path.replace(repo_name, '_%s' % c.dbrepo.repo_id)}
108 )
105 uri_id = uri_tmpl % uri_dict
109 uri_id = uri_tmpl % uri_dict
106
110
107 c.clone_repo_url = uri
111 c.clone_repo_url = uri
108 c.clone_repo_url_id = uri_id
112 c.clone_repo_url_id = uri_id
109 c.repo_tags = OrderedDict()
113 c.repo_tags = OrderedDict()
110 for name, hash in c.rhodecode_repo.tags.items()[:10]:
114 for name, hash_ in c.rhodecode_repo.tags.items()[:10]:
111 try:
115 try:
112 c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash)
116 c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash_)
113 except ChangesetError:
117 except ChangesetError:
114 c.repo_tags[name] = EmptyChangeset(hash)
118 c.repo_tags[name] = EmptyChangeset(hash_)
115
119
116 c.repo_branches = OrderedDict()
120 c.repo_branches = OrderedDict()
117 for name, hash in c.rhodecode_repo.branches.items()[:10]:
121 for name, hash_ in c.rhodecode_repo.branches.items()[:10]:
118 try:
122 try:
119 c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash)
123 c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash_)
120 except ChangesetError:
124 except ChangesetError:
121 c.repo_branches[name] = EmptyChangeset(hash)
125 c.repo_branches[name] = EmptyChangeset(hash_)
122
126
123 td = date.today() + timedelta(days=1)
127 td = date.today() + timedelta(days=1)
124 td_1m = td - timedelta(days=calendar.mdays[td.month])
128 td_1m = td - timedelta(days=calendar.mdays[td.month])
125 td_1y = td - timedelta(days=365)
129 td_1y = td - timedelta(days=365)
126
130
127 ts_min_m = mktime(td_1m.timetuple())
131 ts_min_m = mktime(td_1m.timetuple())
128 ts_min_y = mktime(td_1y.timetuple())
132 ts_min_y = mktime(td_1y.timetuple())
129 ts_max_y = mktime(td.timetuple())
133 ts_max_y = mktime(td.timetuple())
130
134
131 if dbrepo.enable_statistics:
135 if dbrepo.enable_statistics:
132 c.show_stats = True
136 c.show_stats = True
133 c.no_data_msg = _('No data loaded yet')
137 c.no_data_msg = _('No data loaded yet')
134 run_task(get_commits_stats, c.dbrepo.repo_name, ts_min_y, ts_max_y)
138 run_task(get_commits_stats, c.dbrepo.repo_name, ts_min_y, ts_max_y)
135 else:
139 else:
136 c.show_stats = False
140 c.show_stats = False
137 c.no_data_msg = _('Statistics are disabled for this repository')
141 c.no_data_msg = _('Statistics are disabled for this repository')
138 c.ts_min = ts_min_m
142 c.ts_min = ts_min_m
139 c.ts_max = ts_max_y
143 c.ts_max = ts_max_y
140
144
141 stats = self.sa.query(Statistics)\
145 stats = self.sa.query(Statistics)\
142 .filter(Statistics.repository == dbrepo)\
146 .filter(Statistics.repository == dbrepo)\
143 .scalar()
147 .scalar()
144
148
145 c.stats_percentage = 0
149 c.stats_percentage = 0
146
150
147 if stats and stats.languages:
151 if stats and stats.languages:
148 c.no_data = False is dbrepo.enable_statistics
152 c.no_data = False is dbrepo.enable_statistics
149 lang_stats_d = json.loads(stats.languages)
153 lang_stats_d = json.loads(stats.languages)
150 c.commit_data = stats.commit_activity
154 c.commit_data = stats.commit_activity
151 c.overview_data = stats.commit_activity_combined
155 c.overview_data = stats.commit_activity_combined
152
156
153 lang_stats = ((x, {"count": y,
157 lang_stats = ((x, {"count": y,
154 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
158 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
155 for x, y in lang_stats_d.items())
159 for x, y in lang_stats_d.items())
156
160
157 c.trending_languages = json.dumps(
161 c.trending_languages = json.dumps(
158 sorted(lang_stats, reverse=True, key=lambda k: k[1])[:10]
162 sorted(lang_stats, reverse=True, key=lambda k: k[1])[:10]
159 )
163 )
160 last_rev = stats.stat_on_revision + 1
164 last_rev = stats.stat_on_revision + 1
161 c.repo_last_rev = c.rhodecode_repo.count()\
165 c.repo_last_rev = c.rhodecode_repo.count()\
162 if c.rhodecode_repo.revisions else 0
166 if c.rhodecode_repo.revisions else 0
163 if last_rev == 0 or c.repo_last_rev == 0:
167 if last_rev == 0 or c.repo_last_rev == 0:
164 pass
168 pass
165 else:
169 else:
166 c.stats_percentage = '%.2f' % ((float((last_rev)) /
170 c.stats_percentage = '%.2f' % ((float((last_rev)) /
167 c.repo_last_rev) * 100)
171 c.repo_last_rev) * 100)
168 else:
172 else:
169 c.commit_data = json.dumps({})
173 c.commit_data = json.dumps({})
170 c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]])
174 c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]])
171 c.trending_languages = json.dumps({})
175 c.trending_languages = json.dumps({})
172 c.no_data = True
176 c.no_data = True
173
177
174 c.enable_downloads = dbrepo.enable_downloads
178 c.enable_downloads = dbrepo.enable_downloads
175 if c.enable_downloads:
179 if c.enable_downloads:
176 c.download_options = self._get_download_links(c.rhodecode_repo)
180 c.download_options = self._get_download_links(c.rhodecode_repo)
177
181
178 c.readme_data, c.readme_file = self.__get_readme_data(c.rhodecode_repo)
182 c.readme_data, c.readme_file = self.__get_readme_data(c.rhodecode_repo)
179 return render('summary/summary.html')
183 return render('summary/summary.html')
180
184
181 def __get_readme_data(self, repo):
185 def __get_readme_data(self, repo):
182
186
183 @cache_region('long_term')
187 @cache_region('long_term')
184 def _get_readme_from_cache(key):
188 def _get_readme_from_cache(key):
185 readme_data = None
189 readme_data = None
186 readme_file = None
190 readme_file = None
187 log.debug('Fetching readme file')
191 log.debug('Fetching readme file')
188 try:
192 try:
189 cs = repo.get_changeset('tip')
193 cs = repo.get_changeset('tip')
190 renderer = MarkupRenderer()
194 renderer = MarkupRenderer()
191 for f in README_FILES:
195 for f in README_FILES:
192 try:
196 try:
193 readme = cs.get_node(f)
197 readme = cs.get_node(f)
194 readme_file = f
198 readme_file = f
195 readme_data = renderer.render(readme.content, f)
199 readme_data = renderer.render(readme.content, f)
196 log.debug('Found readme %s' % readme_file)
200 log.debug('Found readme %s' % readme_file)
197 break
201 break
198 except NodeDoesNotExistError:
202 except NodeDoesNotExistError:
199 continue
203 continue
200 except ChangesetError:
204 except ChangesetError:
201 pass
205 pass
202 except EmptyRepositoryError:
206 except EmptyRepositoryError:
203 pass
207 pass
204 except Exception:
208 except Exception:
205 log.error(traceback.format_exc())
209 log.error(traceback.format_exc())
206
210
207 return readme_data, readme_file
211 return readme_data, readme_file
208
212
209 key = repo.name + '_README'
213 key = repo.name + '_README'
210 inv = CacheInvalidation.invalidate(key)
214 inv = CacheInvalidation.invalidate(key)
211 if inv is not None:
215 if inv is not None:
212 region_invalidate(_get_readme_from_cache, None, key)
216 region_invalidate(_get_readme_from_cache, None, key)
213 CacheInvalidation.set_valid(inv.cache_key)
217 CacheInvalidation.set_valid(inv.cache_key)
214 return _get_readme_from_cache(key)
218 return _get_readme_from_cache(key)
215
219
216 def _get_download_links(self, repo):
220 def _get_download_links(self, repo):
217
221
218 download_l = []
222 download_l = []
219
223
220 branches_group = ([], _("Branches"))
224 branches_group = ([], _("Branches"))
221 tags_group = ([], _("Tags"))
225 tags_group = ([], _("Tags"))
222
226
223 for name, chs in c.rhodecode_repo.branches.items():
227 for name, chs in c.rhodecode_repo.branches.items():
224 #chs = chs.split(':')[-1]
228 #chs = chs.split(':')[-1]
225 branches_group[0].append((chs, name),)
229 branches_group[0].append((chs, name),)
226 download_l.append(branches_group)
230 download_l.append(branches_group)
227
231
228 for name, chs in c.rhodecode_repo.tags.items():
232 for name, chs in c.rhodecode_repo.tags.items():
229 #chs = chs.split(':')[-1]
233 #chs = chs.split(':')[-1]
230 tags_group[0].append((chs, name),)
234 tags_group[0].append((chs, name),)
231 download_l.append(tags_group)
235 download_l.append(tags_group)
232
236
233 return download_l
237 return download_l
General Comments 0
You need to be logged in to leave comments. Login now