mirror of
git://git.yoctoproject.org/layerindex-web.git
synced 2025-07-19 20:59:01 +02:00
rrs: Add Maintainer statistics page.
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 <anibal.limon@linux.intel.com>
This commit is contained in:
parent
6dfc369f29
commit
dc38557582
|
@ -1,7 +1,7 @@
|
||||||
from django.conf.urls import patterns, include, url
|
from django.conf.urls import patterns, include, url
|
||||||
|
|
||||||
from rrs.models import Milestone
|
from rrs.models import Milestone
|
||||||
from rrs.views import RecipeListView, RecipeDetailView
|
from rrs.views import RecipeListView, RecipeDetailView, MaintainerListView
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
url(r'^$', redirect_to, {'url' : reverse_lazy('recipes', args=(Milestone.get_current().name,))},
|
url(r'^$', redirect_to, {'url' : reverse_lazy('recipes', args=(Milestone.get_current().name,))},
|
||||||
|
@ -14,4 +14,8 @@ urlpatterns = patterns('',
|
||||||
RecipeDetailView.as_view(
|
RecipeDetailView.as_view(
|
||||||
template_name='rrs/recipedetail.html'),
|
template_name='rrs/recipedetail.html'),
|
||||||
name='recipedetail'),
|
name='recipedetail'),
|
||||||
|
url(r'^maintainers/(?P<milestone_name>.*)/$',
|
||||||
|
MaintainerListView.as_view(
|
||||||
|
template_name='rrs/maintainers.html'),
|
||||||
|
name="maintainers"),
|
||||||
)
|
)
|
||||||
|
|
100
rrs/views.py
100
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/"\
|
return ("http://layers.openembedded.org/layerindex/branch/%s/layer/%s/"\
|
||||||
% (branch, layer_name))
|
% (branch, layer_name))
|
||||||
|
|
||||||
def _get_milestone_statistics(milestone):
|
def _get_milestone_statistics(milestone, maintainer_name=None):
|
||||||
milestone_statistics = {}
|
milestone_statistics = {}
|
||||||
|
|
||||||
recipe_upstream_history = RecipeUpstreamHistory.get_last_by_date_range(
|
recipe_upstream_history = RecipeUpstreamHistory.get_last_by_date_range(
|
||||||
|
@ -35,22 +35,51 @@ def _get_milestone_statistics(milestone):
|
||||||
)
|
)
|
||||||
|
|
||||||
if recipe_upstream_history is None:
|
if recipe_upstream_history is None:
|
||||||
|
milestone_statistics['all'] = '0'
|
||||||
milestone_statistics['up_to_date'] = '0'
|
milestone_statistics['up_to_date'] = '0'
|
||||||
milestone_statistics['not_updated'] = '0'
|
milestone_statistics['not_updated'] = '0'
|
||||||
milestone_statistics['unknown'] = '0'
|
milestone_statistics['unknown'] = '0'
|
||||||
milestone_statistics['percentage'] = '0.0'
|
milestone_statistics['percentage'] = '0.0'
|
||||||
else:
|
elif maintainer_name is None:
|
||||||
recipes_all = RecipeUpstream.objects.filter(history =
|
recipe_count = RecipeUpstream.objects.filter(history =
|
||||||
recipe_upstream_history).count()
|
recipe_upstream_history).count()
|
||||||
|
|
||||||
|
milestone_statistics['all'] = recipe_count
|
||||||
milestone_statistics['up_to_date'] = RecipeUpstream.objects.filter(
|
milestone_statistics['up_to_date'] = RecipeUpstream.objects.filter(
|
||||||
history = recipe_upstream_history, status = 'Y').count()
|
history = recipe_upstream_history, status = 'Y').count()
|
||||||
milestone_statistics['not_updated'] = RecipeUpstream.objects.filter(
|
milestone_statistics['not_updated'] = RecipeUpstream.objects.filter(
|
||||||
history = recipe_upstream_history, status = 'N').count()
|
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['up_to_date'] + milestone_statistics['not_updated'])
|
||||||
milestone_statistics['percentage'] = "%.2f" % \
|
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
|
return milestone_statistics
|
||||||
|
|
||||||
|
@ -266,3 +295,64 @@ class RecipeDetailView(DetailView):
|
||||||
context['recipe_distros'] = RecipeDistro.get_distros_by_recipe(recipe)
|
context['recipe_distros'] = RecipeDistro.get_distros_by_recipe(recipe)
|
||||||
|
|
||||||
return context
|
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
|
||||||
|
|
|
@ -56,18 +56,22 @@
|
||||||
<ul class="nav nav-pills">
|
<ul class="nav nav-pills">
|
||||||
{% if this_url_name == 'recipes' %}
|
{% if this_url_name == 'recipes' %}
|
||||||
<li class="active">
|
<li class="active">
|
||||||
|
<a href="#">
|
||||||
{% else %}
|
{% else %}
|
||||||
<li>
|
<li>
|
||||||
|
<a href="{% url 'recipes' milestone_name %}{{ extra_url_param }}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{% url this_url_name milestone_name %}{{ extra_url_param }}">Recipes status</a>
|
Recipes status</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% if this_url_name == 'maintainers' %}
|
{% if this_url_name == 'maintainers' %}
|
||||||
<li class="active">
|
<li class="active">
|
||||||
|
<a href="#">
|
||||||
{% else %}
|
{% else %}
|
||||||
<li>
|
<li>
|
||||||
|
<a href="{% url 'maintainers' milestone_name %}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="#">Maintainer statistics</a>
|
Maintainer statistics</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
99
templates/rrs/maintainers.html
Normal file
99
templates/rrs/maintainers.html
Normal file
|
@ -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 %}
|
||||||
|
<div class="navbar navbar-table-controls">
|
||||||
|
<div class="navbar-inner table-controls">
|
||||||
|
<ul class="nav">
|
||||||
|
<li class="dropdown">
|
||||||
|
<span class="badge" style="margin-top:11px;">{{ maintainer_count }} maintainers</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<form class="navbar-form pull-right">
|
||||||
|
<input type="text" class="input-xxlarge pull-right" placeholder="Search maintainers" id="filter">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if maintainer_count == 0 %}
|
||||||
|
<div class="alert"> No maintainers found</div>
|
||||||
|
{% else %}
|
||||||
|
<table class="table table-bordered table-hover statisticstable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Maintainer</th>
|
||||||
|
<th class="muted">Assigned recipes</th>
|
||||||
|
<th class="muted">Up-to-date</th>
|
||||||
|
<th>Not updated</th>
|
||||||
|
<th class="muted">Unknown</th>
|
||||||
|
<th>% done</th>
|
||||||
|
<th class="current-wk">wk1</th>
|
||||||
|
<th class="muted">wk2</th>
|
||||||
|
<th class="muted">wk3</th>
|
||||||
|
<th class="muted">wk4</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for ml in maintainer_list %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'recipes' milestone_name %}?maintainer_name={{ ml.name|urlencode }}">
|
||||||
|
{{ ml.name }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ ml.recipes_all }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'recipes' milestone_name %}?upstream_status={{ "Up-to-date"|urlencode }}&maintainer_name={{ ml.name|urlencode }}">
|
||||||
|
{{ ml.recipes_up_to_date }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'recipes' milestone_name %}?upstream_status={{ "Not updated"|urlencode }}&maintainer_name={{ ml.name|urlencode }}">
|
||||||
|
{{ ml.recipes_not_updated }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'recipes' milestone_name %}?upstream_status={{ "Unknown"|urlencode }}&maintainer_name={{ ml.name|urlencode }}">
|
||||||
|
{{ ml.recipes_unknown }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ ml.percentage_done }}</td>
|
||||||
|
<td class="current-wk"></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{% if maintainer_count > 0 %}
|
||||||
|
<script src="{% static "js/uitablefilter.js" %}"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#filter").keyup(function() {
|
||||||
|
var table = $('.statisticstable');
|
||||||
|
$.uiTableFilter(table, this.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue
Block a user