Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1911542/?format=api
{ "id": 1911542, "url": "http://patchwork.ozlabs.org/api/patches/1911542/?format=api", "web_url": "http://patchwork.ozlabs.org/project/patchwork/patch/20240313065642.385843-3-andrepapoti@gmail.com/", "project": { "id": 16, "url": "http://patchwork.ozlabs.org/api/projects/16/?format=api", "name": "Patchwork", "link_name": "patchwork", "list_id": "patchwork.lists.ozlabs.org", "list_email": "patchwork@lists.ozlabs.org", "web_url": "http://jk.ozlabs.org/projects/patchwork/", "scm_url": "git://github.com/getpatchwork/patchwork", "webscm_url": "https://github.com/getpatchwork/patchwork", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20240313065642.385843-3-andrepapoti@gmail.com>", "list_archive_url": null, "date": "2024-03-13T06:56:35", "name": "[3/9] api: Add Note view and serializer", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "1c7b6289dfddccb619602fde2e098720ff730170", "submitter": { "id": 88169, "url": "http://patchwork.ozlabs.org/api/people/88169/?format=api", "name": "andrepapoti", "email": "andrepapoti@gmail.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/patchwork/patch/20240313065642.385843-3-andrepapoti@gmail.com/mbox/", "series": [ { "id": 398839, "url": "http://patchwork.ozlabs.org/api/series/398839/?format=api", "web_url": "http://patchwork.ozlabs.org/project/patchwork/list/?series=398839", "date": "2024-03-13T06:56:33", "name": "[1/9] models: Add Note model", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/398839/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1911542/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1911542/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "patchwork@lists.ozlabs.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "patchwork@lists.ozlabs.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20230601 header.b=gg2gQDhy;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org\n (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org;\n envelope-from=patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org;\n receiver=patchwork.ozlabs.org)", "lists.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20230601 header.b=gg2gQDhy;\n\tdkim-atps=neutral", "lists.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20230601 header.b=gg2gQDhy;\n\tdkim-atps=neutral", "lists.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com\n (client-ip=2607:f8b0:4864:20::42b; helo=mail-pf1-x42b.google.com;\n envelope-from=andrepapoti@gmail.com; receiver=lists.ozlabs.org)" ], "Received": [ "from lists.ozlabs.org (lists.ozlabs.org\n [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4TvhCx72Zkz1yWn\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 13 Mar 2024 17:57:49 +1100 (AEDT)", "from boromir.ozlabs.org (localhost [IPv6:::1])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 4TvhCx6GGnz3039\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 13 Mar 2024 17:57:49 +1100 (AEDT)", "from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com\n [IPv6:2607:f8b0:4864:20::42b])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 4TvhCl1g8nz3fNd\n\tfor <patchwork@lists.ozlabs.org>; Wed, 13 Mar 2024 17:57:39 +1100 (AEDT)", "by mail-pf1-x42b.google.com with SMTP id\n d2e1a72fcca58-6e6ac00616cso1317745b3a.0\n for <patchwork@lists.ozlabs.org>;\n Tue, 12 Mar 2024 23:57:39 -0700 (PDT)", "from localhost.localdomain ([2804:1b3:a4c0:b1de:3ec4:883:9cca:f0a7])\n by smtp.gmail.com with ESMTPSA id\n le21-20020a056a004fd500b006e691787eaesm4843998pfb.34.2024.03.12.23.57.34\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 12 Mar 2024 23:57:35 -0700 (PDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20230601; t=1710313056; x=1710917856;\n darn=lists.ozlabs.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=HyHIi+DS3+Y56csRF2FXL6Ic/M9tQhDj9hzXYxBdxmU=;\n b=gg2gQDhyIXGeJ6KPnROssY6kczk9X90FyBeJ75P4ASkLNoCkivhuI0VSKd+JZ1YRoI\n dfXTbOdHTFa/S7GTqKRnE7jNZnSfszJlHXw65Q9kcJYVfJdKKOX6APRUcN3ny+qqImDs\n rUp4GgVeBMUXR10HQIlY8z6iZiTWT4kUee43Tghuj7f675Yl+N6qgMpdsceO70CDZmXI\n ExTdMWy/2kSZ436mM6KVMGKOnlfuMsiy01AbkmMbzumMkqETnodL75Wy+qQiSjlVawHL\n LVFKIT7il6HYKa5P/buS2esKwDUAPfNX4lrSoywDXa06aIHnxBUxiC05RyCzEuAmP48T\n 6NIw==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1710313056; x=1710917856;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=HyHIi+DS3+Y56csRF2FXL6Ic/M9tQhDj9hzXYxBdxmU=;\n b=CXvIUjq0fMMp11vCO/IW2+RhTxDXAAyPNsgBY0k27ah/6Fve6x5u2zBFNk0/uxiIEx\n Zv+OmsRx5OcxywTmJLfCgj64pWThVj5Cv6HHl2REh7YFvT2qEEZfodLzJzGSUiesWFjO\n TkR7pFgQIzXkxbhzTbnIp0/uGIZrLaNV2w87HIu3jgJ0oD6t+cS2k3Yv0KxJWWj77APC\n jZrmm7Yd3eXt9GQsk8QulOBbF63MrnBF3MlxZYZqA/eyr0RCkNZ4VcGchYIzg7xwZHTc\n RnDR4dZ790PLCDBRJxwwgFhRTPfFF1ZlvoJjgRAGl6f6qt3dvfF2VV3p3VSn/OgYxbtF\n NTXw==", "X-Gm-Message-State": "AOJu0YyIuli70wYkKb5MrFYID/9XtOrB9t0CWRB1Khhcge8Qch3sVtya\n\tj2WIXK+Sy0BalUjCL/UjrwdzMGR90yfCKJi0VzG9jrukAzBYCDEBepWo4AgXiWg=", "X-Google-Smtp-Source": "\n AGHT+IEOI7bhu0ZxhIx3tYoup0Wpz5fftI7k63d9pOaoWayuJAMpmVyCz63J1WUbscenzzuxbIkJSA==", "X-Received": "by 2002:a05:6a00:928c:b0:6e6:a8f5:6dc9 with SMTP id\n jw12-20020a056a00928c00b006e6a8f56dc9mr1906842pfb.2.1710313055907;\n Tue, 12 Mar 2024 23:57:35 -0700 (PDT)", "From": "andrepapoti <andrepapoti@gmail.com>", "To": "patchwork@lists.ozlabs.org", "Subject": "[PATCH 3/9] api: Add Note view and serializer", "Date": "Wed, 13 Mar 2024 03:56:35 -0300", "Message-ID": "<20240313065642.385843-3-andrepapoti@gmail.com>", "X-Mailer": "git-send-email 2.44.0", "In-Reply-To": "<20240313065642.385843-1-andrepapoti@gmail.com>", "References": "<20240313065642.385843-1-andrepapoti@gmail.com>", "MIME-Version": "1.0", "X-BeenThere": "patchwork@lists.ozlabs.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "Patchwork development <patchwork.lists.ozlabs.org>", "List-Unsubscribe": "<https://lists.ozlabs.org/options/patchwork>,\n <mailto:patchwork-request@lists.ozlabs.org?subject=unsubscribe>", "List-Archive": "<http://lists.ozlabs.org/pipermail/patchwork/>", "List-Post": "<mailto:patchwork@lists.ozlabs.org>", "List-Help": "<mailto:patchwork-request@lists.ozlabs.org?subject=help>", "List-Subscribe": "<https://lists.ozlabs.org/listinfo/patchwork>,\n <mailto:patchwork-request@lists.ozlabs.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org", "Sender": "\"Patchwork\"\n <patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>" }, "content": "Added NoteList api. It allows the user to fetch all notes from a\nspecific test or create a new one\nAdded NoteDetail api. It allows the user to fetch, update and delete\nnotes\n\nSigned-off-by: andrepapoti <andrepapoti@gmail.com>\n---\n patchwork/api/note.py | 121 ++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 121 insertions(+)\n create mode 100644 patchwork/api/note.py", "diff": "diff --git a/patchwork/api/note.py b/patchwork/api/note.py\nnew file mode 100644\nindex 0000000..29b480a\n--- /dev/null\n+++ b/patchwork/api/note.py\n@@ -0,0 +1,121 @@\n+# Patchwork - automated patch tracking system\n+# Copyright (C) 2018 Red Hat\n+#\n+# SPDX-License-Identifier: GPL-2.0-or-later\n+\n+\n+from rest_framework import permissions\n+from rest_framework.generics import get_object_or_404\n+from rest_framework.generics import CreateAPIView\n+from rest_framework.generics import RetrieveUpdateDestroyAPIView\n+from rest_framework.generics import ListAPIView\n+from patchwork.api.patch import PatchSerializer\n+from patchwork.api.person import PersonSerializer\n+from patchwork.api.base import BaseHyperlinkedModelSerializer\n+from patchwork.models import Note\n+from patchwork.models import Patch\n+from patchwork.models import Person\n+\n+\n+class NoteSerializer(BaseHyperlinkedModelSerializer):\n+ submitter = PersonSerializer(read_only=True)\n+ patch = PatchSerializer(read_only=True)\n+\n+ class Meta:\n+ model = Note\n+ fields = [\n+ 'id',\n+ 'patch',\n+ 'submitter',\n+ 'content',\n+ 'last_modified',\n+ 'maintainer_only',\n+ ]\n+ read_only_fields = [\n+ 'id',\n+ 'patch',\n+ 'submitter',\n+ 'last_modified',\n+ 'maintainer_only',\n+ ]\n+\n+\n+class NoteDetailPermission(permissions.BasePermission):\n+ def has_permission(self, request, view):\n+ if not request.user.is_authenticated:\n+ return False\n+ patch = Patch.objects.get(id=view.kwargs['patch_id'])\n+ return patch.project in request.user.profile.maintainer_projects.all()\n+\n+ def has_object_permission(self, request, view, obj):\n+ if (\n+ not obj.maintainer_only\n+ ) and request.method in permissions.SAFE_METHODS:\n+ return True\n+ patch = Patch.objects.get(id=view.kwargs['patch_id'])\n+ return patch.project in request.user.profile.maintainer_projects.all()\n+\n+\n+class NoteListPermission(permissions.BasePermission):\n+ def has_permission(self, request, view):\n+ if request.method in permissions.SAFE_METHODS:\n+ return True\n+ if not request.user.is_authenticated:\n+ return False\n+ patch = Patch.objects.get(id=view.kwargs['patch_id'])\n+ return patch.project in request.user.profile.maintainer_projects.all()\n+\n+ def has_object_permission(self, request, view, obj):\n+ if request.method in permissions.SAFE_METHODS:\n+ return True\n+\n+\n+class NoteMixin(object):\n+ queryset = Note.objects.all()\n+ serializer_class = NoteSerializer\n+ lookup_field = 'patch_id'\n+\n+ def get_queryset(self):\n+ patch_id = self.kwargs['patch_id']\n+ get_object_or_404(Patch, id=patch_id)\n+\n+ return Note.objects.filter(patch=patch_id)\n+\n+\n+class NoteDetail(NoteMixin, RetrieveUpdateDestroyAPIView):\n+ permission_classes = [NoteDetailPermission]\n+\n+ def get_object(self):\n+ queryset = self.filter_queryset(self.get_queryset())\n+ note_id = self.kwargs.get('note_id')\n+ instance = get_object_or_404(queryset, id=note_id)\n+ self.check_object_permissions(self.request, instance)\n+ return instance\n+\n+\n+class NoteList(NoteMixin, CreateAPIView, ListAPIView):\n+ ordering = 'id'\n+ permission_classes = [NoteListPermission]\n+\n+ def get_queryset(self):\n+ patch_queryset = Patch.objects.all()\n+\n+ queryset = super(NoteMixin, self).get_queryset()\n+ public_notes = queryset.filter(maintainer_only=False)\n+ user_patches = patch_queryset.filter(\n+ project__in=list(\n+ self.request.user.profile.maintainer_projects.all()\n+ )\n+ )\n+ maintainer_notes = queryset.filter(\n+ maintainer_only=True, patch__in=list(user_patches)\n+ )\n+\n+ return public_notes | maintainer_notes\n+\n+ def perform_create(self, serializer):\n+ serializer.save(\n+ submitter=Person.objects.get(user=self.request.user),\n+ patch=Patch.objects.get(id=self.kwargs['patch_id']),\n+ )\n+ return super().perform_create(serializer)\n", "prefixes": [ "3/9" ] }