##// END OF EJS Templates
some small changes to commit activity graph
marcink -
r390:6a506a7a default
parent child Browse files
Show More
@@ -1,121 +1,121
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # summary controller for pylons
3 # summary controller for pylons
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
8 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
9 # of the License or (at your opinion) any later version of the license.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
19 # MA 02110-1301, USA.
20 """
20 """
21 Created on April 18, 2010
21 Created on April 18, 2010
22 summary controller for pylons
22 summary controller for pylons
23 @author: marcink
23 @author: marcink
24 """
24 """
25 from datetime import datetime, timedelta
25 from datetime import datetime, timedelta
26 from pylons import tmpl_context as c, request
26 from pylons import tmpl_context as c, request
27 from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
27 from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
28 from pylons_app.lib.base import BaseController, render
28 from pylons_app.lib.base import BaseController, render
29 from pylons_app.lib.helpers import person
29 from pylons_app.lib.helpers import person
30 from pylons_app.lib.utils import OrderedDict
30 from pylons_app.lib.utils import OrderedDict
31 from pylons_app.model.hg_model import HgModel
31 from pylons_app.model.hg_model import HgModel
32 from time import mktime
32 from time import mktime
33 from webhelpers.paginate import Page
33 from webhelpers.paginate import Page
34 import calendar
34 import calendar
35 import logging
35 import logging
36
36
37 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
38
38
39 class SummaryController(BaseController):
39 class SummaryController(BaseController):
40
40
41 @LoginRequired()
41 @LoginRequired()
42 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
42 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
43 'repository.admin')
43 'repository.admin')
44 def __before__(self):
44 def __before__(self):
45 super(SummaryController, self).__before__()
45 super(SummaryController, self).__before__()
46
46
47 def index(self):
47 def index(self):
48 hg_model = HgModel()
48 hg_model = HgModel()
49 c.repo_info = hg_model.get_repo(c.repo_name)
49 c.repo_info = hg_model.get_repo(c.repo_name)
50 c.repo_changesets = Page(list(c.repo_info[:10]), page=1, items_per_page=20)
50 c.repo_changesets = Page(list(c.repo_info[:10]), page=1, items_per_page=20)
51 e = request.environ
51 e = request.environ
52 uri = u'%(protocol)s://%(user)s@%(host)s/%(repo_name)s' % {
52 uri = u'%(protocol)s://%(user)s@%(host)s/%(repo_name)s' % {
53 'protocol': e.get('wsgi.url_scheme'),
53 'protocol': e.get('wsgi.url_scheme'),
54 'user':str(c.hg_app_user.username),
54 'user':str(c.hg_app_user.username),
55 'host':e.get('HTTP_HOST'),
55 'host':e.get('HTTP_HOST'),
56 'repo_name':c.repo_name, }
56 'repo_name':c.repo_name, }
57 c.clone_repo_url = uri
57 c.clone_repo_url = uri
58 c.repo_tags = OrderedDict()
58 c.repo_tags = OrderedDict()
59 for name, hash in c.repo_info.tags.items()[:10]:
59 for name, hash in c.repo_info.tags.items()[:10]:
60 c.repo_tags[name] = c.repo_info.get_changeset(hash)
60 c.repo_tags[name] = c.repo_info.get_changeset(hash)
61
61
62 c.repo_branches = OrderedDict()
62 c.repo_branches = OrderedDict()
63 for name, hash in c.repo_info.branches.items()[:10]:
63 for name, hash in c.repo_info.branches.items()[:10]:
64 c.repo_branches[name] = c.repo_info.get_changeset(hash)
64 c.repo_branches[name] = c.repo_info.get_changeset(hash)
65
65
66 c.commit_data = self.__get_commit_stats(c.repo_info)
66 c.commit_data = self.__get_commit_stats(c.repo_info)
67
67
68 return render('summary/summary.html')
68 return render('summary/summary.html')
69
69
70
70
71
71
72 def __get_commit_stats(self, repo):
72 def __get_commit_stats(self, repo):
73 aggregate = OrderedDict()
73 aggregate = OrderedDict()
74
74
75 #graph range
75 #graph range
76 td = datetime.today()
76 td = datetime.today() + timedelta(days=1)
77 y = td.year
77 y = td.year
78 m = td.month
78 m = td.month
79 d = td.day
79 d = td.day
80 c.ts_min = mktime((y, (td - timedelta(days=calendar.mdays[m] - 1)).month, d, 0, 0, 0, 0, 0, 0,))
80 c.ts_min = mktime((y, (td - timedelta(days=calendar.mdays[m] - 1)).month, d, 0, 0, 0, 0, 0, 0,))
81 c.ts_max = mktime((y, m, d, 0, 0, 0, 0, 0, 0,))
81 c.ts_max = mktime((y, m, d, 0, 0, 0, 0, 0, 0,))
82
82
83
83
84 def author_key_cleaner(k):
84 def author_key_cleaner(k):
85 k = person(k)
85 k = person(k)
86 return k
86 return k
87
87
88 for cs in repo:
88 for cs in repo:
89 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
89 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
90 cs.date.timetuple()[2])
90 cs.date.timetuple()[2])
91 timetupple = [int(x) for x in k.split('-')]
91 timetupple = [int(x) for x in k.split('-')]
92 timetupple.extend([0 for _ in xrange(6)])
92 timetupple.extend([0 for _ in xrange(6)])
93 k = mktime(timetupple)
93 k = mktime(timetupple)
94 if aggregate.has_key(author_key_cleaner(cs.author)):
94 if aggregate.has_key(author_key_cleaner(cs.author)):
95 if aggregate[author_key_cleaner(cs.author)].has_key(k):
95 if aggregate[author_key_cleaner(cs.author)].has_key(k):
96 aggregate[author_key_cleaner(cs.author)][k] += 1
96 aggregate[author_key_cleaner(cs.author)][k] += 1
97 else:
97 else:
98 #aggregate[author_key_cleaner(cs.author)].update(dates_range)
98 #aggregate[author_key_cleaner(cs.author)].update(dates_range)
99 if k >= c.ts_min and k <= c.ts_max:
99 if k >= c.ts_min and k <= c.ts_max:
100 aggregate[author_key_cleaner(cs.author)][k] = 1
100 aggregate[author_key_cleaner(cs.author)][k] = 1
101 else:
101 else:
102 if k >= c.ts_min and k <= c.ts_max:
102 if k >= c.ts_min and k <= c.ts_max:
103 aggregate[author_key_cleaner(cs.author)] = OrderedDict()
103 aggregate[author_key_cleaner(cs.author)] = OrderedDict()
104 #aggregate[author_key_cleaner(cs.author)].update(dates_range)
104 #aggregate[author_key_cleaner(cs.author)].update(dates_range)
105 aggregate[author_key_cleaner(cs.author)][k] = 1
105 aggregate[author_key_cleaner(cs.author)][k] = 1
106
106
107 d = ''
107 d = ''
108 tmpl0 = u""""%s":%s"""
108 tmpl0 = u""""%s":%s"""
109 tmpl1 = u"""{label:"%s",data:%s},"""
109 tmpl1 = u"""{label:"%s",data:%s},"""
110 for author in aggregate:
110 for author in aggregate:
111 d += tmpl0 % (author.decode('utf8'),
111 d += tmpl0 % (author.decode('utf8'),
112 tmpl1 \
112 tmpl1 \
113 % (author.decode('utf8'),
113 % (author.decode('utf8'),
114 [[x, aggregate[author][x]] for x in aggregate[author]]))
114 [[x, aggregate[author][x]] for x in aggregate[author]]))
115 if d == '':
115 if d == '':
116 d = '"%s":{label:"%s",data:[[0,0],]}' \
116 d = '"%s":{label:"%s",data:[[0,0],]}' \
117 % (author_key_cleaner(repo.contact),
117 % (author_key_cleaner(repo.contact),
118 author_key_cleaner(repo.contact))
118 author_key_cleaner(repo.contact))
119 return d
119 return d
120
120
121
121
@@ -1,272 +1,272
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${_('Mercurial Repository Overview')}
4 ${_('Mercurial Repository Overview')}
5 </%def>
5 </%def>
6
6
7
7
8
8
9 <%def name="breadcrumbs_links()">
9 <%def name="breadcrumbs_links()">
10 ${h.link_to(u'Home',h.url('/'))}
10 ${h.link_to(u'Home',h.url('/'))}
11 &raquo;
11 &raquo;
12 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
12 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
13 &raquo;
13 &raquo;
14 ${_('summary')}
14 ${_('summary')}
15 </%def>
15 </%def>
16
16
17 <%def name="page_nav()">
17 <%def name="page_nav()">
18 ${self.menu('summary')}
18 ${self.menu('summary')}
19 </%def>
19 </%def>
20
20
21 <%def name="main()">
21 <%def name="main()">
22 <script type="text/javascript">
22 <script type="text/javascript">
23 var E = YAHOO.util.Event;
23 var E = YAHOO.util.Event;
24 var D = YAHOO.util.Dom;
24 var D = YAHOO.util.Dom;
25
25
26 E.onDOMReady(function(e){
26 E.onDOMReady(function(e){
27 id = 'clone_url';
27 id = 'clone_url';
28 E.addListener(id,'click',function(e){
28 E.addListener(id,'click',function(e){
29 D.get('clone_url').select();
29 D.get('clone_url').select();
30 })
30 })
31 })
31 })
32 </script>
32 </script>
33 <div class="box box-left">
33 <div class="box box-left">
34 <!-- box / title -->
34 <!-- box / title -->
35 <div class="title">
35 <div class="title">
36 ${self.breadcrumbs()}
36 ${self.breadcrumbs()}
37 </div>
37 </div>
38 <!-- end box / title -->
38 <!-- end box / title -->
39 <div class="form">
39 <div class="form">
40 <div class="fields">
40 <div class="fields">
41
41
42 <div class="field">
42 <div class="field">
43 <div class="label">
43 <div class="label">
44 <label>${_('Name')}:</label>
44 <label>${_('Name')}:</label>
45 </div>
45 </div>
46 <div class="input-short">
46 <div class="input-short">
47 ${c.repo_info.name}
47 ${c.repo_info.name}
48 </div>
48 </div>
49 </div>
49 </div>
50
50
51
51
52 <div class="field">
52 <div class="field">
53 <div class="label">
53 <div class="label">
54 <label>${_('Description')}:</label>
54 <label>${_('Description')}:</label>
55 </div>
55 </div>
56 <div class="input-short">
56 <div class="input-short">
57 ${c.repo_info.description}
57 ${c.repo_info.description}
58 </div>
58 </div>
59 </div>
59 </div>
60
60
61
61
62 <div class="field">
62 <div class="field">
63 <div class="label">
63 <div class="label">
64 <label>${_('Contact')}:</label>
64 <label>${_('Contact')}:</label>
65 </div>
65 </div>
66 <div class="input-short">
66 <div class="input-short">
67 ${c.repo_info.contact}
67 ${c.repo_info.contact}
68 </div>
68 </div>
69 </div>
69 </div>
70
70
71 <div class="field">
71 <div class="field">
72 <div class="label">
72 <div class="label">
73 <label>${_('Last change')}:</label>
73 <label>${_('Last change')}:</label>
74 </div>
74 </div>
75 <div class="input-short">
75 <div class="input-short">
76 ${h.age(c.repo_info.last_change)} - ${h.rfc822date(c.repo_info.last_change)}
76 ${h.age(c.repo_info.last_change)} - ${h.rfc822date(c.repo_info.last_change)}
77 </div>
77 </div>
78 </div>
78 </div>
79
79
80 <div class="field">
80 <div class="field">
81 <div class="label">
81 <div class="label">
82 <label>${_('Clone url')}:</label>
82 <label>${_('Clone url')}:</label>
83 </div>
83 </div>
84 <div class="input-short">
84 <div class="input-short">
85 <input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/>
85 <input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/>
86 </div>
86 </div>
87 </div>
87 </div>
88
88
89 <div class="field">
89 <div class="field">
90 <div class="label">
90 <div class="label">
91 <label>${_('Download')}:</label>
91 <label>${_('Download')}:</label>
92 </div>
92 </div>
93 <div class="input-short">
93 <div class="input-short">
94 %for cnt,archive in enumerate(c.repo_info._get_archives()):
94 %for cnt,archive in enumerate(c.repo_info._get_archives()):
95 %if cnt >=1:
95 %if cnt >=1:
96 |
96 |
97 %endif
97 %endif
98 ${h.link_to(c.repo_info.name+'.'+archive['type'],
98 ${h.link_to(c.repo_info.name+'.'+archive['type'],
99 h.url('files_archive_home',repo_name=c.repo_info.name,
99 h.url('files_archive_home',repo_name=c.repo_info.name,
100 revision='tip',fileformat=archive['extension']),class_="archive_icon")}
100 revision='tip',fileformat=archive['extension']),class_="archive_icon")}
101 %endfor
101 %endfor
102 </div>
102 </div>
103 </div>
103 </div>
104
104
105 <div class="field">
105 <div class="field">
106 <div class="label">
106 <div class="label">
107 <label>${_('Feeds')}:</label>
107 <label>${_('Feeds')}:</label>
108 </div>
108 </div>
109 <div class="input-short">
109 <div class="input-short">
110 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_icon')}
110 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_icon')}
111 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_icon')}
111 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_icon')}
112 </div>
112 </div>
113 </div>
113 </div>
114 </div>
114 </div>
115 </div>
115 </div>
116 </div>
116 </div>
117
117
118 <div class="box box-right">
118 <div class="box box-right">
119 <!-- box / title -->
119 <!-- box / title -->
120 <div class="title">
120 <div class="title">
121 <h5>${_('Last month commit activity')}</h5>
121 <h5>${_('Last month commit activity')}</h5>
122 </div>
122 </div>
123
123
124 <div class="table">
124 <div class="table">
125 <div id="commit_history" style="width:460px;height:370px;float:left"></div>
125 <div id="commit_history" style="width:460px;height:370px;float:left"></div>
126 <div id="legend_data">
126 <div id="legend_data">
127 <div id="legend_container"></div>
127 <div id="legend_container"></div>
128 <div id="legend_choices">
128 <div id="legend_choices">
129 <table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
129 <table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
130 </div>
130 </div>
131 </div>
131 </div>
132 <script type="text/javascript">
132 <script type="text/javascript">
133
133
134 (function () {
134 (function () {
135 var datasets = {${c.commit_data|n}};
135 var datasets = {${c.commit_data|n}};
136 var i = 0;
136 var i = 0;
137 var choiceContainer = YAHOO.util.Dom.get("legend_choices");
137 var choiceContainer = YAHOO.util.Dom.get("legend_choices");
138 var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
138 var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
139 for(var key in datasets) {
139 for(var key in datasets) {
140 datasets[key].color = i;
140 datasets[key].color = i;
141 i++;
141 i++;
142 choiceContainerTable.innerHTML += '<tr>'+
142 choiceContainerTable.innerHTML += '<tr>'+
143 '<td>'+
143 '<td>'+
144 '<input type="checkbox" name="' + key +'" checked="checked" />'+datasets[key].label+
144 '<input type="checkbox" name="' + key +'" checked="checked" />'+datasets[key].label+
145 '</td>'+
145 '</td>'+
146 '</tr>';
146 '</tr>';
147 };
147 };
148
148
149
149
150 function plotAccordingToChoices() {
150 function plotAccordingToChoices() {
151 var data = [];
151 var data = [];
152
152
153 var inputs = choiceContainer.getElementsByTagName("input");
153 var inputs = choiceContainer.getElementsByTagName("input");
154 for(var i=0; i<inputs.length; i++) {
154 for(var i=0; i<inputs.length; i++) {
155 if(!inputs[i].checked)
155 if(!inputs[i].checked)
156 continue;
156 continue;
157
157
158 var key = inputs[i].name;
158 var key = inputs[i].name;
159 if (key && datasets[key])
159 if (key && datasets[key])
160 data.push(datasets[key]);
160 data.push(datasets[key]);
161 };
161 };
162
162
163 if (data.length > 0){
163 if (data.length > 0){
164 var plot = YAHOO.widget.Flot("commit_history", data,
164 var plot = YAHOO.widget.Flot("commit_history", data,
165 { bars: { show: true, align:'center' },
165 { bars: { show: true, align:'center',lineWidth:4 },
166 points: { show: true, radius:0,fill:true },
166 points: { show: true, radius:0,fill:true },
167 legend:{show:true, container:"legend_container"},
167 legend:{show:true, container:"legend_container"},
168 selection: { mode: "xy" },
168 selection: { mode: "xy" },
169 yaxis:{tickSize:[1]},
169 yaxis:{tickSize:[1]},
170 xaxis: { mode: "time", timeformat: "%d",tickSize:[1, "day"],min:${c.ts_min},max:${c.ts_max} },
170 xaxis: { mode: "time", timeformat: "%d",tickSize:[1, "day"],min:${c.ts_min},max:${c.ts_max} },
171 grid: { hoverable: true, clickable: true,autoHighlight:true },
171 grid: { hoverable: true, clickable: true,autoHighlight:true },
172 });
172 });
173
173
174 function showTooltip(x, y, contents) {
174 function showTooltip(x, y, contents) {
175 var div=document.getElementById('tooltip');
175 var div=document.getElementById('tooltip');
176 if(!div) {
176 if(!div) {
177 div = document.createElement('div');
177 div = document.createElement('div');
178 div.id="tooltip";
178 div.id="tooltip";
179 div.style.position="absolute";
179 div.style.position="absolute";
180 div.style.border='1px solid #fdd';
180 div.style.border='1px solid #fdd';
181 div.style.padding='2px';
181 div.style.padding='2px';
182 div.style.backgroundColor='#fee';
182 div.style.backgroundColor='#fee';
183 document.body.appendChild(div);
183 document.body.appendChild(div);
184 }
184 }
185 YAHOO.util.Dom.setStyle(div, 'opacity', 0);
185 YAHOO.util.Dom.setStyle(div, 'opacity', 0);
186 div.innerHTML = contents;
186 div.innerHTML = contents;
187 div.style.top=(y + 5) + "px";
187 div.style.top=(y + 5) + "px";
188 div.style.left=(x + 5) + "px";
188 div.style.left=(x + 5) + "px";
189
189
190 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
190 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
191 anim.animate();
191 anim.animate();
192 }
192 }
193
193
194 var previousPoint = null;
194 var previousPoint = null;
195 plot.subscribe("plothover", function (o) {
195 plot.subscribe("plothover", function (o) {
196 var pos = o.pos;
196 var pos = o.pos;
197 var item = o.item;
197 var item = o.item;
198
198
199 //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2);
199 //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2);
200 //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2);
200 //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2);
201 if (item) {
201 if (item) {
202 if (previousPoint != item.datapoint) {
202 if (previousPoint != item.datapoint) {
203 previousPoint = item.datapoint;
203 previousPoint = item.datapoint;
204
204
205 var tooltip = YAHOO.util.Dom.get("tooltip");
205 var tooltip = YAHOO.util.Dom.get("tooltip");
206 if(tooltip) {
206 if(tooltip) {
207 tooltip.parentNode.removeChild(tooltip);
207 tooltip.parentNode.removeChild(tooltip);
208 }
208 }
209 var x = item.datapoint.x.toFixed(2);
209 var x = item.datapoint.x.toFixed(2);
210 var y = item.datapoint.y.toFixed(2);
210 var y = item.datapoint.y.toFixed(2);
211
211
212 if (!item.series.label){
212 if (!item.series.label){
213 item.series.label = 'commits';
213 item.series.label = 'commits';
214 }
214 }
215 var d = new Date(x*1000);
215 var d = new Date(x*1000);
216 var fd = d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate();
216 var fd = d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate();
217 var nr_commits = parseInt(y);
217 var nr_commits = parseInt(y);
218 var suffix = '';
218 var suffix = '';
219 if(nr_commits > 1){
219 if(nr_commits > 1){
220 var suffix = 's';
220 var suffix = 's';
221 }
221 }
222 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd + ": " + nr_commits+" commit" + suffix);
222 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd + ": " + nr_commits+" commit" + suffix);
223 }
223 }
224 }
224 }
225 else {
225 else {
226 var tooltip = YAHOO.util.Dom.get("tooltip");
226 var tooltip = YAHOO.util.Dom.get("tooltip");
227
227
228 if(tooltip) {
228 if(tooltip) {
229 tooltip.parentNode.removeChild(tooltip);
229 tooltip.parentNode.removeChild(tooltip);
230 }
230 }
231 previousPoint = null;
231 previousPoint = null;
232 }
232 }
233 });
233 });
234
234
235 }
235 }
236 }
236 }
237
237
238 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotAccordingToChoices);
238 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotAccordingToChoices);
239
239
240 plotAccordingToChoices();
240 plotAccordingToChoices();
241 })();
241 })();
242 </script>
242 </script>
243
243
244 </div>
244 </div>
245 </div>
245 </div>
246
246
247 <div class="box">
247 <div class="box">
248 <div class="title">
248 <div class="title">
249 <div class="breadcrumbs">${h.link_to(_('Last ten changes'),h.url('changelog_home',repo_name=c.repo_name))}</div>
249 <div class="breadcrumbs">${h.link_to(_('Last ten changes'),h.url('changelog_home',repo_name=c.repo_name))}</div>
250 </div>
250 </div>
251 <div class="table">
251 <div class="table">
252 <%include file='../shortlog/shortlog_data.html'/>
252 <%include file='../shortlog/shortlog_data.html'/>
253 </div>
253 </div>
254 </div>
254 </div>
255 <div class="box">
255 <div class="box">
256 <div class="title">
256 <div class="title">
257 <div class="breadcrumbs">${h.link_to(_('Last ten tags'),h.url('tags_home',repo_name=c.repo_name))}</div>
257 <div class="breadcrumbs">${h.link_to(_('Last ten tags'),h.url('tags_home',repo_name=c.repo_name))}</div>
258 </div>
258 </div>
259 <div class="table">
259 <div class="table">
260 <%include file='../tags/tags_data.html'/>
260 <%include file='../tags/tags_data.html'/>
261 </div>
261 </div>
262 </div>
262 </div>
263 <div class="box">
263 <div class="box">
264 <div class="title">
264 <div class="title">
265 <div class="breadcrumbs">${h.link_to(_('Last ten branches'),h.url('branches_home',repo_name=c.repo_name))}</div>
265 <div class="breadcrumbs">${h.link_to(_('Last ten branches'),h.url('branches_home',repo_name=c.repo_name))}</div>
266 </div>
266 </div>
267 <div class="table">
267 <div class="table">
268 <%include file='../branches/branches_data.html'/>
268 <%include file='../branches/branches_data.html'/>
269 </div>
269 </div>
270 </div>
270 </div>
271
271
272 </%def> No newline at end of file
272 </%def>
General Comments 0
You need to be logged in to leave comments. Login now