Skip to content

Commit afaddd7

Browse files
authored
Merge pull request #72 from collective/SE-267/odfsplit
Added odfsplit utils
2 parents 42fe2d1 + 2236d87 commit afaddd7

File tree

7 files changed

+91
-3
lines changed

7 files changed

+91
-3
lines changed

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Changelog
1212
[gbastien]
1313
- Made subtemplate icon grey.
1414
[chris-adam]
15+
- Added odfsplit utils.
16+
[chris-adam]
1517

1618
3.45 (2025-06-25)
1719
-----------------

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,7 @@
6666
entry_points="""
6767
[z3c.autoinclude.plugin]
6868
target = plone
69+
[console_scripts]
70+
odfsplit = appy.bin.odfsplit:main
6971
""",
7072
)
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
# -*- coding: utf-8 -*-
22
"""Init and utils."""
3-
43
from zope.i18nmessageid import MessageFactory
54

5+
import os
6+
67

78
_ = MessageFactory('collective.documentgenerator')
89

10+
if os.environ.get("ZOPE_HOME", ""):
11+
BLDT_DIR = "/".join(os.getenv("INSTANCE_HOME", "").split("/")[:-2])
12+
else: # test env
13+
BLDT_DIR = os.getenv("PWD", "")
14+
915

1016
def initialize(context):
1117
"""Initializer called when used as a Zope 2 product."""

src/collective/documentgenerator/browser/generation_view.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,13 +492,18 @@ def __call__(self, document_uid='', document_url_path='', generated_doc_title=''
492492
persisted_doc = self.generate_persistent_doc(self.pod_template, self.output_format)
493493
self.redirects(persisted_doc)
494494

495+
def add_mailing_infos(self, doc, gen_context):
496+
""" store mailing informations on generated doc """
497+
annot = IAnnotations(doc)
498+
annot['documentgenerator'] = {"need_mailing": False, "template_uid": self.pod_template.UID(), "mailed": True}
499+
495500
def _get_base_args(self, template_uid, output_format):
496501
annot = IAnnotations(self.document).get('documentgenerator', '')
497502
if not annot or 'template_uid' not in annot:
498503
raise Exception("Cannot find 'template_uid' on document '{0}'".format(self.document.absolute_url()))
499504
self.orig_template = self.get_pod_template(annot['template_uid'])
500-
if (not base_hasattr(self.orig_template, 'mailing_loop_template') or
501-
not self.orig_template.mailing_loop_template):
505+
if (not base_hasattr(self.orig_template, 'mailing_loop_template')
506+
or not self.orig_template.mailing_loop_template):
502507
raise Exception("Cannot find 'mailing_loop_template' on template '{0}'".format(
503508
self.orig_template.absolute_url()))
504509
loop_template = self.get_pod_template(self.orig_template.mailing_loop_template)
32.7 KB
Binary file not shown.

src/collective/documentgenerator/tests/test_utils.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from collective.documentgenerator.testing import PODTemplateIntegrationTest
33
from collective.documentgenerator.utils import compute_md5
44
from collective.documentgenerator.utils import convert_odt
5+
from collective.documentgenerator.utils import odfsplit
56
from collective.documentgenerator.utils import temporary_file_name
67
from collective.documentgenerator.utils import update_dict_with_validation
78
from collective.documentgenerator.utils import update_oo_config
@@ -210,3 +211,33 @@ def test_convert_odt(self):
210211
self.assertIn("<body", content)
211212
self.assertIn("Page 1", content)
212213
self.assertIn("Page 2", content)
214+
215+
def test_odfsplit(self):
216+
filename = u"test_mailing.odt"
217+
current_path = os.path.dirname(__file__)
218+
content = open(os.path.join(current_path, filename), "rb").read()
219+
code, result, nb = odfsplit(content)
220+
self.assertEqual(code, 0)
221+
self.assertEqual(nb, 2)
222+
results = list(result)
223+
self.assertEqual(len(results), 2)
224+
self.assertEqual(len(results[0]), 32531)
225+
self.assertEqual(len(results[1]), 32352)
226+
227+
filename = u"test_file.odt"
228+
current_path = os.path.dirname(__file__)
229+
content = open(os.path.join(current_path, filename), "rb").read()
230+
code, result, nb = odfsplit(content)
231+
self.assertEqual(code, 0)
232+
self.assertEqual(nb, 1)
233+
results = list(result)
234+
self.assertEqual(len(results), 1)
235+
self.assertEqual(len(results[0]), 9729)
236+
237+
filename = u"test_utils.py"
238+
current_path = os.path.dirname(__file__)
239+
content = open(os.path.join(current_path, filename), "rb").read()
240+
code, result, nb = odfsplit(content)
241+
self.assertEqual(code, 1)
242+
self.assertEqual(nb, 0)
243+
self.assertTrue(result.strip().endswith("zipfile.BadZipfile: File is not a zip file"))

src/collective/documentgenerator/utils.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
from appy.pod.lo_pool import LoPool
44
from appy.pod.renderer import Renderer
55
from collective.documentgenerator import _
6+
from collective.documentgenerator import BLDT_DIR
67
from collective.documentgenerator import config
78
from imio.helpers.content import uuidToObject
89
from imio.helpers.security import fplog
10+
from imio.pyutils.system import runCommand
911
from plone import api
1012
from plone.dexterity.utils import createContentInContainer
1113
from plone.namedfile.file import NamedBlobFile
@@ -307,3 +309,43 @@ def need_mailing_value(document=None, document_uid=None):
307309
if "documentgenerator" in annot and annot["documentgenerator"].get("need_mailing", False):
308310
return True
309311
return False
312+
313+
314+
def odfsplit(content):
315+
"""Splits an ODT document into a series of sub-documents. The split is based on page breaks.
316+
317+
:param content: The binary content of the ODT file to be split.
318+
:return: A tuple containing the exit code, a generator yielding the binary content of each subfile and
319+
the number of files
320+
"""
321+
322+
def get_subfiles(temp_file, nb_files):
323+
if nb_files == 1:
324+
with open(temp_file, "rb") as f:
325+
yield f.read()
326+
remove_tmp_file(temp_file)
327+
return
328+
for i in range(1, nb_files + 1):
329+
subfile = temp_file.replace(".odt", ".{}.odt".format(i))
330+
with open(subfile, "rb") as sf:
331+
yield sf.read()
332+
remove_tmp_file(subfile)
333+
remove_tmp_file(temp_file)
334+
335+
temp_file = temporary_file_name(suffix=".odt")
336+
with open(temp_file, "wb") as f:
337+
f.write(content)
338+
command = "{pwd}/bin/odfsplit {temp_file}".format(temp_file=temp_file, pwd=BLDT_DIR)
339+
out, err, code = runCommand(command)
340+
nb_files = 0
341+
if out and code == 0:
342+
part0 = out[0].split(" ")[0] # Ex: "2 files were generated."
343+
if part0.isdigit():
344+
nb_files = int(part0)
345+
value = get_subfiles(temp_file, nb_files)
346+
else:
347+
nb_files = 1
348+
value = get_subfiles(temp_file, 1)
349+
else:
350+
value = "".join(err)
351+
return code, value, nb_files

0 commit comments

Comments
 (0)