##// END OF EJS Templates
added quickstart page for new repos
marcink -
r1736:e2d76554 beta
parent child Browse files
Show More
@@ -1,59 +1,63 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.shortlog
3 rhodecode.controllers.shortlog
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Shortlog controller for rhodecode
6 Shortlog 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) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 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 logging
26 import logging
27
27
28 from pylons import tmpl_context as c, request, url
28 from pylons import tmpl_context as c, request, url
29
29
30 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
30 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
31 from rhodecode.lib.base import BaseRepoController, render
31 from rhodecode.lib.base import BaseRepoController, render
32 from rhodecode.lib.helpers import RepoPage
32 from rhodecode.lib.helpers import RepoPage
33 from pylons.controllers.util import redirect
33
34
34 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
35
36
36
37
37 class ShortlogController(BaseRepoController):
38 class ShortlogController(BaseRepoController):
38
39
39 @LoginRequired()
40 @LoginRequired()
40 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
41 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
41 'repository.admin')
42 'repository.admin')
42 def __before__(self):
43 def __before__(self):
43 super(ShortlogController, self).__before__()
44 super(ShortlogController, self).__before__()
44
45
45 def index(self, repo_name):
46 def index(self, repo_name):
46 p = int(request.params.get('page', 1))
47 p = int(request.params.get('page', 1))
47 size = int(request.params.get('size', 20))
48 size = int(request.params.get('size', 20))
48
49
49 def url_generator(**kw):
50 def url_generator(**kw):
50 return url('shortlog_home', repo_name=repo_name, size=size, **kw)
51 return url('shortlog_home', repo_name=repo_name, size=size, **kw)
51
52
52 c.repo_changesets = RepoPage(c.rhodecode_repo, page=p,
53 c.repo_changesets = RepoPage(c.rhodecode_repo, page=p,
53 items_per_page=size, url=url_generator)
54 items_per_page=size, url=url_generator)
54
55
56 if not c.repo_changesets:
57 return redirect(url('summary_home', repo_name=repo_name))
58
55 c.shortlog_data = render('shortlog/shortlog_data.html')
59 c.shortlog_data = render('shortlog/shortlog_data.html')
56 if request.environ.get('HTTP_X_PARTIAL_XHR'):
60 if request.environ.get('HTTP_X_PARTIAL_XHR'):
57 return c.shortlog_data
61 return c.shortlog_data
58 r = render('shortlog/shortlog.html')
62 r = render('shortlog/shortlog.html')
59 return r
63 return r
@@ -1,231 +1,228 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) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 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 from time import mktime
29 from time import mktime
30 from datetime import timedelta, date
30 from datetime import timedelta, date
31 from itertools import product
31 from itertools import product
32 from urlparse import urlparse
32 from urlparse import urlparse
33
33
34 from vcs.exceptions import ChangesetError, EmptyRepositoryError, \
34 from vcs.exceptions import ChangesetError, EmptyRepositoryError, \
35 NodeDoesNotExistError
35 NodeDoesNotExistError
36
36
37 from pylons import tmpl_context as c, request, url, config
37 from pylons import tmpl_context as c, request, url, config
38 from pylons.i18n.translation import _
38 from pylons.i18n.translation import _
39
39
40 from beaker.cache import cache_region, region_invalidate
40 from beaker.cache import cache_region, region_invalidate
41
41
42 from rhodecode.model.db import Statistics, CacheInvalidation
42 from rhodecode.model.db import Statistics, CacheInvalidation
43 from rhodecode.lib import ALL_READMES, ALL_EXTS
43 from rhodecode.lib import ALL_READMES, ALL_EXTS
44 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
44 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
45 from rhodecode.lib.base import BaseRepoController, render
45 from rhodecode.lib.base import BaseRepoController, render
46 from rhodecode.lib.utils import EmptyChangeset
46 from rhodecode.lib.utils import EmptyChangeset
47 from rhodecode.lib.markup_renderer import MarkupRenderer
47 from rhodecode.lib.markup_renderer import MarkupRenderer
48 from rhodecode.lib.celerylib import run_task
48 from rhodecode.lib.celerylib import run_task
49 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
49 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
50 LANGUAGES_EXTENSIONS_MAP
50 LANGUAGES_EXTENSIONS_MAP
51 from rhodecode.lib.helpers import RepoPage
51 from rhodecode.lib.helpers import RepoPage
52 from rhodecode.lib.compat import json, OrderedDict
52 from rhodecode.lib.compat import json, OrderedDict
53
53
54 log = logging.getLogger(__name__)
54 log = logging.getLogger(__name__)
55
55
56 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
56 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
57 sorted(list(product(ALL_READMES, ALL_EXTS)),
57 sorted(list(product(ALL_READMES, ALL_EXTS)),
58 key=lambda y:y[0][1] + y[1][1])]
58 key=lambda y:y[0][1] + y[1][1])]
59
59
60 class SummaryController(BaseRepoController):
60 class SummaryController(BaseRepoController):
61
61
62 @LoginRequired()
62 @LoginRequired()
63 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
63 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
64 'repository.admin')
64 'repository.admin')
65 def __before__(self):
65 def __before__(self):
66 super(SummaryController, self).__before__()
66 super(SummaryController, self).__before__()
67
67
68 def index(self, repo_name):
68 def index(self, repo_name):
69
70 e = request.environ
71 c.dbrepo = dbrepo = c.rhodecode_db_repo
69 c.dbrepo = dbrepo = c.rhodecode_db_repo
72
73 c.following = self.scm_model.is_following_repo(repo_name,
70 c.following = self.scm_model.is_following_repo(repo_name,
74 self.rhodecode_user.user_id)
71 self.rhodecode_user.user_id)
75
72
76 def url_generator(**kw):
73 def url_generator(**kw):
77 return url('shortlog_home', repo_name=repo_name, size=10, **kw)
74 return url('shortlog_home', repo_name=repo_name, size=10, **kw)
78
75
79 c.repo_changesets = RepoPage(c.rhodecode_repo, page=1,
76 c.repo_changesets = RepoPage(c.rhodecode_repo, page=1,
80 items_per_page=10, url=url_generator)
77 items_per_page=10, url=url_generator)
81
78
82 if self.rhodecode_user.username == 'default':
79 if self.rhodecode_user.username == 'default':
83 # for default(anonymous) user we don't need to pass credentials
80 # for default(anonymous) user we don't need to pass credentials
84 username = ''
81 username = ''
85 password = ''
82 password = ''
86 else:
83 else:
87 username = str(self.rhodecode_user.username)
84 username = str(self.rhodecode_user.username)
88 password = '@'
85 password = '@'
89
86
90 parsed_url = urlparse(url.current(qualified=True))
87 parsed_url = urlparse(url.current(qualified=True))
91
88
92 default_clone_uri = '{scheme}://{user}{pass}{netloc}{path}'
89 default_clone_uri = '{scheme}://{user}{pass}{netloc}{path}'
93
90
94 uri_tmpl = config.get('clone_uri', default_clone_uri)
91 uri_tmpl = config.get('clone_uri', default_clone_uri)
95 uri_tmpl = uri_tmpl.replace('{', '%(').replace('}', ')s')
92 uri_tmpl = uri_tmpl.replace('{', '%(').replace('}', ')s')
96
93
97 uri = uri_tmpl % {'user': username,
94 uri = uri_tmpl % {'user': username,
98 'pass': password,
95 'pass': password,
99 'scheme': parsed_url.scheme,
96 'scheme': parsed_url.scheme,
100 'netloc':parsed_url.netloc,
97 'netloc':parsed_url.netloc,
101 'path':parsed_url.path}
98 'path':parsed_url.path}
102
99
103 c.clone_repo_url = uri
100 c.clone_repo_url = uri
104 c.repo_tags = OrderedDict()
101 c.repo_tags = OrderedDict()
105 for name, hash in c.rhodecode_repo.tags.items()[:10]:
102 for name, hash in c.rhodecode_repo.tags.items()[:10]:
106 try:
103 try:
107 c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash)
104 c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash)
108 except ChangesetError:
105 except ChangesetError:
109 c.repo_tags[name] = EmptyChangeset(hash)
106 c.repo_tags[name] = EmptyChangeset(hash)
110
107
111 c.repo_branches = OrderedDict()
108 c.repo_branches = OrderedDict()
112 for name, hash in c.rhodecode_repo.branches.items()[:10]:
109 for name, hash in c.rhodecode_repo.branches.items()[:10]:
113 try:
110 try:
114 c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash)
111 c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash)
115 except ChangesetError:
112 except ChangesetError:
116 c.repo_branches[name] = EmptyChangeset(hash)
113 c.repo_branches[name] = EmptyChangeset(hash)
117
114
118 td = date.today() + timedelta(days=1)
115 td = date.today() + timedelta(days=1)
119 td_1m = td - timedelta(days=calendar.mdays[td.month])
116 td_1m = td - timedelta(days=calendar.mdays[td.month])
120 td_1y = td - timedelta(days=365)
117 td_1y = td - timedelta(days=365)
121
118
122 ts_min_m = mktime(td_1m.timetuple())
119 ts_min_m = mktime(td_1m.timetuple())
123 ts_min_y = mktime(td_1y.timetuple())
120 ts_min_y = mktime(td_1y.timetuple())
124 ts_max_y = mktime(td.timetuple())
121 ts_max_y = mktime(td.timetuple())
125
122
126 if dbrepo.enable_statistics:
123 if dbrepo.enable_statistics:
127 c.show_stats = True
124 c.show_stats = True
128 c.no_data_msg = _('No data loaded yet')
125 c.no_data_msg = _('No data loaded yet')
129 run_task(get_commits_stats, c.dbrepo.repo_name, ts_min_y, ts_max_y)
126 run_task(get_commits_stats, c.dbrepo.repo_name, ts_min_y, ts_max_y)
130 else:
127 else:
131 c.show_stats = False
128 c.show_stats = False
132 c.no_data_msg = _('Statistics are disabled for this repository')
129 c.no_data_msg = _('Statistics are disabled for this repository')
133 c.ts_min = ts_min_m
130 c.ts_min = ts_min_m
134 c.ts_max = ts_max_y
131 c.ts_max = ts_max_y
135
132
136 stats = self.sa.query(Statistics)\
133 stats = self.sa.query(Statistics)\
137 .filter(Statistics.repository == dbrepo)\
134 .filter(Statistics.repository == dbrepo)\
138 .scalar()
135 .scalar()
139
136
140 c.stats_percentage = 0
137 c.stats_percentage = 0
141
138
142 if stats and stats.languages:
139 if stats and stats.languages:
143 c.no_data = False is dbrepo.enable_statistics
140 c.no_data = False is dbrepo.enable_statistics
144 lang_stats_d = json.loads(stats.languages)
141 lang_stats_d = json.loads(stats.languages)
145 c.commit_data = stats.commit_activity
142 c.commit_data = stats.commit_activity
146 c.overview_data = stats.commit_activity_combined
143 c.overview_data = stats.commit_activity_combined
147
144
148 lang_stats = ((x, {"count": y,
145 lang_stats = ((x, {"count": y,
149 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
146 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
150 for x, y in lang_stats_d.items())
147 for x, y in lang_stats_d.items())
151
148
152 c.trending_languages = json.dumps(OrderedDict(
149 c.trending_languages = json.dumps(OrderedDict(
153 sorted(lang_stats, reverse=True,
150 sorted(lang_stats, reverse=True,
154 key=lambda k: k[1])[:10]
151 key=lambda k: k[1])[:10]
155 )
152 )
156 )
153 )
157 last_rev = stats.stat_on_revision
154 last_rev = stats.stat_on_revision
158 c.repo_last_rev = c.rhodecode_repo.count() - 1 \
155 c.repo_last_rev = c.rhodecode_repo.count() - 1 \
159 if c.rhodecode_repo.revisions else 0
156 if c.rhodecode_repo.revisions else 0
160 if last_rev == 0 or c.repo_last_rev == 0:
157 if last_rev == 0 or c.repo_last_rev == 0:
161 pass
158 pass
162 else:
159 else:
163 c.stats_percentage = '%.2f' % ((float((last_rev)) /
160 c.stats_percentage = '%.2f' % ((float((last_rev)) /
164 c.repo_last_rev) * 100)
161 c.repo_last_rev) * 100)
165 else:
162 else:
166 c.commit_data = json.dumps({})
163 c.commit_data = json.dumps({})
167 c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]])
164 c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]])
168 c.trending_languages = json.dumps({})
165 c.trending_languages = json.dumps({})
169 c.no_data = True
166 c.no_data = True
170
167
171 c.enable_downloads = dbrepo.enable_downloads
168 c.enable_downloads = dbrepo.enable_downloads
172 if c.enable_downloads:
169 if c.enable_downloads:
173 c.download_options = self._get_download_links(c.rhodecode_repo)
170 c.download_options = self._get_download_links(c.rhodecode_repo)
174
171
175 c.readme_data, c.readme_file = self.__get_readme_data(c.rhodecode_repo)
172 c.readme_data, c.readme_file = self.__get_readme_data(c.rhodecode_repo)
176 return render('summary/summary.html')
173 return render('summary/summary.html')
177
174
178 def __get_readme_data(self, repo):
175 def __get_readme_data(self, repo):
179
176
180 @cache_region('long_term')
177 @cache_region('long_term')
181 def _get_readme_from_cache(key):
178 def _get_readme_from_cache(key):
182 readme_data = None
179 readme_data = None
183 readme_file = None
180 readme_file = None
184 log.debug('Fetching readme file')
181 log.debug('Fetching readme file')
185 try:
182 try:
186 cs = repo.get_changeset('tip')
183 cs = repo.get_changeset('tip')
187 renderer = MarkupRenderer()
184 renderer = MarkupRenderer()
188 for f in README_FILES:
185 for f in README_FILES:
189 try:
186 try:
190 readme = cs.get_node(f)
187 readme = cs.get_node(f)
191 readme_file = f
188 readme_file = f
192 readme_data = renderer.render(readme.content, f)
189 readme_data = renderer.render(readme.content, f)
193 log.debug('Found readme %s' % readme_file)
190 log.debug('Found readme %s' % readme_file)
194 break
191 break
195 except NodeDoesNotExistError:
192 except NodeDoesNotExistError:
196 continue
193 continue
197 except ChangesetError:
194 except ChangesetError:
198 pass
195 pass
199 except EmptyRepositoryError:
196 except EmptyRepositoryError:
200 pass
197 pass
201 except Exception:
198 except Exception:
202 log.error(traceback.format_exc())
199 log.error(traceback.format_exc())
203
200
204 return readme_data, readme_file
201 return readme_data, readme_file
205
202
206 key = repo.name + '_README'
203 key = repo.name + '_README'
207 inv = CacheInvalidation.invalidate(key)
204 inv = CacheInvalidation.invalidate(key)
208 if inv is not None:
205 if inv is not None:
209 region_invalidate(_get_readme_from_cache, None, key)
206 region_invalidate(_get_readme_from_cache, None, key)
210 CacheInvalidation.set_valid(inv.cache_key)
207 CacheInvalidation.set_valid(inv.cache_key)
211 return _get_readme_from_cache(key)
208 return _get_readme_from_cache(key)
212
209
213 def _get_download_links(self, repo):
210 def _get_download_links(self, repo):
214
211
215 download_l = []
212 download_l = []
216
213
217 branches_group = ([], _("Branches"))
214 branches_group = ([], _("Branches"))
218 tags_group = ([], _("Tags"))
215 tags_group = ([], _("Tags"))
219
216
220 for name, chs in c.rhodecode_repo.branches.items():
217 for name, chs in c.rhodecode_repo.branches.items():
221 #chs = chs.split(':')[-1]
218 #chs = chs.split(':')[-1]
222 branches_group[0].append((chs, name),)
219 branches_group[0].append((chs, name),)
223 download_l.append(branches_group)
220 download_l.append(branches_group)
224
221
225 for name, chs in c.rhodecode_repo.tags.items():
222 for name, chs in c.rhodecode_repo.tags.items():
226 #chs = chs.split(':')[-1]
223 #chs = chs.split(':')[-1]
227 tags_group[0].append((chs, name),)
224 tags_group[0].append((chs, name),)
228 download_l.append(tags_group)
225 download_l.append(tags_group)
229
226
230 return download_l
227 return download_l
231
228
@@ -1,62 +1,84 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 % if c.repo_changesets:
2 %if c.repo_changesets:
3 <table>
3 <table>
4 <tr>
4 <tr>
5 <th class="left">${_('commit message')}</th>
5 <th class="left">${_('commit message')}</th>
6 <th class="left">${_('age')}</th>
6 <th class="left">${_('age')}</th>
7 <th class="left">${_('author')}</th>
7 <th class="left">${_('author')}</th>
8 <th class="left">${_('revision')}</th>
8 <th class="left">${_('revision')}</th>
9 <th class="left">${_('branch')}</th>
9 <th class="left">${_('branch')}</th>
10 <th class="left">${_('tags')}</th>
10 <th class="left">${_('tags')}</th>
11 <th class="left">${_('links')}</th>
11 <th class="left">${_('links')}</th>
12
12
13 </tr>
13 </tr>
14 %for cnt,cs in enumerate(c.repo_changesets):
14 %for cnt,cs in enumerate(c.repo_changesets):
15 <tr class="parity${cnt%2}">
15 <tr class="parity${cnt%2}">
16 <td>
16 <td>
17 ${h.link_to(h.truncate(cs.message,50),
17 ${h.link_to(h.truncate(cs.message,50),
18 h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id),
18 h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id),
19 title=cs.message)}
19 title=cs.message)}
20 </td>
20 </td>
21 <td><span class="tooltip" title="${cs.date}">
21 <td><span class="tooltip" title="${cs.date}">
22 ${h.age(cs.date)}</span>
22 ${h.age(cs.date)}</span>
23 </td>
23 </td>
24 <td title="${cs.author}">${h.person(cs.author)}</td>
24 <td title="${cs.author}">${h.person(cs.author)}</td>
25 <td>r${cs.revision}:${h.short_id(cs.raw_id)}</td>
25 <td>r${cs.revision}:${h.short_id(cs.raw_id)}</td>
26 <td>
26 <td>
27 <span class="logtags">
27 <span class="logtags">
28 <span class="branchtag">${cs.branch}</span>
28 <span class="branchtag">${cs.branch}</span>
29 </span>
29 </span>
30 </td>
30 </td>
31 <td>
31 <td>
32 <span class="logtags">
32 <span class="logtags">
33 %for tag in cs.tags:
33 %for tag in cs.tags:
34 <span class="tagtag">${tag}</span>
34 <span class="tagtag">${tag}</span>
35 %endfor
35 %endfor
36 </span>
36 </span>
37 </td>
37 </td>
38 <td class="nowrap">
38 <td class="nowrap">
39 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id),class_="ui-button-small xsmall")}
39 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id),class_="ui-button-small xsmall")}
40 <span style="color:#515151">|</span>
40 <span style="color:#515151">|</span>
41 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id),class_="ui-button-small xsmall")}
41 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id),class_="ui-button-small xsmall")}
42 </td>
42 </td>
43 </tr>
43 </tr>
44 %endfor
44 %endfor
45
45
46 </table>
46 </table>
47
47
48 <script type="text/javascript">
48 <script type="text/javascript">
49 YUE.onDOMReady(function(){
49 YUE.onDOMReady(function(){
50 YUE.delegate("shortlog_data","click",function(e, matchedEl, container){
50 YUE.delegate("shortlog_data","click",function(e, matchedEl, container){
51 ypjax(e.target.href,"shortlog_data",function(){tooltip_activate();});
51 ypjax(e.target.href,"shortlog_data",function(){tooltip_activate();});
52 YUE.preventDefault(e);
52 YUE.preventDefault(e);
53 },'.pager_link');
53 },'.pager_link');
54 });
54 });
55 </script>
55 </script>
56
56
57 <div class="pagination-wh pagination-left">
57 <div class="pagination-wh pagination-left">
58 ${c.repo_changesets.pager('$link_previous ~2~ $link_next')}
58 ${c.repo_changesets.pager('$link_previous ~2~ $link_next')}
59 </div>
59 </div>
60 %else:
60 %else:
61 ${_('There are no changes yet')}
61
62 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name):
63 <h4>${_('Add or upload files directly via RhodeCode')}</h4>
64 <div style="margin: 20px 30px;">
65 <div id="add_node_id" class="add_node">
66 <a class="ui-button-small" href="${h.url('files_add_home',repo_name=c.repo_name,revision=0,f_path='')}">${_('add new file')}</a>
67 </div>
68 </div>
62 %endif
69 %endif
70
71
72 <h4>${_('Push new repo')}</h4>
73 <pre>
74 hg clone ${c.clone_repo_url}
75 hg add README # add first file
76 hg commit -m "Initial" # commit with message
77 hg push # push changes back
78 </pre>
79
80 <h4>${_('Existing repository?')}</h4>
81 <pre>
82 hg push ${c.clone_repo_url}
83 </pre>
84 %endif
@@ -1,683 +1,689 b''
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${c.repo_name} ${_('Summary')} - ${c.rhodecode_name}
4 ${c.repo_name} ${_('Summary')} - ${c.rhodecode_name}
5 </%def>
5 </%def>
6
6
7 <%def name="breadcrumbs_links()">
7 <%def name="breadcrumbs_links()">
8 ${h.link_to(u'Home',h.url('/'))}
8 ${h.link_to(u'Home',h.url('/'))}
9 &raquo;
9 &raquo;
10 ${h.link_to(c.dbrepo.just_name,h.url('summary_home',repo_name=c.repo_name))}
10 ${h.link_to(c.dbrepo.just_name,h.url('summary_home',repo_name=c.repo_name))}
11 &raquo;
11 &raquo;
12 ${_('summary')}
12 ${_('summary')}
13 </%def>
13 </%def>
14
14
15 <%def name="page_nav()">
15 <%def name="page_nav()">
16 ${self.menu('summary')}
16 ${self.menu('summary')}
17 </%def>
17 </%def>
18
18
19 <%def name="main()">
19 <%def name="main()">
20 <%
20 <%
21 summary = lambda n:{False:'summary-short'}.get(n)
21 summary = lambda n:{False:'summary-short'}.get(n)
22 %>
22 %>
23 %if c.show_stats:
23 %if c.show_stats:
24 <div class="box box-left">
24 <div class="box box-left">
25 %else:
25 %else:
26 <div class="box">
26 <div class="box">
27 %endif
27 %endif
28 <!-- box / title -->
28 <!-- box / title -->
29 <div class="title">
29 <div class="title">
30 ${self.breadcrumbs()}
30 ${self.breadcrumbs()}
31 </div>
31 </div>
32 <!-- end box / title -->
32 <!-- end box / title -->
33 <div class="form">
33 <div class="form">
34 <div id="summary" class="fields">
34 <div id="summary" class="fields">
35
35
36 <div class="field">
36 <div class="field">
37 <div class="label-summary">
37 <div class="label-summary">
38 <label>${_('Name')}:</label>
38 <label>${_('Name')}:</label>
39 </div>
39 </div>
40 <div class="input ${summary(c.show_stats)}">
40 <div class="input ${summary(c.show_stats)}">
41 <div style="float:right;padding:5px 0px 0px 5px">
41 <div style="float:right;padding:5px 0px 0px 5px">
42 %if c.rhodecode_user.username != 'default':
42 %if c.rhodecode_user.username != 'default':
43 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='rss_icon')}
43 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='rss_icon')}
44 ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='atom_icon')}
44 ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='atom_icon')}
45 %else:
45 %else:
46 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.dbrepo.repo_name),class_='rss_icon')}
46 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.dbrepo.repo_name),class_='rss_icon')}
47 ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name),class_='atom_icon')}
47 ${h.link_to(_('ATOM'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name),class_='atom_icon')}
48 %endif
48 %endif
49 </div>
49 </div>
50 %if c.rhodecode_user.username != 'default':
50 %if c.rhodecode_user.username != 'default':
51 %if c.following:
51 %if c.following:
52 <span id="follow_toggle" class="following" title="${_('Stop following this repository')}"
52 <span id="follow_toggle" class="following" title="${_('Stop following this repository')}"
53 onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
53 onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
54 </span>
54 </span>
55 %else:
55 %else:
56 <span id="follow_toggle" class="follow" title="${_('Start following this repository')}"
56 <span id="follow_toggle" class="follow" title="${_('Start following this repository')}"
57 onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
57 onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
58 </span>
58 </span>
59 %endif
59 %endif
60 %endif:
60 %endif:
61 ##REPO TYPE
61 ##REPO TYPE
62 %if c.dbrepo.repo_type =='hg':
62 %if c.dbrepo.repo_type =='hg':
63 <img style="margin-bottom:2px" class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
63 <img style="margin-bottom:2px" class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
64 %endif
64 %endif
65 %if c.dbrepo.repo_type =='git':
65 %if c.dbrepo.repo_type =='git':
66 <img style="margin-bottom:2px" class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
66 <img style="margin-bottom:2px" class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
67 %endif
67 %endif
68
68
69 ##PUBLIC/PRIVATE
69 ##PUBLIC/PRIVATE
70 %if c.dbrepo.private:
70 %if c.dbrepo.private:
71 <img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
71 <img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
72 %else:
72 %else:
73 <img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
73 <img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
74 %endif
74 %endif
75
75
76 ##REPO NAME
76 ##REPO NAME
77 <span class="repo_name">${h.repo_link(c.dbrepo.groups_and_repo)}</span>
77 <span class="repo_name">${h.repo_link(c.dbrepo.groups_and_repo)}</span>
78
78
79 ##FORK
79 ##FORK
80 %if c.dbrepo.fork:
80 %if c.dbrepo.fork:
81 <div style="margin-top:5px;clear:both"">
81 <div style="margin-top:5px;clear:both"">
82 <a href="${h.url('summary_home',repo_name=c.dbrepo.fork.repo_name)}"><img class="icon" alt="${_('public')}" title="${_('Fork of')} ${c.dbrepo.fork.repo_name}" src="${h.url('/images/icons/arrow_divide.png')}"/>
82 <a href="${h.url('summary_home',repo_name=c.dbrepo.fork.repo_name)}"><img class="icon" alt="${_('public')}" title="${_('Fork of')} ${c.dbrepo.fork.repo_name}" src="${h.url('/images/icons/arrow_divide.png')}"/>
83 ${_('Fork of')} ${c.dbrepo.fork.repo_name}
83 ${_('Fork of')} ${c.dbrepo.fork.repo_name}
84 </a>
84 </a>
85 </div>
85 </div>
86 %endif
86 %endif
87 ##REMOTE
87 ##REMOTE
88 %if c.dbrepo.clone_uri:
88 %if c.dbrepo.clone_uri:
89 <div style="margin-top:5px;clear:both">
89 <div style="margin-top:5px;clear:both">
90 <a href="${h.url(str(h.hide_credentials(c.dbrepo.clone_uri)))}"><img class="icon" alt="${_('remote clone')}" title="${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}" src="${h.url('/images/icons/connect.png')}"/>
90 <a href="${h.url(str(h.hide_credentials(c.dbrepo.clone_uri)))}"><img class="icon" alt="${_('remote clone')}" title="${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}" src="${h.url('/images/icons/connect.png')}"/>
91 ${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}
91 ${_('Clone from')} ${h.hide_credentials(c.dbrepo.clone_uri)}
92 </a>
92 </a>
93 </div>
93 </div>
94 %endif
94 %endif
95 </div>
95 </div>
96 </div>
96 </div>
97
97
98 <div class="field">
98 <div class="field">
99 <div class="label-summary">
99 <div class="label-summary">
100 <label>${_('Description')}:</label>
100 <label>${_('Description')}:</label>
101 </div>
101 </div>
102 <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(c.dbrepo.description)}</div>
102 <div class="input ${summary(c.show_stats)} desc">${h.urlify_text(c.dbrepo.description)}</div>
103 </div>
103 </div>
104
104
105 <div class="field">
105 <div class="field">
106 <div class="label-summary">
106 <div class="label-summary">
107 <label>${_('Contact')}:</label>
107 <label>${_('Contact')}:</label>
108 </div>
108 </div>
109 <div class="input ${summary(c.show_stats)}">
109 <div class="input ${summary(c.show_stats)}">
110 <div class="gravatar">
110 <div class="gravatar">
111 <img alt="gravatar" src="${h.gravatar_url(c.dbrepo.user.email)}"/>
111 <img alt="gravatar" src="${h.gravatar_url(c.dbrepo.user.email)}"/>
112 </div>
112 </div>
113 ${_('Username')}: ${c.dbrepo.user.username}<br/>
113 ${_('Username')}: ${c.dbrepo.user.username}<br/>
114 ${_('Name')}: ${c.dbrepo.user.name} ${c.dbrepo.user.lastname}<br/>
114 ${_('Name')}: ${c.dbrepo.user.name} ${c.dbrepo.user.lastname}<br/>
115 ${_('Email')}: <a href="mailto:${c.dbrepo.user.email}">${c.dbrepo.user.email}</a>
115 ${_('Email')}: <a href="mailto:${c.dbrepo.user.email}">${c.dbrepo.user.email}</a>
116 </div>
116 </div>
117 </div>
117 </div>
118
118
119 <div class="field">
119 <div class="field">
120 <div class="label-summary">
120 <div class="label-summary">
121 <label>${_('Last change')}:</label>
121 <label>${_('Last change')}:</label>
122 </div>
122 </div>
123 <div class="input ${summary(c.show_stats)}">
123 <div class="input ${summary(c.show_stats)}">
124 <b>${'r%s:%s' % (h.get_changeset_safe(c.rhodecode_repo,'tip').revision,
124 <b>${'r%s:%s' % (h.get_changeset_safe(c.rhodecode_repo,'tip').revision,
125 h.get_changeset_safe(c.rhodecode_repo,'tip').short_id)}</b> -
125 h.get_changeset_safe(c.rhodecode_repo,'tip').short_id)}</b> -
126 <span class="tooltip" title="${c.rhodecode_repo.last_change}">
126 <span class="tooltip" title="${c.rhodecode_repo.last_change}">
127 ${h.age(c.rhodecode_repo.last_change)}</span>
127 ${h.age(c.rhodecode_repo.last_change)}</span>
128 ${_('by')} ${h.get_changeset_safe(c.rhodecode_repo,'tip').author}
128 ${_('by')} ${h.get_changeset_safe(c.rhodecode_repo,'tip').author}
129 </div>
129 </div>
130 </div>
130 </div>
131
131
132 <div class="field">
132 <div class="field">
133 <div class="label-summary">
133 <div class="label-summary">
134 <label>${_('Clone url')}:</label>
134 <label>${_('Clone url')}:</label>
135 </div>
135 </div>
136 <div class="input ${summary(c.show_stats)}">
136 <div class="input ${summary(c.show_stats)}">
137 <input type="text" id="clone_url" readonly="readonly" value="${c.rhodecode_repo.alias} clone ${c.clone_repo_url}" size="70"/>
137 <input type="text" id="clone_url" readonly="readonly" value="${c.rhodecode_repo.alias} clone ${c.clone_repo_url}" size="70"/>
138 </div>
138 </div>
139 </div>
139 </div>
140
140
141 <div class="field">
141 <div class="field">
142 <div class="label-summary">
142 <div class="label-summary">
143 <label>${_('Trending files')}:</label>
143 <label>${_('Trending files')}:</label>
144 </div>
144 </div>
145 <div class="input ${summary(c.show_stats)}">
145 <div class="input ${summary(c.show_stats)}">
146 %if c.show_stats:
146 %if c.show_stats:
147 <div id="lang_stats"></div>
147 <div id="lang_stats"></div>
148 %else:
148 %else:
149 ${_('Statistics are disabled for this repository')}
149 ${_('Statistics are disabled for this repository')}
150 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
150 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
151 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-button-small")}
151 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-button-small")}
152 %endif
152 %endif
153 %endif
153 %endif
154 </div>
154 </div>
155 </div>
155 </div>
156
156
157 <div class="field">
157 <div class="field">
158 <div class="label-summary">
158 <div class="label-summary">
159 <label>${_('Download')}:</label>
159 <label>${_('Download')}:</label>
160 </div>
160 </div>
161 <div class="input ${summary(c.show_stats)}">
161 <div class="input ${summary(c.show_stats)}">
162 %if len(c.rhodecode_repo.revisions) == 0:
162 %if len(c.rhodecode_repo.revisions) == 0:
163 ${_('There are no downloads yet')}
163 ${_('There are no downloads yet')}
164 %elif c.enable_downloads is False:
164 %elif c.enable_downloads is False:
165 ${_('Downloads are disabled for this repository')}
165 ${_('Downloads are disabled for this repository')}
166 %if h.HasPermissionAll('hg.admin')('enable downloads on from summary'):
166 %if h.HasPermissionAll('hg.admin')('enable downloads on from summary'):
167 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-button-small")}
167 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-button-small")}
168 %endif
168 %endif
169 %else:
169 %else:
170 ${h.select('download_options',c.rhodecode_repo.get_changeset().raw_id,c.download_options)}
170 ${h.select('download_options',c.rhodecode_repo.get_changeset().raw_id,c.download_options)}
171 %for cnt,archive in enumerate(c.rhodecode_repo._get_archives()):
171 %for cnt,archive in enumerate(c.rhodecode_repo._get_archives()):
172 %if cnt >=1:
172 %if cnt >=1:
173 |
173 |
174 %endif
174 %endif
175 <span class="tooltip" title="${_('Download %s as %s') %('tip',archive['type'])}"
175 <span class="tooltip" title="${_('Download %s as %s') %('tip',archive['type'])}"
176 id="${archive['type']+'_link'}">${h.link_to(archive['type'],
176 id="${archive['type']+'_link'}">${h.link_to(archive['type'],
177 h.url('files_archive_home',repo_name=c.dbrepo.repo_name,
177 h.url('files_archive_home',repo_name=c.dbrepo.repo_name,
178 fname='tip'+archive['extension']),class_="archive_icon")}</span>
178 fname='tip'+archive['extension']),class_="archive_icon")}</span>
179 %endfor
179 %endfor
180 <span style="vertical-align: bottom">
180 <span style="vertical-align: bottom">
181 <input id="archive_subrepos" type="checkbox" name="subrepos"/> <span class="tooltip" title="${_('Check this to download archive with subrepos')}" >${_('with subrepos')}</span>
181 <input id="archive_subrepos" type="checkbox" name="subrepos"/> <span class="tooltip" title="${_('Check this to download archive with subrepos')}" >${_('with subrepos')}</span>
182 </span>
182 </span>
183 %endif
183 %endif
184 </div>
184 </div>
185 </div>
185 </div>
186 </div>
186 </div>
187 </div>
187 </div>
188 </div>
188 </div>
189
189
190 %if c.show_stats:
190 %if c.show_stats:
191 <div class="box box-right" style="min-height:455px">
191 <div class="box box-right" style="min-height:455px">
192 <!-- box / title -->
192 <!-- box / title -->
193 <div class="title">
193 <div class="title">
194 <h5>${_('Commit activity by day / author')}</h5>
194 <h5>${_('Commit activity by day / author')}</h5>
195 </div>
195 </div>
196
196
197 <div class="graph">
197 <div class="graph">
198 <div style="padding:0 10px 10px 15px;font-size: 1.2em;">
198 <div style="padding:0 10px 10px 15px;font-size: 1.2em;">
199 %if c.no_data:
199 %if c.no_data:
200 ${c.no_data_msg}
200 ${c.no_data_msg}
201 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
201 %if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
202 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-button-small")}
202 ${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name),class_="ui-button-small")}
203 %endif
203 %endif
204 %else:
204 %else:
205 ${_('Loaded in')} ${c.stats_percentage} %
205 ${_('Loaded in')} ${c.stats_percentage} %
206 %endif
206 %endif
207 </div>
207 </div>
208 <div id="commit_history" style="width:450px;height:300px;float:left"></div>
208 <div id="commit_history" style="width:450px;height:300px;float:left"></div>
209 <div style="clear: both;height: 10px"></div>
209 <div style="clear: both;height: 10px"></div>
210 <div id="overview" style="width:450px;height:100px;float:left"></div>
210 <div id="overview" style="width:450px;height:100px;float:left"></div>
211
211
212 <div id="legend_data" style="clear:both;margin-top:10px;">
212 <div id="legend_data" style="clear:both;margin-top:10px;">
213 <div id="legend_container"></div>
213 <div id="legend_container"></div>
214 <div id="legend_choices">
214 <div id="legend_choices">
215 <table id="legend_choices_tables" class="noborder" style="font-size:smaller;color:#545454"></table>
215 <table id="legend_choices_tables" class="noborder" style="font-size:smaller;color:#545454"></table>
216 </div>
216 </div>
217 </div>
217 </div>
218 </div>
218 </div>
219 </div>
219 </div>
220 %endif
220 %endif
221
221
222 <div class="box">
222 <div class="box">
223 <div class="title">
223 <div class="title">
224 <div class="breadcrumbs">${h.link_to(_('Shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}</div>
224 <div class="breadcrumbs">
225 %if c.repo_changesets:
226 ${h.link_to(_('Shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}
227 %else:
228 ${_('Quick start')}
229 %endif
230 </div>
225 </div>
231 </div>
226 <div class="table">
232 <div class="table">
227 <div id="shortlog_data">
233 <div id="shortlog_data">
228 <%include file='../shortlog/shortlog_data.html'/>
234 <%include file='../shortlog/shortlog_data.html'/>
229 </div>
235 </div>
230 </div>
236 </div>
231 </div>
237 </div>
232
238
233 %if c.readme_data:
239 %if c.readme_data:
234 <div class="box" style="background-color: #FAFAFA">
240 <div class="box" style="background-color: #FAFAFA">
235 <div class="title">
241 <div class="title">
236 <div class="breadcrumbs"><a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a></div>
242 <div class="breadcrumbs"><a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a></div>
237 </div>
243 </div>
238 <div class="readme">
244 <div class="readme">
239 <div class="readme_box">
245 <div class="readme_box">
240 ${c.readme_data|n}
246 ${c.readme_data|n}
241 </div>
247 </div>
242 </div>
248 </div>
243 </div>
249 </div>
244 %endif
250 %endif
245
251
246 <script type="text/javascript">
252 <script type="text/javascript">
247 var clone_url = 'clone_url';
253 var clone_url = 'clone_url';
248 YUE.on(clone_url,'click',function(e){
254 YUE.on(clone_url,'click',function(e){
249 if(YUD.hasClass(clone_url,'selected')){
255 if(YUD.hasClass(clone_url,'selected')){
250 return
256 return
251 }
257 }
252 else{
258 else{
253 YUD.addClass(clone_url,'selected');
259 YUD.addClass(clone_url,'selected');
254 YUD.get(clone_url).select();
260 YUD.get(clone_url).select();
255 }
261 }
256 })
262 })
257
263
258 var tmpl_links = {};
264 var tmpl_links = {};
259 %for cnt,archive in enumerate(c.rhodecode_repo._get_archives()):
265 %for cnt,archive in enumerate(c.rhodecode_repo._get_archives()):
260 tmpl_links['${archive['type']}'] = '${h.link_to(archive['type'],
266 tmpl_links['${archive['type']}'] = '${h.link_to(archive['type'],
261 h.url('files_archive_home',repo_name=c.dbrepo.repo_name,
267 h.url('files_archive_home',repo_name=c.dbrepo.repo_name,
262 fname='__CS__'+archive['extension'],subrepos='__SUB__'),class_="archive_icon")}';
268 fname='__CS__'+archive['extension'],subrepos='__SUB__'),class_="archive_icon")}';
263 %endfor
269 %endfor
264
270
265 YUE.on(['download_options','archive_subrepos'],'change',function(e){
271 YUE.on(['download_options','archive_subrepos'],'change',function(e){
266 var sm = YUD.get('download_options');
272 var sm = YUD.get('download_options');
267 var new_cs = sm.options[sm.selectedIndex];
273 var new_cs = sm.options[sm.selectedIndex];
268
274
269 for(k in tmpl_links){
275 for(k in tmpl_links){
270 var s = YUD.get(k+'_link');
276 var s = YUD.get(k+'_link');
271 title_tmpl = "${_('Download %s as %s') % ('__CS_NAME__','__CS_EXT__')}";
277 title_tmpl = "${_('Download %s as %s') % ('__CS_NAME__','__CS_EXT__')}";
272 s.title = title_tmpl.replace('__CS_NAME__',new_cs.text);
278 s.title = title_tmpl.replace('__CS_NAME__',new_cs.text);
273 s.title = s.title.replace('__CS_EXT__',k);
279 s.title = s.title.replace('__CS_EXT__',k);
274 var url = tmpl_links[k].replace('__CS__',new_cs.value);
280 var url = tmpl_links[k].replace('__CS__',new_cs.value);
275 var subrepos = YUD.get('archive_subrepos').checked
281 var subrepos = YUD.get('archive_subrepos').checked
276 url = url.replace('__SUB__',subrepos);
282 url = url.replace('__SUB__',subrepos);
277 s.innerHTML = url
283 s.innerHTML = url
278 }
284 }
279 });
285 });
280 </script>
286 </script>
281 %if c.show_stats:
287 %if c.show_stats:
282 <script type="text/javascript">
288 <script type="text/javascript">
283 var data = ${c.trending_languages|n};
289 var data = ${c.trending_languages|n};
284 var total = 0;
290 var total = 0;
285 var no_data = true;
291 var no_data = true;
286 for (k in data){
292 for (k in data){
287 total += data[k].count;
293 total += data[k].count;
288 no_data = false;
294 no_data = false;
289 }
295 }
290 var tbl = document.createElement('table');
296 var tbl = document.createElement('table');
291 tbl.setAttribute('class','trending_language_tbl');
297 tbl.setAttribute('class','trending_language_tbl');
292 var cnt = 0;
298 var cnt = 0;
293 for (k in data){
299 for (k in data){
294 cnt += 1;
300 cnt += 1;
295 var hide = cnt>2;
301 var hide = cnt>2;
296 var tr = document.createElement('tr');
302 var tr = document.createElement('tr');
297 if (hide){
303 if (hide){
298 tr.setAttribute('style','display:none');
304 tr.setAttribute('style','display:none');
299 tr.setAttribute('class','stats_hidden');
305 tr.setAttribute('class','stats_hidden');
300 }
306 }
301 var percentage = Math.round((data[k].count/total*100),2);
307 var percentage = Math.round((data[k].count/total*100),2);
302 var value = data[k].count;
308 var value = data[k].count;
303 var td1 = document.createElement('td');
309 var td1 = document.createElement('td');
304 td1.width = 150;
310 td1.width = 150;
305 var trending_language_label = document.createElement('div');
311 var trending_language_label = document.createElement('div');
306 trending_language_label.innerHTML = data[k].desc+" ("+k+")";
312 trending_language_label.innerHTML = data[k].desc+" ("+k+")";
307 td1.appendChild(trending_language_label);
313 td1.appendChild(trending_language_label);
308
314
309 var td2 = document.createElement('td');
315 var td2 = document.createElement('td');
310 td2.setAttribute('style','padding-right:14px !important');
316 td2.setAttribute('style','padding-right:14px !important');
311 var trending_language = document.createElement('div');
317 var trending_language = document.createElement('div');
312 var nr_files = value+" ${_('files')}";
318 var nr_files = value+" ${_('files')}";
313
319
314 trending_language.title = k+" "+nr_files;
320 trending_language.title = k+" "+nr_files;
315
321
316 if (percentage>22){
322 if (percentage>22){
317 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"% "+nr_files+ "</b>";
323 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"% "+nr_files+ "</b>";
318 }
324 }
319 else{
325 else{
320 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"%</b>";
326 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"%</b>";
321 }
327 }
322
328
323 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
329 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
324 trending_language.style.width=percentage+"%";
330 trending_language.style.width=percentage+"%";
325 td2.appendChild(trending_language);
331 td2.appendChild(trending_language);
326
332
327 tr.appendChild(td1);
333 tr.appendChild(td1);
328 tr.appendChild(td2);
334 tr.appendChild(td2);
329 tbl.appendChild(tr);
335 tbl.appendChild(tr);
330 if(cnt == 3){
336 if(cnt == 3){
331 var show_more = document.createElement('tr');
337 var show_more = document.createElement('tr');
332 var td = document.createElement('td');
338 var td = document.createElement('td');
333 lnk = document.createElement('a');
339 lnk = document.createElement('a');
334
340
335 lnk.href='#';
341 lnk.href='#';
336 lnk.innerHTML = "${_('show more')}";
342 lnk.innerHTML = "${_('show more')}";
337 lnk.id='code_stats_show_more';
343 lnk.id='code_stats_show_more';
338 td.appendChild(lnk);
344 td.appendChild(lnk);
339
345
340 show_more.appendChild(td);
346 show_more.appendChild(td);
341 show_more.appendChild(document.createElement('td'));
347 show_more.appendChild(document.createElement('td'));
342 tbl.appendChild(show_more);
348 tbl.appendChild(show_more);
343 }
349 }
344
350
345 }
351 }
346
352
347 YUD.get('lang_stats').appendChild(tbl);
353 YUD.get('lang_stats').appendChild(tbl);
348 YUE.on('code_stats_show_more','click',function(){
354 YUE.on('code_stats_show_more','click',function(){
349 l = YUD.getElementsByClassName('stats_hidden')
355 l = YUD.getElementsByClassName('stats_hidden')
350 for (e in l){
356 for (e in l){
351 YUD.setStyle(l[e],'display','');
357 YUD.setStyle(l[e],'display','');
352 };
358 };
353 YUD.setStyle(YUD.get('code_stats_show_more'),
359 YUD.setStyle(YUD.get('code_stats_show_more'),
354 'display','none');
360 'display','none');
355 });
361 });
356 </script>
362 </script>
357 <script type="text/javascript">
363 <script type="text/javascript">
358 /**
364 /**
359 * Plots summary graph
365 * Plots summary graph
360 *
366 *
361 * @class SummaryPlot
367 * @class SummaryPlot
362 * @param {from} initial from for detailed graph
368 * @param {from} initial from for detailed graph
363 * @param {to} initial to for detailed graph
369 * @param {to} initial to for detailed graph
364 * @param {dataset}
370 * @param {dataset}
365 * @param {overview_dataset}
371 * @param {overview_dataset}
366 */
372 */
367 function SummaryPlot(from,to,dataset,overview_dataset) {
373 function SummaryPlot(from,to,dataset,overview_dataset) {
368 var initial_ranges = {
374 var initial_ranges = {
369 "xaxis":{
375 "xaxis":{
370 "from":from,
376 "from":from,
371 "to":to,
377 "to":to,
372 },
378 },
373 };
379 };
374 var dataset = dataset;
380 var dataset = dataset;
375 var overview_dataset = [overview_dataset];
381 var overview_dataset = [overview_dataset];
376 var choiceContainer = YUD.get("legend_choices");
382 var choiceContainer = YUD.get("legend_choices");
377 var choiceContainerTable = YUD.get("legend_choices_tables");
383 var choiceContainerTable = YUD.get("legend_choices_tables");
378 var plotContainer = YUD.get('commit_history');
384 var plotContainer = YUD.get('commit_history');
379 var overviewContainer = YUD.get('overview');
385 var overviewContainer = YUD.get('overview');
380
386
381 var plot_options = {
387 var plot_options = {
382 bars: {show:true,align:'center',lineWidth:4},
388 bars: {show:true,align:'center',lineWidth:4},
383 legend: {show:true, container:"legend_container"},
389 legend: {show:true, container:"legend_container"},
384 points: {show:true,radius:0,fill:false},
390 points: {show:true,radius:0,fill:false},
385 yaxis: {tickDecimals:0,},
391 yaxis: {tickDecimals:0,},
386 xaxis: {
392 xaxis: {
387 mode: "time",
393 mode: "time",
388 timeformat: "%d/%m",
394 timeformat: "%d/%m",
389 min:from,
395 min:from,
390 max:to,
396 max:to,
391 },
397 },
392 grid: {
398 grid: {
393 hoverable: true,
399 hoverable: true,
394 clickable: true,
400 clickable: true,
395 autoHighlight:true,
401 autoHighlight:true,
396 color: "#999"
402 color: "#999"
397 },
403 },
398 //selection: {mode: "x"}
404 //selection: {mode: "x"}
399 };
405 };
400 var overview_options = {
406 var overview_options = {
401 legend:{show:false},
407 legend:{show:false},
402 bars: {show:true,barWidth: 2,},
408 bars: {show:true,barWidth: 2,},
403 shadowSize: 0,
409 shadowSize: 0,
404 xaxis: {mode: "time", timeformat: "%d/%m/%y",},
410 xaxis: {mode: "time", timeformat: "%d/%m/%y",},
405 yaxis: {ticks: 3, min: 0,tickDecimals:0,},
411 yaxis: {ticks: 3, min: 0,tickDecimals:0,},
406 grid: {color: "#999",},
412 grid: {color: "#999",},
407 selection: {mode: "x"}
413 selection: {mode: "x"}
408 };
414 };
409
415
410 /**
416 /**
411 *get dummy data needed in few places
417 *get dummy data needed in few places
412 */
418 */
413 function getDummyData(label){
419 function getDummyData(label){
414 return {"label":label,
420 return {"label":label,
415 "data":[{"time":0,
421 "data":[{"time":0,
416 "commits":0,
422 "commits":0,
417 "added":0,
423 "added":0,
418 "changed":0,
424 "changed":0,
419 "removed":0,
425 "removed":0,
420 }],
426 }],
421 "schema":["commits"],
427 "schema":["commits"],
422 "color":'#ffffff',
428 "color":'#ffffff',
423 }
429 }
424 }
430 }
425
431
426 /**
432 /**
427 * generate checkboxes accordindly to data
433 * generate checkboxes accordindly to data
428 * @param keys
434 * @param keys
429 * @returns
435 * @returns
430 */
436 */
431 function generateCheckboxes(data) {
437 function generateCheckboxes(data) {
432 //append checkboxes
438 //append checkboxes
433 var i = 0;
439 var i = 0;
434 choiceContainerTable.innerHTML = '';
440 choiceContainerTable.innerHTML = '';
435 for(var pos in data) {
441 for(var pos in data) {
436
442
437 data[pos].color = i;
443 data[pos].color = i;
438 i++;
444 i++;
439 if(data[pos].label != ''){
445 if(data[pos].label != ''){
440 choiceContainerTable.innerHTML += '<tr><td>'+
446 choiceContainerTable.innerHTML += '<tr><td>'+
441 '<input type="checkbox" name="' + data[pos].label +'" checked="checked" />'
447 '<input type="checkbox" name="' + data[pos].label +'" checked="checked" />'
442 +data[pos].label+
448 +data[pos].label+
443 '</td></tr>';
449 '</td></tr>';
444 }
450 }
445 }
451 }
446 }
452 }
447
453
448 /**
454 /**
449 * ToolTip show
455 * ToolTip show
450 */
456 */
451 function showTooltip(x, y, contents) {
457 function showTooltip(x, y, contents) {
452 var div=document.getElementById('tooltip');
458 var div=document.getElementById('tooltip');
453 if(!div) {
459 if(!div) {
454 div = document.createElement('div');
460 div = document.createElement('div');
455 div.id="tooltip";
461 div.id="tooltip";
456 div.style.position="absolute";
462 div.style.position="absolute";
457 div.style.border='1px solid #fdd';
463 div.style.border='1px solid #fdd';
458 div.style.padding='2px';
464 div.style.padding='2px';
459 div.style.backgroundColor='#fee';
465 div.style.backgroundColor='#fee';
460 document.body.appendChild(div);
466 document.body.appendChild(div);
461 }
467 }
462 YUD.setStyle(div, 'opacity', 0);
468 YUD.setStyle(div, 'opacity', 0);
463 div.innerHTML = contents;
469 div.innerHTML = contents;
464 div.style.top=(y + 5) + "px";
470 div.style.top=(y + 5) + "px";
465 div.style.left=(x + 5) + "px";
471 div.style.left=(x + 5) + "px";
466
472
467 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
473 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
468 anim.animate();
474 anim.animate();
469 }
475 }
470
476
471 /**
477 /**
472 * This function will detect if selected period has some changesets
478 * This function will detect if selected period has some changesets
473 for this user if it does this data is then pushed for displaying
479 for this user if it does this data is then pushed for displaying
474 Additionally it will only display users that are selected by the checkbox
480 Additionally it will only display users that are selected by the checkbox
475 */
481 */
476 function getDataAccordingToRanges(ranges) {
482 function getDataAccordingToRanges(ranges) {
477
483
478 var data = [];
484 var data = [];
479 var new_dataset = {};
485 var new_dataset = {};
480 var keys = [];
486 var keys = [];
481 var max_commits = 0;
487 var max_commits = 0;
482 for(var key in dataset){
488 for(var key in dataset){
483
489
484 for(var ds in dataset[key].data){
490 for(var ds in dataset[key].data){
485 commit_data = dataset[key].data[ds];
491 commit_data = dataset[key].data[ds];
486 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
492 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
487
493
488 if(new_dataset[key] === undefined){
494 if(new_dataset[key] === undefined){
489 new_dataset[key] = {data:[],schema:["commits"],label:key};
495 new_dataset[key] = {data:[],schema:["commits"],label:key};
490 }
496 }
491 new_dataset[key].data.push(commit_data);
497 new_dataset[key].data.push(commit_data);
492 }
498 }
493 }
499 }
494 if (new_dataset[key] !== undefined){
500 if (new_dataset[key] !== undefined){
495 data.push(new_dataset[key]);
501 data.push(new_dataset[key]);
496 }
502 }
497 }
503 }
498
504
499 if (data.length > 0){
505 if (data.length > 0){
500 return data;
506 return data;
501 }
507 }
502 else{
508 else{
503 //just return dummy data for graph to plot itself
509 //just return dummy data for graph to plot itself
504 return [getDummyData('')];
510 return [getDummyData('')];
505 }
511 }
506 }
512 }
507
513
508 /**
514 /**
509 * redraw using new checkbox data
515 * redraw using new checkbox data
510 */
516 */
511 function plotchoiced(e,args){
517 function plotchoiced(e,args){
512 var cur_data = args[0];
518 var cur_data = args[0];
513 var cur_ranges = args[1];
519 var cur_ranges = args[1];
514
520
515 var new_data = [];
521 var new_data = [];
516 var inputs = choiceContainer.getElementsByTagName("input");
522 var inputs = choiceContainer.getElementsByTagName("input");
517
523
518 //show only checked labels
524 //show only checked labels
519 for(var i=0; i<inputs.length; i++) {
525 for(var i=0; i<inputs.length; i++) {
520 var checkbox_key = inputs[i].name;
526 var checkbox_key = inputs[i].name;
521
527
522 if(inputs[i].checked){
528 if(inputs[i].checked){
523 for(var d in cur_data){
529 for(var d in cur_data){
524 if(cur_data[d].label == checkbox_key){
530 if(cur_data[d].label == checkbox_key){
525 new_data.push(cur_data[d]);
531 new_data.push(cur_data[d]);
526 }
532 }
527 }
533 }
528 }
534 }
529 else{
535 else{
530 //push dummy data to not hide the label
536 //push dummy data to not hide the label
531 new_data.push(getDummyData(checkbox_key));
537 new_data.push(getDummyData(checkbox_key));
532 }
538 }
533 }
539 }
534
540
535 var new_options = YAHOO.lang.merge(plot_options, {
541 var new_options = YAHOO.lang.merge(plot_options, {
536 xaxis: {
542 xaxis: {
537 min: cur_ranges.xaxis.from,
543 min: cur_ranges.xaxis.from,
538 max: cur_ranges.xaxis.to,
544 max: cur_ranges.xaxis.to,
539 mode:"time",
545 mode:"time",
540 timeformat: "%d/%m",
546 timeformat: "%d/%m",
541 },
547 },
542 });
548 });
543 if (!new_data){
549 if (!new_data){
544 new_data = [[0,1]];
550 new_data = [[0,1]];
545 }
551 }
546 // do the zooming
552 // do the zooming
547 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
553 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
548
554
549 plot.subscribe("plotselected", plotselected);
555 plot.subscribe("plotselected", plotselected);
550
556
551 //resubscribe plothover
557 //resubscribe plothover
552 plot.subscribe("plothover", plothover);
558 plot.subscribe("plothover", plothover);
553
559
554 // don't fire event on the overview to prevent eternal loop
560 // don't fire event on the overview to prevent eternal loop
555 overview.setSelection(cur_ranges, true);
561 overview.setSelection(cur_ranges, true);
556
562
557 }
563 }
558
564
559 /**
565 /**
560 * plot only selected items from overview
566 * plot only selected items from overview
561 * @param ranges
567 * @param ranges
562 * @returns
568 * @returns
563 */
569 */
564 function plotselected(ranges,cur_data) {
570 function plotselected(ranges,cur_data) {
565 //updates the data for new plot
571 //updates the data for new plot
566 var data = getDataAccordingToRanges(ranges);
572 var data = getDataAccordingToRanges(ranges);
567 generateCheckboxes(data);
573 generateCheckboxes(data);
568
574
569 var new_options = YAHOO.lang.merge(plot_options, {
575 var new_options = YAHOO.lang.merge(plot_options, {
570 xaxis: {
576 xaxis: {
571 min: ranges.xaxis.from,
577 min: ranges.xaxis.from,
572 max: ranges.xaxis.to,
578 max: ranges.xaxis.to,
573 mode:"time",
579 mode:"time",
574 timeformat: "%d/%m",
580 timeformat: "%d/%m",
575 },
581 },
576 });
582 });
577 // do the zooming
583 // do the zooming
578 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
584 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
579
585
580 plot.subscribe("plotselected", plotselected);
586 plot.subscribe("plotselected", plotselected);
581
587
582 //resubscribe plothover
588 //resubscribe plothover
583 plot.subscribe("plothover", plothover);
589 plot.subscribe("plothover", plothover);
584
590
585 // don't fire event on the overview to prevent eternal loop
591 // don't fire event on the overview to prevent eternal loop
586 overview.setSelection(ranges, true);
592 overview.setSelection(ranges, true);
587
593
588 //resubscribe choiced
594 //resubscribe choiced
589 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
595 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
590 }
596 }
591
597
592 var previousPoint = null;
598 var previousPoint = null;
593
599
594 function plothover(o) {
600 function plothover(o) {
595 var pos = o.pos;
601 var pos = o.pos;
596 var item = o.item;
602 var item = o.item;
597
603
598 //YUD.get("x").innerHTML = pos.x.toFixed(2);
604 //YUD.get("x").innerHTML = pos.x.toFixed(2);
599 //YUD.get("y").innerHTML = pos.y.toFixed(2);
605 //YUD.get("y").innerHTML = pos.y.toFixed(2);
600 if (item) {
606 if (item) {
601 if (previousPoint != item.datapoint) {
607 if (previousPoint != item.datapoint) {
602 previousPoint = item.datapoint;
608 previousPoint = item.datapoint;
603
609
604 var tooltip = YUD.get("tooltip");
610 var tooltip = YUD.get("tooltip");
605 if(tooltip) {
611 if(tooltip) {
606 tooltip.parentNode.removeChild(tooltip);
612 tooltip.parentNode.removeChild(tooltip);
607 }
613 }
608 var x = item.datapoint.x.toFixed(2);
614 var x = item.datapoint.x.toFixed(2);
609 var y = item.datapoint.y.toFixed(2);
615 var y = item.datapoint.y.toFixed(2);
610
616
611 if (!item.series.label){
617 if (!item.series.label){
612 item.series.label = 'commits';
618 item.series.label = 'commits';
613 }
619 }
614 var d = new Date(x*1000);
620 var d = new Date(x*1000);
615 var fd = d.toDateString()
621 var fd = d.toDateString()
616 var nr_commits = parseInt(y);
622 var nr_commits = parseInt(y);
617
623
618 var cur_data = dataset[item.series.label].data[item.dataIndex];
624 var cur_data = dataset[item.series.label].data[item.dataIndex];
619 var added = cur_data.added;
625 var added = cur_data.added;
620 var changed = cur_data.changed;
626 var changed = cur_data.changed;
621 var removed = cur_data.removed;
627 var removed = cur_data.removed;
622
628
623 var nr_commits_suffix = " ${_('commits')} ";
629 var nr_commits_suffix = " ${_('commits')} ";
624 var added_suffix = " ${_('files added')} ";
630 var added_suffix = " ${_('files added')} ";
625 var changed_suffix = " ${_('files changed')} ";
631 var changed_suffix = " ${_('files changed')} ";
626 var removed_suffix = " ${_('files removed')} ";
632 var removed_suffix = " ${_('files removed')} ";
627
633
628
634
629 if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";}
635 if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";}
630 if(added==1){added_suffix=" ${_('file added')} ";}
636 if(added==1){added_suffix=" ${_('file added')} ";}
631 if(changed==1){changed_suffix=" ${_('file changed')} ";}
637 if(changed==1){changed_suffix=" ${_('file changed')} ";}
632 if(removed==1){removed_suffix=" ${_('file removed')} ";}
638 if(removed==1){removed_suffix=" ${_('file removed')} ";}
633
639
634 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
640 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
635 +'<br/>'+
641 +'<br/>'+
636 nr_commits + nr_commits_suffix+'<br/>'+
642 nr_commits + nr_commits_suffix+'<br/>'+
637 added + added_suffix +'<br/>'+
643 added + added_suffix +'<br/>'+
638 changed + changed_suffix + '<br/>'+
644 changed + changed_suffix + '<br/>'+
639 removed + removed_suffix + '<br/>');
645 removed + removed_suffix + '<br/>');
640 }
646 }
641 }
647 }
642 else {
648 else {
643 var tooltip = YUD.get("tooltip");
649 var tooltip = YUD.get("tooltip");
644
650
645 if(tooltip) {
651 if(tooltip) {
646 tooltip.parentNode.removeChild(tooltip);
652 tooltip.parentNode.removeChild(tooltip);
647 }
653 }
648 previousPoint = null;
654 previousPoint = null;
649 }
655 }
650 }
656 }
651
657
652 /**
658 /**
653 * MAIN EXECUTION
659 * MAIN EXECUTION
654 */
660 */
655
661
656 var data = getDataAccordingToRanges(initial_ranges);
662 var data = getDataAccordingToRanges(initial_ranges);
657 generateCheckboxes(data);
663 generateCheckboxes(data);
658
664
659 //main plot
665 //main plot
660 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
666 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
661
667
662 //overview
668 //overview
663 var overview = YAHOO.widget.Flot(overviewContainer,
669 var overview = YAHOO.widget.Flot(overviewContainer,
664 overview_dataset, overview_options);
670 overview_dataset, overview_options);
665
671
666 //show initial selection on overview
672 //show initial selection on overview
667 overview.setSelection(initial_ranges);
673 overview.setSelection(initial_ranges);
668
674
669 plot.subscribe("plotselected", plotselected);
675 plot.subscribe("plotselected", plotselected);
670 plot.subscribe("plothover", plothover)
676 plot.subscribe("plothover", plothover)
671
677
672 overview.subscribe("plotselected", function (ranges) {
678 overview.subscribe("plotselected", function (ranges) {
673 plot.setSelection(ranges);
679 plot.setSelection(ranges);
674 });
680 });
675
681
676 // user choices on overview
682 // user choices on overview
677 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
683 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
678 }
684 }
679 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
685 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
680 </script>
686 </script>
681 %endif
687 %endif
682
688
683 </%def>
689 </%def>
General Comments 0
You need to be logged in to leave comments. Login now