|
3 | 3 | from django.contrib.auth.decorators import login_required |
4 | 4 | from django.contrib.auth.models import User |
5 | 5 | from django.db import connection, transaction |
6 | | -from django.db.models import Q |
| 6 | +from django.db.models import Count, Q |
7 | 7 | from django.http import ( |
8 | 8 | Http404, |
9 | 9 | HttpResponse, |
@@ -699,25 +699,148 @@ def global_search(request): |
699 | 699 | patches = patches_by_messageid(cleaned_id) |
700 | 700 |
|
701 | 701 | if not patches: |
702 | | - patches = ( |
703 | | - Patch.objects.select_related() |
704 | | - .filter(name__icontains=searchterm) |
705 | | - .order_by( |
706 | | - "created", |
| 702 | + patches_query = ( |
| 703 | + Patch.objects.select_related("targetversion", "committer") |
| 704 | + .prefetch_related( |
| 705 | + "authors", |
| 706 | + "reviewers", |
| 707 | + "tags", |
| 708 | + "patchoncommitfest_set__commitfest", |
| 709 | + "mailthread_set", |
707 | 710 | ) |
708 | | - .all() |
| 711 | + .select_related("cfbot_branch") |
| 712 | + .filter(name__icontains=searchterm) |
709 | 713 | ) |
710 | 714 |
|
| 715 | + # Apply filters using the same logic as patchlist |
| 716 | + if request.GET.get("status", "-1") != "-1": |
| 717 | + try: |
| 718 | + status = int(request.GET["status"]) |
| 719 | + patches_query = patches_query.filter( |
| 720 | + patchoncommitfest__status=status |
| 721 | + ).distinct() |
| 722 | + except ValueError: |
| 723 | + pass |
| 724 | + |
| 725 | + if request.GET.get("targetversion", "-1") != "-1": |
| 726 | + if request.GET["targetversion"] == "-2": |
| 727 | + patches_query = patches_query.filter(targetversion_id__isnull=True) |
| 728 | + else: |
| 729 | + try: |
| 730 | + ver_id = int(request.GET["targetversion"]) |
| 731 | + patches_query = patches_query.filter(targetversion_id=ver_id) |
| 732 | + except ValueError: |
| 733 | + pass |
| 734 | + |
| 735 | + if request.GET.getlist("tag"): |
| 736 | + try: |
| 737 | + tag_ids = [int(t) for t in request.GET.getlist("tag")] |
| 738 | + for tag_id in tag_ids: |
| 739 | + patches_query = patches_query.filter(tags__id=tag_id) |
| 740 | + patches_query = patches_query.distinct() |
| 741 | + except ValueError: |
| 742 | + pass |
| 743 | + |
| 744 | + # Apply author filter |
| 745 | + if request.GET.get("author", "-1") != "-1": |
| 746 | + if request.GET["author"] == "-2": |
| 747 | + patches_query = patches_query.filter(authors__isnull=True) |
| 748 | + elif request.GET["author"] == "-3": |
| 749 | + # Filter for current user's patches |
| 750 | + if not request.user.is_authenticated: |
| 751 | + return HttpResponseRedirect( |
| 752 | + f"{settings.LOGIN_URL}?next={request.path}?searchterm={searchterm}" |
| 753 | + ) |
| 754 | + patches_query = patches_query.filter(authors=request.user) |
| 755 | + else: |
| 756 | + try: |
| 757 | + author_id = int(request.GET["author"]) |
| 758 | + patches_query = patches_query.filter(authors__id=author_id) |
| 759 | + except ValueError: |
| 760 | + pass |
| 761 | + |
| 762 | + # Apply reviewer filter |
| 763 | + if request.GET.get("reviewer", "-1") != "-1": |
| 764 | + if request.GET["reviewer"] == "-2": |
| 765 | + patches_query = patches_query.filter(reviewers__isnull=True) |
| 766 | + elif request.GET["reviewer"] == "-3": |
| 767 | + # Filter for current user's reviews |
| 768 | + if not request.user.is_authenticated: |
| 769 | + return HttpResponseRedirect( |
| 770 | + f"{settings.LOGIN_URL}?next={request.path}?searchterm={searchterm}" |
| 771 | + ) |
| 772 | + patches_query = patches_query.filter(reviewers=request.user) |
| 773 | + else: |
| 774 | + try: |
| 775 | + reviewer_id = int(request.GET["reviewer"]) |
| 776 | + patches_query = patches_query.filter(reviewers__id=reviewer_id) |
| 777 | + except ValueError: |
| 778 | + pass |
| 779 | + |
| 780 | + # Ensure distinct results after filtering on many-to-many relationships |
| 781 | + patches_query = patches_query.distinct() |
| 782 | + |
| 783 | + # Apply sorting based on sortkey parameter (adapted for Django ORM) |
| 784 | + sortkey = request.GET.get("sortkey", "1") |
| 785 | + if sortkey == "2": # Latest mail |
| 786 | + patches_query = patches_query.order_by("-modified") # Use modified as proxy |
| 787 | + elif sortkey == "-2": |
| 788 | + patches_query = patches_query.order_by("modified") |
| 789 | + elif sortkey == "3": # Num cfs |
| 790 | + patches_query = patches_query.annotate( |
| 791 | + num_cfs=Count("patchoncommitfest") |
| 792 | + ).order_by("-num_cfs") |
| 793 | + elif sortkey == "-3": |
| 794 | + patches_query = patches_query.annotate( |
| 795 | + num_cfs=Count("patchoncommitfest") |
| 796 | + ).order_by("num_cfs") |
| 797 | + elif sortkey == "4": # ID |
| 798 | + patches_query = patches_query.order_by("id") |
| 799 | + elif sortkey == "-4": |
| 800 | + patches_query = patches_query.order_by("-id") |
| 801 | + elif sortkey == "5": # Patch name |
| 802 | + patches_query = patches_query.order_by("name") |
| 803 | + elif sortkey == "-5": |
| 804 | + patches_query = patches_query.order_by("-name") |
| 805 | + elif sortkey == "8": # CF |
| 806 | + patches_query = patches_query.order_by("patchoncommitfest__commitfest__id") |
| 807 | + elif sortkey == "-8": |
| 808 | + patches_query = patches_query.order_by("-patchoncommitfest__commitfest__id") |
| 809 | + else: # Default: Created (sortkey 1) |
| 810 | + patches_query = patches_query.order_by("created") |
| 811 | + |
| 812 | + patches = patches_query.all() |
| 813 | + |
711 | 814 | if len(patches) == 1: |
712 | 815 | patch = patches[0] |
713 | 816 | return HttpResponseRedirect(f"/patch/{patch.id}/") |
714 | 817 |
|
| 818 | + # Use the existing filter form |
| 819 | + form = CommitFestFilterForm(request.GET) |
| 820 | + |
| 821 | + # Get user profile for timestamp preferences |
| 822 | + userprofile = None |
| 823 | + if request.user.is_authenticated: |
| 824 | + try: |
| 825 | + from pgcommitfest.userprofile.models import UserProfile |
| 826 | + |
| 827 | + userprofile = UserProfile.objects.get(user=request.user) |
| 828 | + except UserProfile.DoesNotExist: |
| 829 | + pass |
| 830 | + |
715 | 831 | return render( |
716 | 832 | request, |
717 | 833 | "patchsearch.html", |
718 | 834 | { |
719 | 835 | "patches": patches, |
720 | 836 | "title": "Patch search results", |
| 837 | + "searchterm": searchterm, |
| 838 | + "form": form, |
| 839 | + "cf": None, # No specific commitfest context |
| 840 | + "sortkey": int(request.GET.get("sortkey") or "1"), |
| 841 | + "tags_data": get_tags_data(), |
| 842 | + "all_tags": {t.id: t for t in Tag.objects.all()}, |
| 843 | + "userprofile": userprofile, |
721 | 844 | }, |
722 | 845 | ) |
723 | 846 |
|
|
0 commit comments