{% load person %}
{% load patch %}
-{% block title %}{{patch.name}}{% endblock %}
+{% block title %}{{submission.name}}{% endblock %}
{% block body %}
<script type="text/javascript">
}
</script>
-<h1>{{ patch.name }}</h1>
+<h1>{{ submission.name }}</h1>
<div class="core-info">
- <span>Submitted by {{ patch.submitter|personify:project }} on {{ patch.date }}</span>
+ <span>Submitted by {{ submission.submitter|personify:project }} on {{ submission.date }}</span>
</div>
<h2>Details</h2>
<table class="patchmeta">
<tr>
<th>Message ID</th>
- <td>{{ patch.msgid|msgid }}</td>
+ <td>{{ submission.msgid|msgid }}</td>
+ </tr>
+{% if submission.state %}
+ <tr>
+ <th>State</th>
+ <td>{{ submission.state.name }}{% if submission.archived %}, archived{% endif %}</td>
</tr>
- <tr>
- <th>State</th>
- <td>{{ patch.state.name }}{% if patch.archived %}, archived{% endif %}</td>
- </tr>
-{% if patch.commit_ref %}
- <tr>
- <th>Commit</th>
- <td>{{ patch.commit_ref }}</td>
- </tr>
{% endif %}
-{% if patch.delegate %}
- <tr>
- <th>Delegated to:</th>
- <td>{{ patch.delegate.profile.name }}</td>
- </tr>
+{% if submission.commit_ref %}
+ <tr>
+ <th>Commit</th>
+ <td>{{ submission.commit_ref }}</td>
+ </tr>
+{% endif %}
+{% if submission.delegate %}
+ <tr>
+ <th>Delegated to:</th>
+ <td>{{ submission.delegate.profile.name }}</td>
+ </tr>
{% endif %}
<tr>
<th>Headers</th>
href="javascript:toggle_headers('togglepatchheaders', 'patchheaders')"
>show</a>
<div id="patchheaders" class="patchheaders" style="display:none;">
- <pre>{{patch.headers}}</pre>
+ <pre>{{submission.headers}}</pre>
</div>
</td>
</tr>
</table>
<div class="patchforms">
-
{% if patchform %}
<div class="patchform patchform-properties">
<h3>Patch Properties</h3>
</div>
</div>
-{% if patch.pull_url %}
+{% if submission.pull_url %}
<h2>Pull-request</h2>
-<a class="patch-pull-url" href="{{patch.pull_url}}"
- >{{ patch.pull_url }}</a>
+<a class="patch-pull-url" href="{{submission.pull_url}}"
+ >{{ submission.pull_url }}</a>
{% endif %}
-{% if patch.checks %}
+{% if submission.checks %}
<h2>Checks</h2>
<table class="checks">
<tr>
<th>Check</th>
<th>Description</th>
</tr>
-{% for check in patch.checks %}
+{% for check in submission.checks %}
<tr>
<td>{{ check.context }}</td>
<td>
</table>
{% endif %}
+{% if submission.diff %}
<h2>Commit Message</h2>
+{% else %}
+<h2>Message</h2>
+{% endif %}
<div class="comment">
<div class="meta">
- <span>{{ patch.submitter|personify:project }}</span>
- <span class="pull-right">{{ patch.date }}</span>
+ <span>{{ submission.submitter|personify:project }}</span>
+ <span class="pull-right">{{ submission.date }}</span>
</div>
<pre class="content">
-{{ patch|commentsyntax }}
+{{ submission|commentsyntax }}
</pre>
</div>
-{% for item in patch.comments.all %}
+{% for item in submission.comments.all %}
{% if forloop.first %}
<h2>Comments</h2>
{% endif %}
</div>
{% endfor %}
-{% if patch.diff %}
+{% if submission.diff %}
<h2>
Patch
<a href="javascript:toggle_headers('hide-patch', 'patch')" id="hide-patch">hide</a></span>
<span>|</span>
- <a href="{% url 'patch-raw' patch_id=patch.id %}"
+ <a href="{% url 'patch-raw' patch_id=submission.id %}"
>download patch</a>
<span>|</span>
- <a href="{% url 'patch-mbox' patch_id=patch.id %}"
+ <a href="{% url 'patch-mbox' patch_id=submission.id %}"
>download mbox</a>
</h2>
<div id="patch" class="patch">
<pre class="content">
-{{ patch|patchsyntax }}
+{{ submission|patchsyntax }}
</pre>
</div>
{% endif %}
@register.filter
-def commentsyntax(patch):
- content = escape(patch.content)
+def commentsyntax(submission):
+ content = escape(submission.content)
for (r, cls) in _comment_span_res:
content = r.sub(lambda x: _span % (cls, x.group(0)), content)
--- /dev/null
+# Patchwork - automated patch tracking system
+# Copyright (C) 2016 Intel Corporation
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+from __future__ import absolute_import
+
+from django.core.urlresolvers import reverse
+from django.test import TestCase
+
+from patchwork.tests.utils import create_covers
+from patchwork.tests.utils import create_patches
+
+
+class CoverLetterViewTest(TestCase):
+ fixtures = ['default_states']
+
+ def testRedirect(self):
+ patches = create_patches()
+ patch_id = patches[0].id
+
+ requested_url = reverse('cover-detail', kwargs={'cover_id': patch_id})
+ redirect_url = reverse('patch-detail', kwargs={'patch_id': patch_id})
+
+ response = self.client.post(requested_url)
+ self.assertRedirects(response, redirect_url)
+
+
+class PatchViewTest(TestCase):
+ fixtures = ['default_states']
+
+ def testRedirect(self):
+ covers = create_covers()
+ cover_id = covers[0].id
+
+ requested_url = reverse('patch-detail', kwargs={'patch_id': cover_id})
+ redirect_url = reverse('cover-detail', kwargs={'cover_id': cover_id})
+
+ response = self.client.post(requested_url)
+ self.assertRedirects(response, redirect_url)
from django.contrib.auth.models import User
-from patchwork.models import Project, Person, Patch
+from patchwork.models import CoverLetter
+from patchwork.models import Patch
+from patchwork.models import Person
+from patchwork.models import Project
# helper functions for tests
return patches
+def create_covers(count=1):
+ """Create 'count' unique cover letters."""
+ defaults.project.save()
+ defaults.patch_author_person.save()
+
+ covers = []
+
+ for i in range(0, count):
+ cover = CoverLetter(project=defaults.project,
+ submitter=defaults.patch_author_person,
+ msgid=make_msgid(),
+ name='testcover%d' % (i + 1))
+ cover.save()
+ covers.append(cover)
+
+ return covers
+
+
def find_in_context(context, key):
if isinstance(context, list):
for c in context:
from patchwork import views
from patchwork.views import api as api_views
from patchwork.views import bundle as bundle_views
+from patchwork.views import cover as cover_views
from patchwork.views import help as help_views
from patchwork.views import mail as mail_views
from patchwork.views import patch as patch_views
url(r'^patch/(?P<patch_id>\d+)/mbox/$', patch_views.mbox,
name='patch-mbox'),
+ # cover views
+ url(r'^cover/(?P<cover_id>\d+)/$', cover_views.cover,
+ name='cover-detail'),
+
# logged-in user stuff
url(r'^user/$', user_views.profile, name='user-profile'),
--- /dev/null
+# Patchwork - automated patch tracking system
+# Copyright (C) 2016 Intel Corporation
+#
+# This file is part of the Patchwork package.
+#
+# Patchwork is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Patchwork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Patchwork; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+from __future__ import absolute_import
+
+from django.core import urlresolvers
+from django.http import Http404
+from django.http import HttpResponseRedirect
+from django.shortcuts import render_to_response, get_object_or_404
+
+from patchwork.models import CoverLetter, Submission
+
+
+def cover(request, cover_id):
+ context = {}
+
+ # redirect to patches where necessary
+ try:
+ cover = get_object_or_404(CoverLetter, id=cover_id)
+ except Http404 as exc:
+ submissions = Submission.objects.filter(id=cover_id)
+ if submissions:
+ return HttpResponseRedirect(
+ urlresolvers.reverse(
+ 'patch-detail',
+ kwargs={'patch_id': cover_id}))
+ raise exc
+
+ context = {
+ 'submission': cover,
+ 'project': cover.project,
+ }
+
+ return render_to_response('patchwork/submission.html', context)
from __future__ import absolute_import
from django.contrib import messages
-from django.http import HttpResponse, HttpResponseForbidden
+from django.core import urlresolvers
+from django.http import Http404
+from django.http import HttpResponse
+from django.http import HttpResponseForbidden
+from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.utils import six
from patchwork.forms import PatchForm, CreateBundleForm
-from patchwork.models import Patch, Project, Bundle
+from patchwork.models import Patch, Project, Bundle, Submission
from patchwork.views import generic_list, patch_to_mbox
def patch(request, patch_id):
- patch = get_object_or_404(Patch, id=patch_id)
- editable = patch.is_editable(request.user)
+ # redirect to cover letters where necessary
+ try:
+ patch = get_object_or_404(Patch, id=patch_id)
+ except Http404 as exc:
+ submissions = Submission.objects.filter(id=patch_id)
+ if submissions:
+ return HttpResponseRedirect(
+ urlresolvers.reverse(
+ 'cover-detail',
+ kwargs={'cover_id': patch_id}))
+ raise exc
+ editable = patch.is_editable(request.user)
context = {
'project': patch.project
}
if request.user.is_authenticated():
context['bundles'] = Bundle.objects.filter(owner=request.user)
- context['patch'] = patch
+ context['submission'] = patch
context['patchform'] = form
context['createbundleform'] = createbundleform
context['project'] = patch.project
- return render(request, 'patchwork/patch.html', context)
+ return render(request, 'patchwork/submission.html', context)
def content(request, patch_id):