Mercurial > public > src > rhodecode
changeset 531:b12ea84fb906 celery
Some fixes to summary, and total rewrite of summary graphs implemented more interactive graph.
Some small fixes for tasks (sorting,limit)
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sun, 19 Sep 2010 03:29:49 +0200 |
parents | 5c376ac2d4c9 |
children | 853b9425742a |
files | pylons_app/lib/celerylib/__init__.py pylons_app/lib/celerylib/tasks.py pylons_app/templates/summary/summary.html |
diffstat | 3 files changed, 348 insertions(+), 187 deletions(-) [+] |
line wrap: on
line diff
--- a/pylons_app/lib/celerylib/__init__.py Sat Sep 18 17:03:29 2010 +0200 +++ b/pylons_app/lib/celerylib/__init__.py Sun Sep 19 03:29:49 2010 +0200 @@ -14,13 +14,16 @@ def result(self): return self.task -def run_task(task,*args,**kwargs): +def run_task(task, *args, **kwargs): try: - t = task.delay(*args,**kwargs) - log.info('running task %s',t.task_id) + t = task.delay(*args, **kwargs) + log.info('running task %s', t.task_id) return t - except: - log.error(traceback.format_exc()) + except Exception, e: + if e.errno == 111: + log.debug('Unnable to connect. Sync execution') + else: + log.error(traceback.format_exc()) #pure sync version - return ResultWrapper(task(*args,**kwargs)) - \ No newline at end of file + return ResultWrapper(task(*args, **kwargs)) +
--- a/pylons_app/lib/celerylib/tasks.py Sat Sep 18 17:03:29 2010 +0200 +++ b/pylons_app/lib/celerylib/tasks.py Sun Sep 19 03:29:49 2010 +0200 @@ -7,8 +7,9 @@ from pylons_app.lib.helpers import person from pylons_app.lib.smtp_mailer import SmtpMailer from pylons_app.lib.utils import OrderedDict +from operator import itemgetter +from vcs.backends.hg import MercurialRepository from time import mktime -from vcs.backends.hg import MercurialRepository import calendar import traceback import json @@ -98,13 +99,14 @@ d, 0, 0, 0, 0, 0, 0,)) ts_max_y = mktime((y, m, d, 0, 0, 0, 0, 0, 0,)) - + skip_date_limit = True + def author_key_cleaner(k): k = person(k) k = k.replace('"', "") #for js data compatibilty return k - for cs in repo[:1000]:#added limit 200 until fix #29 is made + for cs in repo[:200]:#added limit 200 until fix #29 is made k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1], cs.date.timetuple()[2]) timetupple = [int(x) for x in k.split('-')] @@ -119,7 +121,7 @@ else: #aggregate[author_key_cleaner(cs.author)].update(dates_range) - if k >= ts_min_y and k <= ts_max_y: + if k >= ts_min_y and k <= ts_max_y or skip_date_limit: aggregate[author_key_cleaner(cs.author)][k] = {} aggregate[author_key_cleaner(cs.author)][k]["commits"] = 1 aggregate[author_key_cleaner(cs.author)][k]["added"] = len(cs.added) @@ -127,7 +129,7 @@ aggregate[author_key_cleaner(cs.author)][k]["removed"] = len(cs.removed) else: - if k >= ts_min_y and k <= ts_max_y: + if k >= ts_min_y and k <= ts_max_y or skip_date_limit: aggregate[author_key_cleaner(cs.author)] = OrderedDict() #aggregate[author_key_cleaner(cs.author)].update(dates_range) aggregate[author_key_cleaner(cs.author)][k] = {} @@ -145,15 +147,19 @@ overview_data = [] for k, v in overview_aggregate.items(): overview_data.append([k, v]) + overview_data = sorted(overview_data, key=itemgetter(0)) data = {} for author in aggregate: - data[author] = {"label":author, - "data":[{"time":x, + commit_data = sorted([{"time":x, "commits":aggregate[author][x]['commits'], "added":aggregate[author][x]['added'], "changed":aggregate[author][x]['changed'], "removed":aggregate[author][x]['removed'], } for x in aggregate[author]], + key=itemgetter('time')) + + data[author] = {"label":author, + "data":commit_data, "schema":["commits"] }
--- a/pylons_app/templates/summary/summary.html Sat Sep 18 17:03:29 2010 +0200 +++ b/pylons_app/templates/summary/summary.html Sun Sep 19 03:29:49 2010 +0200 @@ -76,7 +76,9 @@ <label>${_('Last change')}:</label> </div> <div class="input-short"> - ${h.age(c.repo_info.last_change)} - ${h.rfc822date(c.repo_info.last_change)} + ${h.age(c.repo_info.last_change)} - ${h.rfc822date(c.repo_info.last_change)} + ${_('by')} ${c.repo_info.get_changeset('tip').author} + </div> </div> @@ -121,7 +123,7 @@ <div class="box box-right" style="min-height:455px"> <!-- box / title --> <div class="title"> - <h5>${_('Last month commit activity')}</h5> + <h5>${_('Commit activity')}</h5> </div> <div class="table"> @@ -136,191 +138,341 @@ </div> </div> <script type="text/javascript"> - - (function () { - var datasets = ${c.commit_data|n}; - var overview_data = ${c.overview_data|n}; - - var i = 0; + /** + * Plots summary graph + * + * @class SummaryPlot + * @param {from} initial from for detailed graph + * @param {to} initial to for detailed graph + * @param {dataset} + * @param {overview_dataset} + */ + function SummaryPlot(from,to,dataset,overview_dataset) { + var initial_ranges = { + "xaxis":{ + "from":from, + "to":to, + }, + }; + var dataset = dataset; + var overview_dataset = [overview_dataset]; var choiceContainer = YAHOO.util.Dom.get("legend_choices"); var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables"); - for(var key in datasets) { - datasets[key].color = i; - i++; - choiceContainerTable.innerHTML += '<tr><td>'+ - '<input type="checkbox" name="' + key +'" checked="checked" />' - +datasets[key].label+ - '</td></tr>'; + var plotContainer = YAHOO.util.Dom.get('commit_history'); + var overviewContainer = YAHOO.util.Dom.get('overview'); + + var plot_options = { + bars: {show:true,align:'center',lineWidth:4}, + legend: {show:true, container:"legend_container"}, + points: {show:true,radius:0,fill:false}, + yaxis: {tickDecimals:0,}, + xaxis: { + mode: "time", + timeformat: "%d/%m", + min:from, + max:to, + }, + grid: { + hoverable: true, + clickable: true, + autoHighlight:true, + color: "#999" + }, + //selection: {mode: "x"} }; - - function plotAccordingToChoices() { - var data = []; - - var inputs = choiceContainer.getElementsByTagName("input"); - for(var i=0; i<inputs.length; i++) { - var key = inputs[i].name; - if (key && datasets[key]){ - if(!inputs[i].checked){ - data.push({label:key,data:[[0,1],]}); - } - else{ - data.push(datasets[key]); - } - } - }; - - if (data.length > 0){ - var options = { - bars: {show:true,align:'center',lineWidth:4}, - legend: {show:true, container:"legend_container"}, - points: {show:true,radius:0,fill:false}, - yaxis: {tickDecimals:0,}, - xaxis: {mode: "time", - timeformat: "%d/%m", - min:${c.ts_min}, - max:${c.ts_max}, - - }, - grid: {hoverable: true, - clickable: true, - autoHighlight:true, - color: "#999"}, - selection: {mode: "x"} - }; + var overview_options = { + legend:{show:false}, + bars: {show:true,barWidth: 2,}, + shadowSize: 0, + xaxis: {mode: "time", timeformat: "%d/%m/%y",}, + yaxis: {ticks: 3, min: 0,}, + grid: {color: "#999",}, + selection: {mode: "x"} + }; - //main plot - var plot = YAHOO.widget.Flot("commit_history",data,options); - - //overview - var overview = YAHOO.widget.Flot("overview", [overview_data], { - legend:{show:false}, - bars: {show:true, - barWidth: 2, - }, - shadowSize: 0, - xaxis: {mode: "time", - timeformat: "%d/%m/%y", - }, - yaxis: {ticks: 3, min: 0,}, - grid: {color: "#999",}, - selection: {mode: "x"} - }); + /** + *get dummy data needed in few places + */ + function getDummyData(label){ + return {"label":label, + "data":[{"time":0, + "commits":0, + "added":0, + "changed":0, + "removed":0, + }], + "schema":["commits"], + "color":'#ffffff', + } + } + + /** + * generate checkboxes accordindly to data + * @param keys + * @returns + */ + function generateCheckboxes(data) { + //append checkboxes + var i = 0; + choiceContainerTable.innerHTML = ''; + for(var pos in data) { + + data[pos].color = i; + i++; + if(data[pos].label != ''){ + choiceContainerTable.innerHTML += '<tr><td>'+ + '<input type="checkbox" name="' + data[pos].label +'" checked="checked" />' + +data[pos].label+ + '</td></tr>'; + } + } + } + + /** + * ToolTip show + */ + function showTooltip(x, y, contents) { + var div=document.getElementById('tooltip'); + if(!div) { + div = document.createElement('div'); + div.id="tooltip"; + div.style.position="absolute"; + div.style.border='1px solid #fdd'; + div.style.padding='2px'; + div.style.backgroundColor='#fee'; + document.body.appendChild(div); + } + YAHOO.util.Dom.setStyle(div, 'opacity', 0); + div.innerHTML = contents; + div.style.top=(y + 5) + "px"; + div.style.left=(x + 5) + "px"; - var ranges = {"xaxis":{"from":${c.ts_min}, - "to":${c.ts_max},},} - overview.setSelection(ranges); - - function showTooltip(x, y, contents) { - var div=document.getElementById('tooltip'); - if(!div) { - div = document.createElement('div'); - div.id="tooltip"; - div.style.position="absolute"; - div.style.border='1px solid #fdd'; - div.style.padding='2px'; - div.style.backgroundColor='#fee'; - document.body.appendChild(div); - } - YAHOO.util.Dom.setStyle(div, 'opacity', 0); - div.innerHTML = contents; - div.style.top=(y + 5) + "px"; - div.style.left=(x + 5) + "px"; - - var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2); - anim.animate(); + var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2); + anim.animate(); + } + + /** + * This function will detect if selected period has some changesets for this user + if it does this data is then pushed for displaying + Additionally it will only display users that are selected by the checkbox + */ + function getDataAccordingToRanges(ranges) { + + var data = []; + var keys = []; + for(var key in dataset){ + var push = false; + //method1 slow !! + ///* + for(var ds in dataset[key].data){ + commit_data = dataset[key].data[ds]; + //console.log(key); + //console.log(new Date(commit_data.time*1000)); + //console.log(new Date(ranges.xaxis.from*1000)); + //console.log(new Date(ranges.xaxis.to*1000)); + if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){ + push = true; + break; + } } + //*/ + /*//method2 sorted commit data !!! + var first_commit = dataset[key].data[0].time; + var last_commit = dataset[key].data[dataset[key].data.length-1].time; - var previousPoint = null; + console.log(first_commit); + console.log(last_commit); + + if (first_commit >= ranges.xaxis.from && last_commit <= ranges.xaxis.to){ + push = true; + } + */ + if(push){ + data.push(dataset[key]); + } + } + if(data.length >= 1){ + return data; + } + else{ + //just return dummy data for graph to plot itself + return [getDummyData('')]; + } + + } + + /** + * redraw using new checkbox data + */ + function plotchoiced(e,args){ + var cur_data = args[0]; + var cur_ranges = args[1]; + + var new_data = []; + var inputs = choiceContainer.getElementsByTagName("input"); - function plothover(o) { - var pos = o.pos; - var item = o.item; - - //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2); - //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2); - if (item) { - if (previousPoint != item.datapoint) { - previousPoint = item.datapoint; - - var tooltip = YAHOO.util.Dom.get("tooltip"); - if(tooltip) { - tooltip.parentNode.removeChild(tooltip); - } - var x = item.datapoint.x.toFixed(2); - var y = item.datapoint.y.toFixed(2); - - if (!item.series.label){ - item.series.label = 'commits'; - } - var d = new Date(x*1000); - var fd = d.toDateString() - var nr_commits = parseInt(y); - - var cur_data = datasets[item.series.label].data[item.dataIndex]; - var added = cur_data.added; - var changed = cur_data.changed; - var removed = cur_data.removed; - - var nr_commits_suffix = " ${_('commits')} "; - var added_suffix = " ${_('files added')} "; - var changed_suffix = " ${_('files changed')} "; - var removed_suffix = " ${_('files removed')} "; + //show only checked labels + for(var i=0; i<inputs.length; i++) { + var checkbox_key = inputs[i].name; + + if(inputs[i].checked){ + for(var d in cur_data){ + if(cur_data[d].label == checkbox_key){ + new_data.push(cur_data[d]); + } + } + } + else{ + //push dummy data to not hide the label + new_data.push(getDummyData(checkbox_key)); + } + } + + var new_options = YAHOO.lang.merge(plot_options, { + xaxis: { + min: cur_ranges.xaxis.from, + max: cur_ranges.xaxis.to, + mode:"time", + timeformat: "%d/%m", + } + }); + if (!new_data){ + new_data = [[0,1]]; + } + // do the zooming + plot = YAHOO.widget.Flot(plotContainer, new_data, new_options); + + plot.subscribe("plotselected", plotselected); + + //resubscribe plothover + plot.subscribe("plothover", plothover); + + // don't fire event on the overview to prevent eternal loop + overview.setSelection(cur_ranges, true); + + } + + /** + * plot only selected items from overview + * @param ranges + * @returns + */ + function plotselected(ranges,cur_data) { + //updates the data for new plot + data = getDataAccordingToRanges(ranges); + generateCheckboxes(data); + + var new_options = YAHOO.lang.merge(plot_options, { + xaxis: { + min: ranges.xaxis.from, + max: ranges.xaxis.to, + mode:"time", + timeformat: "%d/%m", + } + }); + // do the zooming + plot = YAHOO.widget.Flot(plotContainer, data, new_options); + + plot.subscribe("plotselected", plotselected); + + //resubscribe plothover + plot.subscribe("plothover", plothover); + + // don't fire event on the overview to prevent eternal loop + overview.setSelection(ranges, true); + + //resubscribe choiced + YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]); + } + + var previousPoint = null; - - if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";} - if(added==1){added_suffix=" ${_('file added')} ";} - if(changed==1){changed_suffix=" ${_('file changed')} ";} - if(removed==1){removed_suffix=" ${_('file removed')} ";} - - showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd - +'<br/>'+ - nr_commits + nr_commits_suffix+'<br/>'+ - added + added_suffix +'<br/>'+ - changed + changed_suffix + '<br/>'+ - removed + removed_suffix + '<br/>'); - } + function plothover(o) { + var pos = o.pos; + var item = o.item; + + //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2); + //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2); + if (item) { + if (previousPoint != item.datapoint) { + previousPoint = item.datapoint; + + var tooltip = YAHOO.util.Dom.get("tooltip"); + if(tooltip) { + tooltip.parentNode.removeChild(tooltip); } - else { - var tooltip = YAHOO.util.Dom.get("tooltip"); - - if(tooltip) { - tooltip.parentNode.removeChild(tooltip); - } - previousPoint = null; + var x = item.datapoint.x.toFixed(2); + var y = item.datapoint.y.toFixed(2); + + if (!item.series.label){ + item.series.label = 'commits'; } - } - - plot.subscribe("plothover", plothover); - - function plotselected(ranges) { - // do the zooming - plot = YAHOO.widget.Flot("commit_history", data, - YAHOO.lang.merge(options, { - xaxis: { min: ranges.xaxis.from, - max: ranges.xaxis.to, - mode:"time", - timeformat: "%d/%m", - } - })); - plot.subscribe("plotselected", plotselected); - plot.subscribe("plothover", plothover); + var d = new Date(x*1000); + var fd = d.toDateString() + var nr_commits = parseInt(y); + + var cur_data = dataset[item.series.label].data[item.dataIndex]; + var added = cur_data.added; + var changed = cur_data.changed; + var removed = cur_data.removed; + + var nr_commits_suffix = " ${_('commits')} "; + var added_suffix = " ${_('files added')} "; + var changed_suffix = " ${_('files changed')} "; + var removed_suffix = " ${_('files removed')} "; - // don't fire event on the overview to prevent eternal loop - overview.setSelection(ranges, true); - } - plot.subscribe("plotselected", plotselected); - - overview.subscribe("plotselected", function (ranges) { - plot.setSelection(ranges); - }); - } + + if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";} + if(added==1){added_suffix=" ${_('file added')} ";} + if(changed==1){changed_suffix=" ${_('file changed')} ";} + if(removed==1){removed_suffix=" ${_('file removed')} ";} + + showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd + +'<br/>'+ + nr_commits + nr_commits_suffix+'<br/>'+ + added + added_suffix +'<br/>'+ + changed + changed_suffix + '<br/>'+ + removed + removed_suffix + '<br/>'); + } + } + else { + var tooltip = YAHOO.util.Dom.get("tooltip"); + + if(tooltip) { + tooltip.parentNode.removeChild(tooltip); + } + previousPoint = null; + } } - - YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotAccordingToChoices); + + /** + * MAIN EXECUTION + */ + + var data = getDataAccordingToRanges(initial_ranges); + generateCheckboxes(data); + + //main plot + var plot = YAHOO.widget.Flot(plotContainer,data,plot_options); + + //overview + var overview = YAHOO.widget.Flot(overviewContainer, overview_dataset, overview_options); + + //show initial selection on overview + overview.setSelection(initial_ranges); + + plot.subscribe("plotselected", plotselected); + + overview.subscribe("plotselected", function (ranges) { + plot.setSelection(ranges); + }); + + plot.subscribe("plothover", plothover); - plotAccordingToChoices(); - })(); - </script> + YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]); + } + SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n}); + </script> </div> </div>