rrs: add charts page

Add some basic charts to show recipe upstream / patch status.

Implements [YOCTO #7909].

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2018-04-09 14:45:49 +12:00
parent 130ff8e803
commit 183ba0f7eb
4 changed files with 146 additions and 3 deletions

View File

@ -2,7 +2,8 @@ from django.conf.urls import patterns, include, url
from rrs.models import Release, Milestone from rrs.models import Release, Milestone
from rrs.views import RecipeListView, recipes_report, RecipeDetailView, \ from rrs.views import RecipeListView, recipes_report, RecipeDetailView, \
MaintainerListView, FrontPageRedirect, MaintenancePlanRedirect MaintainerListView, FrontPageRedirect, MaintenancePlanRedirect, \
MaintenanceStatsView
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^$', FrontPageRedirect.as_view(), url(r'^$', FrontPageRedirect.as_view(),
@ -25,4 +26,8 @@ urlpatterns = patterns('',
MaintainerListView.as_view( MaintainerListView.as_view(
template_name='rrs/maintainers.html'), template_name='rrs/maintainers.html'),
name="rrs_maintainers"), name="rrs_maintainers"),
url(r'^stats/(?P<maintplan_name>.*)/(?P<release_name>.*)/(?P<milestone_name>.*)/$',
MaintenanceStatsView.as_view(
template_name='rrs/rrs_stats.html'),
name="rrs_stats"),
) )

View File

@ -6,7 +6,7 @@ from django.http import HttpResponse
from datetime import date, datetime from datetime import date, datetime
from django.http import Http404 from django.http import Http404
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.views.generic import ListView, DetailView, RedirectView from django.views.generic import TemplateView, ListView, DetailView, RedirectView
from django.core.urlresolvers import resolve, reverse, reverse_lazy from django.core.urlresolvers import resolve, reverse, reverse_lazy
from django.db import connection from django.db import connection
@ -841,3 +841,83 @@ class MaintainerListView(ListView):
return context return context
class MaintenanceStatsView(TemplateView):
def get_context_data(self, **kwargs):
context = super(MaintenanceStatsView, self).get_context_data(**kwargs)
context['this_url_name'] = resolve(self.request.path_info).url_name
self.maintplan_name = self.kwargs['maintplan_name']
maintplan = get_object_or_404(MaintenancePlan, name=self.maintplan_name)
self.release_name = self.kwargs['release_name']
release = get_object_or_404(Release, plan=maintplan, name=self.release_name)
self.milestone_name = self.kwargs['milestone_name']
milestone = get_object_or_404(Milestone, release = release, name=self.milestone_name)
self.milestone_statistics = _get_milestone_statistics(milestone)
context['recipes_percentage'] = self.milestone_statistics['percentage']
context['recipes_all_upgraded'] = self.milestone_statistics['all_upgraded']
context['recipes_all_not_upgraded'] = self.milestone_statistics['all_not_upgraded']
context['recipes_up_to_date'] = self.milestone_statistics['up_to_date']
context['recipes_not_updated'] = self.milestone_statistics['not_updated']
context['recipes_cant_be_updated'] = self.milestone_statistics['cant_be_updated']
context['recipes_unknown'] = self.milestone_statistics['unknown']
context['recipes_percentage_up_to_date'] = \
self.milestone_statistics['percentage_up_to_date']
context['recipes_percentage_not_updated'] = \
self.milestone_statistics['percentage_not_updated']
context['recipes_percentage_cant_be_updated'] = \
self.milestone_statistics['percentage_cant_be_updated']
context['recipes_percentage_unknown'] = \
self.milestone_statistics['percentage_unknown']
# *** Upstream status chart ***
statuses = []
status_counts = {}
statuses.append('Up-to-date')
status_counts['Up-to-date'] = self.milestone_statistics['up_to_date']
statuses.append('Not updated')
status_counts['Not updated'] = self.milestone_statistics['not_updated']
statuses.append('Can\'t be updated')
status_counts['Can\'t be updated'] = self.milestone_statistics['cant_be_updated']
statuses.append('Unknown')
status_counts['Unknown'] = self.milestone_statistics['unknown']
statuses = sorted(statuses, key=lambda status: status_counts[status], reverse=True)
chartdata = {'x': statuses, 'y': [status_counts[k] for k in statuses]}
context['charttype_status'] = 'discreteBarChart'
context['chartdata_status'] = chartdata
context['extra_status'] = {
'x_is_date': False,
'x_axis_format': '',
'tag_script_js': True,
'jquery_on_ready': False,
}
# *** Patch status chart ***
patch_statuses = []
patch_status_counts = {}
for maintplanlayer in maintplan.maintenanceplanlayerbranch_set.all():
layerbranch = maintplanlayer.layerbranch
patches = Patch.objects.filter(recipe__layerbranch=layerbranch)
for choice, desc in Patch.PATCH_STATUS_CHOICES:
if desc not in patch_statuses:
patch_statuses.append(desc)
patch_status_counts[desc] = patch_status_counts.get(desc, 0) + patches.filter(status=choice).count()
patch_statuses = sorted(patch_statuses, key=lambda status: patch_status_counts[status], reverse=True)
chartdata = {'x': patch_statuses, 'y': [patch_status_counts[k] for k in patch_statuses]}
context['charttype_patchstatus'] = 'discreteBarChart'
context['chartdata_patchstatus'] = chartdata
context['extra_patchstatus'] = {
'x_is_date': False,
'x_axis_format': '',
'tag_script_js': True,
'jquery_on_ready': False,
}
return context

View File

@ -131,7 +131,17 @@
{% endif %} {% endif %}
Maintainer statistics</a> Maintainer statistics</a>
</li> </li>
</ul>
{% if this_url_name == 'rrs_stats' %}
<li class="active">
<a href="#">
{% else %}
<li>
<a href="{% url 'rrs_stats' maintplan_name release_name milestone_name %}">
{% endif %}
Charts</a>
</li>
</ul>
{% endblock %} {% endblock %}
{% block content_inner %}{% endblock %} {% block content_inner %}{% endblock %}

View File

@ -0,0 +1,48 @@
{% extends "rrs/base_toplevel.html" %}
{% load i18n %}
{% load nvd3_tags %}
{% load staticfiles %}
{% comment %}
rrs-web - recipe maintenance stats template
Copyright (C) 2013, 2018 Intel Corporation
Licensed under the MIT license, see COPYING.MIT for details
{% endcomment %}
<!--
{% block title_append %} - recipe maintenance statistics - {{ maintplan_name }} {{ release_name }} {{ milestone_name }}{% endblock %}
-->
{% block content_inner %}
{% autoescape on %}
<div class="row-fluid">
<h2>Maintenance statistics - {{ maintplan_name }} {{ release_name }} {{ milestone_name }}</h2>
<h3>Upstream status (milestone)</h3>
{% include_container "chart_status" 400 500 %}
<h3>Patch status (current)</h3>
{% include_container "chart_patchstatus" 400 700 %}
</div>
{% endautoescape %}
{% endblock %}
{% block scripts %}
<link media="all" href="{% static "css/nv.d3.css" %}" type="text/css" rel="stylesheet" />
<script src="{% static "js/d3.js" %}" type="text/javascript"></script>
<script src="{% static "js/nv.d3.js" %}" type="text/javascript"></script>
{% load_chart charttype_status chartdata_status "chart_status" extra_status %}
{% load_chart charttype_patchstatus chartdata_patchstatus "chart_patchstatus" extra_patchstatus %}
{% endblock %}