Changeset - b12ea84fb906
[Not reviewed]
celery
0 3 0
Marcin Kuzminski - 15 years ago 2010-09-19 03:29:49
marcin@python-works.com
Some fixes to summary, and total rewrite of summary graphs implemented more interactive graph.
Some small fixes for tasks (sorting,limit)
3 files changed with 348 insertions and 187 deletions:
0 comments (0 inline, 0 general)
pylons_app/lib/celerylib/__init__.py
Show inline comments
 
@@ -14,13 +14,16 @@ class ResultWrapper(object):
 
    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))
 
    
pylons_app/lib/celerylib/tasks.py
Show inline comments
 
@@ -7,8 +7,9 @@ from pylons_app.lib.celerylib import run
 
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 @@ def get_commits_stats(repo):
 
                        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 @@ def get_commits_stats(repo):
 
                
 
            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 @@ def get_commits_stats(repo):
 
                    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 @@ def get_commits_stats(repo):
 
    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"]
 
                      }
 
        
pylons_app/templates/summary/summary.html
Show inline comments
 
@@ -76,7 +76,9 @@ E.onDOMReady(function(e){
 
			      <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 @@ E.onDOMReady(function(e){
 
<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 @@ E.onDOMReady(function(e){
 
	    	</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>    
0 comments (0 inline, 0 general)