]> git.ipfire.org Git - thirdparty/patchwork.git/commitdiff
Add 'dumparchive' management command
authorMete Polat <metepolat2000@gmail.com>
Mon, 15 Jul 2019 14:50:28 +0000 (16:50 +0200)
committerStephen Finucane <stephen@that.guru>
Fri, 19 Jul 2019 18:16:10 +0000 (19:16 +0100)
Introduces a new management command which can export all patches in a
project as one mbox file. Export of multiple projects is supported.
Additionally allows to compress the output.

Signed-off-by: Mete Polat <metepolat2000@gmail.com>
Signed-off-by: Stephen Finucane <stephen@that.guru>
docs/deployment/management.rst
patchwork/management/commands/dumparchive.py [new file with mode: 0644]
releasenotes/notes/mbox-export-project-cmd-090cb74c68608aa8.yaml [new file with mode: 0644]

index c50b7b69d33d7c40743d35c711e3877356e9d378..9c57f1962283ee0607502665447e18447a2c600c 100644 (file)
@@ -46,6 +46,28 @@ request them and is helpful to expire unused users created by spambots. For
 more information on integration of this script, refer to the :ref:`deployment
 installation guide <deployment-cron>`.
 
+dumparchive
+~~~~~~~~~~~
+
+.. program:: manage.py dumparchive
+
+Export Patchwork projects as tarball of mbox files.
+
+.. code-block:: shell
+
+   ./manage.py dumparchive [-c | --compress] [PROJECT [PROJECT...]]
+
+This is mostly useful for exporting the patch dataset of a Patchwork project
+for use with other programs.
+
+.. option:: -c, --compress
+
+   compress generated archive.
+
+.. option:: PROJECT
+
+   list ID of project(s) to export. Export all projects if none specified.
+
 parsearchive
 ~~~~~~~~~~~~
 
@@ -123,7 +145,7 @@ Update the tag (Ack/Review/Test) counts on existing patches.
 
 .. code-block:: shell
 
-  ./manage.py retag [<patch_id>...]
+   ./manage.py retag [<patch_id>...]
 
 Patchwork extracts :ref:`tags <overview-tags>` from each patch it receives. By
 default, three tags are extracted, but it's possible to change this on a
diff --git a/patchwork/management/commands/dumparchive.py b/patchwork/management/commands/dumparchive.py
new file mode 100644 (file)
index 0000000..9ee80c8
--- /dev/null
@@ -0,0 +1,73 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2019, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from datetime import datetime
+import tarfile
+import tempfile
+
+from django.core.management import BaseCommand
+from django.core.management import CommandError
+from django.utils.encoding import force_bytes
+
+from patchwork.models import Patch
+from patchwork.models import Project
+from patchwork.views.utils import patch_to_mbox
+
+
+class Command(BaseCommand):
+    help = 'Export patchwork projects as tarball of mbox files'
+
+    def add_arguments(self, parser):
+        parser.add_argument(
+            '-c', '--compress', action='store_true',
+            help='compress generated archive.',
+        )
+        parser.add_argument(
+            'projects', metavar='PROJECT', nargs='*',
+            help='list ID of project(s) to export. If not supplied, all '
+            'projects will be exported.',
+        )
+
+    def handle(self, *args, **options):
+        if options['projects']:
+            projects = []
+            for listid in options['projects']:
+                try:
+                    projects.append(Project.objects.get(listid=listid))
+                except Project.DoesNotExist:
+                    raise CommandError('Project not found: %s' % listid)
+        else:
+            projects = list(Project.objects.all())
+
+        name = 'patchwork_dump_' + datetime.now().strftime('%Y_%m_%d_%H%M%S')
+
+        if options['compress']:
+            name += '.tar.gz'
+            compress_level = 9
+        else:
+            name += '.tar'
+            compress_level = 1
+
+        self.stdout.write('Generating patch archive...')
+
+        with tarfile.open(name, 'w:gz', compresslevel=compress_level) as tar:
+            for i, project in enumerate(projects):
+                self.stdout.write('Project %02d/%02d (%s)' % (
+                    i + 1, len(projects), project.linkname))
+
+                with tempfile.NamedTemporaryFile(delete=False) as mbox:
+                    patches = Patch.objects.filter(patch_project=project)
+                    count = patches.count()
+                    for j, patch in enumerate(patches):
+                        if not (j % 10):
+                            self.stdout.write('%06d/%06d\r' % (j, count),
+                                              ending='')
+                            self.stdout.flush()
+
+                        mbox.write(force_bytes(patch_to_mbox(patch) + '\n'))
+
+                tar.add(mbox.name, arcname='%s.mbox' % project.linkname)
+
+        self.stdout.write('Dumped patch archive to %r' % name)
diff --git a/releasenotes/notes/mbox-export-project-cmd-090cb74c68608aa8.yaml b/releasenotes/notes/mbox-export-project-cmd-090cb74c68608aa8.yaml
new file mode 100644 (file)
index 0000000..3f3bfa2
--- /dev/null
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Exporting patchwork projects as mbox files and optionally compressing them
+    is now possible with the ``./manage exportproject`` management command.