From patchwork Mon Jul 15 14:50:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mete Polat X-Patchwork-Id: 1132069 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45nRNy06JQz9sPv for ; Tue, 16 Jul 2019 00:53:38 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="piEfPNhD"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 45nRNw3TkmzDqBj for ; Tue, 16 Jul 2019 00:53:36 +1000 (AEST) X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gmail.com (client-ip=2a00:1450:4864:20::330; helo=mail-wm1-x330.google.com; envelope-from=metepolat2000@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="piEfPNhD"; dkim-atps=neutral Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 45nRL818lLzDqS1 for ; Tue, 16 Jul 2019 00:51:11 +1000 (AEST) Received: by mail-wm1-x330.google.com with SMTP id p74so15469642wme.4 for ; Mon, 15 Jul 2019 07:51:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=8sNLN5sSm3r8S0DalbStCrnGFBlGFf9JFAkLThtsX9I=; b=piEfPNhD1A/DoKD9phnI0Jd+q5ZxiPWegcyM66QF6cxCQixallFU24uRfyN5P5PV51 elvw5qz+jV/uXW/d304xFfu+YeHdPtF72WLEyculHUULki5yY0bnWUKoWq9ac2jVOCR2 xwNp+z4FLVeRvc6KAjeELvJ/ieiYHHraJEC7oMO8jmx2sLi3eS7Xm9yYPb3LQsfNY1i2 jotufXNFbRJNHNnzzt+/ikWlrrSbCjuad0MglrtKJxTRv6VuR77bG8VcqDpQXBrI/fjp yM5c96eqPriNA1cyiBk0+wysiy+3mZQHU1YVWDimz+3p37UvYfsTwDuGZ3AvjDccMEye 8iaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=8sNLN5sSm3r8S0DalbStCrnGFBlGFf9JFAkLThtsX9I=; b=KbybPNB+In91cBOTE27Sd/dd4Ly4pYWHS5vbRI+GNfvNrsFlzuF2To2yxpID3nj62O FLXC3ys48yNG3PVfctPNP2CMY8odPK7E4fZSbSn82JWVxKfIgFXo8EDxJVIQ9F7dIwdL ThAnCBHI2t6loqyVinNqlmMgF4TsaMj2Rkb/PWZPuPR9QyDPiZcZoWgdIJezWh4UUl65 qjoEI+aVCHb5gvExApcR/72svt3A2dVq6WwoQHVuZE3+t/wrb433eflE09CgnsejHRqW 4kknHFWp2HB6uXxNtaA51VvXLvgf4yCL8W4ejS+pQbVUk0HHM2GhCqBEFXdgjf/VAxn9 5Kbw== X-Gm-Message-State: APjAAAU7yyRPw7MtV0TqRACOI/4hRiG3GezarCpKBC9B4YZcN7At3c1A 3O+sltrUxZ+OGqITT16vBJEiwVAY2YwY6A== X-Google-Smtp-Source: APXvYqy4Iho/dTah/hJr+lANo63qHGpvdVFnsGNWqKQdsKrDDjMuQLrats1p4tKN/4EOHhxJ7g73yw== X-Received: by 2002:a1c:e009:: with SMTP id x9mr24565801wmg.5.1563202264953; Mon, 15 Jul 2019 07:51:04 -0700 (PDT) Received: from localhost.localdomain ([193.23.33.53]) by smtp.gmail.com with ESMTPSA id z6sm13466262wrw.2.2019.07.15.07.51.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 15 Jul 2019 07:51:04 -0700 (PDT) From: Mete Polat To: patchwork@lists.ozlabs.org Subject: [PATCH 1/3] Add export project as mbox management command Date: Mon, 15 Jul 2019 16:50:28 +0200 Message-Id: <20190715145030.7877-1-metepolat2000@gmail.com> X-Mailer: git-send-email 2.22.0 MIME-Version: 1.0 X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ralf.ramsauer@oth-regensburg.de, wolfgang.mauerer@oth-regensburg.de Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" Introduces a new management command which can export all patches in a project as one mbox file. Export of multiple projects is supported. Additionaly allows to compress the output. Signed-off-by: Mete Polat --- Also supports python2 with the force_bytes() function. .../management/commands/exportproject.py | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 patchwork/management/commands/exportproject.py diff --git a/patchwork/management/commands/exportproject.py b/patchwork/management/commands/exportproject.py new file mode 100644 index 0000000..7e18234 --- /dev/null +++ b/patchwork/management/commands/exportproject.py @@ -0,0 +1,71 @@ +# Patchwork - automated patch tracking system +# Copyright (C) 2019, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import tarfile +from uuid import uuid4 + +from django.core.management import BaseCommand, CommandError +from django.utils.encoding import force_bytes + +from patchwork.models import Project, Patch +from patchwork.views.utils import patch_to_mbox + + +class Command(BaseCommand): + help = 'Export patchwork projects as mbox files and optionally compress ' + 'the result.' + + def add_arguments(self, parser): + parser.add_argument( + '-c', '--compress', action='store_true', + help='Bundle and compress projects.' + ) + parser.add_argument( + '-l', '--level', action='store', type=int, default=9, + help='Set a compression level between 0 and 9 (default). 0 is no ' + 'compression. ' + ) + parser.add_argument( + 'project_linkname', nargs='*', + help='Project linknames. Export all projects if none specified.' + ) + + def handle(self, *args, **options): + if options['project_linkname']: + projects = [] + for p_linkname in options['project_linkname']: + try: + projects.append(Project.objects.get(linkname=p_linkname)) + except Project.DoesNotExist: + raise CommandError('%s: Project not found' % p_linkname) + else: + projects = Project.objects.all() + + compress = options['compress'] + level = options['level'] + + tar = None + if compress: + name = projects[0].linkname if len(projects) == 1 else 'patchwork' + name += '.tar' if level == 0 else '.tar.gz' + tar = tarfile.open(name, 'w:gz', compresslevel=level) + + try: + for project in projects: + name = project.linkname + '.mbox' + tmp_name = '%s_%s' % (project.linkname, uuid4().hex) + with open(tmp_name, 'wb') as mbox: + for patch in Patch.objects.filter(patch_project=project): + mbox.write(force_bytes(patch_to_mbox(patch) + '\n')) + mbox.close() + if compress: + tar.add(tmp_name, arcname=name) + os.remove(tmp_name) + else: + os.rename(tmp_name, name) + finally: + if tar is not None: + tar.close()