From dc3855758288d6377ed1fb201cdd9bd0819f57ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=C3=ADbal=20Lim=C3=B3n?= Date: Thu, 29 Jan 2015 18:13:28 -0600 Subject: [PATCH] rrs: Add Maintainer statistics page. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maintainer statistics page gives information by Milestone and Maintainers assigned recipes, status of recipes (up-to-date, not-update, unknown) and percertange of work done. Signed-off-by: Aníbal Limón --- rrs/urls.py | 6 +- rrs/views.py | 100 +++++++++++++++++++++++++++++-- templates/rrs/base_toplevel.html | 8 ++- templates/rrs/maintainers.html | 99 ++++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 templates/rrs/maintainers.html diff --git a/rrs/urls.py b/rrs/urls.py index 8403ebb..49f5e63 100644 --- a/rrs/urls.py +++ b/rrs/urls.py @@ -1,7 +1,7 @@ from django.conf.urls import patterns, include, url from rrs.models import Milestone -from rrs.views import RecipeListView, RecipeDetailView +from rrs.views import RecipeListView, RecipeDetailView, MaintainerListView urlpatterns = patterns('', url(r'^$', redirect_to, {'url' : reverse_lazy('recipes', args=(Milestone.get_current().name,))}, @@ -14,4 +14,8 @@ urlpatterns = patterns('', RecipeDetailView.as_view( template_name='rrs/recipedetail.html'), name='recipedetail'), + url(r'^maintainers/(?P.*)/$', + MaintainerListView.as_view( + template_name='rrs/maintainers.html'), + name="maintainers"), ) diff --git a/rrs/views.py b/rrs/views.py index 388a527..53c6e11 100644 --- a/rrs/views.py +++ b/rrs/views.py @@ -26,7 +26,7 @@ def _get_layer_branch_url(branch, layer_name): return ("http://layers.openembedded.org/layerindex/branch/%s/layer/%s/"\ % (branch, layer_name)) -def _get_milestone_statistics(milestone): +def _get_milestone_statistics(milestone, maintainer_name=None): milestone_statistics = {} recipe_upstream_history = RecipeUpstreamHistory.get_last_by_date_range( @@ -35,22 +35,51 @@ def _get_milestone_statistics(milestone): ) if recipe_upstream_history is None: + milestone_statistics['all'] = '0' milestone_statistics['up_to_date'] = '0' milestone_statistics['not_updated'] = '0' milestone_statistics['unknown'] = '0' milestone_statistics['percentage'] = '0.0' - else: - recipes_all = RecipeUpstream.objects.filter(history = + elif maintainer_name is None: + recipe_count = RecipeUpstream.objects.filter(history = recipe_upstream_history).count() + milestone_statistics['all'] = recipe_count milestone_statistics['up_to_date'] = RecipeUpstream.objects.filter( history = recipe_upstream_history, status = 'Y').count() milestone_statistics['not_updated'] = RecipeUpstream.objects.filter( history = recipe_upstream_history, status = 'N').count() - milestone_statistics['unknown'] = recipes_all - \ + milestone_statistics['unknown'] = milestone_statistics['all'] - \ (milestone_statistics['up_to_date'] + milestone_statistics['not_updated']) milestone_statistics['percentage'] = "%.2f" % \ - ((float(milestone_statistics['up_to_date']) / float(recipes_all)) * 100) + ((float(milestone_statistics['up_to_date']) / + float(milestone_statistics['all'])) * 100) + else: + recipe_maintainer_history = RecipeMaintainerHistory.get_by_end_date( + milestone.end_date) + + recipes_all = [] + for rm in RecipeMaintainer.objects.filter(history = recipe_maintainer_history, + maintainer__name = maintainer_name): + ru = RecipeUpstream.objects.filter(recipe = rm.recipe, history = + recipe_upstream_history)[0] + recipes_all.append(ru) + + milestone_statistics['all'] = len(recipes_all) + milestone_statistics['up_to_date'] = 0 + milestone_statistics['not_updated'] = 0 + milestone_statistics['unknown'] = 0 + for ru in recipes_all: + if ru.status == 'Y': + milestone_statistics['up_to_date'] += 1 + elif ru.status == 'N': + milestone_statistics['not_updated'] += 1 + else: + milestone_statistics['unknown'] += 1 + + milestone_statistics['percentage'] = "%.2f" % \ + ((float(milestone_statistics['up_to_date']) / + float(milestone_statistics['all'])) * 100) return milestone_statistics @@ -266,3 +295,64 @@ class RecipeDetailView(DetailView): context['recipe_distros'] = RecipeDistro.get_distros_by_recipe(recipe) return context + +class MaintainerList(): + name = None + recipes_all = 0 + recipes_up_to_date = '0' + recipes_not_updated = '0' + recipes_unknown = '0' + percentage_done = '0.00' + + def __init__(self, name): + self.name = name + +class MaintainerListView(ListView): + context_object_name = 'maintainer_list' + + def get_queryset(self): + maintainer_list = [] + self.maintainer_count = 0 + + self.milestone_name = self.kwargs['milestone_name'] + milestone = get_object_or_404(Milestone, name=self.milestone_name) + + self.milestone_statistics = _get_milestone_statistics(milestone) + + recipe_maintainer_history = RecipeMaintainerHistory.get_by_end_date( + milestone.end_date) + + if recipe_maintainer_history: + for rm in RecipeMaintainer.objects.filter(history = + recipe_maintainer_history).values( + 'maintainer__name').distinct().order_by('maintainer__name'): + maintainer_list.append(MaintainerList(rm['maintainer__name'])) + + self.maintainer_count = len(maintainer_list) + + for ml in maintainer_list: + milestone_statistics = _get_milestone_statistics(milestone, ml.name) + ml.recipes_all = milestone_statistics['all'] + ml.recipes_up_to_date = milestone_statistics['up_to_date'] + ml.recipes_not_updated = milestone_statistics['not_updated'] + ml.recipes_unknown = milestone_statistics['unknown'] + ml.percentage_done = milestone_statistics['percentage'] + + return maintainer_list + + def get_context_data(self, **kwargs): + context = super(MaintainerListView, self).get_context_data(**kwargs) + + context['this_url_name'] = resolve(self.request.path_info).url_name + + context['milestone_name'] = self.milestone_name + context['all_milestones'] = Milestone.objects.filter().order_by('-id') + + context['recipes_percentage'] = self.milestone_statistics['percentage'] + context['recipes_up_to_date'] = self.milestone_statistics['up_to_date'] + context['recipes_not_updated'] = self.milestone_statistics['not_updated'] + context['recipes_unknown'] = self.milestone_statistics['unknown'] + + context['maintainer_count'] = self.maintainer_count + + return context diff --git a/templates/rrs/base_toplevel.html b/templates/rrs/base_toplevel.html index 9524eb0..ebb0a3f 100644 --- a/templates/rrs/base_toplevel.html +++ b/templates/rrs/base_toplevel.html @@ -56,18 +56,22 @@ {% endblock %} diff --git a/templates/rrs/maintainers.html b/templates/rrs/maintainers.html new file mode 100644 index 0000000..5650daf --- /dev/null +++ b/templates/rrs/maintainers.html @@ -0,0 +1,99 @@ +{% extends "rrs/base_toplevel.html" %} +{% load i18n %} +{% load staticfiles %} + +{% load url from future %} + +{% comment %} + + rrs-web - maintainers page template + + Copyright (C) 2015 Intel Corporation + Licensed under the MIT license, see COPYING.MIT for details + +{% endcomment %} + +{% block navs %} +{% endblock %} + +{% block content_inner %} + + +{% if maintainer_count == 0 %} +
No maintainers found
+{% else %} + + + + + + + + + + + + + + + + +{% for ml in maintainer_list %} + + + + + + + + + + + + +{% endfor %} + +
MaintainerAssigned recipesUp-to-dateNot updatedUnknown% donewk1wk2wk3wk4
+ + {{ ml.name }} + + {{ ml.recipes_all }} + + {{ ml.recipes_up_to_date }} + + + + {{ ml.recipes_not_updated }} + + + + {{ ml.recipes_unknown }} + + {{ ml.percentage_done }}
+{% endif %} +{% endblock %} + +{% block scripts %} +{% if maintainer_count > 0 %} + + +{% endif %} +{% endblock %}