##// END OF EJS Templates
rewrote graph plotting, added zooming and json dump insted of stupid string formating.
marcink -
r486:5c376ac2 celery
parent child Browse files
Show More
@@ -65,6 +65,7 class SummaryController(BaseController):
65 c.ts_min = task.result[0]
65 c.ts_min = task.result[0]
66 c.ts_max = task.result[1]
66 c.ts_max = task.result[1]
67 c.commit_data = task.result[2]
67 c.commit_data = task.result[2]
68 c.overview_data = task.result[3]
68
69
69 return render('summary/summary.html')
70 return render('summary/summary.html')
70
71
@@ -11,6 +11,7 from time import mktime
11 from vcs.backends.hg import MercurialRepository
11 from vcs.backends.hg import MercurialRepository
12 import calendar
12 import calendar
13 import traceback
13 import traceback
14 import json
14
15
15 __all__ = ['whoosh_index', 'get_commits_stats',
16 __all__ = ['whoosh_index', 'get_commits_stats',
16 'reset_user_password', 'send_email']
17 'reset_user_password', 'send_email']
@@ -84,21 +85,26 def whoosh_index(repo_location, full_ind
84 def get_commits_stats(repo):
85 def get_commits_stats(repo):
85 log = get_commits_stats.get_logger()
86 log = get_commits_stats.get_logger()
86 aggregate = OrderedDict()
87 aggregate = OrderedDict()
88 overview_aggregate = OrderedDict()
87 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
89 repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
88 repo = MercurialRepository(repos_path + repo)
90 repo = MercurialRepository(repos_path + repo)
89 #graph range
91 #graph range
90 td = datetime.today() + timedelta(days=1)
92 td = datetime.today() + timedelta(days=1)
91 y, m, d = td.year, td.month, td.day
93 y, m, d = td.year, td.month, td.day
92 ts_min = mktime((y, (td - timedelta(days=calendar.mdays[m])).month,
94
95 ts_min_y = mktime((y - 1, (td - timedelta(days=calendar.mdays[m])).month,
93 d, 0, 0, 0, 0, 0, 0,))
96 d, 0, 0, 0, 0, 0, 0,))
94 ts_max = mktime((y, m, d, 0, 0, 0, 0, 0, 0,))
97 ts_min_m = mktime((y, (td - timedelta(days=calendar.mdays[m])).month,
98 d, 0, 0, 0, 0, 0, 0,))
99
100 ts_max_y = mktime((y, m, d, 0, 0, 0, 0, 0, 0,))
95
101
96 def author_key_cleaner(k):
102 def author_key_cleaner(k):
97 k = person(k)
103 k = person(k)
98 k = k.replace('"', "'") #for js data compatibilty
104 k = k.replace('"', "") #for js data compatibilty
99 return k
105 return k
100
106
101 for cs in repo[:200]:#added limit 200 until fix #29 is made
107 for cs in repo[:1000]:#added limit 200 until fix #29 is made
102 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
108 k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
103 cs.date.timetuple()[2])
109 cs.date.timetuple()[2])
104 timetupple = [int(x) for x in k.split('-')]
110 timetupple = [int(x) for x in k.split('-')]
@@ -113,7 +119,7 def get_commits_stats(repo):
113
119
114 else:
120 else:
115 #aggregate[author_key_cleaner(cs.author)].update(dates_range)
121 #aggregate[author_key_cleaner(cs.author)].update(dates_range)
116 if k >= ts_min and k <= ts_max:
122 if k >= ts_min_y and k <= ts_max_y:
117 aggregate[author_key_cleaner(cs.author)][k] = {}
123 aggregate[author_key_cleaner(cs.author)][k] = {}
118 aggregate[author_key_cleaner(cs.author)][k]["commits"] = 1
124 aggregate[author_key_cleaner(cs.author)][k]["commits"] = 1
119 aggregate[author_key_cleaner(cs.author)][k]["added"] = len(cs.added)
125 aggregate[author_key_cleaner(cs.author)][k]["added"] = len(cs.added)
@@ -121,7 +127,7 def get_commits_stats(repo):
121 aggregate[author_key_cleaner(cs.author)][k]["removed"] = len(cs.removed)
127 aggregate[author_key_cleaner(cs.author)][k]["removed"] = len(cs.removed)
122
128
123 else:
129 else:
124 if k >= ts_min and k <= ts_max:
130 if k >= ts_min_y and k <= ts_max_y:
125 aggregate[author_key_cleaner(cs.author)] = OrderedDict()
131 aggregate[author_key_cleaner(cs.author)] = OrderedDict()
126 #aggregate[author_key_cleaner(cs.author)].update(dates_range)
132 #aggregate[author_key_cleaner(cs.author)].update(dates_range)
127 aggregate[author_key_cleaner(cs.author)][k] = {}
133 aggregate[author_key_cleaner(cs.author)][k] = {}
@@ -130,25 +136,35 def get_commits_stats(repo):
130 aggregate[author_key_cleaner(cs.author)][k]["changed"] = len(cs.changed)
136 aggregate[author_key_cleaner(cs.author)][k]["changed"] = len(cs.changed)
131 aggregate[author_key_cleaner(cs.author)][k]["removed"] = len(cs.removed)
137 aggregate[author_key_cleaner(cs.author)][k]["removed"] = len(cs.removed)
132
138
133 d = ''
139
134 tmpl0 = u""""%s":%s"""
140 if overview_aggregate.has_key(k):
135 tmpl1 = u"""{label:"%s",data:%s,schema:["commits"]},"""
141 overview_aggregate[k] += 1
136 for author in aggregate:
142 else:
143 overview_aggregate[k] = 1
137
144
138 d += tmpl0 % (author,
145 overview_data = []
139 tmpl1 \
146 for k, v in overview_aggregate.items():
140 % (author,
147 overview_data.append([k, v])
141 [{"time":x,
148 data = {}
149 for author in aggregate:
150 data[author] = {"label":author,
151 "data":[{"time":x,
142 "commits":aggregate[author][x]['commits'],
152 "commits":aggregate[author][x]['commits'],
143 "added":aggregate[author][x]['added'],
153 "added":aggregate[author][x]['added'],
144 "changed":aggregate[author][x]['changed'],
154 "changed":aggregate[author][x]['changed'],
145 "removed":aggregate[author][x]['removed'],
155 "removed":aggregate[author][x]['removed'],
146 } for x in aggregate[author]]))
156 } for x in aggregate[author]],
147 if d == '':
157 "schema":["commits"]
148 d = '"%s":{label:"%s",data:[[0,1],]}' \
158 }
149 % (author_key_cleaner(repo.contact),
159
150 author_key_cleaner(repo.contact))
160 if not data:
151 return (ts_min, ts_max, d)
161 data[author_key_cleaner(repo.contact)] = {
162 "label":author_key_cleaner(repo.contact),
163 "data":[0, 1],
164 "schema":["commits"],
165 }
166
167 return (ts_min_m, ts_max_y, json.dumps(data), json.dumps(overview_data))
152
168
153 @task
169 @task
154 def reset_user_password(user_email):
170 def reset_user_password(user_email):
@@ -157,7 +173,6 def reset_user_password(user_email):
157 from pylons_app.model.db import User
173 from pylons_app.model.db import User
158
174
159 try:
175 try:
160
161 try:
176 try:
162 sa = get_session()
177 sa = get_session()
163 user = sa.query(User).filter(User.email == user_email).scalar()
178 user = sa.query(User).filter(User.email == user_email).scalar()
@@ -126,7 +126,10 E.onDOMReady(function(e){
126
126
127 <div class="table">
127 <div class="table">
128 <div id="commit_history" style="width:560px;height:300px;float:left"></div>
128 <div id="commit_history" style="width:560px;height:300px;float:left"></div>
129 <div id="legend_data" style="clear:both;margin-top:10px">
129 <div style="clear: both;height: 10px"></div>
130 <div id="overview" style="width:560px;height:100px;float:left"></div>
131
132 <div id="legend_data" style="clear:both;margin-top:10px;">
130 <div id="legend_container"></div>
133 <div id="legend_container"></div>
131 <div id="legend_choices">
134 <div id="legend_choices">
132 <table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
135 <table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
@@ -135,7 +138,9 E.onDOMReady(function(e){
135 <script type="text/javascript">
138 <script type="text/javascript">
136
139
137 (function () {
140 (function () {
138 var datasets = {${c.commit_data|n}};
141 var datasets = ${c.commit_data|n};
142 var overview_data = ${c.overview_data|n};
143
139 var i = 0;
144 var i = 0;
140 var choiceContainer = YAHOO.util.Dom.get("legend_choices");
145 var choiceContainer = YAHOO.util.Dom.get("legend_choices");
141 var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
146 var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
@@ -148,7 +153,6 E.onDOMReady(function(e){
148 '</td></tr>';
153 '</td></tr>';
149 };
154 };
150
155
151
152 function plotAccordingToChoices() {
156 function plotAccordingToChoices() {
153 var data = [];
157 var data = [];
154
158
@@ -162,23 +166,50 E.onDOMReady(function(e){
162 else{
166 else{
163 data.push(datasets[key]);
167 data.push(datasets[key]);
164 }
168 }
165
166 }
169 }
167
168 };
170 };
169
171
170 if (data.length > 0){
172 if (data.length > 0){
171
173 var options = {
172 var plot = YAHOO.widget.Flot("commit_history", data,
174 bars: {show:true,align:'center',lineWidth:4},
173 { bars: { show: true, align:'center',lineWidth:4 },
174 points: { show: true, radius:0,fill:true },
175 legend:{show:true, container:"legend_container"},
175 legend: {show:true, container:"legend_container"},
176 selection: { mode: "xy" },
176 points: {show:true,radius:0,fill:false},
177 yaxis: {tickDecimals:0},
177 yaxis: {tickDecimals:0,},
178 xaxis: { mode: "time", timeformat: "%d",tickSize:[1, "day"],min:${c.ts_min},max:${c.ts_max} },
178 xaxis: {mode: "time",
179 grid: { hoverable: true, clickable: true,autoHighlight:true },
179 timeformat: "%d/%m",
180 min:${c.ts_min},
181 max:${c.ts_max},
182
183 },
184 grid: {hoverable: true,
185 clickable: true,
186 autoHighlight:true,
187 color: "#999"},
188 selection: {mode: "x"}
189 };
190
191 //main plot
192 var plot = YAHOO.widget.Flot("commit_history",data,options);
193
194 //overview
195 var overview = YAHOO.widget.Flot("overview", [overview_data], {
196 legend:{show:false},
197 bars: {show:true,
198 barWidth: 2,
199 },
200 shadowSize: 0,
201 xaxis: {mode: "time",
202 timeformat: "%d/%m/%y",
203 },
204 yaxis: {ticks: 3, min: 0,},
205 grid: {color: "#999",},
206 selection: {mode: "x"}
180 });
207 });
181
208
209 var ranges = {"xaxis":{"from":${c.ts_min},
210 "to":${c.ts_max},},}
211 overview.setSelection(ranges);
212
182 function showTooltip(x, y, contents) {
213 function showTooltip(x, y, contents) {
183 var div=document.getElementById('tooltip');
214 var div=document.getElementById('tooltip');
184 if(!div) {
215 if(!div) {
@@ -200,7 +231,8 E.onDOMReady(function(e){
200 }
231 }
201
232
202 var previousPoint = null;
233 var previousPoint = null;
203 plot.subscribe("plothover", function (o) {
234
235 function plothover(o) {
204 var pos = o.pos;
236 var pos = o.pos;
205 var item = o.item;
237 var item = o.item;
206
238
@@ -221,7 +253,7 E.onDOMReady(function(e){
221 item.series.label = 'commits';
253 item.series.label = 'commits';
222 }
254 }
223 var d = new Date(x*1000);
255 var d = new Date(x*1000);
224 var fd = d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate();
256 var fd = d.toDateString()
225 var nr_commits = parseInt(y);
257 var nr_commits = parseInt(y);
226
258
227 var cur_data = datasets[item.series.label].data[item.dataIndex];
259 var cur_data = datasets[item.series.label].data[item.dataIndex];
@@ -256,8 +288,31 E.onDOMReady(function(e){
256 }
288 }
257 previousPoint = null;
289 previousPoint = null;
258 }
290 }
291 }
292
293 plot.subscribe("plothover", plothover);
294
295 function plotselected(ranges) {
296 // do the zooming
297 plot = YAHOO.widget.Flot("commit_history", data,
298 YAHOO.lang.merge(options, {
299 xaxis: { min: ranges.xaxis.from,
300 max: ranges.xaxis.to,
301 mode:"time",
302 timeformat: "%d/%m",
303 }
304 }));
305 plot.subscribe("plotselected", plotselected);
306 plot.subscribe("plothover", plothover);
307
308 // don't fire event on the overview to prevent eternal loop
309 overview.setSelection(ranges, true);
310 }
311 plot.subscribe("plotselected", plotselected);
312
313 overview.subscribe("plotselected", function (ranges) {
314 plot.setSelection(ranges);
259 });
315 });
260
261 }
316 }
262 }
317 }
263
318
@@ -24,7 +24,7 setup(
24 "pygments>=1.3.0",
24 "pygments>=1.3.0",
25 "mercurial>=1.6",
25 "mercurial>=1.6",
26 "pysqlite",
26 "pysqlite",
27 "whoosh==1.0.0b16",
27 "whoosh==1.0.0b17",
28 "py-bcrypt",
28 "py-bcrypt",
29 "celery",
29 "celery",
30 ],
30 ],
General Comments 0
You need to be logged in to leave comments. Login now