PDFUnite: added warnings and errors about missing input files

- Also simplified the create_pdf.py error handling.
  - We are not catching I/O errors, they are fatal and should be
    catched at a higher level.
  - We already check the input files and create the output dir.
- Added tests
This commit is contained in:
Salvador E. Tropea 2022-06-13 08:56:25 -03:00
parent ad6bafd856
commit e6cfe15dd0
5 changed files with 44 additions and 25 deletions

View File

@ -6,38 +6,22 @@
# Project: KiBot (formerly KiPlot)
# Base idea: https://gitlab.com/dennevi/Board2Pdf/ (Released as Public Domain)
from . import PyPDF2
from .error import KiPlotConfigurationError
def create_pdf_from_pages(input_files, output_fn):
output = PyPDF2.PdfFileWriter()
# Collect all pages
open_files = []
er = None
for filename in input_files:
try:
file = open(filename, 'rb')
open_files.append(file)
pdf_reader = PyPDF2.PdfFileReader(file)
page_obj = pdf_reader.getPage(0)
page_obj.compressContentStreams()
output.addPage(page_obj)
except (IOError, ValueError, EOFError) as e:
er = str(e)
if er:
raise KiPlotConfigurationError('Error reading `{}` ({})'.format(filename, er))
# Write all pages to a file
pdf_output = None
try:
pdf_output = open(output_fn, 'wb')
with open(output_fn, 'wb') as pdf_output:
output.write(pdf_output)
except (IOError, ValueError, EOFError) as e:
er = str(e)
finally:
if pdf_output:
pdf_output.close()
if er:
raise KiPlotConfigurationError('Error creating `{}` ({})'.format(output_fn, er))
# Close the files
for f in open_files:
f.close()

View File

@ -38,6 +38,7 @@ RENDER_3D_ERR = 24
FAILED_EXECUTE = 25
KICOST_ERROR = 26
MISSING_WKS = 27
MISSING_FILES = 28
error_level_to_name = ['NONE',
'INTERNAL_ERROR',
'WRONG_ARGUMENTS',
@ -241,6 +242,7 @@ W_ECCLASST = '(W088) '
W_PDMASKFAIL = '(W089) '
W_MISSTOOL = '(W090) '
W_NOTYET = '(W091) '
W_NOMATCH = '(W092) '
# Somehow arbitrary, the colors are real, but can be different
PCB_MAT_COLORS = {'fr1': "937042", 'fr2': "949d70", 'fr3': "adacb4", 'fr4': "332B16", 'fr5': "6cc290"}
PCB_FINISH_COLORS = {'hal': "8b898c", 'hasl': "8b898c", 'imag': "8b898c", 'enig': "cfb96e", 'enepig': "cfb96e",

View File

@ -11,7 +11,7 @@ from subprocess import check_output, STDOUT, CalledProcessError
from .gs import GS
from .error import KiPlotConfigurationError
from .kiplot import config_output, get_output_dir, run_output
from .misc import MISSING_TOOL, WRONG_INSTALL, WRONG_ARGUMENTS, INTERNAL_ERROR, W_NOTPDF
from .misc import MISSING_TOOL, WRONG_INSTALL, WRONG_ARGUMENTS, INTERNAL_ERROR, W_NOTPDF, MISSING_FILES, W_NOMATCH
from .optionable import Optionable, BaseOptions
from .registrable import RegOutput
from .create_pdf import create_pdf_from_pages
@ -88,12 +88,15 @@ class PDFUniteOptions(BaseOptions):
source = f.expand_filename_both(f.source, make_safe=False)
files_list = glob.iglob(os.path.join(out_dir, source), recursive=True)
# Filter and adapt them
old_len = len(files)
for fname in filter(re.compile(f.filter).match, files_list):
fname_real = os.path.realpath(fname)
# Avoid including the output
if fname_real == output_real:
continue
files.append(fname_real)
if len(files) == old_len:
logger.warning(W_NOMATCH+'No match found for `{}`'.format(f.from_output if f.from_output else f.source))
return files
def get_targets(self, out_dir):
@ -128,6 +131,9 @@ class PDFUniteOptions(BaseOptions):
sig = f.read(4)
if sig != b'%PDF':
logger.warning(W_NOTPDF+'Joining a non PDF file `{}`, will most probably fail'.format(fn))
if len(files) < 2:
logger.error('At least two files must be joined ({})'.format(files))
exit(MISSING_FILES)
logger.debug('Generating `{}` PDF'.format(output))
if os.path.isfile(output):
os.remove(output)

View File

@ -35,7 +35,7 @@ import subprocess
import json
from . import context
from kibot.misc import (EXIT_BAD_ARGS, EXIT_BAD_CONFIG, NO_PCB_FILE, NO_SCH_FILE, EXAMPLE_CFG, WONT_OVERWRITE, CORRUPTED_PCB,
PCBDRAW_ERR, NO_PCBNEW_MODULE, NO_YAML_MODULE, INTERNAL_ERROR)
PCBDRAW_ERR, NO_PCBNEW_MODULE, NO_YAML_MODULE, INTERNAL_ERROR, MISSING_FILES)
POS_DIR = 'positiondir'
@ -1037,6 +1037,21 @@ def test_pdfunite_2(test_dir):
ctx.clean_up()
def test_pdfunite_no_input(test_dir):
prj = 'bom'
ctx = context.TestContext(test_dir, prj, 'pdfunite_2', POS_DIR)
ctx.run(MISSING_FILES, extra=['PDF_Joined'])
ctx.clean_up()
def test_pdfunite_wrong_input(test_dir):
prj = 'bom'
ctx = context.TestContext(test_dir, prj, 'error_pdfunite_wrong_files', POS_DIR)
ctx.run(MISSING_FILES, extra=['PDF_Joined'])
ctx.search_err('No match found for')
ctx.clean_up()
def check_refs(ctx, refs):
rows, _, _ = ctx.load_csv('ano_pcb-bom.csv')
for r in rows:

View File

@ -0,0 +1,12 @@
kiplot:
version: 1
outputs:
- name: PDF_Joined
comment: "PDF files for top layer + mirrored bottom layer"
type: pdfunite
options:
use_external_command: false
outputs:
- source: PDF/a.pdf
- source: PDF/b.pdf