From nobody Tue May 13 08:36:01 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=patchew-devel-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=patchew-devel-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1527761049952159.8613105775911; Thu, 31 May 2018 03:04:09 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 10E3B8B11B; Thu, 31 May 2018 10:04:09 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 047A92010CA1; Thu, 31 May 2018 10:04:09 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id EB6D418005D1; Thu, 31 May 2018 10:04:08 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w4VA47Oh025017 for ; Thu, 31 May 2018 06:04:07 -0400 Received: by smtp.corp.redhat.com (Postfix) id 58BFC5D9CC; Thu, 31 May 2018 10:04:07 +0000 (UTC) Received: from mx1.redhat.com (ext-mx02.extmail.prod.ext.phx2.redhat.com [10.5.110.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5117E5D9CB for ; Thu, 31 May 2018 10:04:04 +0000 (UTC) Received: from mail-wr0-f172.google.com (mail-wr0-f172.google.com [209.85.128.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9C8CF78991 for ; Thu, 31 May 2018 10:03:52 +0000 (UTC) Received: by mail-wr0-f172.google.com with SMTP id w7-v6so20460122wrn.6 for ; Thu, 31 May 2018 03:03:52 -0700 (PDT) Received: from donizetti.lan (dynamic-adsl-78-12-189-60.clienti.tiscali.it. [78.12.189.60]) by smtp.gmail.com with ESMTPSA id g16-v6sm3520664wro.86.2018.05.31.03.03.49 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 03:03:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=d+aVNF2xlFBTKjtUJxjf9ehiA+lSJ2D87TwYiGnVTn8=; b=SqHZe9S5L7sJTdofvd+LdGVSKmWpcyfQfkl+79VILg6Rnvjg79LcnjSJerRmnRfpXA AwAQaqn6wbt4A8Ysz870FQfqvpr78oVPcJwh+HGo520qujcof0Rng8/sj85Gf3tBi0WS K6lBoAfMwicL+OjxpdpHBaHMrMRA+T0zOqBQjN6fy3k7Y0CdYNfqfRBCARJLHZJl7APu Gg/tb8Vkts/8nZFTjxwLjGrVKmGdamgs7pcIFUdcDmhgCsj2/Ao7iMvXLAW08sLsighw tphcdPicD6HRdPxj1zvUzVCByNdYZvIzHJ3T5OsK4wun699+Egp8cEswT0xNcEmmc03N VgSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references; bh=d+aVNF2xlFBTKjtUJxjf9ehiA+lSJ2D87TwYiGnVTn8=; b=d3cpwRXLk6bwrYFbZdEebtwspKE4oLekXvc+l1h2DyK63Gpg6rl86X8CN+1jbJuJPC o+0LRGS5CAVv9fSbAyw9vvr6MrwaeUxkGHwodPNbLD83eA+zdePGeSde5FLVIJJ9C+H0 wuHytZWDfDntkdy+P0S4iOGJZRd1bVQmJ9pJ+LQvGFFi6hK2Gv9Aksrhj8p7o1fvPwUF 2E/mDBJXYz9nrxoBbWD5CTZq1Xnq2leciQB10HWNe7CkNOd35v9rAoMjTSFj+SNaR7qs H7OWonb4YQO/0XFNP2fw/lRXrbFtmpzSyV1afoQdYZaTm/Qpg/CPoWhA+JPHbi25w7WE y1ZQ== X-Gm-Message-State: ALKqPwccwC/879S9brx+ML3XHHrv5/RG9Sv6mO735yw+kWcTcPv5EE7d Q/9PakuEmKTeADxe5Xj0YAXB+LQC X-Google-Smtp-Source: ADUXVKLyxIHHZN8q1BdfSeI8VbJw6XOehc1Gs/qciHQBzrLFcT7gdZPu6O3kurc8ikS0W3zo20xfog== X-Received: by 2002:adf:cd08:: with SMTP id w8-v6mr5103485wrm.187.1527761030909; Thu, 31 May 2018 03:03:50 -0700 (PDT) From: Paolo Bonzini To: patchew-devel@redhat.com Date: Thu, 31 May 2018 12:03:32 +0200 Message-Id: <20180531100334.2249-9-pbonzini@redhat.com> In-Reply-To: <20180531100334.2249-1-pbonzini@redhat.com> References: <20180531100334.2249-1-pbonzini@redhat.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 31 May 2018 10:03:52 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 31 May 2018 10:03:52 +0000 (UTC) for IP:'209.85.128.172' DOMAIN:'mail-wr0-f172.google.com' HELO:'mail-wr0-f172.google.com' FROM:'paolo.bonzini@gmail.com' RCPT:'' X-RedHat-Spam-Score: -1.1 (DKIM_SIGNED, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_PASS, T_DKIM_INVALID) 209.85.128.172 mail-wr0-f172.google.com 209.85.128.172 mail-wr0-f172.google.com X-RedHat-Possible-Forgery: Paolo Bonzini X-Scanned-By: MIMEDefang 2.78 on 10.5.110.26 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: patchew-devel@redhat.com Subject: [Patchew-devel] [PATCH 08/10] complete switch to database-based Results X-BeenThere: patchew-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Patchew development and discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: patchew-devel-bounces@redhat.com Errors-To: patchew-devel-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.25 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 31 May 2018 10:04:09 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" All results are stored in the database now and there is no need for the ResultTuple infrastructure. Remove all the code invoking the rest_results_hook and switch ResultsViewSet and ResultSerializer to be model-based. Signed-off-by: Paolo Bonzini --- api/models.py | 46 --------------------------------------- api/rest.py | 58 ++++++++++++++++--------------------------------- mods/git.py | 5 +---- mods/testing.py | 5 +---- www/views.py | 17 +++++---------- 5 files changed, 27 insertions(+), 104 deletions(-) diff --git a/api/models.py b/api/models.py index b5f7ebd..0a78419 100644 --- a/api/models.py +++ b/api/models.py @@ -16,7 +16,6 @@ import re =20 from django.core import validators from django.db import models -from django.db.models import Q from django.contrib.auth.models import User from django.urls import reverse import jsonfield @@ -125,14 +124,6 @@ class Result(models.Model): log_url =3D request.build_absolute_uri(log_url) return log_url =20 - @staticmethod - def get_result_tuples(obj, module, results): - name_filter =3D Q(name=3Dmodule) | Q(name__startswith=3Dmodule + '= .') - renderer =3D mod.get_module(module) - for r in obj.results.filter(name_filter): - results.append(ResultTuple(name=3Dr.name, obj=3Dobj, status=3D= r.status, - log=3Dr.log, data=3Dr.data, rendere= r=3Drenderer)) - def __str__(self): return '%s (%s)' % (self.name, self.status) =20 @@ -756,40 +747,3 @@ class Module(models.Model): =20 def __str__(self): return self.name - -class ResultTuple(namedtuple("ResultTuple", "name status log obj data rend= erer")): - __slots__ =3D () - - def __new__(cls, name, status, obj, log=3DNone, data=3DNone, renderer= =3DNone): - if status not in Result.VALID_STATUSES: - raise ValueError("invalid value '%s' for status field" % statu= s) - return super(cls, ResultTuple).__new__(cls, status=3Dstatus, log= =3Dlog, - obj=3Dobj, data=3Ddata, name=3Dn= ame, renderer=3Drenderer) - - def is_success(self): - return self.status =3D=3D Result.SUCCESS - - def is_failure(self): - return self.status =3D=3D Result.FAILURE - - def is_completed(self): - return self.is_success() or self.is_failure() - - def is_pending(self): - return self.status =3D=3D Result.PENDING - - def is_running(self): - return self.status =3D=3D Result.RUNNING - - def render(self): - if self.renderer is None: - return None - return self.renderer.render_result(self) - - def get_log_url(self, request=3DNone): - if not self.is_completed() or self.renderer is None: - return None - log_url =3D self.renderer.get_result_log_url(self) - if log_url is not None and request is not None: - log_url =3D request.build_absolute_uri(log_url) - return log_url diff --git a/api/rest.py b/api/rest.py index f36cf28..bb2276c 100644 --- a/api/rest.py +++ b/api/rest.py @@ -14,7 +14,7 @@ from django.http import Http404 from django.template import loader =20 from mod import dispatch_module_hook -from .models import Project, Message +from .models import Project, ProjectResult, Message, MessageResult, Result from .search import SearchEngine from rest_framework import (permissions, serializers, viewsets, filters, mixins, generics, renderers, status) @@ -425,10 +425,12 @@ class HyperlinkedResultField(HyperlinkedIdentityField= ): kwargs['projects_pk'] =3D obj.id return self.reverse(view_name, kwargs=3Dkwargs, request=3Drequest,= format=3Dformat) =20 -class ResultSerializer(serializers.Serializer): +class ResultSerializer(serializers.ModelSerializer): + class Meta: + model =3D Result + fields =3D ('resource_uri', 'name', 'status', 'last_update', 'data= ', 'log_url') + resource_uri =3D HyperlinkedResultField(view_name=3D'results-detail') - name =3D CharField() - status =3D CharField() # one of 'failure', 'success', 'pending', 'runn= ing' log_url =3D SerializerMethodField(required=3DFalse) data =3D JSONField(required=3DFalse) =20 @@ -437,53 +439,31 @@ class ResultSerializer(serializers.Serializer): return obj.get_log_url(request) =20 class ResultSerializerFull(ResultSerializer): + class Meta: + model =3D Result + fields =3D ResultSerializer.Meta.fields + ('log',) + + # The database field is log_xz, so this is needed here log =3D CharField(required=3DFalse) =20 -class ResultsViewSet(viewsets.ViewSet, generics.GenericAPIView): +class ResultsViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, + viewsets.GenericViewSet): lookup_field =3D 'name' lookup_value_regex =3D '[^/]+' - permission_classes =3D (PatchewPermission,) + filter_backends =3D (filters.OrderingFilter,) + ordering_fields =3D ('name',) + ordering =3D ('name',) =20 def get_serializer_class(self, *args, **kwargs): if self.lookup_field in self.kwargs: return ResultSerializerFull return ResultSerializer =20 - def get_results(self, detailed): - queryset =3D self.get_queryset() - try: - obj =3D queryset[0] - except IndexError: - raise Http404 - results =3D [] - dispatch_module_hook("rest_results_hook", obj=3Dobj, results=3Dres= ults, - detailed=3Ddetailed) - return {x.name: x for x in results} - - def list(self, request, *args, **kwargs): - results =3D self.get_results(detailed=3DFalse).values() - serializer =3D self.get_serializer(results, many=3DTrue) - # Fake paginator response for forwards-compatibility, in case - # this ViewSet becomes model-based - return Response(OrderedDict([ - ('count', len(results)), - ('results', serializer.data) - ])) - - def retrieve(self, request, name, *args, **kwargs): - results =3D self.get_results(detailed=3DTrue) - try: - result =3D results[name] - except KeyError: - raise Http404 - serializer =3D self.get_serializer(result) - return Response(serializer.data) - class ProjectResultsViewSet(ResultsViewSet): def get_queryset(self): - return Project.objects.filter(id=3Dself.kwargs['projects_pk']) + return ProjectResult.objects.filter(project=3Dself.kwargs['project= s_pk']) =20 class SeriesResultsViewSet(ResultsViewSet): def get_queryset(self): - return Message.objects.filter(project=3Dself.kwargs['projects_pk'], - message_id=3Dself.kwargs['series_mes= sage_id']) + return MessageResult.objects.filter(message__project=3Dself.kwargs= ['projects_pk'], + message__message_id=3Dself.kwa= rgs['series_message_id']) diff --git a/mods/git.py b/mods/git.py index b8c2ff0..2b24b24 100644 --- a/mods/git.py +++ b/mods/git.py @@ -18,7 +18,7 @@ from django.core.exceptions import PermissionDenied from django.utils.html import format_html from mod import PatchewModule from event import declare_event, register_handler, emit_event -from api.models import Message, MessageProperty, Project, Result, ResultTu= ple +from api.models import Message, MessageProperty, Project, Result from api.rest import PluginMethodField from api.views import APILoginRequiredView, prepare_series from patchew.logviewer import LogView @@ -134,9 +134,6 @@ class GitModule(PatchewModule): def rest_series_fields_hook(self, request, fields, detailed): fields['based_on'] =3D PluginMethodField(obj=3Dself, required=3DFa= lse) =20 - def rest_results_hook(self, obj, results, detailed=3DFalse): - Result.get_result_tuples(obj, "git", results) - def prepare_message_hook(self, request, message, detailed): if not message.is_series_head: return diff --git a/mods/testing.py b/mods/testing.py index 9c053a7..7dfc5a2 100644 --- a/mods/testing.py +++ b/mods/testing.py @@ -19,7 +19,7 @@ import time import math from api.views import APILoginRequiredView from api.models import (Message, MessageProperty, MessageResult, - Project, ProjectResult, Result, ResultTuple) + Project, ProjectResult, Result) from api.search import SearchEngine from event import emit_event, declare_event, register_handler from patchew.logviewer import LogView @@ -272,9 +272,6 @@ class TestingModule(PatchewModule): }) return ret =20 - def rest_results_hook(self, obj, results, detailed=3DFalse): - Result.get_result_tuples(obj, "testing", results) - def prepare_message_hook(self, request, message, detailed): if not message.is_series_head: return diff --git a/www/views.py b/www/views.py index c2010c5..5685f23 100644 --- a/www/views.py +++ b/www/views.py @@ -92,19 +92,14 @@ def prepare_series(request, s, skip_patches=3DFalse): return r =20 def prepare_results(request, obj): - results =3D [] - dispatch_module_hook("rest_results_hook", obj=3Dobj, - results=3Dresults, detailed=3DFalse) - - results_dicts =3D [] - for result in results: - html =3D result.render() + rendered_results =3D [] + for result in obj.results.all(): + html =3D result.render(obj) if html is None: continue - d =3D result._asdict() - d['html'] =3D html - results_dicts.append(d) - return results_dicts + result.html =3D html + rendered_results.append(result) + return rendered_results =20 def prepare_series_list(request, sl): return [prepare_message(request, s.project, s, False) for s in sl] --=20 2.17.0 _______________________________________________ Patchew-devel mailing list Patchew-devel@redhat.com https://www.redhat.com/mailman/listinfo/patchew-devel