Libksieve

sievedebugdialog.cpp
1 /*
2  sievedebugdialog.cpp
3 
4  SPDX-FileCopyrightText: 2005 Martijn Klingens <[email protected]>
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
9 #include "sievedebugdialog.h"
10 #include "util/findaccountinfojob.h"
11 #include "util/util_p.h"
12 #include <KPIMTextEdit/PlainTextEditor>
13 #include <KPIMTextEdit/PlainTextEditorWidget>
14 
15 #include "libksieve_debug.h"
16 #include <KLocalizedString>
17 #include <KSyntaxHighlighting/Definition>
18 #include <KSyntaxHighlighting/SyntaxHighlighter>
19 #include <KSyntaxHighlighting/Theme>
20 #include <kmanagesieve/sievejob.h>
21 
22 #include <KConfigGroup>
23 #include <KSharedConfig>
24 #include <QDialogButtonBox>
25 #include <QPushButton>
26 #include <QTimer>
27 #include <QVBoxLayout>
28 
29 using namespace KSieveUi;
30 
31 SieveDebugDialog::SieveDebugDialog(SieveImapPasswordProvider *passwordProvider, QWidget *parent)
32  : QDialog(parent)
33  , mPasswordProvider(passwordProvider)
34 {
35  setWindowTitle(i18nc("@title:window", "Sieve Diagnostics"));
36  auto mainLayout = new QVBoxLayout(this);
37 
38  // Collect all accounts
39  mResourceIdentifier = KSieveUi::Util::sieveImapResourceNames();
40 
41  mEdit = new KPIMTextEdit::PlainTextEditorWidget(this);
42  mEdit->setReadOnly(true);
43  const KSyntaxHighlighting::Definition def = mRepo.definitionForName(QStringLiteral("Sieve"));
44  if (!def.isValid()) {
45  qCWarning(LIBKSIEVE_LOG) << "Invalid definition name";
46  }
47 
48  auto hl = new KSyntaxHighlighting::SyntaxHighlighter(mEdit->editor()->document());
49  hl->setTheme((palette().color(QPalette::Base).lightness() < 128) ? mRepo.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme)
50  : mRepo.defaultTheme(KSyntaxHighlighting::Repository::LightTheme));
51  hl->setDefinition(def);
52 
53  auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this);
54  connect(buttonBox, &QDialogButtonBox::rejected, this, &SieveDebugDialog::reject);
55 
56  mainLayout->addWidget(mEdit);
57  mainLayout->addWidget(buttonBox);
58 
59  if (!mResourceIdentifier.isEmpty()) {
60  mEdit->editor()->setPlainText(i18n("Collecting diagnostic information about Sieve support...\n\n"));
61  QTimer::singleShot(0, this, &SieveDebugDialog::slotDiagNextAccount);
62  } else {
63  mEdit->editor()->setPlainText(i18n("No IMAP resource found."));
64  }
65  readConfig();
66 }
67 
68 SieveDebugDialog::~SieveDebugDialog()
69 {
70  if (mSieveJob) {
71  mSieveJob->kill();
72  mSieveJob = nullptr;
73  }
74  qCDebug(LIBKSIEVE_LOG);
75  writeConfig();
76 }
77 
78 void SieveDebugDialog::readConfig()
79 {
80  KConfigGroup group(KSharedConfig::openStateConfig(), "SieveDebugDialog");
81  const QSize sizeDialog = group.readEntry("Size", QSize(640, 480));
82  if (sizeDialog.isValid()) {
83  resize(sizeDialog);
84  }
85 }
86 
87 void SieveDebugDialog::writeConfig()
88 {
89  KConfigGroup group(KSharedConfig::openStateConfig(), "SieveDebugDialog");
90  group.writeEntry("Size", size());
91 }
92 
93 void SieveDebugDialog::slotShutDownJob()
94 {
95  disconnect(mSieveJob, &KManageSieve::SieveJob::gotList, this, &SieveDebugDialog::slotGetScriptList);
96  mSieveJob->kill();
97  mSieveJob = nullptr;
98  mEdit->editor()->appendPlainText(i18n("Unable to get the info\n\n"));
99  mResourceIdentifier.pop_front();
100  QTimer::singleShot(0, this, &SieveDebugDialog::slotDiagNextAccount);
101 }
102 
103 void SieveDebugDialog::slotDiagNextAccount()
104 {
105  if (mResourceIdentifier.isEmpty()) {
106  return;
107  }
108  if (!mShutDownJob) {
109  mShutDownJob = new QTimer(this);
110  mShutDownJob->setSingleShot(true);
111  connect(mShutDownJob, &QTimer::timeout, this, &SieveDebugDialog::slotShutDownJob);
112  }
113  mShutDownJob->start(30 * 1000); // 30 seconds
114  const QString ident = mResourceIdentifier.first();
115 
116  mEdit->editor()->appendPlainText(i18n("Collecting data for account '%1'...\n", ident));
117  mEdit->editor()->appendPlainText(i18n("------------------------------------------------------------\n"));
118 
119  auto job = new FindAccountInfoJob(this);
120  connect(job, &FindAccountInfoJob::findAccountInfoFinished, this, &SieveDebugDialog::slotFindAccountInfoFinished);
121  job->setIdentifier(ident);
122  job->setProvider(mPasswordProvider);
123  job->start();
124 }
125 
126 void SieveDebugDialog::slotFindAccountInfoFinished(const KSieveUi::Util::AccountInfo &info)
127 {
128  // Detect URL for this IMAP account
129  const QUrl url = info.sieveUrl;
130  if (!url.isValid()) {
131  mEdit->editor()->appendPlainText(i18n("(Account does not support Sieve)\n\n"));
132  } else {
133  mUrl = url;
134 
135  mSieveJob = KManageSieve::SieveJob::list(mUrl);
136 
137  // Laurent: not necessary as it's a readonly dialog
138  // mSieveJob->setProperty("sieveimapaccountsettings", QVariant::fromValue(info.sieveImapAccountSettings));
139  connect(mSieveJob, &KManageSieve::SieveJob::gotList, this, &SieveDebugDialog::slotGetScriptList);
140 
141  // Bypass the singleShot timer -- it's fired when we get our data
142  return;
143  }
144 
145  // Handle next account async
146  mResourceIdentifier.pop_front();
147  QTimer::singleShot(0, this, &SieveDebugDialog::slotDiagNextAccount);
148 }
149 
150 void SieveDebugDialog::slotDiagNextScript()
151 {
152  if (mScriptList.isEmpty()) {
153  // Continue handling accounts instead
154  mScriptList.clear();
155  mResourceIdentifier.pop_front();
156  QTimer::singleShot(0, this, &SieveDebugDialog::slotDiagNextAccount);
157  return;
158  }
159 
160  const QString scriptFile = mScriptList.constFirst();
161  mScriptList.pop_front();
162 
163  mEdit->editor()->appendPlainText(i18n("Contents of script '%1':\n", scriptFile));
164 
165  auto job = new FindAccountInfoJob(this);
166  connect(job, &FindAccountInfoJob::findAccountInfoFinished, this, &SieveDebugDialog::slotFindAccountInfoForScriptFinished);
167  job->setIdentifier(mResourceIdentifier.constFirst());
168  job->setProvider(mPasswordProvider);
169  job->setProperty("scriptfile", scriptFile);
170  job->start();
171 }
172 
173 void SieveDebugDialog::slotFindAccountInfoForScriptFinished(const KSieveUi::Util::AccountInfo &info)
174 {
175  mUrl = info.sieveUrl;
176 
177  mUrl = mUrl.adjusted(QUrl::RemoveFilename);
178  const QString scriptFile = sender()->property("scriptfile").toString();
179  mUrl.setPath(mUrl.path() + QLatin1Char('/') + scriptFile);
180 
181  mSieveJob = KManageSieve::SieveJob::get(mUrl);
182 
183  connect(mSieveJob, &KManageSieve::SieveJob::gotScript, this, &SieveDebugDialog::slotGetScript);
184 }
185 
186 void SieveDebugDialog::slotGetScript(KManageSieve::SieveJob *job, bool success, const QString &script, bool active)
187 {
188  qCDebug(LIBKSIEVE_LOG) << "( ??," << success << ", ?," << active << ")" << Qt::endl << "script:" << Qt::endl << script;
189  mSieveJob = nullptr; // job deletes itself after returning from this slot!
190 
191  if (!success) {
192  mEdit->editor()->appendPlainText(
193  i18n("Retrieving the script failed.\n"
194  "The server responded:\n%1",
195  job->errorString()));
196  } else if (script.isEmpty()) {
197  mEdit->editor()->appendPlainText(i18n("(This script is empty)\n\n"));
198  } else {
199  mEdit->editor()->appendPlainText(
200  i18n("------------------------------------------------------------\n"
201  "%1\n"
202  "------------------------------------------------------------\n\n",
203  script));
204  }
205 
206  // Fetch next script
207  QTimer::singleShot(0, this, &SieveDebugDialog::slotDiagNextScript);
208 }
209 
210 void SieveDebugDialog::slotGetScriptList(KManageSieve::SieveJob *job, bool success, const QStringList &scriptList, const QString &activeScript)
211 {
212  if (mShutDownJob->isActive()) {
213  mShutDownJob->stop();
214  }
215  qCDebug(LIBKSIEVE_LOG) << "Success:" << success << ", List:" << scriptList.join(QLatin1Char(',')) << ", active:" << activeScript;
216  mSieveJob = nullptr; // job deletes itself after returning from this slot!
217 
218  mEdit->editor()->appendPlainText(i18n("Sieve capabilities:\n"));
219  const QStringList caps = job->sieveCapabilities();
220  if (caps.isEmpty()) {
221  mEdit->editor()->appendPlainText(i18n("(No special capabilities available)"));
222  } else {
224  for (QStringList::const_iterator it = caps.constBegin(); it != end; ++it) {
225  mEdit->editor()->appendPlainText(QLatin1String("* ") + *it + QLatin1Char('\n'));
226  }
227  mEdit->editor()->appendPlainText(QStringLiteral("\n"));
228  }
229 
230  mEdit->editor()->appendPlainText(i18n("Available Sieve scripts:\n"));
231 
232  if (scriptList.isEmpty()) {
233  mEdit->editor()->appendPlainText(i18n("(No Sieve scripts available on this server)\n\n"));
234  } else {
235  mScriptList = scriptList;
236  QStringList::const_iterator end = scriptList.constEnd();
237  for (QStringList::const_iterator it = scriptList.constBegin(); it != end; ++it) {
238  mEdit->editor()->appendPlainText(QLatin1String("* ") + *it + QLatin1Char('\n'));
239  }
240  mEdit->editor()->appendPlainText(QStringLiteral("\n"));
241  mEdit->editor()->appendPlainText(i18n("Active script: '%1'\n\n", activeScript));
242  }
243 
244  // Handle next job: dump scripts for this server
245  QTimer::singleShot(0, this, &SieveDebugDialog::slotDiagNextScript);
246 }
RemoveFilename
bool isValid() const const
QObject * sender() const const
QTextStream & endl(QTextStream &stream)
QString join(const QString &separator) const const
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
The SieveImapPasswordProvider class.
void timeout()
static KSharedConfig::Ptr openStateConfig(const QString &fileName=QString())
QVariant property(const char *name) const const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
bool isEmpty() const const
QStringList sieveCapabilities() const
Returns the sieve capabilities of the IMAP server.
Definition: sievejob.cpp:254
void gotScript(KManageSieve::SieveJob *job, bool success, const QString &script, bool active)
This signal is emitted when a get job has finished.
QString errorString() const
A human-readable error message.
Definition: sievejob.cpp:268
void gotList(KManageSieve::SieveJob *job, bool success, const QStringList &scriptList, const QString &activeScript)
This signal is emitted when a list job has finished.
QString i18n(const char *text, const TYPE &arg...)
void readConfig()
const QList< QKeySequence > & end()
bool isValid() const const
QList::const_iterator constEnd() const const
static SieveJob * get(const QUrl &source)
Gets a sieve script from an IMAP server.
Definition: sievejob.cpp:300
QList::const_iterator constBegin() const const
virtual void setTheme(const Theme &theme)
static SieveJob * list(const QUrl &url)
Lists all available scripts at the given sieve url.
Definition: sievejob.cpp:314
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
A job to manage sieve scripts.
Definition: sievejob.h:37
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Fri Apr 16 2021 23:09:34 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.