1 /*
2    SPDX-FileCopyrightText: 2019-2021 Laurent Montel <montel@kde.org>
3 
4    SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "grammalecteresultjob.h"
8 #include "libgrammalecte_debug.h"
9 
10 #include <QFileInfo>
11 #include <QTemporaryFile>
12 
GrammalecteResultJob(QObject * parent)13 GrammalecteResultJob::GrammalecteResultJob(QObject *parent)
14     : QObject(parent)
15 {
16 }
17 
~GrammalecteResultJob()18 GrammalecteResultJob::~GrammalecteResultJob()
19 {
20 }
21 
start()22 void GrammalecteResultJob::start()
23 {
24     if (canStart()) {
25         mProcess = new QProcess(this);
26 
27         auto file = new QTemporaryFile(this);
28         file->open();
29         file->setPermissions(QFile::ReadUser);
30         file->write(mText.toUtf8());
31         file->close();
32 
33         mProcess->setProgram(mPythonPath);
34         QStringList args;
35         args.reserve(6);
36         args << mGrammarlecteCliPath;
37         if (!mArguments.isEmpty()) {
38             args << QStringLiteral("-on") << mArguments;
39         }
40         args << QStringLiteral("-f") << file->fileName() << QStringLiteral("-j");
41         mProcess->setArguments(args);
42         connect(mProcess, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &GrammalecteResultJob::slotFinished);
43         connect(mProcess, qOverload<QProcess::ProcessError>(&QProcess::errorOccurred), this, &GrammalecteResultJob::receivedError);
44         connect(mProcess, &QProcess::readyReadStandardError, this, &GrammalecteResultJob::receivedStdErr);
45         connect(mProcess, &QProcess::readyReadStandardOutput, this, &GrammalecteResultJob::receivedStandardOutput);
46 
47         mProcess->start();
48         if (!mProcess->waitForStarted()) {
49             qCWarning(LIBGRAMMALECTE_PLUGIN_LOG) << "Impossible to start grammarresultjob";
50             Q_EMIT error(ErrorType::Unknown);
51             deleteLater();
52         }
53     } else {
54         if (mErrorType != ErrorType::TextIsEmpty) {
55             Q_EMIT error(mErrorType);
56         }
57         deleteLater();
58     }
59 }
60 
receivedStandardOutput()61 void GrammalecteResultJob::receivedStandardOutput()
62 {
63     mResult += QString::fromUtf8(mProcess->readAllStandardOutput());
64 }
65 
receivedError()66 void GrammalecteResultJob::receivedError()
67 {
68     mLastError += mProcess->errorString();
69 }
70 
receivedStdErr()71 void GrammalecteResultJob::receivedStdErr()
72 {
73     mLastError += QLatin1String(mProcess->readAllStandardError());
74 }
75 
slotFinished(int exitCode,QProcess::ExitStatus exitStatus)76 void GrammalecteResultJob::slotFinished(int exitCode, QProcess::ExitStatus exitStatus)
77 {
78     if (exitStatus != 0 || exitCode != 0) {
79         qCWarning(LIBGRAMMALECTE_PLUGIN_LOG) << "Error during running GrammarResultJob: " << mLastError;
80     } else {
81         Q_EMIT finished(mResult);
82     }
83     deleteLater();
84 }
85 
arguments() const86 QStringList GrammalecteResultJob::arguments() const
87 {
88     return mArguments;
89 }
90 
setArguments(const QStringList & arguments)91 void GrammalecteResultJob::setArguments(const QStringList &arguments)
92 {
93     mArguments = arguments;
94 }
95 
grammarlecteCliPath() const96 QString GrammalecteResultJob::grammarlecteCliPath() const
97 {
98     return mGrammarlecteCliPath;
99 }
100 
setGrammarlecteCliPath(const QString & grammarlecteCliPath)101 void GrammalecteResultJob::setGrammarlecteCliPath(const QString &grammarlecteCliPath)
102 {
103     mGrammarlecteCliPath = grammarlecteCliPath;
104 }
105 
pythonPath() const106 QString GrammalecteResultJob::pythonPath() const
107 {
108     return mPythonPath;
109 }
110 
setPythonPath(const QString & pythonPath)111 void GrammalecteResultJob::setPythonPath(const QString &pythonPath)
112 {
113     mPythonPath = pythonPath;
114 }
115 
hasNotEmptyText(const QString & text)116 static bool hasNotEmptyText(const QString &text)
117 {
118     for (int i = 0, total = text.length(); i < total; ++i) {
119         if (!text.at(i).isSpace()) {
120             return true;
121         }
122     }
123     return false;
124 }
125 
canStart()126 bool GrammalecteResultJob::canStart()
127 {
128     if (!hasNotEmptyText(mText)) {
129         mErrorType = ErrorType::TextIsEmpty;
130         return false;
131     }
132     if (mGrammarlecteCliPath.isEmpty()) {
133         mErrorType = ErrorType::GrammalecteMissing;
134         return false;
135     }
136     if (mPythonPath.isEmpty()) {
137         mErrorType = ErrorType::PythonPathMissing;
138         return false;
139     }
140     if (!QFileInfo::exists(mPythonPath)) {
141         mErrorType = ErrorType::PythonPathNotExist;
142         return false;
143     }
144     if (!QFileInfo::exists(mGrammarlecteCliPath)) {
145         mErrorType = ErrorType::GrammarlectCliNotExist;
146         return false;
147     }
148     return true;
149 }
150 
text() const151 QString GrammalecteResultJob::text() const
152 {
153     return mText;
154 }
155 
setText(const QString & text)156 void GrammalecteResultJob::setText(const QString &text)
157 {
158     mText = text;
159 }
160