[scribus] Using scribus to create PDFs from the commandline

Juraj Fedel wtxnh-scribus at yahoo.com.au
Sun Jul 27 17:32:02 UTC 2014


On Sun, Jul 20, 2014 at 07:26:28PM +0200, Marc Balmer wrote:
> Or, in other words, are there ways to automate Scribus without user
> interaction, i.e. from the commandline?

Let me try once more to present my solution to this problem! At the
bottom of the mail is small patch that enables exactly what Marc is
asking for.

You can create template scribus document 'mydoc.sla' with two text
frames and this small python script 'data.py' in the same directory:

import scribus
scribus.openDoc('mydoc.sla')
scribus.setText('Name', 'Text1') # get 'Name' and 'Address' from database
scribus.setText('Address', 'Text2')
pdf = scribus.PDFfile()
pdf.file = 'output1.pdf'
pdf.save()

Then run scribus as folow:
scribus --python-script data.py

and you have your output1.pdf file created!

WARNING!
- This is for linux only. And it is for stable version of Scribus-1.4.4
  (because that is what I use).
- Use only python script without bugs (he, he :)
- You will anyway find some limitation because scribus really is not in
  its core coded for use without GUI

PS:
I have been posting this or similar solution since 2006 (and Scribus
version 1.2 I was using at that time). I would be glad if at least one
person try to compile scribus with this patch and confirm that it works
on some other computer than mine! If you find it useful it would be
extra bonus.

Here is patch for running scribus from CLI against Srcibus-1.4.4 version

	Modified scribus/main_nix.cpp
diff --git a/scribus/main_nix.cpp b/scribus/main_nix.cpp
index 03db7e8..039f703 100644
--- a/scribus/main_nix.cpp
+++ b/scribus/main_nix.cpp
@@ -37,6 +37,7 @@ for which a new license (GPL+exception) is in place.
 #include "scribus.h"
 
 #include "scconfig.h"
+#include "scraction.h" // JF: need to be able to trigger action for scripter to run without GUI
 
 int mainApp(int argc, char **argv);
 void initCrashHandler();
@@ -81,7 +82,16 @@ int mainApp(int argc, char **argv)
 		int appRetVal=app.init();
 		if (appRetVal==EXIT_FAILURE)
 			return(EXIT_FAILURE);
-		return app.exec();
+		// JF: This is ugly
+		// it is this way because for now scribus use app.useGUI variable
+		// as synonym for 'run scribus with GUI or not at all'
+		if (!app.pythonScript.isNull())
+		{
+			if (ScCore->primaryMainWindow()->scrActions.contains("scripterRunPythonScript"))
+				ScCore->primaryMainWindow()->scrActions.value("scripterRunPythonScript")->trigger();
+		}
+		else
+			return app.exec();
 	}
 	return EXIT_SUCCESS;	
 }
	Modified scribus/plugins/scriptplugin/scriptercore.cpp
diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp
index 14979f1..ffc0c6e 100644
--- a/scribus/plugins/scriptplugin/scriptercore.cpp
+++ b/scribus/plugins/scriptplugin/scriptercore.cpp
@@ -32,6 +32,7 @@ for which a new license (GPL+exception) is in place.
 #include "prefscontext.h"
 #include "prefstable.h"
 #include "prefsmanager.h"
+#include "scribusapp.h" // JF: need it to acces ScQApp->pythonScript
 
 ScripterCore::ScripterCore(QWidget* parent)
 {
@@ -57,6 +58,10 @@ ScripterCore::ScripterCore(QWidget* parent)
 	QObject::connect( scrScripterActions["scripterShowConsole"], SIGNAL(toggled(bool)) , this, SLOT(slotInteractiveScript(bool)) );
 	QObject::connect( scrScripterActions["scripterAboutScript"], SIGNAL(triggered()) , this, SLOT(aboutScript()) );
 
+	// JF: Create an action that will run python file without GUI
+	ScCore->primaryMainWindow()->scrActions.insert("scripterRunPythonScript", new ScrAction(this));
+	QObject::connect( ScCore->primaryMainWindow()->scrActions.value("scripterRunPythonScript"), SIGNAL(triggered()) , this, SLOT(slotRunPythonScript()) );
+
 	SavedRecentScripts.clear();
 	ReadPlugPrefs();
 
@@ -404,6 +409,13 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)
 	enableMainWindowMenu();
 }
 
+// JF: needed for running script without GUI - this is activated by action from main_nix.cpp
+void ScripterCore::slotRunPythonScript()
+{
+	slotRunScriptFile(ScQApp->pythonScript);
+	FinishScriptRun();
+}
+
 void ScripterCore::slotRunScript(const QString Script)
 {
 	// Prevent two scripts to be run concurrently or face crash!
	Modified scribus/plugins/scriptplugin/scriptercore.h
diff --git a/scribus/plugins/scriptplugin/scriptercore.h b/scribus/plugins/scriptplugin/scriptercore.h
index 47e96ac..2c84b75 100644
--- a/scribus/plugins/scriptplugin/scriptercore.h
+++ b/scribus/plugins/scriptplugin/scriptercore.h
@@ -39,6 +39,7 @@ public slots:
 	void StdScript(QString filebasename);
 	void RecentScript(QString fn);
 	void slotRunScriptFile(QString fileName, bool inMainInterpreter = false);
+	void slotRunPythonScript(); // JF: needed for running python script without GUI
 	void slotRunScript(const QString Script);
 	void slotInteractiveScript(bool);
 	void slotExecute();
	Modified scribus/scribus.cpp
diff --git a/scribus/scribus.cpp b/scribus/scribus.cpp
index a999a29..60bd026 100644
--- a/scribus/scribus.cpp
+++ b/scribus/scribus.cpp
@@ -285,7 +285,8 @@ int ScribusMainWindow::initScMW(bool primaryMainWindow)
 	setAttribute(Qt::WA_KeyCompression, false);
 	setWindowIcon(loadIcon("AppIcon.png"));
 	scrActionGroups.clear();
-	scrActions.clear();
+	// JF: DO NOT clear actions : scripter plugin has created one allready!
+//	scrActions.clear();
 	scrRecentFileActions.clear();
 	scrRecentPasteActions.clear();
 	scrWindowsActions.clear();
	Modified scribus/scribusapp.cpp
diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp
index 82582d1..8686e43 100644
--- a/scribus/scribusapp.cpp
+++ b/scribus/scribusapp.cpp
@@ -61,6 +61,7 @@ for which a new license (GPL+exception) is in place.
 #define ARG_SWAPDIABUTTONS "--swap-buttons"
 #define ARG_PREFS "--prefs"
 #define ARG_UPGRADECHECK "--upgradecheck"
+#define ARG_PYTHONSCRIPT "--python-script"
 
 #define ARG_VERSION_SHORT "-v"
 #define ARG_HELP_SHORT "-h"
@@ -75,6 +76,7 @@ for which a new license (GPL+exception) is in place.
 #define ARG_SWAPDIABUTTONS_SHORT "-sb"
 #define ARG_PREFS_SHORT "-pr"
 #define ARG_UPGRADECHECK_SHORT "-u"
+#define ARG_PYTHONSCRIPT_SHORT "-py"
 
 // Qt wants -display not --display or -d
 #define ARG_DISPLAY_QT "-display"
@@ -218,6 +220,21 @@ void ScribusQApp::parseCommandLine()
 		} else if (strncmp(arg.toLocal8Bit().data(),"-psn_",4) == 0)
 		{
 			// Andreas Vox: Qt/Mac has -psn_blah flags that must be accepted.
+		} else if (arg == ARG_PYTHONSCRIPT || arg == ARG_PYTHONSCRIPT_SHORT) {
+			pythonScript = QFile::decodeName(argv()[i + 1]);
+			if (!QFileInfo(pythonScript).exists()) {
+				showHeader();
+				if (pythonScript.left(1) == "-" || pythonScript.left(2) == "--") {
+					std::cout << tr("Invalid argument: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl;
+				} else {
+					std::cout << tr("File %1 does not exist, aborting.").arg(pythonScript).toLocal8Bit().data() << std::endl;
+				}
+				showUsage();
+				useGUI=false;
+				return;
+			} else {
+				++i;
+			}
 		} else {
 			fileName = QFile::decodeName(argv()[i]);
 			if (!QFileInfo(fileName).exists()) {
@@ -428,7 +445,7 @@ void ScribusQApp::showUsage()
 	printArgLine(ts, ARG_SWAPDIABUTTONS_SHORT, ARG_SWAPDIABUTTONS, tr("Use right to left dialog button ordering (eg. Cancel/No/Yes instead of Yes/No/Cancel)") );
 	printArgLine(ts, ARG_UPGRADECHECK_SHORT, ARG_UPGRADECHECK, tr("Download a file from the Scribus website and show the latest available version.") );
 	printArgLine(ts, ARG_VERSION_SHORT, ARG_VERSION, tr("Output version information and exit") );
-	
+	printArgLine(ts, ARG_PYTHONSCRIPT_SHORT, QString(QString(ARG_PYTHONSCRIPT) + QString(" ") + tr("filename")).toLocal8Bit().constData(), tr("Run filename in Python scripter") );
 	
 #if defined(_WIN32) && !defined(_CONSOLE)
 	printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") );
	Modified scribus/scribusapp.h
diff --git a/scribus/scribusapp.h b/scribus/scribusapp.h
index 9048328..cf9b555 100644
--- a/scribus/scribusapp.h
+++ b/scribus/scribusapp.h
@@ -67,6 +67,7 @@ class SCRIBUS_API ScribusQApp : public QApplication
 		bool neverSplashExists();
 		const QString& currGUILanguage() {return GUILang;};
 		ScDLManager* dlManager() { return m_scDLMgr; }
+		QString pythonScript; // JF: script to be run in pythoun without GUI
 
 	public slots:
 




More information about the scribus mailing list