Merge "Open reviews report is added"

This commit is contained in:
Jenkins
2013-10-29 09:27:37 +00:00
committed by Gerrit Code Review
4 changed files with 165 additions and 19 deletions

View File

@@ -12,6 +12,7 @@
# implied. # implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import json
import operator import operator
import time import time
@@ -48,27 +49,74 @@ def blueprint_summary(module, blueprint_name):
return {'blueprint': bpd, 'activity': activity} return {'blueprint': bpd, 'activity': activity}
def _get_day(timestamp, time_now):
return int((time_now - timestamp) / 60 / 60 / 24)
def _process_stat(data, key, time_now):
if not data:
return None
data = sorted(data, key=operator.itemgetter(key))
days = _get_day(data[0][key], time_now)
chart_data = [0] * (days + 1)
sum_ages = 0
for review in data:
age = time_now - review[key]
sum_ages += age
review[key + '_age'] = utils.make_age_string(age)
chart_data[_get_day(review[key], time_now)] += 1
return {
'reviews': data,
'average': utils.make_age_string(sum_ages / len(data)),
'max': data[0][key + '_age'],
'chart_data': json.dumps(chart_data),
}
@blueprint.route('/reviews/<module>') @blueprint.route('/reviews/<module>')
@decorators.templated() @decorators.templated()
@decorators.exception_handler() @decorators.exception_handler()
def open_reviews(module): def open_reviews(module):
memory_storage = vault.get_memory_storage() memory_storage_inst = vault.get_memory_storage()
now = int(time.time()) time_now = int(time.time())
review_ids = (memory_storage.get_record_ids_by_modules([module]) &
memory_storage.get_record_ids_by_type('review')) review_marks = {}
records = [] reviews = {}
for review in memory_storage.get_records(review_ids):
if review['status'] != 'NEW': mark_ids = (memory_storage_inst.get_record_ids_by_modules([module]) &
continue memory_storage_inst.get_record_ids_by_type('mark'))
processed_review = review.copy()
helpers.extend_record(processed_review) for mark in memory_storage_inst.get_records(mark_ids):
processed_review['age'] = utils.make_age_string( review_id = mark['review_id']
now - processed_review['date']) if review_id in review_marks:
records.append(processed_review) if mark['date'] > review_marks[review_id]['date']:
review_marks[review_id] = mark
else:
review = memory_storage_inst.get_record_by_primary_key(review_id)
if not review:
continue # todo because we filter jenkins
review_marks[review_id] = mark
reviews[review_id] = review
waiting_on_reviewer = []
total_open = 0
for review_id, mark in review_marks.iteritems():
if reviews[review_id]['open']:
total_open += 1
if mark['value'] in ['1', '2']:
waiting_on_reviewer.append(reviews[review_id])
return { return {
'module': module, 'module': module,
'oldest': sorted(records, key=operator.itemgetter('date'))[:5] 'total_open': total_open,
'waiting_on_reviewer': len(waiting_on_reviewer),
'waiting_on_submitter': total_open - len(waiting_on_reviewer),
'latest_revision': _process_stat(
waiting_on_reviewer, 'lastUpdated', time_now),
'first_revision': _process_stat(waiting_on_reviewer, 'date', time_now),
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -3,6 +3,65 @@
<head> <head>
<title>Open reviews report for {{ module }}</title> <title>Open reviews report for {{ module }}</title>
<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/style.css') }}">
<link href='http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic&subset=latin,cyrillic' rel='stylesheet' type='text/css' />
<link href='http://fonts.googleapis.com/css?family=PT+Sans+Caption&subset=latin,cyrillic' rel='stylesheet' type='text/css' />
<link href='http://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700&subset=latin,cyrillic' rel='stylesheet' type='text/css' />
<link rel="icon" href="{{ url_for('static', filename='images/favicon.png') }}" type="image/png"/>
<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') }}">
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/select2.css') }}">
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/style.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.barRenderer.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.categoryAxisRenderer.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" src="{{ url_for('static', filename='js/select2.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery.tmpl.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/stackalytics-ui.js') }}"></script>
<script type="text/javascript">
function render_bar_chart(chart_id, chart_data) {
$.jqplot(chart_id, chart_data, {
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
rendererOptions: {
barMargin: 1
},
pointLabels: {show: true}
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
label: "Age"
},
yaxis: {
label: "Count"
}
}
});
}
$(document).ready(function () {
render_bar_chart("latest_revision_chart", [{{ latest_revision.chart_data }}]);
render_bar_chart("first_revision_chart", [{{ first_revision.chart_data }}]);
});
</script>
<style> <style>
.label { .label {
font-weight: bold; font-weight: bold;
@@ -16,11 +75,44 @@
</head> </head>
<body style="margin: 2em;"> <body style="margin: 2em;">
<h1>Open Reviews Report</h1> <h1>Open reviews for {{ module }}</h1>
<h3>Summary:</h3>
<ul>
<li>Total open reviews: {{ total_open }}</li>
<li>Waiting on reviewer: {{ waiting_on_reviewer }}</li>
<li>Waiting on submitter: {{ waiting_on_submitter }}</li>
</ul>
{% if total_open %}
<h3>Stats since last revision</h3>
<ul>
<li>Average wait time: {{ latest_revision.average }}</li>
<li>Max wait time: {{ latest_revision.max }}</li>
</ul>
<div id="latest_revision_chart" style="width: 100%; height: 350px;"></div>
<h3>Longest waiting reviews (since first revision, total age): </h3>
<ol> <ol>
{% for item in oldest %} {% for item in latest_revision.reviews[:5] %}
<li>{{ item.age }} <a href="{{ item.url }}">{{ item.url }}</a> {{ item.subject }}</li> <li>{{ item.lastUpdated_age }} <a href="{{ item.url }}">{{ item.url }}</a> {{ item.subject }} by {{ item.author_name }} ({{ item.company_name }})</li>
{% endfor %} {% endfor %}
</ol> </ol>
<h3>Stats since first revision</h3>
<ul>
<li>Average wait time: {{ first_revision.average }}</li>
<li>Max wait time: {{ first_revision.max }}</li>
</ul>
<div id="first_revision_chart" style="width: 100%; height: 350px;"></div>
<ol>
{% for item in first_revision.reviews[:5] %}
<li>{{ item.date_age }} <a href="{{ item.url }}">{{ item.url }}</a> {{ item.subject }} by {{ item.author_name }} ({{ item.company_name }})</li>
{% endfor %}
</ol>
{% endif %}