barbacompta/eo_gestion/eo_facture/facturx.py

67 lines
2.5 KiB
Python

# barbacompta - invoicing for dummies
# Copyright (C) 2010-2012 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import os
import subprocess
import tempfile
import facturx
from django.template.loader import render_to_string
logger = logging.getLogger(__name__)
GS_INCLUDE_DIR = os.path.join(os.path.dirname(__file__), 'gs-includes')
DEFAULT_ICC_PROFILE = os.path.join(GS_INCLUDE_DIR, 'compatibleWithAdobeRGB1998.icc')
def to_pdfa(pdf_bytes: bytes, icc_profile: str = DEFAULT_ICC_PROFILE):
with tempfile.NamedTemporaryFile() as output_fd, tempfile.NamedTemporaryFile() as input_fd:
input_fd.write(pdf_bytes)
input_fd.flush()
args = [
'gs',
'-dPDFA',
'-dBATCH',
'-dNOPAUSE',
'-sICCProfile=' + icc_profile,
'-sProcessColorModel=DeviceCMYK',
'-sDEVICE=pdfwrite',
'-dPDFACompatibilityPolicy=2',
# ghostscript needs percent character in output filename to be quoted
'-sOutputFile=' + output_fd.name.replace('%', '%%'),
# give right to GS of reading local PDF_def.ps and ICC profile
'-I' + GS_INCLUDE_DIR,
'PDFA_def.ps',
input_fd.name,
]
logger.debug('converting to PDF/A, calling %s', args)
completed = subprocess.run(args, capture_output=True, text=True, check=False)
logger.debug('ghostscript result %s', completed)
if completed.returncode != 0:
logger.error('ghostcript call failed %s', completed)
completed.check_returncode()
return output_fd.read()
DEFAULT_FACTURX_TEMPLATE = 'factur-x.xml'
def add_facturx_from_bytes(pdf_bytes: bytes, facturx_context: dict, template: str = DEFAULT_FACTURX_TEMPLATE):
pdfa_bytes = to_pdfa(pdf_bytes)
facturx_xml = str(render_to_string(template, facturx_context)).encode('utf-8')
return facturx.generate_facturx_from_binary(pdfa_bytes, facturx_xml)