Skip to content

Commit

Permalink
Take arbitrary PDF saving parameters (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
mara004 committed Nov 20, 2022
1 parent fb509ed commit 7862c2f
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 93 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ convert(
## Behaviour

sla2pdf uses lossy image compression by default, to prevent the resulting files from getting too large.
Quality settings can be controlled precisely using command-line options.
Quality settings can be controlled using the `--params` option.


## Development
Expand Down
10 changes: 4 additions & 6 deletions TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@

# Tasks

* add ability to set any attribute on the Scribus PDFFile object using a key-value sequence and `setattr()`
* avoid parsing arguments twice and pass options to scribus in a single key-value string
* runner/converter: handle parameters on a per-document basis
* make downsampling optional, also think about making conversion lossless by default
* add tests and documentation
* cli: use argparse choices parameter
* runner/converter: handle parameters on a per-dcument basis, at least in the Python API
* consider making conversion lossless by default
* improve the readme
* add tests and sphinx documentation
48 changes: 40 additions & 8 deletions src/sla2pdf/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# SPDX-FileCopyrightText: 2022 geisserml <geisserml@gmail.com>
# SPDX-License-Identifier: MPL-2.0

import ast
import logging
import argparse
from sla2pdf.runner import convert
from sla2pdf._parser import extend_parser
from sla2pdf._version import V_SLA2PDF

try:
Expand All @@ -22,43 +22,75 @@ def parse_args():
prog = "sla2pdf",
description = "Export Scribus SLA documents to PDF from the command line",
)

parser.add_argument(
"--version", "-v",
action = "version",
version = "sla2pdf %s" % V_SLA2PDF,
)

parser.add_argument(
"inputs",
nargs = "+",
)
parser.add_argument(
"--outputs", "-o",
nargs = "+",
help = "Either an output directory, or a sequence of explicit output paths. Defaults to the current directory.",
help = "An output directory, or a sequence of explicit output paths. Defaults to the current directory.",
)
parser.add_argument(
"--show-gui",
action = "store_true",
help = "Show the Scribus GUI",
)
extend_parser(parser)
parser.add_argument(
"--params", "-p",
nargs = "+",
default = [],
help = "A sequence of Scribus key=value PDF saving paramters (see the Scribus Scripter docs).",
)

if argcomplete is not None:
argcomplete.autocomplete(parser)

return parser.parse_args()


def _parse_params(params_list):

params_dict = {}

for param in params_list:

key, value = param.split("=", maxsplit=1)
key, value = key.strip(), value.strip()
value_lc = value.lower()

if value.isnumeric():
value = int(value)
elif value_lc == "true":
value = True
elif value_lc == "false":
value = False
elif value_lc == "none":
value = None
elif not value.isalnum():
value = ast.literal_eval(value)

params_dict[key] = value

return params_dict


def main():

logger.addHandler( logging.StreamHandler() )
logger.setLevel(logging.DEBUG)

args = parse_args()

convert(
args.inputs, args.outputs,
hide_gui = not args.show_gui,
quality = args.quality,
compression = args.compression,
downsample = args.downsample,
params = _parse_params(args.params),
)


Expand Down
25 changes: 15 additions & 10 deletions src/sla2pdf/_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
# -- This code needs to remain compatible with Py2 --

import sys
import ast
import argparse
from os.path import dirname
sys.path.insert(0, dirname(dirname(__file__)))

from sla2pdf._parser import extend_parser

try:
import scribus
except ImportError:
Expand All @@ -18,12 +17,20 @@
def parse_args(argv=sys.argv[1:]):

parser = argparse.ArgumentParser()
parser.add_argument(
"inputs",
nargs = "+",
)
parser.add_argument(
"--outputs", "-o",
required = True,
nargs = "+",
)
extend_parser(parser)
parser.add_argument(
"--params", "-p",
required = True,
type = ast.literal_eval,
)

return parser.parse_args(argv)

Expand All @@ -33,16 +40,14 @@ def sla_to_pdf(args):
for in_path, out_path in zip(args.inputs, args.outputs):

scribus.openDoc(in_path)

pdf = scribus.PDFfile()
pdf.compress = True
pdf.compressmtd = args.compression.value
pdf.quality = args.quality.value
pdf.resolution = args.downsample
pdf.downsample = args.downsample

for key, value in args.params.items():
if value is not None:
setattr(pdf, key, value)

pdf.file = out_path
pdf.save()

scribus.closeDoc()


Expand Down
37 changes: 0 additions & 37 deletions src/sla2pdf/_parser.py

This file was deleted.

20 changes: 0 additions & 20 deletions src/sla2pdf/constants.py

This file was deleted.

38 changes: 27 additions & 11 deletions src/sla2pdf/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,9 @@
import logging
import subprocess
from pathlib import Path
from sla2pdf.constants import (
ImageQuality,
ImageCompression,
)

logger = logging.getLogger(__name__)


Converter = Path(__file__).resolve().parent / "_converter.py"
Scribus = shutil.which("scribus")

Expand All @@ -26,14 +21,34 @@ def _run_command(command):
subprocess.run(command, check=True, cwd=os.getcwd())


#: Default PDF saving parameters.
DefaultParams = dict(
compress = True,
compressmtd = 0, # automatic
quality = 1, # high
resolution = 300,
downsample = 300,
)


def convert(
inputs,
outputs = None,
hide_gui = True,
quality = ImageQuality.HIGH,
compression = ImageCompression.JPEG,
downsample = 400,
params = {},
):
"""
Parameters:
inputs (typing.Sequence[str|pathlib.Path]):
List of input file paths (Scribus SLA documents).
outputs (str | pathlib.Path | typing.Sequence[str|pathlib.Path]):
Output directory or list of explicit output paths for the PDF files to generate.
hide_gui (bool):
If True, the Scribus GUI will be hidden using ``QT_QPA_PLATFORM=offscreen``.
Otherwise, it will be shown.
params (dict):
Dictionary of saving parameters (see the Scribus Scripter PDFfile API).
"""

if Scribus is None:
raise RuntimeError("Scribus could not be found.")
Expand All @@ -57,16 +72,17 @@ def convert(
if len(input_paths) != len(output_paths):
raise ValueError("Length of inputs and outputs does not match (%s != %s)" % (len(input_paths), len(output_paths)))

conv_params = DefaultParams.copy()
conv_params.update(params)

command = [Scribus, "--no-gui", "--no-splash"]
if hide_gui:
command += ["-platform", "offscreen"]

command += ["--python-script", Converter]
command += input_paths
command += ["-o"] + output_paths
command += ["--compression", compression.name]
command += ["--quality", quality.name]
command += ["--downsample", downsample]
command += ["-p", conv_params]

_run_command(command)

Expand Down

0 comments on commit 7862c2f

Please sign in to comment.