[postprocessor:zip] implement 'files' option (#2872)
This commit is contained in:
@@ -3805,6 +3805,19 @@ Description
|
|||||||
Filename extension for the created ZIP archive.
|
Filename extension for the created ZIP archive.
|
||||||
|
|
||||||
|
|
||||||
|
zip.files
|
||||||
|
---------
|
||||||
|
Type
|
||||||
|
``list`` of |Path|
|
||||||
|
Example
|
||||||
|
``["info.json"]``
|
||||||
|
Description
|
||||||
|
List of extra files to be added to a ZIP archive.
|
||||||
|
|
||||||
|
Note: Relative paths are relative to the current
|
||||||
|
`download directory <extractor.*.directory_>`__.
|
||||||
|
|
||||||
|
|
||||||
zip.keep-files
|
zip.keep-files
|
||||||
--------------
|
--------------
|
||||||
Type
|
Type
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class ZipPP(PostProcessor):
|
|||||||
def __init__(self, job, options):
|
def __init__(self, job, options):
|
||||||
PostProcessor.__init__(self, job)
|
PostProcessor.__init__(self, job)
|
||||||
self.delete = not options.get("keep-files", False)
|
self.delete = not options.get("keep-files", False)
|
||||||
|
self.files = options.get("files")
|
||||||
ext = "." + options.get("extension", "zip")
|
ext = "." + options.get("extension", "zip")
|
||||||
algorithm = options.get("compression", "store")
|
algorithm = options.get("compression", "store")
|
||||||
if algorithm not in self.COMPRESSION_ALGORITHMS:
|
if algorithm not in self.COMPRESSION_ALGORITHMS:
|
||||||
@@ -56,6 +57,9 @@ class ZipPP(PostProcessor):
|
|||||||
# 'NameToInfo' is not officially documented, but it's available
|
# 'NameToInfo' is not officially documented, but it's available
|
||||||
# for all supported Python versions and using it directly is a lot
|
# for all supported Python versions and using it directly is a lot
|
||||||
# faster than calling getinfo()
|
# faster than calling getinfo()
|
||||||
|
if self.files:
|
||||||
|
self.write_extra(pathfmt, zfile, self.files)
|
||||||
|
self.files = None
|
||||||
if pathfmt.filename not in zfile.NameToInfo:
|
if pathfmt.filename not in zfile.NameToInfo:
|
||||||
zfile.write(pathfmt.temppath, pathfmt.filename)
|
zfile.write(pathfmt.temppath, pathfmt.filename)
|
||||||
pathfmt.delete = self.delete
|
pathfmt.delete = self.delete
|
||||||
@@ -69,6 +73,21 @@ class ZipPP(PostProcessor):
|
|||||||
with self.open() as zfile:
|
with self.open() as zfile:
|
||||||
self.write(pathfmt, zfile)
|
self.write(pathfmt, zfile)
|
||||||
|
|
||||||
|
def write_extra(self, pathfmt, zfile, files):
|
||||||
|
for path in map(util.expand_path, files):
|
||||||
|
if not os.path.isabs(path):
|
||||||
|
path = os.path.join(pathfmt.realdirectory, path)
|
||||||
|
try:
|
||||||
|
zfile.write(path, os.path.basename(path))
|
||||||
|
except OSError as exc:
|
||||||
|
self.log.warning(
|
||||||
|
"Unable to write %s to %s", path, zfile.filename)
|
||||||
|
self.log.debug("%s: %s", exc, exc.__class__.__name__)
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if self.delete:
|
||||||
|
util.remove_file(path)
|
||||||
|
|
||||||
def finalize(self, pathfmt, status):
|
def finalize(self, pathfmt, status):
|
||||||
if self.zfile:
|
if self.zfile:
|
||||||
self.zfile.close()
|
self.zfile.close()
|
||||||
|
|||||||
@@ -452,9 +452,11 @@ class ZipTest(BasePostprocessorTest):
|
|||||||
self.assertTrue(pp.args[0].endswith("/test.cbz"))
|
self.assertTrue(pp.args[0].endswith("/test.cbz"))
|
||||||
|
|
||||||
def test_zip_write(self):
|
def test_zip_write(self):
|
||||||
pp = self._create()
|
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile("w", dir=self.dir.name) as file:
|
with tempfile.NamedTemporaryFile("w", dir=self.dir.name) as file:
|
||||||
|
pp = self._create({"files": [file.name, "_info_.json"],
|
||||||
|
"keep-files": True})
|
||||||
|
|
||||||
|
filename = os.path.basename(file.name)
|
||||||
file.write("foobar\n")
|
file.write("foobar\n")
|
||||||
|
|
||||||
# write dummy file with 3 different names
|
# write dummy file with 3 different names
|
||||||
@@ -466,18 +468,19 @@ class ZipTest(BasePostprocessorTest):
|
|||||||
self._trigger()
|
self._trigger()
|
||||||
|
|
||||||
nti = pp.zfile.NameToInfo
|
nti = pp.zfile.NameToInfo
|
||||||
self.assertEqual(len(nti), i+1)
|
self.assertEqual(len(nti), i+2)
|
||||||
self.assertIn(name, nti)
|
self.assertIn(name, nti)
|
||||||
|
|
||||||
# check file contents
|
# check file contents
|
||||||
self.assertEqual(len(nti), 3)
|
self.assertEqual(len(nti), 4)
|
||||||
self.assertIn("file0.ext", nti)
|
self.assertIn("file0.ext", nti)
|
||||||
self.assertIn("file1.ext", nti)
|
self.assertIn("file1.ext", nti)
|
||||||
self.assertIn("file2.ext", nti)
|
self.assertIn("file2.ext", nti)
|
||||||
|
self.assertIn(filename, nti)
|
||||||
|
|
||||||
# write the last file a second time (will be skipped)
|
# write the last file a second time (will be skipped)
|
||||||
self._trigger()
|
self._trigger()
|
||||||
self.assertEqual(len(pp.zfile.NameToInfo), 3)
|
self.assertEqual(len(pp.zfile.NameToInfo), 4)
|
||||||
|
|
||||||
# close file
|
# close file
|
||||||
self._trigger(("finalize",), 0)
|
self._trigger(("finalize",), 0)
|
||||||
@@ -485,10 +488,11 @@ class ZipTest(BasePostprocessorTest):
|
|||||||
# reopen to check persistence
|
# reopen to check persistence
|
||||||
with zipfile.ZipFile(pp.zfile.filename) as file:
|
with zipfile.ZipFile(pp.zfile.filename) as file:
|
||||||
nti = file.NameToInfo
|
nti = file.NameToInfo
|
||||||
self.assertEqual(len(pp.zfile.NameToInfo), 3)
|
self.assertEqual(len(pp.zfile.NameToInfo), 4)
|
||||||
self.assertIn("file0.ext", nti)
|
self.assertIn("file0.ext", nti)
|
||||||
self.assertIn("file1.ext", nti)
|
self.assertIn("file1.ext", nti)
|
||||||
self.assertIn("file2.ext", nti)
|
self.assertIn("file2.ext", nti)
|
||||||
|
self.assertIn(filename, nti)
|
||||||
|
|
||||||
os.unlink(pp.zfile.filename)
|
os.unlink(pp.zfile.filename)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user