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
parent da47f8f344
commit de3cdd338d
5 changed files with 267 additions and 9 deletions

View File

@ -23,14 +23,19 @@ class Milestone(models.Model):
@staticmethod
def get_current():
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,
end_date__gte = current).order_by('-id')
""" Get milestone by date """
@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:
return milestone_set[0]
else:
return Milestone.objects.filter().order_by('-id')[0]
return None
""" Get month intervals between the start and the end of the milestone """
def get_intervals(self):
@ -147,6 +152,17 @@ class RecipeDistro(models.Model):
def __unicode__(self):
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):
recipe = models.ForeignKey(Recipe)
maintainer = models.ForeignKey(Maintainer, blank=True, null=True)

View File

@ -7,7 +7,7 @@ from django.conf.urls import patterns, url
from layerindex.views import EditProfileFormView
from rrs.models import Milestone
from rrs.views import RecipeListView
from rrs.views import RecipeListView, RecipeDetailView
urlpatterns = patterns('',
url(r'^$', redirect_to, {'url' : reverse_lazy('recipes', args=(Milestone.get_current().name,))},
@ -16,6 +16,10 @@ urlpatterns = patterns('',
RecipeListView.as_view(
template_name='rrs/recipes.html'),
name='recipes'),
url(r'^recipedetail/(?P<pk>\d+)/$',
RecipeDetailView.as_view(
template_name='rrs/recipedetail.html'),
name='recipedetail'),
url(r'^profile/$',
EditProfileFormView.as_view(
template_name='layerindex/profile.html'),

View File

@ -7,7 +7,7 @@ from django.core.urlresolvers import resolve
from layerindex.models import Recipe
from rrs.models import Milestone, Maintainer, RecipeMaintainer, RecipeUpstream, \
RecipeUpstreamHistory
RecipeUpstreamHistory, RecipeDistro, RecipeUpgrade
def _check_url_params(upstream_status, 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:
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():
pk = None
name = None
version = None
summary = None
@ -29,8 +34,9 @@ class RecipeList():
upstream_version = 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):
self.pk = pk
self.name = name
self.version = version
self.summary = summary
@ -98,7 +104,7 @@ class RecipeListView(ListView):
if self.maintainer_name != 'All' and self.maintainer_name != maintainer.name:
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_list.append(recipe_list_item)
@ -141,3 +147,94 @@ class RecipeListView(ListView):
context['extra_url_param'] = extra_url_param
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">
<thead>
<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="upstream_status_column"><b class="caret"></b>Upstream status</th>
<th class="upstream_version_column muted">Upstream version</th>
@ -88,7 +88,7 @@
<tbody>
{% for r in recipe_list %}
<tr>
<td>{{ r.name }}</td>
<td><a href="{% url "recipedetail" r.pk %}">{{ r.name }}</a></td>
<td>{{ r.version }}</td>
<td>{{ r.upstream_status }}</td>
<td>{{ r.upstream_version }}</td>