From 2b9d76105b2c313c8bdb464c097413b7bd480385 Mon Sep 17 00:00:00 2001 From: Juraj Fedel Date: Sun, 31 Aug 2014 15:56:42 +0200 Subject: [PATCH] All in one: Run python script from CLI Add the '--python-script file' CLI option to run 'file' as python script. Also enable the use of --no-gui CLI option This option is useful to run a python script and then exit scribus with: scribus --no-gui --python-script myscript.py if it is run as: scribus --python-script myscript.py then after myscript.py finishes, the GUI is started. I moved signal appStarted() from scribuscore to scribusapp, it seems to be better place. --- scribus/main_nix.cpp | 8 ++--- scribus/main_win32.cpp | 6 ++-- scribus/plugins/scriptplugin/scriptercore.cpp | 29 +++++++++++----- scribus/plugins/scriptplugin/scriptercore.h | 1 + scribus/scribusapp.cpp | 46 +++++++++++++++++++----- scribus/scribusapp.h | 4 ++ scribus/scribuscore.cpp | 5 --- scribus/scribuscore.h | 5 --- 8 files changed, 67 insertions(+), 37 deletions(-) diff --git a/scribus/main_nix.cpp b/scribus/main_nix.cpp index 8132b43..56156a1 100644 --- a/scribus/main_nix.cpp +++ b/scribus/main_nix.cpp @@ -78,13 +78,11 @@ int mainApp(int argc, char **argv) #endif // QT_VERSION == 0x040400 #endif // Q_OS_UNIX app.parseCommandLine(); + int appRetVal=app.init(); + if (appRetVal==EXIT_FAILURE) + return(EXIT_FAILURE); if (app.useGUI) - { - int appRetVal=app.init(); - if (appRetVal==EXIT_FAILURE) - return(EXIT_FAILURE); return app.exec(); - } return EXIT_SUCCESS; } diff --git a/scribus/main_win32.cpp b/scribus/main_win32.cpp index 9dccfa1..5ea48bc 100644 --- a/scribus/main_win32.cpp +++ b/scribus/main_win32.cpp @@ -114,10 +114,10 @@ int mainApp(ScribusQApp& app) { #endif app.parseCommandLine(); - if (app.useGUI) + appRetVal = app.init(); + if (appRetVal != EXIT_FAILURE) { - appRetVal = app.init(); - if (appRetVal != EXIT_FAILURE) + if (app.useGUI) appRetVal = app.exec(); } #ifndef _DEBUG diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp index 797f0ad..ac98839 100644 --- a/scribus/plugins/scriptplugin/scriptercore.cpp +++ b/scribus/plugins/scriptplugin/scriptercore.cpp @@ -36,6 +36,7 @@ for which a new license (GPL+exception) is in place. #include "prefscontext.h" #include "prefstable.h" #include "prefsmanager.h" +#include "scribusapp.h" // need it to acces ScQApp->pythonScript ScripterCore::ScripterCore(QWidget* parent) { @@ -66,6 +67,8 @@ ScripterCore::ScripterCore(QWidget* parent) QObject::connect(pcon, SIGNAL(runCommand()), this, SLOT(slotExecute())); QObject::connect(pcon, SIGNAL(paletteShown(bool)), this, SLOT(slotInteractiveScript(bool))); + + QObject::connect(ScQApp, SIGNAL(appStarted()) , this, SLOT(slotRunPythonScript()) ); } ScripterCore::~ScripterCore() @@ -177,7 +180,7 @@ void ScripterCore::FinishScriptRun() void ScripterCore::runScriptDialog() { QString fileName; - QString curDirPath = QDir::currentPath(); + // QString curDirPath = QDir::currentPath(); RunScriptDialog dia( ScCore->primaryMainWindow(), m_enableExtPython ); if (dia.exec()) { @@ -193,7 +196,7 @@ void ScripterCore::runScriptDialog() } rebuildRecentScriptsMenu(); } - QDir::setCurrent(curDirPath); + // QDir::setCurrent(curDirPath); FinishScriptRun(); } @@ -247,7 +250,7 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter) global_state = PyThreadState_Get(); state = Py_NewInterpreter(); // Chdir to the dir the script is in - QDir::setCurrent(fi.absolutePath()); + // QDir::setCurrent(fi.absolutePath()); // Init the scripter module in the sub-interpreter initscribus(ScCore->primaryMainWindow()); } @@ -292,11 +295,9 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter) // into a StringIO buffer for later extraction. cm += QString("except:\n"); cm += QString(" import traceback\n"); - cm += QString(" import scribus\n"); // we stash our working vars here - cm += QString(" scribus._f=cStringIO.StringIO()\n"); - cm += QString(" traceback.print_exc(file=scribus._f)\n"); - cm += QString(" _errorMsg = scribus._f.getvalue()\n"); - cm += QString(" del(scribus._f)\n"); + cm += QString(" _errorMsg = traceback.format_exc()\n"); + if (!ScCore->usingGUI()) + cm += QString(" traceback.print_exc()\n"); // We re-raise the exception so the return value of PyRun_StringFlags reflects // the fact that an exception has ocurred. cm += QString(" raise\n"); @@ -321,7 +322,7 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter) qDebug("Exception was:"); PyErr_Print(); } - else + else if (ScCore->usingGUI()) { QString errorMsg = PyString_AsString(errorMsgPyStr); // Display a dialog to the user with the exception @@ -353,6 +354,16 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter) enableMainWindowMenu(); } +// needed for running script from CLI - this is activated by signal ScribusQApp::appStarted() +void ScripterCore::slotRunPythonScript() +{ + if (!ScQApp->pythonScript.isNull()) + { + slotRunScriptFile(ScQApp->pythonScript, true); + FinishScriptRun(); + } +} + void ScripterCore::slotRunScript(const QString Script) { // Prevent two scripts to be run concurrently or face crash! diff --git a/scribus/plugins/scriptplugin/scriptercore.h b/scribus/plugins/scriptplugin/scriptercore.h index ff1e001..1e929f4 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(); // needed for running python script from CLI void slotRunScript(const QString Script); void slotInteractiveScript(bool); void slotExecute(); diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp index 98e397c..fc56dbd 100644 --- a/scribus/scribusapp.cpp +++ b/scribus/scribusapp.cpp @@ -66,6 +66,7 @@ for which a new license (GPL+exception) is in place. #define ARG_PREFS "--prefs" #define ARG_UPGRADECHECK "--upgradecheck" #define ARG_TESTS "--tests" +#define ARG_PYTHONSCRIPT "--python-script" #define ARG_VERSION_SHORT "-v" #define ARG_HELP_SHORT "-h" @@ -81,6 +82,7 @@ for which a new license (GPL+exception) is in place. #define ARG_PREFS_SHORT "-pr" #define ARG_UPGRADECHECK_SHORT "-u" #define ARG_TESTS_SHORT "-T" +#define ARG_PYTHONSCRIPT_SHORT "-py" // Qt wants -display not --display or -d #define ARG_DISPLAY_QT "-display" @@ -204,10 +206,9 @@ void ScribusQApp::parseCommandLine() uc.fetch(); } //Dont run the GUI init process called from main.cpp, and return - if (!header) - useGUI=true; - else - return; + if (header) + std::exit(EXIT_SUCCESS); + useGUI = true; //We are going to run something other than command line help for(int i = 1; i < argsc; i++) { arg = args[i]; @@ -244,14 +245,27 @@ void ScribusQApp::parseCommandLine() std::cout << tr("File %1 does not exist, aborting.").arg(prefsUserFile).toLocal8Bit().data() << std::endl; } showUsage(); - useGUI=false; - return; + std::exit(EXIT_FAILURE); } else { ++i; } } 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(args[i + 1].toLocal8Bit()); + 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(); + std::exit(EXIT_FAILURE); + } else { + ++i; + } } else { fileName = QFile::decodeName(args[i].toLocal8Bit()); if (!QFileInfo(fileName).exists()) { @@ -262,8 +276,7 @@ void ScribusQApp::parseCommandLine() std::cout << tr("File %1 does not exist, aborting.").arg(fileName).toLocal8Bit().data() << std::endl; } showUsage(); - useGUI=false; - return; + std::exit(EXIT_FAILURE); } else { @@ -283,8 +296,20 @@ int ScribusQApp::init() processEvents(); ScCore->init(useGUI, swapDialogButtonOrder, filesToLoad); int retVal=EXIT_SUCCESS; - if (useGUI) + /* TODO: + * When Scribus is truly able to run without GUI + * we should uncomment if (useGUI) + * and delete if (true) + */ + // if (useGUI) + if (true) retVal=ScCore->startGUI(showSplash, showFontInfo, showProfileInfo, lang, prefsUserFile); + + // A hook for plugins and scripts to trigger on. Some plugins and scripts + // require the app to be fully set up (in particular, the main window to be + // built and shown) before running their setup. + emit appStarted(); + return retVal; } @@ -464,7 +489,8 @@ 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") ); + printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") ); #if defined(_WIN32) && !defined(_CONSOLE) printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") ); diff --git a/scribus/scribusapp.h b/scribus/scribusapp.h index fe27092..e2f78a1 100644 --- a/scribus/scribusapp.h +++ b/scribus/scribusapp.h @@ -69,6 +69,7 @@ class SCRIBUS_API ScribusQApp : public QApplication bool neverSplashExists(); const QString& currGUILanguage() { return GUILang; } ScDLManager* dlManager() { return m_scDLMgr; } + QString pythonScript; // script to be run in python from CLI private: ScribusCore* m_ScCore; @@ -105,6 +106,9 @@ class SCRIBUS_API ScribusQApp : public QApplication protected slots: void downloadComplete(const QString& t); + + signals: + void appStarted(); }; #endif diff --git a/scribus/scribuscore.cpp b/scribus/scribuscore.cpp index 292406b..a275161 100644 --- a/scribus/scribuscore.cpp +++ b/scribus/scribuscore.cpp @@ -140,11 +140,6 @@ int ScribusCore::startGUI(bool showSplash, bool showFontInfo, bool showProfileIn { scribus->slotRaiseOnlineHelp(); } - - // A hook for plugins and scripts to trigger on. Some plugins and scripts - // require the app to be fully set up (in particular, the main window to be - // built and shown) before running their setup. - emit appStarted(); return EXIT_SUCCESS; } diff --git a/scribus/scribuscore.h b/scribus/scribuscore.h index ce0e6ef..91f5eb2 100644 --- a/scribus/scribuscore.h +++ b/scribus/scribuscore.h @@ -142,11 +142,6 @@ protected: bool m_HaveGS; bool m_HavePngAlpha; bool m_HaveTiffSep; - - -signals: - void appStarted(); - }; /* -- 1.7.2.3