File indexing completed on 2024-04-28 08:44:23

0001 /*
0002     SPDX-FileCopyrightText: 2021 Vincent Pinon <vpinon@kde.org>
0003     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 
0006 #include "renderserver.h"
0007 #include "core.h"
0008 #include "mainwindow.h"
0009 #include <KLocalizedString>
0010 #include <QCoreApplication>
0011 #include <QJsonDocument>
0012 
0013 RenderServer::RenderServer(QObject *parent)
0014     : QObject(parent)
0015 {
0016     qWarning() << "Starting render server";
0017     m_server.setSocketOptions(QLocalServer::UserAccessOption);
0018     QString servername = QStringLiteral("org.kde.kdenlive-%1").arg(QCoreApplication::applicationPid());
0019     if (m_server.listen(servername)) {
0020         connect(&m_server, &QLocalServer::newConnection, this, &RenderServer::jobConnected);
0021     } else {
0022         pCore->displayMessage(i18n("Can't open communication with render job %1", servername), ErrorMessage);
0023         qWarning() << "Render server failed to listen on " << servername;
0024     }
0025     connect(pCore->window(), &MainWindow::abortRenderJob, this, &RenderServer::abortJob);
0026     connect(this, &RenderServer::setRenderingProgress, pCore->window(), &MainWindow::setRenderingProgress);
0027     connect(this, &RenderServer::setRenderingFinished, pCore->window(), &MainWindow::setRenderingFinished);
0028 }
0029 
0030 RenderServer::~RenderServer() {}
0031 
0032 void RenderServer::jobConnected()
0033 {
0034     QLocalSocket *socket = m_server.nextPendingConnection();
0035     connect(socket, &QLocalSocket::readyRead, this, &RenderServer::jobSent);
0036 }
0037 
0038 void RenderServer::jobSent()
0039 {
0040     QLocalSocket *socket = reinterpret_cast<QLocalSocket *>(sender());
0041     QTextStream text(socket);
0042 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0043     text.setCodec("UTF-8");
0044 #endif
0045     QString block, line;
0046     while (text.readLineInto(&line)) {
0047         block.append(line);
0048         if (line == QLatin1String("}")) { // end of json object
0049             QJsonParseError error;
0050             const QJsonObject json = QJsonDocument::fromJson(block.toUtf8(), &error).object();
0051             if (error.error != QJsonParseError::NoError) {
0052                 pCore->displayMessage(i18n("Communication error with render job"), ErrorMessage);
0053                 qWarning() << "RenderServer recieve error: " << error.errorString() << block;
0054             }
0055             handleJson(json, socket);
0056             block.clear();
0057         }
0058     }
0059 }
0060 
0061 void RenderServer::handleJson(const QJsonObject &json, QLocalSocket *socket)
0062 {
0063     if (json.contains("url")) {
0064         m_jobSocket[json["url"].toString()] = socket;
0065     }
0066     if (json.contains("setRenderingProgress")) {
0067         const auto url = json["setRenderingProgress"]["url"].toString();
0068         const auto progress = json["setRenderingProgress"]["progress"].toInt();
0069         const auto frame = json["setRenderingProgress"]["frame"].toInt();
0070         Q_EMIT setRenderingProgress(url, progress, frame);
0071     }
0072     if (json.contains("setRenderingFinished")) {
0073         const auto url = json["setRenderingFinished"]["url"].toString();
0074         const auto status = json["setRenderingFinished"]["status"].toInt();
0075         const auto error = json["setRenderingFinished"]["error"].toString();
0076         Q_EMIT setRenderingFinished(url, status, error);
0077         m_jobSocket.remove(url);
0078     }
0079 }
0080 
0081 void RenderServer::abortJob(const QString &job)
0082 {
0083     if (m_jobSocket.contains(job)) {
0084         m_jobSocket[job]->write("abort");
0085         m_jobSocket[job]->flush();
0086     } else {
0087         pCore->displayMessage(i18n("Can't open communication with render job %1", job), ErrorMessage);
0088     }
0089 }