1 /*
2     SPDX-FileCopyrightText: 2021 Vincent Pinon <vpinon@kde.org>
3     SPDX-License-Identifier: GPL-2.0-or-later
4 */
5 
6 #include "renderserver.h"
7 #include "core.h"
8 #include "mainwindow.h"
9 #include <KI18n/KLocalizedString>
10 #include <QCoreApplication>
11 #include <QJsonDocument>
12 
RenderServer(QObject * parent)13 RenderServer::RenderServer(QObject *parent)
14     : QObject(parent)
15 {
16     qWarning() << "Starting render server";
17     m_server.setSocketOptions(QLocalServer::UserAccessOption);
18     QString servername = QStringLiteral("org.kde.kdenlive-%1").arg(QCoreApplication::applicationPid());
19     if (m_server.listen(servername)) {
20         connect(&m_server, &QLocalServer::newConnection, this, &RenderServer::jobConnected);
21     } else {
22         pCore->displayMessage(i18n("Can't open communication with render job %1", servername), ErrorMessage);
23         qWarning() << "Render server failed to listen on " << servername;
24     }
25     connect(pCore->window(), &MainWindow::abortRenderJob, this, &RenderServer::abortJob);
26     connect(this, &RenderServer::setRenderingProgress, pCore->window(), &MainWindow::setRenderingProgress);
27     connect(this, &RenderServer::setRenderingFinished, pCore->window(), &MainWindow::setRenderingFinished);
28 }
29 
~RenderServer()30 RenderServer::~RenderServer() {}
31 
jobConnected()32 void RenderServer::jobConnected()
33 {
34     QLocalSocket* socket = m_server.nextPendingConnection();
35     connect(socket, &QLocalSocket::readyRead, this, &RenderServer::jobSent);
36 }
37 
jobSent()38 void RenderServer::jobSent() {
39     QLocalSocket* socket = reinterpret_cast<QLocalSocket*>(sender());
40     QTextStream text(socket);
41     QString block, line;
42     while(text.readLineInto(&line)) {
43         block.append(line);
44         if(line == QLatin1String("}")) { // end of json object
45             QJsonParseError error;
46             const QJsonObject json = QJsonDocument::fromJson(block.toUtf8(), &error).object();
47             if (error.error != QJsonParseError::NoError) {
48                 pCore->displayMessage(i18n("Communication error with render job"), ErrorMessage);
49                 qWarning() << "RenderServer recieve error: " << error.errorString() << block;
50             }
51             if (json.contains("url")) {
52                 m_jobSocket[json["url"].toString()] = socket;
53             }
54             if (json.contains("setRenderingProgress")) {
55                 emit setRenderingProgress(
56                             json["setRenderingProgress"]["url"].toString(),
57                             json["setRenderingProgress"]["progress"].toInt(),
58                             json["setRenderingProgress"]["frame"].toInt());
59             }
60             if (json.contains("setRenderingFinished")) {
61                 emit setRenderingFinished(
62                             json["setRenderingFinished"]["url"].toString(),
63                             json["setRenderingFinished"]["status"].toInt(),
64                             json["setRenderingFinished"]["error"].toString());
65                 m_jobSocket.remove(json["setRenderingFinished"]["url"].toString());
66             }
67             block.clear();
68         }
69     }
70 }
71 
abortJob(const QString & job)72 void RenderServer::abortJob(const QString &job) {
73     if (m_jobSocket.contains(job)) {
74         m_jobSocket[job]->write("abort");
75         m_jobSocket[job]->flush();
76     } else {
77         pCore->displayMessage(i18n("Can't open communication with render job %1", job), ErrorMessage);
78     }
79 }
80