File indexing completed on 2024-12-22 04:15:07

0001 /*
0002  * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include <cstdlib>
0008 #include <random>
0009 
0010 #include <QString>
0011 #include <QCommandLineParser>
0012 #include <QCommandLineOption>
0013 
0014 #include <KisApplication.h>
0015 #include "PythonPluginManager.h"
0016 #include <opengl/kis_opengl.h>
0017 
0018 extern "C" int main(int argc, char **argv)
0019 {
0020     // The global initialization of the random generator
0021     {
0022         std::random_device urandom;
0023         qsrand(urandom());
0024     }
0025     KLocalizedString::setApplicationDomain("kritarunner");
0026     QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
0027     KisOpenGL::testingInitializeDefaultSurfaceFormat();
0028 
0029 
0030     // first create the application so we can create a pixmap
0031     KisApplication app("kritarunner", argc, argv);
0032     app.setApplicationDisplayName("Krita Script Runner");
0033     app.setApplicationName("kritarunner");
0034     app.setOrganizationDomain("krita.org");
0035 
0036     QCommandLineParser parser;
0037     parser.setApplicationDescription("kritarunner executes one python script and then returns.");
0038     parser.addVersionOption();
0039     parser.addHelpOption();
0040 
0041     QCommandLineOption scriptOption(QStringList() << "s" << "script", "The script to run. Do not append the .py extension.", "script");
0042     parser.addOption(scriptOption);
0043 
0044     QCommandLineOption functionOption(QStringList() << "f" << "function",
0045                                       "The function to call (by default __main__ is called).", "function", "__main__");
0046     parser.addOption(functionOption);
0047 
0048     parser.addPositionalArgument("[argument(s)]", "The arguments for the script");
0049     parser.process(app);
0050 
0051     if (!parser.isSet(scriptOption)) {
0052         qDebug("No script given, aborting.");
0053         return 1;
0054     }
0055 
0056     qDebug() << "running:" << parser.value(scriptOption) << parser.value(functionOption);
0057     qDebug() << parser.positionalArguments();
0058 
0059     app.addResourceTypes();
0060     app.registerResources();
0061     app.loadPlugins();
0062 
0063 
0064     QByteArray pythonPath = qgetenv("PYTHONPATH");
0065     qDebug() << "\tPython path:" << pythonPath;
0066 
0067     qDebug() << "Creating engine";
0068 
0069     // TODO: refactor to share common parts with plugin.cpp
0070 
0071     PyKrita::InitResult initResult = PyKrita::initialize();
0072 
0073     switch (initResult) {
0074         case PyKrita::INIT_OK:
0075             break;
0076         case PyKrita::INIT_CANNOT_LOAD_PYTHON_LIBRARY:
0077             qWarning() << i18n("Cannot load Python library");
0078             return 1;
0079         case PyKrita::INIT_CANNOT_SET_PYTHON_PATHS:
0080             qWarning() << i18n("Cannot set Python paths");
0081             return 1;
0082         case PyKrita::INIT_CANNOT_LOAD_PYKRITA_MODULE:
0083             qWarning() << i18n("Cannot load built-in pykrita module");
0084             return 1;
0085         default:
0086             qWarning() << i18n("Unexpected error initializing python plugin.");
0087             return 1;
0088     }
0089 
0090     qDebug() << "Try to import the pykrita module";
0091     PyKrita::Python py = PyKrita::Python();
0092     PyObject* pykritaPackage = py.moduleImport("pykrita");
0093     pykritaPackage = py.moduleImport("krita");
0094 
0095     if (!pykritaPackage) {
0096         qDebug("Cannot load the PyKrita module, aborting");
0097         return 1;
0098     }
0099 
0100     PyObject *argsList = PyList_New(0);
0101     Q_FOREACH(const QString arg, parser.positionalArguments()) {
0102         PyObject* const u = py.unicode(arg);
0103         PyList_Append(argsList, u);
0104         Py_DECREF(u);
0105     }
0106 
0107     PyObject *args = PyTuple_New(1);
0108     PyTuple_SetItem(args, 0, argsList);
0109 
0110     py.functionCall(parser.value(functionOption).toUtf8().constData(), parser.value(scriptOption).toUtf8().constData(), args);
0111 
0112     Py_DECREF(argsList);
0113     Py_DECREF(args);
0114 
0115     app.quit();
0116     return 0;
0117 }
0118