
* Data updater is implemented * Completed implementation of commit processor * Logging is added into commit processor and runtime storage * Commit processor is fixed * Domain-company map is inverted * Extracted get update count into separate function * Fixed regex that matches diff statistics (lines inserted, lines deleted and files changed) * Implemented caching of unknown users * Replaced dictionaries by sets for pids and branches * Vcs is responsible for module and branches fields of commit record * Added release tags support * Implemented statistics by company * Added config for releases * Implemented front-end for companies details * Implemented front-end for modules details * Fixed metric switch * Implemented timeline rendering * Release selector is fixed * Chdir is needed after cloning a new repo * Company details screen is implemented * Fixed invalid emails processing by Launchpad * Fixed parsing of 0 files changed case * Module details screen implemented * Commit message is cleared and links are inserted * Engineer details screen is implemented * Fixed mapping from company to email for subdomains of 3rd level * Fixed wrong user structure for users not found by LP * Also coverage for commit processor * Fixed company matching algorithm * The company was not matched when user email had more domains than company's one * Add option to enforce sync with default data * Default data is added. Old confs removed * Add *.local into gitignore Scripts cleanup Moved from pylibmc to python-memcached Library pylibmc depends on libmemcached and doesn't work on CentOS (version conflict bw lib requirement and memcached). Change-Id: I0cc61c6d344ba24442ec954635010b518c0efa95
296 lines
10 KiB
HTML
296 lines
10 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block head %}
|
|
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/style.css') }}">
|
|
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/jquery.jqplot.min.css') }}">
|
|
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/jquery.dataTables.css') }}">
|
|
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery-1.9.1.min.js') }}"></script>
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery.dataTables.min.js') }}"></script>
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery.jqplot.min.js') }}"></script>
|
|
<!--[if lt IE 9]><script type="text/javascript" src="{{ url_for('static', filename='js/excanvas.min.js') }}"></script><![endif]-->
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.json2.min.js') }}"></script>
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.pieRenderer.min.js') }}"></script>
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.dateAxisRenderer.min.js') }}"></script>
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.canvasTextRenderer.min.js') }}"></script>
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.canvasAxisTickRenderer.min.js') }}"></script>
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.cursor.min.js') }}"></script>
|
|
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.highlighter.min.js') }}"></script>
|
|
|
|
<script type="text/javascript">
|
|
|
|
function showTimeline(data) {
|
|
var plot = $.jqplot('timeline', data, {
|
|
gridPadding: {
|
|
right: 35
|
|
},
|
|
cursor: {
|
|
show: false
|
|
},
|
|
highlighter: {
|
|
show: true,
|
|
sizeAdjust: 6
|
|
},
|
|
axes: {
|
|
xaxis: {
|
|
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
|
|
tickOptions: {
|
|
fontSize: '8pt',
|
|
angle: -90,
|
|
formatString: '%b \'%y'
|
|
},
|
|
renderer: $.jqplot.DateAxisRenderer,
|
|
tickInterval: '1 month'
|
|
},
|
|
yaxis: {
|
|
min: 0,
|
|
label: ''
|
|
},
|
|
y2axis: {
|
|
min: 0,
|
|
label: ''
|
|
}
|
|
},
|
|
series: [
|
|
{
|
|
shadow: false,
|
|
fill: true,
|
|
fillColor: '#4bb2c5',
|
|
fillAlpha: 0.3
|
|
},
|
|
{
|
|
shadow: false,
|
|
fill: true,
|
|
color: '#4bb2c5',
|
|
fillColor: '#4bb2c5'
|
|
},
|
|
{
|
|
shadow: false,
|
|
lineWidth: 1.5,
|
|
showMarker: true,
|
|
markerOptions: { size: 5 },
|
|
yaxis: 'y2axis'
|
|
}
|
|
]
|
|
});
|
|
}
|
|
|
|
function timelineRenderer(options) {
|
|
$(document).ready(function () {
|
|
$.ajax({
|
|
url: make_uri("/data/timeline", options),
|
|
dataType: "json",
|
|
success: function (data) {
|
|
showTimeline(data);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function chartAndTableRenderer(url, table_id, chart_id, link_prefix, options) {
|
|
|
|
$(document).ready(function () {
|
|
|
|
$.ajax({
|
|
url: make_uri(url, options),
|
|
dataType: "json",
|
|
success: function (data) {
|
|
|
|
var tableData = [];
|
|
var chartData = [];
|
|
|
|
var limit = 10;
|
|
var aggregate = 0;
|
|
var index = 1;
|
|
var i;
|
|
|
|
for (i = 0; i < data.length; i++) {
|
|
if (i < limit - 1) {
|
|
chartData.push([data[i].name, data[i].metric]);
|
|
} else {
|
|
aggregate += data[i].metric;
|
|
}
|
|
|
|
var index_label = index;
|
|
if (data[i].name == "*independent") {
|
|
index_label = "";
|
|
} else {
|
|
index++;
|
|
}
|
|
var link = make_link(link_prefix, data[i].id, data[i].name);
|
|
tableData.push({"index": index_label, "link": link, "metric": data[i].metric});
|
|
}
|
|
|
|
if (i == limit) {
|
|
chartData.push([data[i-1].name, data[i-1].metric]);
|
|
} else if (i > limit) {
|
|
chartData.push(["others", aggregate]);
|
|
}
|
|
|
|
$("#" + table_id).dataTable({
|
|
"aLengthMenu": [
|
|
[25, 50, -1],
|
|
[25, 50, "All"]
|
|
],
|
|
"aaSorting": [
|
|
[ 2, "desc" ]
|
|
],
|
|
"sPaginationType": "full_numbers",
|
|
"iDisplayLength": 25,
|
|
"aaData": tableData,
|
|
"aoColumns": [
|
|
{ "mData": "index" },
|
|
{ "mData": "link" },
|
|
{ "mData": "metric" }
|
|
]
|
|
});
|
|
|
|
var plot = $.jqplot(chart_id, [chartData], {
|
|
seriesDefaults: {
|
|
renderer: jQuery.jqplot.PieRenderer,
|
|
rendererOptions: {
|
|
showDataLabels: true
|
|
}
|
|
},
|
|
legend: { show: true, location: 'e' }
|
|
});
|
|
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function getUrlVars() {
|
|
var vars = {};
|
|
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
|
|
vars[key] = value;
|
|
});
|
|
return vars;
|
|
}
|
|
|
|
$(document).ready(function () {
|
|
$('#metric').val('{{ metric }}');
|
|
$('#release').val('{{ release }}');
|
|
$('#project_type').val('{{ project_type }}');
|
|
});
|
|
|
|
function make_link(uri_prefix, id, title, options) {
|
|
var link = make_uri(uri_prefix + encodeURIComponent(id).toLowerCase(), options);
|
|
return "<a href=\"" + link + "\">" + title + "</a>"
|
|
}
|
|
|
|
function make_uri(uri, options) {
|
|
var ops = {};
|
|
if (options != null) {
|
|
$.extend(ops, options);
|
|
}
|
|
$.extend(ops, getUrlVars());
|
|
var str = $.map(ops,function (val, index) {
|
|
return index + "=" + val;
|
|
}).join("&");
|
|
|
|
return uri + "?" + str;
|
|
}
|
|
|
|
function make_std_options() {
|
|
var options = {};
|
|
{# if (getRelease() != 'havana') {#}
|
|
options['release'] = getRelease();
|
|
{# }#}
|
|
if (getMetric() != 'loc') {
|
|
options['metric'] = getMetric();
|
|
}
|
|
if (getProjectType() != 'incubation') {
|
|
options['project_type'] = getProjectType();
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
function reload() {
|
|
window.location.search = $.map(make_std_options(),function (val, index) {
|
|
return index + "=" + val;
|
|
}).join("&")
|
|
}
|
|
|
|
$(document).on('change', '#metric', function (evt) {
|
|
reload();
|
|
});
|
|
|
|
$(document).on('change', '#release', function (evt) {
|
|
reload();
|
|
});
|
|
|
|
$(document).on('change', '#project_type', function (evt) {
|
|
reload();
|
|
});
|
|
|
|
function getRelease() {
|
|
return $('#release').val()
|
|
}
|
|
|
|
function getMetric() {
|
|
return $('#metric').val()
|
|
}
|
|
|
|
function getProjectType() {
|
|
return $('#project_type').val()
|
|
}
|
|
|
|
</script>
|
|
|
|
{% block scripts %}{% endblock %}
|
|
|
|
{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="Xpage">
|
|
<div class="Xaheader">
|
|
<div class="drops" style='margin: 0.8em; height: 2em;'>
|
|
<span class="drop_metric" style="float: right;">
|
|
<label for="project_type">Projects </label><select id="project_type" name="project_type">
|
|
<option value="core">Core</option>
|
|
<option value="incubation">Core+Incubation</option>
|
|
<option value="all">All</option>
|
|
</select>
|
|
</span>
|
|
<span class="drop_metric" style="float: right;">
|
|
<label for="metric">Metric </label><select id="metric" name="metric">
|
|
<option value="commits">Commits</option>
|
|
<option value="loc">Lines of code</option>
|
|
</select>
|
|
</span>
|
|
<span class="drop_release" style="float: right;">
|
|
<label for="release">Release </label><select id="release" name="release">
|
|
<option value="all">All times</option>
|
|
<option value="havana">Havana</option>
|
|
<option value="grizzly">Grizzly</option>
|
|
<option value="folsom">Folsom</option>
|
|
<option value="essex">Essex</option>
|
|
</select>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="navigation">
|
|
<div id="timeline" style="width: 100%; height: 120px; margin-top: 15px;"></div>
|
|
</div>
|
|
|
|
<table style="width: 100%" cellspacing="0">
|
|
<tr>
|
|
<td style="width: 50%; vertical-align: top;">
|
|
<div class="body" style="margin-right: 2em;">
|
|
{% block left_frame %}{% endblock %}
|
|
</div>
|
|
</td>
|
|
<td style="width: 50%; vertical-align: top;">
|
|
<div class="body" style="margin-left: 2em;">
|
|
{% block right_frame %}{% endblock %}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
{% endblock %}
|