1 /*
2 SPDX-FileCopyrightText: 2013-2021 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-only
5 */
6
7 #include "parseuserscriptjob.h"
8 #include "ksieveui/scriptsparsing/parsingutil.h"
9 #include <KLocalizedString>
10 #include <QXmlStreamReader>
11 #include <kmanagesieve/sievejob.h>
12
13 using namespace KSieveUi;
ParseUserScriptJob(const QUrl & url,QObject * parent)14 ParseUserScriptJob::ParseUserScriptJob(const QUrl &url, QObject *parent)
15 : QObject(parent)
16 , mCurrentUrl(url)
17 {
18 }
19
~ParseUserScriptJob()20 ParseUserScriptJob::~ParseUserScriptJob()
21 {
22 kill();
23 delete mStreamReader;
24 }
25
kill()26 void ParseUserScriptJob::kill()
27 {
28 if (mSieveJob) {
29 mSieveJob->kill();
30 }
31 mSieveJob = nullptr;
32 }
33
scriptUrl() const34 QUrl ParseUserScriptJob::scriptUrl() const
35 {
36 return mCurrentUrl;
37 }
38
start()39 void ParseUserScriptJob::start()
40 {
41 if (mCurrentUrl.isEmpty()) {
42 emitError(i18n("Path is not specified."));
43 return;
44 }
45 if (mSieveJob) {
46 mSieveJob->kill();
47 }
48 mActiveScripts = QStringList();
49 mError = QString();
50 mSieveJob = KManageSieve::SieveJob::get(mCurrentUrl);
51 connect(mSieveJob, &KManageSieve::SieveJob::result, this, &ParseUserScriptJob::slotGetResult);
52 }
53
setAutoDelete(bool deleteMe)54 void ParseUserScriptJob::setAutoDelete(bool deleteMe)
55 {
56 mAutoDelete = deleteMe;
57 }
58
slotGetResult(KManageSieve::SieveJob * job,bool success,const QString & script,bool)59 void ParseUserScriptJob::slotGetResult(KManageSieve::SieveJob *job, bool success, const QString &script, bool)
60 {
61 mSieveJob = nullptr;
62 if (!success) {
63 emitError(
64 i18n("Retrieving the script failed.\n"
65 "The server responded:\n%1",
66 job->errorString()));
67 return;
68 }
69 if (script.isEmpty()) {
70 emitError(i18n("Script is empty. (%1)", mCurrentUrl.fileName()));
71 return;
72 }
73 bool result;
74 const QStringList lst = parsescript(script, result);
75 if (result) {
76 emitSuccess(lst);
77 } else {
78 emitError(i18n("Script parsing error."));
79 }
80 }
81
emitError(const QString & msgError)82 void ParseUserScriptJob::emitError(const QString &msgError)
83 {
84 mError = msgError;
85 Q_EMIT finished(this);
86 if (mAutoDelete) {
87 deleteLater();
88 }
89 }
90
emitSuccess(const QStringList & activeScriptList)91 void ParseUserScriptJob::emitSuccess(const QStringList &activeScriptList)
92 {
93 mActiveScripts = activeScriptList;
94 Q_EMIT finished(this);
95 if (mAutoDelete) {
96 deleteLater();
97 }
98 }
99
parsescript(const QString & script,bool & result)100 QStringList ParseUserScriptJob::parsescript(const QString &script, bool &result)
101 {
102 QStringList lst;
103 const QString doc = ParsingUtil::parseScript(script, result);
104 if (result) {
105 lst = extractActiveScript(doc);
106 }
107 return lst;
108 }
109
activeScriptList() const110 QStringList ParseUserScriptJob::activeScriptList() const
111 {
112 return mActiveScripts;
113 }
114
error() const115 QString ParseUserScriptJob::error() const
116 {
117 return mError;
118 }
119
extractActiveScript(const QString & doc)120 QStringList ParseUserScriptJob::extractActiveScript(const QString &doc)
121 {
122 mStreamReader = new QXmlStreamReader(doc);
123 QStringList lstScript;
124 if (mStreamReader->readNextStartElement()) {
125 while (mStreamReader->readNextStartElement()) {
126 const QStringRef tagname = mStreamReader->name();
127 if (tagname == QLatin1String("action")) {
128 if (mStreamReader->attributes().hasAttribute(QLatin1String("name"))) {
129 const QString actionName = mStreamReader->attributes().value(QLatin1String("name")).toString();
130 if (actionName == QLatin1String("include")) {
131 // Load includes
132 const QString str = loadInclude();
133 if (!str.isEmpty()) {
134 if (!lstScript.contains(str)) {
135 lstScript.append(str);
136 }
137 }
138 } else {
139 mStreamReader->skipCurrentElement();
140 }
141 }
142 } else {
143 mStreamReader->skipCurrentElement();
144 }
145 }
146 }
147 return lstScript;
148 }
149
loadInclude()150 QString ParseUserScriptJob::loadInclude()
151 {
152 QString scriptName;
153 while (mStreamReader->readNextStartElement()) {
154 if (mStreamReader->name() == QLatin1String("str")) {
155 scriptName = mStreamReader->readElementText();
156 } else {
157 mStreamReader->skipCurrentElement();
158 }
159 }
160 return scriptName;
161 }
162