aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2018-04-09 14:45:49 +1200
committerPaul Eggleton <paul.eggleton@linux.intel.com>2018-05-04 23:57:53 +1200
commit183ba0f7eb3024cd8072689736ae8ca7fb5f9477 (patch)
tree6ff72358b62fa663751cd40b431901c76ad65bf0
parent130ff8e8030e038359ad38b379a69d8644096f5e (diff)
downloadopenembedded-core-contrib-183ba0f7eb3024cd8072689736ae8ca7fb5f9477.tar.gz
openembedded-core-contrib-183ba0f7eb3024cd8072689736ae8ca7fb5f9477.tar.bz2
openembedded-core-contrib-183ba0f7eb3024cd8072689736ae8ca7fb5f9477.zip
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>
-rw-r--r--rrs/urls.py7
-rw-r--r--rrs/views.py82
-rw-r--r--templates/rrs/base_toplevel.html12
-rw-r--r--templates/rrs/rrs_stats.html48
4 files changed, 146 insertions, 3 deletions
diff --git a/rrs/urls.py b/rrs/urls.py
index 18fa61be54..4524b9633e 100644
--- a/rrs/urls.py
+++ b/rrs/urls.py
@@ -2,7 +2,8 @@ from django.conf.urls import patterns, include, url
from rrs.models import Release, Milestone
from rrs.views import RecipeListView, recipes_report, RecipeDetailView, \
- MaintainerListView, FrontPageRedirect, MaintenancePlanRedirect
+ MaintainerListView, FrontPageRedirect, MaintenancePlanRedirect, \
+ MaintenanceStatsView
urlpatterns = patterns('',
url(r'^$', FrontPageRedirect.as_view(),
@@ -25,4 +26,8 @@ urlpatterns = patterns('',
MaintainerListView.as_view(
template_name='rrs/maintainers.html'),
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"),
)
diff --git a/rrs/views.py b/rrs/views.py
index ed05e8196e..432e30ac03 100644
--- a/rrs/views.py
+++ b/rrs/views.py
@@ -6,7 +6,7 @@ from django.http import HttpResponse
from datetime import date, datetime
from django.http import Http404
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.db import connection
@@ -841,3 +841,83 @@ class MaintainerListView(ListView):
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
+
+
diff --git a/templates/rrs/base_toplevel.html b/templates/rrs/base_toplevel.html
index e22684b497..47bc71900f 100644
--- a/templates/rrs/base_toplevel.html
+++ b/templates/rrs/base_toplevel.html
@@ -131,7 +131,17 @@
{% endif %}
Maintainer statistics</a>
</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 %}
{% block content_inner %}{% endblock %}
diff --git a/templates/rrs/rrs_stats.html b/templates/rrs/rrs_stats.html
new file mode 100644
index 0000000000..092d817b9f
--- /dev/null
+++ b/templates/rrs/rrs_stats.html
@@ -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 %}