Aside 'review' and 'reject' we add operations to add and drop whole
series from/to ustom queues.
Initially a "add to new queue..." link is shown in the extra ops menu,
which prompts for a queue name before creating and adding the current
series there. Implementing the prompt takes a little enhancement to the
HTML js.
Once added to a queue, the series will show a new op "drop from queue
'...'".
A convenient op will show in the ops, "add to queue 'foo'", if the user
has previously created and added some other series. This saves typing
the queue name.
Signed-off-by: Fam Zheng <famz@redhat.com>
---
mods/maintainer.py | 156 +++++++++++++++++++++++--------
www/templates/series-detail.html | 30 +++++-
2 files changed, 145 insertions(+), 41 deletions(-)
diff --git a/mods/maintainer.py b/mods/maintainer.py
index 7f4f5fe..d5d7c8c 100644
--- a/mods/maintainer.py
+++ b/mods/maintainer.py
@@ -8,17 +8,31 @@
# This work is licensed under the MIT License. Please see the LICENSE file or
# http://opensource.org/licenses/MIT.
+import re
from django.conf.urls import url
-from django.http import Http404, HttpResponseRedirect
+from django.http import Http404, HttpResponseRedirect, HttpResponseBadRequest
from django.urls import reverse
from mod import PatchewModule
-from api.models import Message, Queue
+from api.models import Message, Queue, WatchedQuery
class MaintainerModule(PatchewModule):
""" Project maintainer related tasks """
name = "maintainer"
+ def _add_to_queue(self, user, m, queue):
+ for x in [m] + list(m.get_patches()):
+ q, created = Queue.objects.get_or_create(user=user, message=x, name=queue)
+ if created:
+ emit_event("MessageQueued", message=x, queue=q)
+
+ def _drop_from_queue(self, user, m, queue):
+ query = Queue.objects.filter(user=user, message__in=m.get_patches() + [m],
+ name=queue)
+ for q in query:
+ emit_event("MessageDropping", message=q.message, queue=q)
+ q.delete()
+
def _update_review_state(self, request, message_id, accept):
if not request.user.is_authenticated:
return HttpResponseForbidden()
@@ -69,6 +83,27 @@ class MaintainerModule(PatchewModule):
def www_view_clear_reviewed(self, request, message_id):
return self._delete_review(request, message_id)
+ def www_view_add_to_queue(self, request, message_id):
+ if not request.user.is_authenticated:
+ raise PermissionDenied()
+ m = Message.objects.filter(message_id=message_id).first()
+ if not m:
+ raise Http404("Series not found")
+ queue = request.GET.get("queue")
+ if not queue or re.match(r'[^_a-zA-Z0-9\-]', queue):
+ return HttpResponseBadRequest("Invalid queue name")
+ self._add_to_queue(request.user, m, queue)
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
+
+ def www_view_drop_from_queue(self, request, queue, message_id):
+ if not request.user.is_authenticated:
+ raise PermissionDenied()
+ m = Message.objects.filter(message_id=message_id).first()
+ if not m:
+ raise Http404("Series not found")
+ self._drop_from_queue(request.user, m, queue)
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
+
def www_url_hook(self, urlpatterns):
urlpatterns.append(url(r"^mark-as-merged/(?P<message_id>.*)/",
self.www_view_mark_as_merged,
@@ -85,50 +120,91 @@ class MaintainerModule(PatchewModule):
urlpatterns.append(url(r"^clear-reviewed/(?P<message_id>.*)/",
self.www_view_clear_reviewed,
name="clear-reviewed"))
+ urlpatterns.append(url(r"^add-to-queue/(?P<message_id>.*)/",
+ self.www_view_add_to_queue,
+ name="add-to-queue"))
+ urlpatterns.append(url(r"^drop-from-queue/(?P<queue>[^/]*)/(?P<message_id>.*)/",
+ self.www_view_drop_from_queue,
+ name="drop-from-queue"))
def prepare_message_hook(self, request, message, detailed):
if not detailed or not request.user.is_authenticated:
return
- if message.is_series_head:
- if message.is_merged:
- message.extra_ops.append({"url": reverse("clear-merged",
- kwargs={"message_id": message.message_id}),
- "icon": "eraser",
- "title": "Clear merged state"})
+ if not message.is_series_head:
+ return
+ if message.is_merged:
+ message.extra_ops.append({"url": reverse("clear-merged",
+ kwargs={"message_id": message.message_id}),
+ "icon": "eraser",
+ "title": "Clear merged state"})
+ else:
+ message.extra_ops.append({"url": reverse("mark-as-merged",
+ kwargs={"message_id": message.message_id}),
+ "icon": "check",
+ "title": "Mark series as merged"})
+
+ accepted = False
+ rejected = False
+ queues = []
+ for r in Queue.objects.filter(user=request.user, message=message):
+ if r.name == 'accept':
+ message.extra_status.append({
+ "icon": "fa-check",
+ "html": 'The series is marked for merging'
+ })
+ accepted = True
+ elif r.name == 'reject':
+ message.extra_status.append({
+ "icon": "fa-times",
+ "html": 'The series is marked as rejected'
+ })
+ rejected = True
else:
- message.extra_ops.append({"url": reverse("mark-as-merged",
- kwargs={"message_id": message.message_id}),
- "icon": "check",
- "title": "Mark series as merged"})
-
- r = Queue.objects.filter(user=request.user, message=message,
- name__in=['accept', 'reject']).first()
- if r and r.name == 'accept':
- message.extra_status.append({
- "icon": "fa-check",
- "html": 'The series is marked for merging'
- })
- else:
- if message.is_series_head:
- message.extra_ops.append({"url": reverse("mark-as-accepted",
- kwargs={"message_id": message.message_id}),
- "icon": "check",
- "title": "Mark series as accepted"})
-
- if r and r.name == 'reject':
- message.extra_status.append({
- "icon": "fa-times",
- "html": 'The series is marked as rejected'
- })
- else:
- if message.is_series_head:
- message.extra_ops.append({"url": reverse("mark-as-rejected",
- kwargs={"message_id": message.message_id}),
- "icon": "times",
- "title": "Mark series as rejected"})
-
- if r:
+ queues.append(r.name)
+ message.extra_ops.append({
+ "url": reverse("drop-from-queue",
+ kwargs={
+ "queue": r.name,
+ "message_id": message.message_id
+ }),
+ "icon": "remove",
+ "title": "Drop from queue '%s'" % r.name})
+ if not accepted:
+ message.extra_ops.append({"url": reverse("mark-as-accepted",
+ kwargs={"message_id": message.message_id}),
+ "icon": "check",
+ "title": "Mark series as accepted"})
+ if not rejected:
+ message.extra_ops.append({"url": reverse("mark-as-rejected",
+ kwargs={"message_id": message.message_id}),
+ "icon": "times",
+ "title": "Mark series as rejected"})
+ if accepted or rejected:
message.extra_ops.append({"url": reverse("clear-reviewed",
kwargs={"message_id": message.message_id}),
"icon": "eraser",
"title": "Clear review state"})
+
+ if queues:
+ message.extra_status.append({
+ "icon": "fa-bookmark",
+ "html": 'The series is queued in: %s' % ', '.join(queues),
+ })
+ for q in Queue.objects.filter(user=request.user).values("name").distinct():
+ qn = q["name"]
+ if qn in queues + ['reject', 'accept']:
+ continue
+ message.extra_ops.append({
+ "url": "%s?queue=%s" % (\
+ reverse("add-to-queue",
+ kwargs={"message_id": message.message_id}),
+ qn),
+ "icon": "bookmark",
+ "title": "Add to '%s' queue" % qn})
+
+ message.extra_ops.append({
+ "url": reverse("add-to-queue",
+ kwargs={"message_id": message.message_id}),
+ "get_prompt": {"queue": "What is the name of the new queue?" },
+ "icon": "bookmark",
+ "title": "Add to new queue..."})
diff --git a/www/templates/series-detail.html b/www/templates/series-detail.html
index c7b7f1d..dcf7b79 100644
--- a/www/templates/series-detail.html
+++ b/www/templates/series-detail.html
@@ -40,11 +40,39 @@
<ul>
{% for op in series.extra_ops %}
<li>
+ {% if op.get_prompt %}
+ {% for k, v in op.get_prompt.items %}
+ <input type="hidden" name="{{ k }}" value="{{ v }}" />
+ {% endfor %}
+ {% endif %}
<span class="fa fa-{{ op.icon | default:"question" }}"></span><a
- href="{{ op.url }}">{{ op.title }}</a></li>
+ {% if op.get_prompt %}
+ href="#"
+ onclick="prompt_and_open(this, '{{ op.url }}')"
+ {% else %}
+ href="{{ op.url }}"
+ {% endif %}">{{ op.title }}</a></li>
{% endfor %}
</ul>
</div>
+<script type="text/javascript">
+function prompt_and_open(obj, url) {
+ params = {};
+ cancel = false;
+ $(obj).parent().find("input").each(function() {
+ field = this.name;
+ val = prompt(this.value);
+ if (!val) {
+ cancel = true;
+ return false;
+ }
+ params[field] = val;
+ });
+ if (!cancel) {
+ window.location.href = url + "?" + $.param(params);
+ }
+}
+</script>
{% endif %}
<div class="status">
--
2.17.2
_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel
© 2016 - 2025 Red Hat, Inc.