diff --git a/pgcommitfest/commitfest/templates/patch.html b/pgcommitfest/commitfest/templates/patch.html index d4822d1..7964b8c 100644 --- a/pgcommitfest/commitfest/templates/patch.html +++ b/pgcommitfest/commitfest/templates/patch.html @@ -44,9 +44,9 @@ {%endif%} {%if cfbot_branch %} + git remote add commitfest https://github.com/postgresql-cfbot/postgresql.git + git fetch commitfest cf/{{patch.id}} + git checkout commitfest/cf/{{patch.id}}" onclick="addGitCheckoutToClipboard({{patch.id}})">Copy git checkout commands {%endif%} diff --git a/pgcommitfest/commitfest/templates/patchsearch.html b/pgcommitfest/commitfest/templates/patchsearch.html index be31a10..6f19ce7 100644 --- a/pgcommitfest/commitfest/templates/patchsearch.html +++ b/pgcommitfest/commitfest/templates/patchsearch.html @@ -2,34 +2,119 @@ {%load commitfest %} {%block contents%} -
-
- + + +
+
- + + +
+
+ + + + + {%for f in form%} + {%if not f.is_hidden%} + + {%else%} + + {%endif%} + {%endfor%} + + + + + + {%for f in form%} + + {%endfor%} + + + +
{{f.label}}
+ {%if not f.name in form.selectize_fields%}{{f|field_class:"form-control"}}{%else%}{{f}}{%endif%} + + + Clear +
+
+
+ + {% if patches %} +

Found {{patches|length}} patch{% if patches|length != 1 %}es{% endif %} matching "{{searchterm}}"

+ {% endif %} + - + + + + + + + + + {%for p in patches %} - {%with p.patchoncommitfest_set.all as cfs %} - - - - - - {%endwith%} + + + + + + + + + + + + + {%endfor%}
PatchPatch{%if sortkey == 5%}
{%elif sortkey == -5%}
{%endif%}
ID{%if sortkey == 4%}
{%elif sortkey == -4%}
{%endif%}
+ CF + + {%if sortkey == 8%}
{%elif sortkey == -8%}
{%endif%} +
StatusTagsVer AuthorReviewersCommitterNum cfs{%if sortkey == 3%}
{%elif sortkey == -3%}
{%endif%}
Latest mail{%if sortkey == 2%}
{%elif sortkey == -2%}
{%endif%}
{%with cfs|first as firstcf%}{{p}}{%endwith%}{%for c in cfs %} -
{{c.commitfest}}: {{c.statusstring}}
- {%endfor%}
{{p.authors_string|default:''}}
{{p.name}}{{p.id}} + {%with p.patchoncommitfest_set.all|first as poc%} + {%if poc%}{{poc.commitfest.name}}{%endif%} + {%endwith%} + + {%with p.patchoncommitfest_set.all|first as poc%} + {%if poc%}{{poc.status|patchstatusstring}}{%endif%} + {%endwith%} + + {%for tag in p.tags.all%} + + {{tag.name}} + + {%endfor%} + {%if p.targetversion%}{{p.targetversion}}{%endif%} + {% for author in p.authors.all %} + {{author.get_full_name|default:author.username}}{% if not forloop.last %}, {% endif %} + {% endfor %} + + {% for reviewer in p.reviewers.all %} + {{reviewer.get_full_name|default:reviewer.username}}{% if not forloop.last %}, {% endif %} + {% endfor %} + {% if p.committer %}{{p.committer.fullname}}{% endif %}{{p.patchoncommitfest_set.count}} + {%if p.modified and userprofile.show_relative_timestamps %}{% cfwhen p.modified %}{%elif p.modified %}{{p.modified|date:"Y-m-d"}}
{{p.modified|date:"H:i"}}{%endif%} +
{%endblock%} + +{%block morescript%} + {%include "selectize_js.html" %} +{%endblock%} diff --git a/pgcommitfest/commitfest/views.py b/pgcommitfest/commitfest/views.py index 5b89514..f72cc3d 100644 --- a/pgcommitfest/commitfest/views.py +++ b/pgcommitfest/commitfest/views.py @@ -3,7 +3,7 @@ from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.db import connection, transaction -from django.db.models import Q +from django.db.models import Count, Q from django.http import ( Http404, HttpResponse, @@ -692,25 +692,109 @@ def global_search(request): patches = patches_by_messageid(cleaned_id) if not patches: - patches = ( - Patch.objects.select_related() - .filter(name__icontains=searchterm) - .order_by( - "created", + patches_query = ( + Patch.objects.select_related("targetversion", "committer") + .prefetch_related( + "authors", + "reviewers", + "tags", + "patchoncommitfest_set__commitfest", + "mailthread_set", ) - .all() + .select_related("cfbot_branch") + .filter(name__icontains=searchterm) ) + # Apply filters using the same logic as patchlist + if request.GET.get("status", "-1") != "-1": + try: + status = int(request.GET["status"]) + patches_query = patches_query.filter( + patchoncommitfest__status=status + ).distinct() + except ValueError: + pass + + if request.GET.get("targetversion", "-1") != "-1": + if request.GET["targetversion"] == "-2": + patches_query = patches_query.filter(targetversion_id__isnull=True) + else: + try: + ver_id = int(request.GET["targetversion"]) + patches_query = patches_query.filter(targetversion_id=ver_id) + except ValueError: + pass + + if request.GET.getlist("tag"): + try: + tag_ids = [int(t) for t in request.GET.getlist("tag")] + for tag_id in tag_ids: + patches_query = patches_query.filter(tags__id=tag_id) + patches_query = patches_query.distinct() + except ValueError: + pass + + # Apply sorting based on sortkey parameter (adapted for Django ORM) + sortkey = request.GET.get("sortkey", "1") + if sortkey == "2": # Latest mail + patches_query = patches_query.order_by("-modified") # Use modified as proxy + elif sortkey == "-2": + patches_query = patches_query.order_by("modified") + elif sortkey == "3": # Num cfs + patches_query = patches_query.annotate( + num_cfs=Count("patchoncommitfest") + ).order_by("-num_cfs") + elif sortkey == "-3": + patches_query = patches_query.annotate( + num_cfs=Count("patchoncommitfest") + ).order_by("num_cfs") + elif sortkey == "4": # ID + patches_query = patches_query.order_by("id") + elif sortkey == "-4": + patches_query = patches_query.order_by("-id") + elif sortkey == "5": # Patch name + patches_query = patches_query.order_by("name") + elif sortkey == "-5": + patches_query = patches_query.order_by("-name") + elif sortkey == "8": # CF + patches_query = patches_query.order_by("patchoncommitfest__commitfest__id") + elif sortkey == "-8": + patches_query = patches_query.order_by("-patchoncommitfest__commitfest__id") + else: # Default: Created (sortkey 1) + patches_query = patches_query.order_by("created") + + patches = patches_query.all() + if len(patches) == 1: patch = patches[0] return HttpResponseRedirect(f"/patch/{patch.id}/") + # Use the existing filter form + form = CommitFestFilterForm(request.GET) + + # Get user profile for timestamp preferences + userprofile = None + if request.user.is_authenticated: + try: + from pgcommitfest.userprofile.models import UserProfile + + userprofile = UserProfile.objects.get(user=request.user) + except UserProfile.DoesNotExist: + pass + return render( request, "patchsearch.html", { "patches": patches, "title": "Patch search results", + "searchterm": searchterm, + "form": form, + "cf": None, # No specific commitfest context + "sortkey": int(request.GET.get("sortkey") or "1"), + "tags_data": get_tags_data(), + "all_tags": {t.id: t for t in Tag.objects.all()}, + "userprofile": userprofile, }, )