View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0014597 | Scribus | Scripter | public | 2017-01-29 19:16 | 2026-02-15 19:51 |
| Reporter | JLuc | Assigned To | ale | ||
| Priority | normal | Severity | feature | Reproducibility | N/A |
| Status | acknowledged | Resolution | open | ||
| Platform | Linux | OS | Ubuntu | OS Version | 14.04 |
| Summary | 0014597: [PATCH] Script command to get preflight errors or warnings | ||||
| Description | Provide scripter a command to get preflight errors or warnings or to export them to a file so as to manage them in some not interactive way | ||||
| Additional Information | Either get them all according to the document preferences for preflight check or enable the scripter function to receive a parameter being a specific preflight check option as : check image resolution / or / check text overflow ... | ||||
| Tags | No tags attached. | ||||
| Patch | Yes | ||||
|
|
I'm working on a way to get the scripter to export the information from the preflight verifier to json. |
|
|
That'd be great @ale ! |
|
|
Here is my proposal... scripter-export-preflight.diff (9,860 bytes)
From 3f96675c8faa0738fa41ab0bbc0e3ff73b6f5288 Mon Sep 17 00:00:00 2001
From: ale rimoldi <ale@graphicslab.org>
Date: Sun, 15 Feb 2026 20:42:00 +0100
Subject: scripter command to export preflight information
diff --git a/scribus/plugins/scriptplugin/cmddoc.cpp b/scribus/plugins/scriptplugin/cmddoc.cpp
index 00b63cd7e..ef858d963 100644
--- a/scribus/plugins/scriptplugin/cmddoc.cpp
+++ b/scribus/plugins/scriptplugin/cmddoc.cpp
@@ -6,6 +6,7 @@ for which a new license (GPL+exception) is in place.
*/
#include "cmddoc.h"
#include "cmdutil.h"
+#include "documentchecker.h"
#include "documentinformation.h"
#include "pyesstring.h"
#include "scribuscore.h"
@@ -14,6 +15,11 @@ for which a new license (GPL+exception) is in place.
#include "units.h"
#include <QApplication>
+#include <qdebug.h>
+#include <qjsonarray.h>
+#include <qjsondocument.h>
+#include <qjsonobject.h>
+#include <qobject.h>
/*
newDocument(size, margins, orientation, firstPageNumber,
@@ -562,6 +568,172 @@ PyObject* scribus_applymasterpage(PyObject* /* self */, PyObject* args)
Py_RETURN_NONE;
}
+PyObject* scribus_exportdocumentcheck(PyObject* /* self */, PyObject* args, PyObject* kw)
+{
+ PyESString targetFilenameArg;
+ PyESString checkProfileNameArg;
+ bool showNonPrintingLayerErrors = false;
+ char *kwargs[] = {const_cast<char*>("jsonFilename"), const_cast<char*>("checkProfile"),
+ const_cast<char*>("nonPrintingLayers"), nullptr};
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|es$esp", kwargs,
+ "utf-8", targetFilenameArg.ptr(), "utf-8", checkProfileNameArg.ptr(),
+ &showNonPrintingLayerErrors))
+ return nullptr;
+
+ if (!checkHaveDocument())
+ return nullptr;
+ const QString targetFileName(targetFilenameArg.c_str());
+ const QString checkProfileName(checkProfileNameArg.c_str());
+
+ ScribusDoc* currentDoc = ScCore->primaryMainWindow()->doc;
+
+ if (checkProfileName.isEmpty())
+ DocumentChecker::checkDocument(currentDoc);
+ else
+ DocumentChecker::checkDocument(currentDoc, checkProfileName);
+
+ // "Standard" Errors
+ // (Taken from PreflightError in scribusstruct.h)
+ QMap<PreflightError, QString> errorsList = {
+ {PreflightError::MissingGlyph, "MissingGlyph"},
+ {PreflightError::TextOverflow, "TextOverflow"},
+ {PreflightError::ObjectNotOnPage, "ObjectNotOnPage"},
+ {PreflightError::MissingImage, "MissingImage"},
+ {PreflightError::ImageDPITooLow, "ImageDPITooLow"},
+ {PreflightError::Transparency, "Transparency"},
+ {PreflightError::PDFAnnotField, "PDFAnnotField"},
+ {PreflightError::PlacedPDF, "PlacedPDF"},
+ {PreflightError::ImageDPITooHigh, "ImageDPITooHigh"},
+ {PreflightError::ImageIsGIF, "ImageIsGIF"},
+ {PreflightError::BlendMode, "BlendMode"},
+ {PreflightError::WrongFontInAnnotation, "WrongFontInAnnotation"},
+ {PreflightError::NotCMYKOrSpot, "NotCMYKOrSpot"},
+ {PreflightError::DeviceColorsAndOutputIntent, "DeviceColorsAndOutputIntent"},
+ {PreflightError::FontNotEmbedded, "FontNotEmbedded"},
+ {PreflightError::EmbeddedFontIsOpenType, "EmbeddedFontIsOpenType"},
+ {PreflightError::OffConflictLayers, "OffConflictLayers"},
+ {PreflightError::PartFilledImageFrame, "PartFilledImageFrame"},
+ {PreflightError::MarksChanged, "MarksChanged"},
+ {PreflightError::AppliedMasterDifferentSide, "AppliedMasterDifferentSide"},
+ {PreflightError::EmptyTextFrame, "EmptyTextFrame"},
+ {PreflightError::ImageHasProgressiveEncoding, "ImageHasProgressiveEncoding"},
+ };
+ // Custom Errors
+ // "DocumentModifiedAfterMarksUpdate"
+
+ QJsonObject json;
+
+ if (currentDoc->notesChanged())
+ {
+ json["marks"] = QJsonObject{{"", "DocumentModifiedAfterMarksUpdate"}};
+ }
+ else
+ {
+ json["marks"] = QJsonObject{};
+ }
+
+ QJsonArray jsonLayers;
+ for (const auto& [layerId, layerErrors]: currentDoc->docLayerErrors.asKeyValueRange())
+ {
+ for (const auto& [key, errorLevel]: layerErrors.asKeyValueRange())
+ {
+ jsonLayers.push_back(QJsonObject{{"layer", currentDoc->layerName(layerId)}, {"error", errorsList[key]}});
+ }
+ }
+ json["layers"] = jsonLayers;
+
+ QMap<int, QVector<QPair<QString, QString>>> pagesWithErrors;
+
+ for (auto [pageItem, itemError]: currentDoc->masterItemErrors.asKeyValueRange())
+ {
+ const int pageNumber = pageItem->OwnPage;
+ for (auto [errorCode, errorLevel]: itemError.asKeyValueRange())
+ {
+ if (!showNonPrintingLayerErrors && !currentDoc->layerPrintable(pageItem->m_layerID))
+ continue;
+
+ if (!pagesWithErrors.contains(pageNumber))
+ pagesWithErrors[pageNumber] = {};
+
+ pagesWithErrors[pageNumber].push_back({pageItem->itemName(), errorsList[errorCode]});
+ }
+ }
+
+ QJsonObject jsonMasterPages;
+ for (auto [pageNumber, value]: pagesWithErrors.asKeyValueRange())
+ {
+ QJsonArray pageItems;
+ for (const auto& [item, error]: value)
+ {
+ pageItems.push_back(QJsonObject{{{"item", item}, {"error", error}}});
+ }
+ jsonMasterPages[currentDoc->MasterPages.at(pageNumber)->pageName()] = pageItems;
+ }
+ json["masterPages"] = jsonMasterPages;
+
+
+ pagesWithErrors.clear();
+
+ for (auto [pageNumber, pageErrors]: currentDoc->pageErrors.asKeyValueRange())
+ {
+ pagesWithErrors[pageNumber] = {};
+
+ for (auto [errorCode, value]: pageErrors.asKeyValueRange())
+ {
+ pagesWithErrors[pageNumber].push_back({"", errorsList[errorCode]});
+ }
+ }
+ QJsonArray jsonFreeItems;
+ for (auto [pageItem, itemErrors]: currentDoc->docItemErrors.asKeyValueRange())
+ {
+ if (!showNonPrintingLayerErrors && !currentDoc->layerPrintable(pageItem->m_layerID))
+ continue;
+ const int pageNumber = pageItem->OwnPage;
+ if (!pagesWithErrors.contains(pageNumber))
+ pagesWithErrors[pageNumber] = {};
+ for (auto [errorCode, errorLevel]: itemErrors.asKeyValueRange())
+ {
+ pagesWithErrors[pageNumber].push_back({pageItem->itemName(), errorsList[errorCode]});
+ }
+ if (currentDoc->OnPage(pageItem) == -1)
+ {
+ jsonFreeItems.push_back(pageItem->itemName());
+ }
+ }
+
+ QJsonObject jsonPages;
+ for (auto [pageNumber, value]: pagesWithErrors.asKeyValueRange())
+ {
+ QJsonArray pageItems;
+ for (const auto& [item, error]: value)
+ {
+ pageItems.push_back(QJsonObject{{{"item", item}, {"error", error}}});
+ }
+ jsonPages[QString::number(pageNumber + 1)] = pageItems;
+ }
+ json["pages"] = jsonPages;
+
+ json["freeItems"] = jsonFreeItems;
+
+ currentDoc->pageErrors.clear();
+ currentDoc->docItemErrors.clear();
+ currentDoc->masterItemErrors.clear();
+ currentDoc->docLayerErrors.clear();
+
+ if (targetFileName.isEmpty())
+ return PyUnicode_FromString(QJsonDocument(json).toJson());
+
+ QFile saveFile(targetFileName);
+ if (!saveFile.open(QIODevice::WriteOnly))
+ {
+ PyErr_SetString(ScribusException, QObject::tr("Failed to open the file '%1' for writing","python error").arg(targetFileName).toUtf8().constData());
+ return nullptr;
+ }
+ saveFile.write(QJsonDocument(json).toJson());
+
+ Py_RETURN_NONE;
+}
+
/*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
with header files structure untouched (docstrings are kept near declarations)
PV */
diff --git a/scribus/plugins/scriptplugin/cmddoc.h b/scribus/plugins/scriptplugin/cmddoc.h
index 8a01a35e5..6638b2a0c 100644
--- a/scribus/plugins/scriptplugin/cmddoc.h
+++ b/scribus/plugins/scriptplugin/cmddoc.h
@@ -385,6 +385,49 @@ Apply master page masterPageName on page pageNumber.\n\
"));
PyObject* scribus_applymasterpage(PyObject* self, PyObject* args);
+PyDoc_STRVAR(scribus_exportdocumentcheck__doc__,
+QT_TR_NOOP("exportDocumentCheck([jsonFilePath, checkProfile=\"\", nonPrintingLayers=False])\n\
+\n\
+Export the result of the preflight verifier into a JSON string or a JSON file.\n\
+\n\
+jsonFilePath: the path to the json file to be written. If empty, a JSON string \n\
+is returned.\n\
+checkProfileName is the name of an existing preflight verifier profile.\n\
+\n\
+The resulting JSON always has five sections:\n\
+- freeItems: a list of page items that are in no page;\n\
+- layers: a list of errors in layers;\n\
+- marks: errors relating the the marks;\n\
+- masterPages: list of erroneous page items for each master page;\n\
+- pages: list of erroneous page items for each page.\n\
+\n\
+The errors are strings, mostly names from the PreflightError enum in scribusstruct.h:\n\
+- MissingGlyph\n\
+- TextOverflow\n\
+- ObjectNotOnPage\n\
+- MissingImage\n\
+- ImageDPITooLow\n\
+- Transparency\n\
+- PDFAnnotField\n\
+- PlacedPDF\n\
+- ImageDPITooHigh\n\
+- ImageIsGIF\n\
+- BlendMode\n\
+- WrongFontInAnnotation\n\
+- NotCMYKOrSpot\n\
+- DeviceColorsAndOutputIntent\n\
+- FontNotEmbedded\n\
+- EmbeddedFontIsOpenType\n\
+- OffConflictLayers\n\
+- PartFilledImageFrame\n\
+- MarksChanged\n\
+- AppliedMasterDifferentSide\n\
+- EmptyTextFrame\n\
+- ImageHasProgressiveEncoding\n\
+- DocumentModifiedAfterMarksUpdate\n\
+"));
+PyObject* scribus_exportdocumentcheck(PyObject* self, PyObject* args, PyObject* kw);
+
#endif
diff --git a/scribus/plugins/scriptplugin/scriptplugin.cpp b/scribus/plugins/scriptplugin/scriptplugin.cpp
index fabb7350a..bc790d097 100644
--- a/scribus/plugins/scriptplugin/scriptplugin.cpp
+++ b/scribus/plugins/scriptplugin/scriptplugin.cpp
@@ -326,6 +326,7 @@ PyMethodDef scribus_methods[] = {
{ "deselectAll", (PyCFunction) scribus_deselectall, METH_NOARGS, tr(scribus_deselectall__doc__)},
{ "docChanged", scribus_docchanged, METH_VARARGS, tr(scribus_docchanged__doc__)},
{ "editMasterPage", scribus_editmasterpage, METH_VARARGS, tr(scribus_editmasterpage__doc__)},
+ { "exportDocumentCheck", (PyCFunction) scribus_exportdocumentcheck, METH_VARARGS|METH_KEYWORDS, tr(scribus_exportdocumentcheck__doc__)},
{ "fileDialog", (PyCFunction) scribus_filedialog, METH_VARARGS|METH_KEYWORDS, tr(scribus_filedialog__doc__)},
{ "fileQuit", scribus_filequit, METH_VARARGS, tr(scribus_filequit__doc__)},
{ "flipObject", scribus_flipobject, METH_VARARGS, tr(scribus_flipobject__doc__)},
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2017-01-29 19:16 | JLuc | New Issue | |
| 2017-01-29 19:21 | JLuc | Additional Information Updated | |
| 2017-01-30 23:18 | jghali | Severity | minor => feature |
| 2025-11-26 21:55 | ale | Note Added: 0053308 | |
| 2025-11-26 21:55 | ale | Assigned To | => ale |
| 2025-11-26 21:55 | ale | Status | new => assigned |
| 2025-11-26 21:55 | ale | Status | assigned => acknowledged |
| 2025-12-23 11:19 | JLuc | Note Added: 0053402 | |
| 2026-02-15 19:51 | ale | Note Added: 0053496 | |
| 2026-02-15 19:51 | ale | File Added: scripter-export-preflight.diff | |
| 2026-02-15 19:51 | ale | Summary | Script command to get preflight errors or warnings => [PATCH] Script command to get preflight errors or warnings |
| 2026-02-15 19:51 | ale | Patch | No => Yes |