rrs: Add support for Recipe detail page

Recipe detail page gives information about Recipe like summary,
section, license, file, etc. also display's upgrade history.

rrs/models.py: Milestone add get_by_date and rewrite get_current
for use get_by_date and RecipeDistro add get_distros_by_recipe.

rrs/urls.py: Add url for recipe_detail with pk.
rrs/views.py: Add RecipeUpgradeDetail view.
templates/rrs/recipedetail.html: Add recipedetail template.

templates/rrs/recipes.html: Add link to Recipe detail by row.

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
This commit is contained in:
Aníbal Limón 2015-01-26 16:59:04 -06:00 committed by Paul Eggleton
parent a021f8d441
commit 4e00337d93
5 changed files with 267 additions and 9 deletions

View File

@ -23,14 +23,19 @@ class Milestone(models.Model):
@staticmethod @staticmethod
def get_current(): def get_current():
current = date.today() current = date.today()
current_milestone = Milestone.get_by_date(current)
return current_milestone or Milestone.objects.filter().order_by('-id')[0]
milestone_set = Milestone.objects.filter(start_date__lte = current, """ Get milestone by date """
end_date__gte = current).order_by('-id') @staticmethod
def get_by_date(date):
milestone_set = Milestone.objects.filter(start_date__lte = date,
end_date__gte = date).order_by('-id')
if milestone_set: if milestone_set:
return milestone_set[0] return milestone_set[0]
else: else:
return Milestone.objects.filter().order_by('-id')[0] return None
""" Get month intervals between the start and the end of the milestone """ """ Get month intervals between the start and the end of the milestone """
def get_intervals(self): def get_intervals(self):
@ -147,6 +152,17 @@ class RecipeDistro(models.Model):
def __unicode__(self): def __unicode__(self):
return '%s: %s' % (self.recipe.pn, self.distro) return '%s: %s' % (self.recipe.pn, self.distro)
@staticmethod
def get_distros_by_recipe(recipe):
recipe_distros = []
query = RecipeDistro.objects.filter(recipe = recipe).order_by('distro')
for q in query:
recipe_distros.append(q.distro)
return recipe_distros
class RecipeUpgrade(models.Model): class RecipeUpgrade(models.Model):
recipe = models.ForeignKey(Recipe) recipe = models.ForeignKey(Recipe)
maintainer = models.ForeignKey(Maintainer, blank=True, null=True) maintainer = models.ForeignKey(Maintainer, blank=True, null=True)

View File

@ -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 from rrs.views import RecipeListView, RecipeDetailView
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,))},
@ -10,4 +10,8 @@ urlpatterns = patterns('',
RecipeListView.as_view( RecipeListView.as_view(
template_name='rrs/recipes.html'), template_name='rrs/recipes.html'),
name='recipes'), name='recipes'),
url(r'^recipedetail/(?P<pk>\d+)/$',
RecipeDetailView.as_view(
template_name='rrs/recipedetail.html'),
name='recipedetail'),
) )

View File

@ -7,7 +7,7 @@ from django.core.urlresolvers import resolve
from layerindex.models import Recipe from layerindex.models import Recipe
from rrs.models import Milestone, Maintainer, RecipeMaintainer, RecipeUpstream, \ from rrs.models import Milestone, Maintainer, RecipeMaintainer, RecipeUpstream, \
RecipeUpstreamHistory RecipeUpstreamHistory, RecipeDistro, RecipeUpgrade
def _check_url_params(upstream_status, maintainer_name): def _check_url_params(upstream_status, maintainer_name):
get_object_or_404(Maintainer, name=maintainer_name) get_object_or_404(Maintainer, name=maintainer_name)
@ -21,7 +21,12 @@ def _check_url_params(upstream_status, maintainer_name):
if found == 0: if found == 0:
raise Http404 raise Http404
def _get_layer_branch_url(branch, layer_name):
return ("http://layers.openembedded.org/layerindex/branch/%s/layer/%s/"\
% (branch, layer_name))
class RecipeList(): class RecipeList():
pk = None
name = None name = None
version = None version = None
summary = None summary = None
@ -29,8 +34,9 @@ class RecipeList():
upstream_version = None upstream_version = None
maintainer_name = None maintainer_name = None
def __init__(self, name, version, summary, upstream_status, def __init__(self, pk, name, version, summary, upstream_status,
upstream_version, maintainer_name): upstream_version, maintainer_name):
self.pk = pk
self.name = name self.name = name
self.version = version self.version = version
self.summary = summary self.summary = summary
@ -98,7 +104,7 @@ class RecipeListView(ListView):
if self.maintainer_name != 'All' and self.maintainer_name != maintainer.name: if self.maintainer_name != 'All' and self.maintainer_name != maintainer.name:
continue continue
recipe_list_item = RecipeList(recipe.pn, recipe.pv, recipe.summary, recipe_list_item = RecipeList(recipe.id, recipe.pn, recipe.pv, recipe.summary,
recipe_upstream_status, recipe_upstream.version, maintainer.name) recipe_upstream_status, recipe_upstream.version, maintainer.name)
recipe_list.append(recipe_list_item) recipe_list.append(recipe_list_item)
@ -141,3 +147,94 @@ class RecipeListView(ListView):
context['extra_url_param'] = extra_url_param context['extra_url_param'] = extra_url_param
return context return context
class RecipeUpgradeDetail():
title = None
version = None
milestone_name = None
date = None
maintainer_name = None
is_recipe_maintainer = None
commit = None
commit_url = None
def __init__(self, title, version, milestone_name, date,
maintainer_name, is_recipe_maintainer, commit, commit_url):
self.title = title
self.version = version
self.milestone_name = milestone_name
self.date = date
self.maintainer_name = maintainer_name
self.is_recipe_maintainer = is_recipe_maintainer
self.commit = commit
self.commit_url = commit_url
def _get_recipe_upgrade_detail(recipe_upgrade):
milestone_name = Milestone.get_by_date(recipe_upgrade.commit_date)
if milestone_name is None:
milestone_name = ''
is_recipe_maintainer = False
maintainer_name = ''
if not recipe_upgrade.maintainer is None:
maintainer_name = recipe_upgrade.maintainer.name
if RecipeMaintainer.objects.filter(maintainer__name
= maintainer_name).count() > 0:
is_recipe_maintainer = True
commit = recipe_upgrade.sha1[:10]
commit_url = recipe_upgrade.recipe.layerbranch.layer.vcs_web_url + \
'/commit/?id=' + recipe_upgrade.sha1
rud = RecipeUpgradeDetail(recipe_upgrade.title, recipe_upgrade.version, \
milestone_name, recipe_upgrade.commit_date, maintainer_name, \
is_recipe_maintainer, commit, commit_url)
return rud
class RecipeDetailView(DetailView):
model = Recipe
def get_context_data(self, **kwargs):
context = super(RecipeDetailView, self).get_context_data(**kwargs)
recipe = self.get_object()
milestone = Milestone.get_current()
context['milestone_name'] = milestone.name
recipe_upstream_history = RecipeUpstreamHistory.get_last_by_date_range(
milestone.start_date,
milestone.end_date
)
recipe_upstream = RecipeUpstream.get_by_recipe_and_history(
recipe, recipe_upstream_history)
context['upstream_status'] = \
RecipeUpstream.RECIPE_UPSTREAM_STATUS_CHOICES_DICT[recipe_upstream.status]
context['upstream_version'] = recipe_upstream.version
context['upstream_no_update_reason'] = recipe_upstream.no_update_reason
recipe_maintainer = RecipeMaintainer.objects.filter(recipe = recipe)[0]
maintainer = recipe_maintainer.maintainer
context['maintainer_name'] = maintainer.name
context['recipe_upgrade_details'] = []
for ru in RecipeUpgrade.objects.filter(recipe =
recipe).order_by('-commit_date'):
context['recipe_upgrade_details'].append(_get_recipe_upgrade_detail(ru))
context['recipe_upgrade_detail_count'] = len(context['recipe_upgrade_details'])
context['recipe_layer_branch_url'] = _get_layer_branch_url(
recipe.layerbranch.branch.name, recipe.layerbranch.layer.name)
context['recipe_provides'] = []
for p in recipe.provides.split():
context['recipe_provides'].append(p)
context['recipe_depends'] = []
for d in recipe.depends.split():
context['recipe_depends'].append(d)
context['recipe_distros'] = RecipeDistro.get_distros_by_recipe(recipe)
return context

View File

@ -0,0 +1,141 @@
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% comment %}
rrs-web - recipe detail page template
Copyright (C) 2015 Intel Corporation
Licensed under the MIT license, see COPYING.MIT for details
{% endcomment %}
{% autoescape on %}
{% block title_append %} - {{ recipe.pn }}{% endblock %}
{% endautoescape %}
{% block content %}
<link rel="stylesheet" href="{% static "css/rrs-additional.css" %}" />
{% autoescape on %}
<div class="page-header">
<h1>
{{ recipe.name }} {{ recipe.pv }}
<small>{{ milestone_name }}</small>
</h1>
</div>
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
<li class="lead">Upstream status: <strong class="text-error">{{ upstream_status }}</strong></li>
<li class="divider-vertical"></li>
<li class="lead">Upstream version: <strong>{{ upstream_version }}</strong></li>
<li class="divider-vertical"></li>
<li class="lead">Maintainer: <strong><a href="{% url recipes milestone_name %}?maintainer_name={{ maintainer_name|urlencode }}">{{ maintainer_name }}</a></strong></li>
<li class="divider-vertical"></li>
</ul>
</div>
</div>
<div class="row-fluid">
<div class="span8">
{% if upstream_no_update_reason %}
<h2>Reason why this recipe can't be updated</h2>
<p class="lead">{{ upstream_no_update_reason }}</p>
{% endif %}
<h2>Upgrades</h2>
{% if recipe_upgrade_detail_count == 0 %}
<div class="alert alert-info">
There are no updates prior to <strong>{{ milestone_name }}</strong>
</div>
{% else %}
<table class="table table-striped table-bordered">
<tbody>
<tr>
<th>Title</th>
<th>Version</th>
<th>Milestone</th>
<th>Date</th>
<th>Maintainer</th>
<th>Commit</th>
</tr>
{% for rud in recipe_upgrade_details %}
<tr>
<td>{{ rud.title }}</td>
<td>{{ rud.version }}</td>
{% if rud.milestone_name %}
<td><a href="{% url recipes rud.milestone_name %}">{{ rud.milestone_name }}</a></td>
{% else %}
<td>{{ rud.milestone_name }}</td>
{% endif %}
<td>{{ rud.date }}</td>
{% if rud.is_recipe_maintainer %}
<td><a href="{% url recipes rud.milestone_name %}?maintainer_name={{ rud.maintainer_name|urlencode }}">{{ rud.maintainer_name }}</a></td>
{% else %}
<td>{{ rud.maintainer_name }}</a></td>
{% endif %}
<td><a href="{{ rud.commit_url }}">{{ rud.commit }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
<div class="span4">
<h2>About {{ recipe.pn }}</h2>
<dl>
<dt>Summary</dt>
<dd>{{ recipe.summary }}</dd>
<dt>Section</dt>
<dd>{{ recipe.section }}</dd>
<dt>License</dt>
<dd>{{ recipe.license }}</dd>
<dt>Recipe file</dt>
<dd>
{% if recipe.vcs_web_url %}
<a href="{{ recipe.vcs_web_url }}">{{ recipe.full_path }}</a>
{% else %}
{{ recipe.full_path }}
{% endif %}
</dd>
<dt>Source URI</dt>
<dd><a href="{{ recipe.src_uri }}">{{ recipe.src_uri }}</a></dd>
<dt>Layer</dd>
<dd><a href="{{ recipe_layer_branch_url }}">{{ recipe.layerbranch.layer.name }} ({{ recipe.layerbranch.branch.name}} branch)</a></dd>
<dt>Homepage</dt>
<dd>{% if recipe.homepage %}<a href="{{ recipe.homepage }}">{{ recipe.homepage }}</a>{% endif %}</dd>
<dt>Bug tracker</dt>
<dd><a href="{{ recipe.bugtracker }}">{{ recipe.bugtracker }}</a></dd>
<dt>Provides</dt>
<dd>
<ul class="unstyled">
{% for p in recipe_provides %}
<li>{{ p }}</li>
{% endfor %}
</ul>
</dd>
<dt>Depends</dt>
<dd>
<ul class="unstyled">
{% for d in recipe_depends %}
<li>{{ d }}</li>
{% endfor %}
</ul>
</dd>
<dt>Distributions</dt>
<dd>
<ul class="unstyled">
{% for d in recipe_distros %}
<li>{{ d }}</li>
{% endfor %}
</ul>
</dd>
</dl>
</div>
</div>
{% endautoescape %}
{% endblock %}

View File

@ -77,7 +77,7 @@
<table class="table table-bordered statustable tablesorter table-hover"> <table class="table table-bordered statustable tablesorter table-hover">
<thead> <thead>
<tr> <tr>
<th class="recipe_column"><a href="#">Recipe</a></th> <th class="recipe_column">Recipe</th>
<th class="version_column muted">Version</th> <th class="version_column muted">Version</th>
<th class="upstream_status_column"><b class="caret"></b>Upstream status</th> <th class="upstream_status_column"><b class="caret"></b>Upstream status</th>
<th class="upstream_version_column muted">Upstream version</th> <th class="upstream_version_column muted">Upstream version</th>
@ -88,7 +88,7 @@
<tbody> <tbody>
{% for r in recipe_list %} {% for r in recipe_list %}
<tr> <tr>
<td>{{ r.name }}</td> <td><a href="{% url "recipedetail" r.pk %}">{{ r.name }}</a></td>
<td>{{ r.version }}</td> <td>{{ r.version }}</td>
<td>{{ r.upstream_status }}</td> <td>{{ r.upstream_status }}</td>
<td>{{ r.upstream_version }}</td> <td>{{ r.upstream_version }}</td>