File indexing completed on 2024-04-21 04:52:00
0001 /* 0002 SPDX-FileCopyrightText: 2022 Julius Künzel <jk.kdedev@smartlab.uber.space> 0003 0004 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #pragma once 0008 #include "kdenlivesettings.h" 0009 0010 #include <KMessageWidget> 0011 #include <QObject> 0012 #include <QString> 0013 #include <QMap> 0014 #include <QPair> 0015 0016 class KJob; 0017 0018 class AbstractPythonInterface : public QObject 0019 { 0020 Q_OBJECT 0021 public: 0022 explicit AbstractPythonInterface(QObject *parent = nullptr); 0023 /** @brief Check if python and pip are installed, as well as all required scripts. 0024 If a check failed setupError() will be emitted with an error message that can be 0025 shown to the user. 0026 @returns wether all checks succeeded. 0027 */ 0028 ~AbstractPythonInterface() override; 0029 /** @brief Check if python is found and use venv if requested. */ 0030 bool checkPython(bool useVenv, bool calculateSize = false, bool forceInstall = false); 0031 bool checkSetup(); 0032 /** @brief Check which versions of the dependencies are installed. 0033 @param Whether checkVersionsResult() will be emitted once the result is available. 0034 */ 0035 void checkVersions(bool signalOnResult = true); 0036 void updateDependencies(); 0037 /** @brief Returns a cached list of all missing dependencies 0038 * To update the cache run checkDependencies(). 0039 * @param filter If this is empty all missing packages will be returned, 0040 * otherwise only those of the filter (in case they are missing). 0041 */ 0042 QStringList missingDependencies(const QStringList &filter = {}); 0043 QString runScript(const QString &scriptpath, QStringList args = {}, const QString &firstarg = {}, bool concurrent = false, bool packageFeedback = false); 0044 QString pythonExec() { return KdenliveSettings::pythonPath(); }; 0045 void proposeMaybeUpdate(const QString &dependency, const QString &minVersion); 0046 bool installDisabled() { return m_disableInstall; }; 0047 void runConcurrentScript(const QString &script, QStringList args); 0048 /** @brief Delete the python venv folder. */ 0049 bool removePythonVenv(); 0050 /** @brief Python venv setup in progress. */ 0051 bool installInProcess() const; 0052 0053 friend class PythonDependencyMessage; 0054 0055 public Q_SLOTS: 0056 /** @brief Check if all dependencies are installed. 0057 If everything is okay dependenciesAvailable() will be emitted, 0058 otherwise dependenciesMissing() with a message that can be shown 0059 to the user telling wich dependencies are missing. 0060 To get a list of all missing dependencies use missingDependencies 0061 @returns wether all checks succeeded. 0062 */ 0063 void checkDependencies(bool force = false, bool async = true); 0064 void checkDependenciesConcurrently(); 0065 void checkVersionsConcurrently(); 0066 0067 private: 0068 QMap<QString, QString> m_dependencies; 0069 QStringList m_missing; 0070 QMap<QString, QString> *m_versions; 0071 bool m_disableInstall; 0072 bool m_dependenciesChecked; 0073 0074 void installMissingDependencies(); 0075 QString locateScript(const QString &script); 0076 QString runPackageScript(const QString &mode, bool concurrent = false); 0077 int versionToInt(const QString &version); 0078 /** @brief Create a python virtualenv */ 0079 bool setupVenv(); 0080 void gotFolderSize(KJob *job); 0081 QString installPackage(const QStringList packageNames); 0082 0083 protected: 0084 QMap<QString, QString> *m_scripts; 0085 void addDependency(const QString &pipname, const QString &purpose); 0086 void addScript(const QString &script); 0087 virtual QString featureName() { return {}; }; 0088 bool m_installInProgress{false}; 0089 0090 Q_SIGNALS: 0091 void setupError(const QString &message); 0092 void setupMessage(const QString &message, int messageType); 0093 void checkVersionsResult(const QStringList &versions); 0094 void dependenciesMissing(const QStringList &messages); 0095 void dependenciesAvailable(); 0096 void proposeUpdate(const QString &message); 0097 void scriptFeedback(const QStringList message); 0098 void installFeedback(const QString &message); 0099 void gotPythonSize(const QString &message); 0100 void scriptGpuCheckFinished(); 0101 void scriptFinished(); 0102 void scriptStarted(); 0103 void abortScript(); 0104 void venvSetupChanged(); 0105 }; 0106 0107 class PythonDependencyMessage : public KMessageWidget { 0108 Q_OBJECT 0109 0110 public: 0111 PythonDependencyMessage(QWidget *parent, AbstractPythonInterface *interface, bool setupErrorOnly = false); 0112 0113 public Q_SLOTS: 0114 void checkAfterInstall(); 0115 void doShowMessage(const QString &message, KMessageWidget::MessageType messageType = KMessageWidget::Information); 0116 0117 private: 0118 AbstractPythonInterface * m_interface; 0119 QAction *m_installAction{nullptr}; 0120 QAction *m_abortAction{nullptr}; 0121 bool m_updated; 0122 0123 };