Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F16723632
D31.id61.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
132 KB
Referenced Files
None
Subscribers
None
D31.id61.diff
View Options
Index: libksieve/ksieve/scriptbuilder.h
===================================================================
--- libksieve/ksieve/scriptbuilder.h
+++ libksieve/ksieve/scriptbuilder.h
@@ -51,8 +51,8 @@
virtual void stringListEntry( const QString & string, bool multiLine, const QString & embeddedHashComment ) = 0;
virtual void stringListArgumentEnd() = 0;
- virtual void commandStart( const QString & identifier ) = 0;
- virtual void commandEnd() = 0;
+ virtual void commandStart( const QString & identifier, int lineNumber ) = 0;
+ virtual void commandEnd(int lineNumber) = 0;
virtual void testStart( const QString & identifier ) = 0;
virtual void testEnd() = 0;
@@ -60,8 +60,8 @@
virtual void testListStart() = 0;
virtual void testListEnd() = 0;
- virtual void blockStart() = 0;
- virtual void blockEnd() = 0;
+ virtual void blockStart(int lineNumber) = 0;
+ virtual void blockEnd(int lineNumber) = 0;
/** A hash comment always includes an implicit lineFeed() at it's end. */
virtual void hashComment( const QString & comment ) = 0;
Index: libksieve/ksieveui/CMakeLists.txt
===================================================================
--- libksieve/ksieveui/CMakeLists.txt
+++ libksieve/ksieveui/CMakeLists.txt
@@ -153,6 +153,7 @@
widgets/managesievewidget.cpp
debug/sievedebugdialog.cpp
util/util.cpp
+ managescriptsjob/checkkep14supportjob.cpp
managescriptsjob/generateglobalscriptjob.cpp
managescriptsjob/parseuserscriptjob.cpp
templates/sievetemplatewidget.cpp
Index: libksieve/ksieveui/managescriptsjob/checkkep14supportjob.h
===================================================================
--- libksieve/ksieveui/managescriptsjob/checkkep14supportjob.h
+++ libksieve/ksieveui/managescriptsjob/checkkep14supportjob.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2014 Montel Laurent <montel@kde.org>
+ Copyright (c) 2015 Sandro Knauß <knauss@kolabsys.com>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2, as
@@ -15,10 +15,11 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef VACATIONCREATESCRIPTJOB_H
-#define VACATIONCREATESCRIPTJOB_H
+#ifndef CHECKKEP14SUPPORTJOB_H
+#define CHECKKEP14SUPPORTJOB_H
#include <QObject>
+#include <QStringList>
#include "ksieveui_export.h"
@@ -29,37 +30,36 @@
}
namespace KSieveUi {
-class KSIEVEUI_EXPORT VacationCreateScriptJob : public QObject
+class KSIEVEUI_EXPORT CheckKep14SupportJob : public QObject
{
Q_OBJECT
public:
- explicit VacationCreateScriptJob(QObject *parent=0);
- ~VacationCreateScriptJob();
+ explicit CheckKep14SupportJob(QObject *parent=0);
+ ~CheckKep14SupportJob();
void start();
void setServerUrl(const KUrl &url);
- void setScript(const QString &script);
- void setServerName(const QString &servername);
- void setStatus(bool activate, bool wasActive);
+ void setServerName(const QString &name);
+ QString serverName();
-Q_SIGNALS:
- void result(bool);
- void scriptActive(bool activated, const QString &serverName);
+ QStringList availableScripts();
+ bool hasKep14Support();
+ KUrl serverUrl();
-private slots:
- void slotPutActiveResult(KManageSieve::SieveJob *job, bool success);
- void slotPutInactiveResult(KManageSieve::SieveJob *job, bool success);
+Q_SIGNALS:
+ void result(CheckKep14SupportJob*, bool);
private:
- void handlePutResult(KManageSieve::SieveJob *, bool success, bool activated);
KUrl mUrl;
- QString mScript;
- QString mServerName;
- bool mActivate;
- bool mWasActive;
KManageSieve::SieveJob *mSieveJob;
+ QStringList mAvailableScripts;
+ bool mKep14Support;
+ QString mServerName;
+
+private slots:
+ void slotCheckKep14Support(KManageSieve::SieveJob *job, bool success, const QStringList &availableScripts, const QString &activeScript);
};
}
-#endif // VACATIONCREATESCRIPTJOB_H
+#endif // CHECKKEP14SUPPORTJOB_H
Index: libksieve/ksieveui/managescriptsjob/checkkep14supportjob.cpp
===================================================================
--- /dev/null
+++ libksieve/ksieveui/managescriptsjob/checkkep14supportjob.cpp
@@ -0,0 +1,93 @@
+/*
+ Copyright (c) 2015 Sandro Knauß <knauss@kolabsys.com>
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License, version 2, as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "checkkep14supportjob.h"
+#include <util/util.h>
+#include <kmanagesieve/sievejob.h>
+
+#include <KMessageBox>
+#include <KLocalizedString>
+#include <KDebug>
+
+using namespace KSieveUi;
+
+CheckKep14SupportJob::CheckKep14SupportJob(QObject *parent)
+ : QObject(parent),
+ mSieveJob(0)
+{
+
+}
+
+CheckKep14SupportJob::~CheckKep14SupportJob()
+{
+
+}
+
+void CheckKep14SupportJob::start()
+{
+ if (mUrl.isEmpty()) {
+ qDebug() << " server url is empty";
+ deleteLater();
+ return;
+ }
+ mSieveJob = KManageSieve::SieveJob::list(mUrl);
+ connect(mSieveJob, SIGNAL(gotList(KManageSieve::SieveJob*,bool,QStringList,QString)),
+ this, SLOT(slotCheckKep14Support(KManageSieve::SieveJob*,bool,QStringList,QString)));
+}
+
+void CheckKep14SupportJob::setServerUrl(const KUrl &url)
+{
+ mUrl = url;
+}
+
+KUrl CheckKep14SupportJob::serverUrl()
+{
+ return mUrl;
+}
+
+void CheckKep14SupportJob::setServerName(const QString &name)
+{
+ mServerName = name;
+}
+
+QString CheckKep14SupportJob::serverName()
+{
+ return mServerName;
+}
+
+
+QStringList CheckKep14SupportJob::availableScripts()
+{
+ return mAvailableScripts;
+}
+
+bool CheckKep14SupportJob::hasKep14Support()
+{
+ return mKep14Support;
+}
+
+void CheckKep14SupportJob::slotCheckKep14Support(KManageSieve::SieveJob *job, bool success, const QStringList &availableScripts, const QString &activeScript)
+{
+ if (!success) {
+ emit result(this, false);
+ return;
+ }
+
+ mKep14Support = Util::hasKep14Support(job->sieveCapabilities(), availableScripts, activeScript);
+ mAvailableScripts = availableScripts;
+ emit result(this, true);
+}
Index: libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.h
===================================================================
--- libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.h
+++ libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.h
@@ -33,6 +33,7 @@
~GenerateGlobalScriptJob();
void start();
+ void kill();
void addUserActiveScripts(const QStringList &lstScript);
@@ -50,7 +51,7 @@
void writeUserScript();
QStringList mListUserActiveScripts;
KUrl mCurrentUrl;
- KManageSieve::SieveJob *mMasterjob;
+ KManageSieve::SieveJob *mMasterJob;
KManageSieve::SieveJob *mUserJob;
};
}
Index: libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.cpp
===================================================================
--- libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.cpp
+++ libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.cpp
@@ -25,19 +25,30 @@
GenerateGlobalScriptJob::GenerateGlobalScriptJob(const KUrl &url, QObject *parent)
: QObject(parent),
mCurrentUrl(url),
- mMasterjob(0),
+ mMasterJob(0),
mUserJob(0)
{
}
GenerateGlobalScriptJob::~GenerateGlobalScriptJob()
{
- if (mMasterjob)
- mMasterjob->kill();
- if (mUserJob)
+ kill();
+}
+
+void GenerateGlobalScriptJob::kill()
+{
+ if (mMasterJob) {
+ mMasterJob->kill();
+ }
+ mMasterJob = 0;
+
+ if (mUserJob) {
mUserJob->kill();
+ }
+ mUserJob = 0;
}
+
void GenerateGlobalScriptJob::addUserActiveScripts(const QStringList &lstScript)
{
mListUserActiveScripts = lstScript;
@@ -49,7 +60,7 @@
Q_EMIT error(i18n("Path is not specified."));
return;
}
- writeMasterScript();
+ writeUserScript();
}
void GenerateGlobalScriptJob::writeMasterScript()
@@ -79,8 +90,8 @@
KUrl url(mCurrentUrl);
url.setFileName(QLatin1String("MASTER"));
- mMasterjob = KManageSieve::SieveJob::put(url, masterScript, true, true );
- connect( mMasterjob, SIGNAL(result(KManageSieve::SieveJob*,bool,QString,bool)),
+ mMasterJob = KManageSieve::SieveJob::put(url, masterScript, true, true );
+ connect( mMasterJob, SIGNAL(result(KManageSieve::SieveJob*,bool,QString,bool)),
this, SLOT(slotPutMasterResult(KManageSieve::SieveJob*,bool)) );
}
@@ -90,7 +101,7 @@
Q_EMIT error(i18n("Error when we wrote \"MASTER\" script on server."));
return;
}
- mMasterjob = 0;
+ mMasterJob = 0;
writeUserScript();
}
@@ -107,7 +118,7 @@
"require [\"include\"];\n");
Q_FOREACH (const QString &activeScript, mListUserActiveScripts) {
- userScript += QString::fromLatin1("\ninclude :personal \"%1\"").arg(activeScript);
+ userScript += QString::fromLatin1("\ninclude :personal \"%1\";").arg(activeScript);
}
KUrl url(mCurrentUrl);
Index: libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h
===================================================================
--- libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h
+++ libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h
@@ -19,6 +19,7 @@
#define PARSEUSERSCRIPTJOB_H
#include <QObject>
+#include <QStringList>
#include <KUrl>
#include "ksieveui_export.h"
class QDomDocument;
@@ -31,28 +32,36 @@
class KSIEVEUI_EXPORT ParseUserScriptJob : public QObject
{
Q_OBJECT
+
+ friend class ParseUserJobTest;
public:
- explicit ParseUserScriptJob(QObject *parent=0);
+ explicit ParseUserScriptJob(const KUrl &url,QObject *parent=0);
~ParseUserScriptJob();
void start();
- void scriptUrl(const KUrl &url);
- static QStringList parsescript(const QString &script, bool &result);
+ KUrl scriptUrl() const;
+ QStringList activeScriptList() const;
+ QString error() const;
+ void kill();
private Q_SLOTS:
void slotGetResult( KManageSieve::SieveJob *, bool, const QString &, bool );
Q_SIGNALS:
- void success(const QStringList &activeScriptList);
- void error(const QString &msgError);
+ void finished(ParseUserScriptJob* job);
private:
+ void emitSuccess(const QStringList &activeScriptList);
+ void emitError(const QString &msgError);
static QString loadInclude(const QDomElement &element);
static QStringList extractActiveScript(const QDomDocument &doc);
+ static QStringList parsescript(const QString &script, bool &result);
KUrl mCurrentUrl;
KManageSieve::SieveJob *mSieveJob;
+ QStringList mActiveScripts;
+ QString mError;
};
}
Index: libksieve/ksieveui/managescriptsjob/parseuserscriptjob.cpp
===================================================================
--- libksieve/ksieveui/managescriptsjob/parseuserscriptjob.cpp
+++ libksieve/ksieveui/managescriptsjob/parseuserscriptjob.cpp
@@ -24,32 +24,33 @@
using namespace KSieveUi;
-ParseUserScriptJob::ParseUserScriptJob(QObject *parent)
+ParseUserScriptJob::ParseUserScriptJob(const KUrl &url, QObject *parent)
: QObject(parent),
mSieveJob(0)
+ , mCurrentUrl(url)
{
}
ParseUserScriptJob::~ParseUserScriptJob()
{
- if ( mSieveJob )
- mSieveJob->kill();
- mSieveJob = 0;
+ kill();
}
-void ParseUserScriptJob::scriptUrl(const KUrl &url)
+KUrl ParseUserScriptJob::scriptUrl() const
{
- mCurrentUrl = url;
+ return mCurrentUrl;
}
void ParseUserScriptJob::start()
{
if (mCurrentUrl.isEmpty()) {
- Q_EMIT error(i18n("Path is not specified."));
+ emitError(i18n("Path is not specified."));
return;
}
if ( mSieveJob )
mSieveJob->kill();
+ mActiveScripts = QStringList();
+ mError = QString();
mSieveJob = KManageSieve::SieveJob::get( mCurrentUrl );
connect( mSieveJob, SIGNAL(result(KManageSieve::SieveJob*,bool,QString,bool)),
this, SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool)) );
@@ -59,15 +60,27 @@
{
mSieveJob = 0;
if (script.isEmpty()) {
- Q_EMIT error(i18n("Script is empty."));
+ emitError(i18n("Script is empty."));
return;
}
bool result;
const QStringList lst = parsescript(script, result);
if (result)
- Q_EMIT success(lst);
+ emitSuccess(lst);
else
- Q_EMIT error(i18n("Script parsing error"));
+ emitError(i18n("Script parsing error"));
+}
+
+void ParseUserScriptJob::emitError(const QString &msgError)
+{
+ mError = msgError;
+ emit finished(this);
+}
+
+void ParseUserScriptJob::emitSuccess(const QStringList &activeScriptList)
+{
+ mActiveScripts = activeScriptList;
+ emit finished(this);
}
QStringList ParseUserScriptJob::parsescript(const QString &script, bool &result)
@@ -80,6 +93,24 @@
return lst;
}
+QStringList ParseUserScriptJob::activeScriptList() const
+{
+ return mActiveScripts;
+}
+
+QString ParseUserScriptJob::error() const
+{
+ return mError;
+}
+
+void ParseUserScriptJob::kill()
+{
+ if ( mSieveJob )
+ mSieveJob->kill();
+ mSieveJob = 0;
+}
+
+
QStringList ParseUserScriptJob::extractActiveScript(const QDomDocument &doc)
{
QStringList lstScript;
Index: libksieve/ksieveui/managescriptsjob/tests/parseuserjobtest.h
===================================================================
--- libksieve/ksieveui/managescriptsjob/tests/parseuserjobtest.h
+++ libksieve/ksieveui/managescriptsjob/tests/parseuserjobtest.h
@@ -19,7 +19,9 @@
#define PARSEUSERJOBTEST_H
#include <QObject>
-class ParseUserTest : public QObject
+
+namespace KSieveUi {
+class ParseUserJobTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
@@ -29,5 +31,5 @@
void testParseUserDuplicateActiveScriptJob();
void testParseUserErrorScriptJob();
};
-
+}
#endif // PARSEUSERJOBTEST_H
Index: libksieve/ksieveui/managescriptsjob/tests/parseuserjobtest.cpp
===================================================================
--- libksieve/ksieveui/managescriptsjob/tests/parseuserjobtest.cpp
+++ libksieve/ksieveui/managescriptsjob/tests/parseuserjobtest.cpp
@@ -18,19 +18,20 @@
#include "ksieveui/managescriptsjob/parseuserscriptjob.h"
#include <qtest_kde.h>
+using namespace KSieveUi;
-QTEST_KDEMAIN( ParseUserTest, NoGUI )
+QTEST_KDEMAIN( ParseUserJobTest, NoGUI )
-void ParseUserTest::testParseEmptyUserJob()
+void ParseUserJobTest::testParseEmptyUserJob()
{
const QString script;
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 0);
QCOMPARE(result, true);
}
-void ParseUserTest::testParseUserTwoActiveScriptJob()
+void ParseUserJobTest::testParseUserTwoActiveScriptJob()
{
const QString script = QLatin1String("# USER Management Script\n"
"#\n"
@@ -44,12 +45,12 @@
"include :personal \"file1\";\n"
"include :personal \"file2\";\n");
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 2);
QCOMPARE(result, true);
}
-void ParseUserTest::testParseUserNoActiveScriptJob()
+void ParseUserJobTest::testParseUserNoActiveScriptJob()
{
const QString script = QLatin1String("# USER Management Script\n"
"#\n"
@@ -61,12 +62,12 @@
"\n"
"require [\"include\"];\n");
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 0);
QCOMPARE(result, true);
}
-void ParseUserTest::testParseUserDuplicateActiveScriptJob()
+void ParseUserJobTest::testParseUserDuplicateActiveScriptJob()
{
const QString script = QLatin1String("# USER Management Script\n"
"#\n"
@@ -80,12 +81,12 @@
"include :personal \"file1\";\n"
"include :personal \"file1\";\n");
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 1);
QCOMPARE(result, true);
}
-void ParseUserTest::testParseUserErrorScriptJob()
+void ParseUserJobTest::testParseUserErrorScriptJob()
{
const QString script = QLatin1String("# USER Management Script\n"
"#\n"
@@ -97,7 +98,7 @@
"\n"
"errorscript\n");
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 0);
QCOMPARE(result, false);
}
Index: libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h
===================================================================
--- libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h
+++ libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h
@@ -33,14 +33,14 @@
void taggedArgument( const QString &tag );
void stringArgument( const QString &string, bool multiLine, const QString & /*fixme*/ );
void numberArgument( unsigned long number, char quantifier );
- void commandStart( const QString &identifier );
- void commandEnd();
+ void commandStart( const QString &identifier, int lineNumber);
+ void commandEnd(int lineNumber);
void testStart( const QString &identifier );
void testEnd();
void testListStart();
void testListEnd();
- void blockStart();
- void blockEnd();
+ void blockStart(int lineNumber);
+ void blockEnd(int lineNumber);
void stringListArgumentStart();
void stringListArgumentEnd();
void stringListEntry( const QString &string, bool multiline, const QString &hashComment );
Index: libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp
===================================================================
--- libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp
+++ libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp
@@ -50,7 +50,7 @@
write( QLatin1String("num"), ( quantifier ? QString::fromLatin1("quantifier=\"%1\"").arg( quantifier ) : QString()) , QString::number( number ) );
}
-void XMLPrintingScriptBuilder::commandStart( const QString &identifier )
+void XMLPrintingScriptBuilder::commandStart( const QString &identifier, int lineNumber )
{
if ( identifier == QLatin1String("else") ||
identifier == QLatin1String("break") ||
@@ -66,7 +66,7 @@
}
}
-void XMLPrintingScriptBuilder::commandEnd()
+void XMLPrintingScriptBuilder::commandEnd(int lineNumber)
{
if (mIsAction) {
write( QLatin1String("</action>") );
@@ -96,12 +96,12 @@
write( QLatin1String("</testlist>") );
}
-void XMLPrintingScriptBuilder::blockStart()
+void XMLPrintingScriptBuilder::blockStart(int lineNumber)
{
write( QLatin1String("<block>") );
}
-void XMLPrintingScriptBuilder::blockEnd()
+void XMLPrintingScriptBuilder::blockEnd(int lineNumber)
{
write( QLatin1String("</block>") );
}
Index: libksieve/ksieveui/util/util.h
===================================================================
--- libksieve/ksieveui/util/util.h
+++ libksieve/ksieveui/util/util.h
@@ -45,6 +45,7 @@
class KUrl;
class QString;
+class QStringList;
namespace KSieveUi
{
@@ -75,6 +76,17 @@
* be available at all.
*/
KSIEVEUI_EXPORT bool allowOutOfOfficeSettings();
+
+ /**
+ * Checks if a server has KEP:14 support
+ */
+ bool hasKep14Support(const QStringList &sieveCapabilities, const QStringList &availableScripts, const QString &activeScript);
+
+ /**
+ * Is the given scriptName a protected KEP:14 name, that a normal user should not touch directly.
+ * it tests against MASTER, USER and MANAGEMENT script
+ */
+ bool isKep14ProtectedName(const QString &scriptName);
}
}
Index: libksieve/ksieveui/util/util.cpp
===================================================================
--- libksieve/ksieveui/util/util.cpp
+++ libksieve/ksieveui/util/util.cpp
@@ -166,3 +166,45 @@
{
return VacationSettings::self()->allowOutOfOfficeSettings();
}
+
+bool Util::hasKep14Support(const QStringList &sieveCapabilities, const QStringList &availableScripts, const QString &activeScript)
+{
+ const bool hasIncludeCapability = sieveCapabilities.contains(QLatin1String("include"));
+ if (!hasIncludeCapability) {
+ return false;
+ }
+
+ bool masterIsActive = !activeScript.isEmpty();
+ if (masterIsActive) {
+ const QString scriptName = activeScript.split(QLatin1Char('.')).first().toLower();
+ masterIsActive = (scriptName == QLatin1String("master") || scriptName == QLatin1String("user"));
+ }
+ if (!masterIsActive) {
+ return false;
+ }
+
+ bool hasUserScript = false;
+ foreach(const QString &script, availableScripts) {
+ if (script.isEmpty()) {
+ continue;
+ }
+ const QString name = script.split(QLatin1Char('.')).first().toLower();
+ if (name == QLatin1String("user")) {
+ hasUserScript = true;
+ break;
+ }
+ }
+
+ return hasIncludeCapability && masterIsActive && hasUserScript;
+}
+
+bool Util::isKep14ProtectedName(const QString &name)
+{
+ QString n = name.split(QLatin1Char('.')).first().toLower();
+ if (n == QLatin1String("master") ||
+ n == QLatin1String("user") ||
+ n == QLatin1String("management")) {
+ return true;
+ }
+ return false;
+}
\ No newline at end of file
Index: libksieve/ksieveui/vacation/multiimapvacationdialog.h
===================================================================
--- libksieve/ksieveui/vacation/multiimapvacationdialog.h
+++ libksieve/ksieveui/vacation/multiimapvacationdialog.h
@@ -26,11 +26,12 @@
class QStackedWidget;
namespace KSieveUi {
class VacationCreateScriptJob;
+class MultiImapVacationManager;
class KSIEVEUI_EXPORT MultiImapVacationDialog : public KDialog
{
Q_OBJECT
public:
- explicit MultiImapVacationDialog(QWidget *parent=0);
+ explicit MultiImapVacationDialog(MultiImapVacationManager *manager, QWidget *parent=0);
~MultiImapVacationDialog();
QList<VacationCreateScriptJob *> listCreateJob() const;
@@ -49,6 +50,7 @@
QList<VacationCreateScriptJob *> mListCreateJob;
KTabWidget *mTabWidget;
QStackedWidget *mStackedWidget;
+ MultiImapVacationManager* mVacationManager;
};
}
Index: libksieve/ksieveui/vacation/multiimapvacationdialog.cpp
===================================================================
--- libksieve/ksieveui/vacation/multiimapvacationdialog.cpp
+++ libksieve/ksieveui/vacation/multiimapvacationdialog.cpp
@@ -18,6 +18,7 @@
#include "multiimapvacationdialog.h"
#include "vacationpagewidget.h"
+#include "multiimapvacationmanager.h"
#include "ksieveui/util/util.h"
#include <Akonadi/AgentInstance>
@@ -34,8 +35,9 @@
using namespace KSieveUi;
-MultiImapVacationDialog::MultiImapVacationDialog(QWidget *parent)
+MultiImapVacationDialog::MultiImapVacationDialog(MultiImapVacationManager *manager, QWidget *parent)
: KDialog(parent)
+ , mVacationManager(manager)
{
setCaption( i18n("Configure \"Out of Office\" Replies") );
@@ -87,17 +89,12 @@
void MultiImapVacationDialog::init()
{
bool foundOneImap = false;
- const Akonadi::AgentInstance::List instances = KSieveUi::Util::imapAgentInstances();
- foreach ( const Akonadi::AgentInstance &instance, instances ) {
- if ( instance.status() == Akonadi::AgentInstance::Broken )
- continue;
-
- const KUrl url = KSieveUi::Util::findSieveUrlForAccount( instance.identifier() );
- if ( !url.isEmpty() ) {
- const QString serverName = instance.name();
- createPage(serverName, url);
- foundOneImap = true;
- }
+
+ QMap <QString, KUrl> list = mVacationManager->serverList();
+ foreach (const QString &serverName, list.keys()) {
+ const KUrl url = list.value(serverName);
+ createPage(serverName, url);
+ foundOneImap = true;
}
if (foundOneImap) {
setButtons( Ok | Cancel | Default );
@@ -115,6 +112,7 @@
VacationPageWidget *page = new VacationPageWidget;
page->setServerUrl(url);
page->setServerName(serverName);
+ page->setVacationManager(mVacationManager);
mTabWidget->addTab(page,serverName);
}
Index: libksieve/ksieveui/vacation/multiimapvacationmanager.h
===================================================================
--- libksieve/ksieveui/vacation/multiimapvacationmanager.h
+++ libksieve/ksieveui/vacation/multiimapvacationmanager.h
@@ -19,10 +19,15 @@
#define MULTIIMAPVACATIONMANAGER_H
#include <QObject>
+#include <QMap>
#include "ksieveui_export.h"
+class KUrl;
+
namespace KSieveUi {
+class CheckKep14SupportJob;
+class VacationCheckJob;
class KSIEVEUI_EXPORT MultiImapVacationManager : public QObject
{
Q_OBJECT
@@ -31,18 +36,24 @@
~MultiImapVacationManager();
void checkVacation();
+ QMap<QString, KUrl> serverList();
+ void checkVacation(const QString &serverName, const KUrl &url);
+
+ bool kep14Support(QString serverName);
Q_SIGNALS:
void scriptActive(bool active, const QString &serverName);
- void requestEditVacation();
+ void scriptAvailable(const QString &serverName, const QStringList &sieveCapabilities, const QString &scriptName, const QString &script, bool active);
private slots:
- void slotScriptActive(bool active, const QString &serverName);
+ void slotScriptActive(VacationCheckJob* job, QString scriptName, bool active);
+ void slotCheckKep14Ended(CheckKep14SupportJob *job, bool success);
private:
int mNumberOfJobs;
- bool mQuestionAsked;
bool mCheckInProgress;
+
+ QMap<QString, bool> mKep14Support; //if the server has KEP:14 support
};
}
#endif // MULTIIMAPVACATIONMANAGER_H
Index: libksieve/ksieveui/vacation/multiimapvacationmanager.cpp
===================================================================
--- libksieve/ksieveui/vacation/multiimapvacationmanager.cpp
+++ libksieve/ksieveui/vacation/multiimapvacationmanager.cpp
@@ -18,17 +18,21 @@
#include "multiimapvacationmanager.h"
#include "vacationcheckjob.h"
#include "util/util.h"
+#include <managescriptsjob/checkkep14supportjob.h>
+#include <managescriptsjob/parseuserscriptjob.h>
+#include <kmanagesieve/sievejob.h>
#include <Akonadi/AgentInstance>
#include <KMessageBox>
#include <KLocalizedString>
+#include <KDebug>
+
using namespace KSieveUi;
MultiImapVacationManager::MultiImapVacationManager(QObject *parent)
: QObject(parent),
mNumberOfJobs(0),
- mQuestionAsked(false),
mCheckInProgress(false)
{
}
@@ -38,14 +42,9 @@
}
-void MultiImapVacationManager::checkVacation()
+QMap <QString, KUrl> MultiImapVacationManager::serverList()
{
- if (mCheckInProgress)
- return;
- mNumberOfJobs = 0;
- mCheckInProgress = true;
- mQuestionAsked = false;
-
+ QMap <QString, KUrl> list;
const Akonadi::AgentInstance::List instances = KSieveUi::Util::imapAgentInstances();
foreach ( const Akonadi::AgentInstance &instance, instances ) {
if ( instance.status() == Akonadi::AgentInstance::Broken )
@@ -53,32 +52,84 @@
const KUrl url = KSieveUi::Util::findSieveUrlForAccount( instance.identifier() );
if ( !url.isEmpty() ) {
- const QString serverName = instance.name();
- ++mNumberOfJobs;
- VacationCheckJob *job = new VacationCheckJob(url, serverName, this);
- connect(job, SIGNAL(scriptActive(bool,QString)), this, SLOT(slotScriptActive(bool,QString)));
+ list.insert(instance.name(), url);
}
}
+ return list;
}
-void MultiImapVacationManager::slotScriptActive(bool active, const QString &serverName)
+void MultiImapVacationManager::checkVacation(const QString &serverName, const KUrl &url)
{
- --mNumberOfJobs;
- Q_EMIT scriptActive(active, serverName);
-
- if (active) {
- if (!mQuestionAsked) {
- mQuestionAsked = true;
- if ( KMessageBox::questionYesNo( 0, i18n( "There is still an active out-of-office reply configured.\n"
- "Do you want to edit it?"), i18n("Out-of-office reply still active"),
- KGuiItem( i18n( "Edit"), QLatin1String("document-properties") ),
- KGuiItem( i18n("Ignore"), QLatin1String("dialog-cancel") ) )
- == KMessageBox::Yes ) {
- Q_EMIT requestEditVacation();
- }
- }
+ ++mNumberOfJobs;
+ if (!mKep14Support.contains(serverName)) {
+ CheckKep14SupportJob *checkKep14Job = new CheckKep14SupportJob(this);
+ checkKep14Job->setProperty(QLatin1String("triggerScript").latin1(), true);
+ checkKep14Job->setServerName(serverName);
+ checkKep14Job->setServerUrl(url);
+ connect(checkKep14Job, SIGNAL(result(CheckKep14SupportJob*,bool)), SLOT(slotCheckKep14Ended(CheckKep14SupportJob*,bool)));
+ checkKep14Job->start();
+ }
+
+ VacationCheckJob *job = new VacationCheckJob(url, serverName, this);
+ job->setKep14Support(mKep14Support[serverName]);
+ connect(job, SIGNAL(scriptActive(VacationCheckJob*,QString,bool)), this, SLOT(slotScriptActive(VacationCheckJob*,QString,bool)));
+ job->start();
+}
+
+void MultiImapVacationManager::checkVacation()
+{
+ if (mCheckInProgress)
+ return;
+ mNumberOfJobs = 0;
+ mCheckInProgress = true;
+
+ QMap <QString, KUrl> list = serverList();
+ foreach ( const QString &serverName, list.keys() ) {
+ const KUrl url = list.value(serverName);
+ checkVacation(serverName, url);
}
+}
- if (mNumberOfJobs == 0)
+void MultiImapVacationManager::slotScriptActive(VacationCheckJob* job, QString scriptName, bool active)
+{
+ --mNumberOfJobs;
+ if (mNumberOfJobs == 0) {
mCheckInProgress = false;
+ }
+
+ job->deleteLater();
+
+ if (job->noScriptFound()) {
+ emit scriptActive(false, job->serverName());
+ return;
+ }
+ emit scriptActive(active, job->serverName());
+ emit scriptAvailable(job->serverName(), job->sieveCapabilities(), scriptName, job->script(), active);
+}
+
+void MultiImapVacationManager::slotCheckKep14Ended(CheckKep14SupportJob *job, bool success)
+{
+ job->deleteLater();
+ if (!success) {
+ --mNumberOfJobs;
+ return;
+ }
+
+ mKep14Support.insert(job->serverName(), job->hasKep14Support());
+
+ VacationCheckJob *checkJob = new VacationCheckJob(job->serverUrl(), job->serverName(), this);
+ checkJob->setKep14Support(job->hasKep14Support());
+ connect(checkJob, SIGNAL(scriptActive(VacationCheckJob*,QString,bool)),
+ SLOT(slotScriptActive(VacationCheckJob*,QString,bool)));
+ checkJob->start();
+}
+
+bool MultiImapVacationManager::kep14Support(QString serverName)
+{
+ if (mKep14Support.contains(serverName)) {
+ return mKep14Support[serverName];
+ } else {
+ kWarning() << "We don't know the KEP:14 support for this server." << serverName;
+ }
+ return false;
}
Index: libksieve/ksieveui/vacation/tests/CMakeLists.txt
===================================================================
--- libksieve/ksieveui/vacation/tests/CMakeLists.txt
+++ libksieve/ksieveui/vacation/tests/CMakeLists.txt
@@ -1,5 +1,7 @@
include_directories(${CMAKE_SOURCE_DIR}/libksieve
${CMAKE_SOURCE_DIR}/libksieve/ksieveui
+ ${CMAKE_BINARY_DIR}/libksieve
+ ${CMAKE_BINARY_DIR}/libksieve/ksieveui
)
@@ -10,3 +12,25 @@
KDE4_ADD_EXECUTABLE(vacationmultiservertest ${vacation_multi_server_SRCS} )
TARGET_LINK_LIBRARIES(vacationmultiservertest ${KDE4_KDEUI_LIBS} ksieveui ksieve)
+set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
+
+macro( add_vacation_test _source )
+ set( _test ${_source}test.cpp
+ ../${_source}.cpp
+ ../vacationscriptextractor.cpp
+ ${CMAKE_BINARY_DIR}/libksieve/ksieveui/sieve-vacation.cpp
+ ${CMAKE_SOURCE_DIR}/libksieve/parser/lexer.cpp
+ ${CMAKE_SOURCE_DIR}/libksieve/parser/parser.cpp
+ ${CMAKE_SOURCE_DIR}/libksieve/parser/utf8validator.cpp
+ )
+ get_filename_component( _name ${_source} NAME_WE )
+ kde4_add_unit_test( ${_name} TESTNAME vacation-${_name} ${_test} )
+ set_target_properties(${_name} PROPERTIES COMPILE_FLAGS -DVACATIONTESTDATADIR="\\"${CMAKE_CURRENT_SOURCE_DIR}/data/\\"")
+ target_link_libraries( ${_name}
+ ksieveui
+ kmanagesieve
+ ksieve
+ ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} ${KDE4_KDEUI_LIBS} ${KDEPIMLIBS_KMIME_LIBS} ${KDEPIMLIBS_KPIMIDENTITIES_LIBS})
+endmacro()
+
+add_vacation_test( vacationutils )
\ No newline at end of file
Index: libksieve/ksieveui/vacation/tests/data/vacation-complex.siv
===================================================================
--- /dev/null
+++ libksieve/ksieveui/vacation/tests/data/vacation-complex.siv
@@ -0,0 +1,8 @@
+require ["date","relational","vacation"];
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if allof (currentdate :zone "+0100" :value "ge" "date" "2015-01-02", currentdate :zone "+0100" :value "le" "date" "2015-03-04", not header :contains "X-Spam-Flag" "YES")
+{
+ vacation :days 7 :addresses "test@test.de" :subject "XXX" "dsfgsdfgsdfg";
+}
\ No newline at end of file
Index: libksieve/ksieveui/vacation/tests/data/vacation-deactivate-complex.siv
===================================================================
--- /dev/null
+++ libksieve/ksieveui/vacation/tests/data/vacation-deactivate-complex.siv
@@ -0,0 +1,8 @@
+require ["date","relational","vacation"];
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if false # allof (currentdate :zone "+0100" :value "ge" "date" "2015-01-02", currentdate :zone "+0100" :value "le" "date" "2015-03-04", not header :contains "X-Spam-Flag" "YES")
+{
+ vacation :days 7 :addresses "test@test.de" :subject "XXX" "dsfgsdfgsdfg";
+}
\ No newline at end of file
Index: libksieve/ksieveui/vacation/tests/data/vacation-deactivate-multiple.siv
===================================================================
--- /dev/null
+++ libksieve/ksieveui/vacation/tests/data/vacation-deactivate-multiple.siv
@@ -0,0 +1,19 @@
+require ["vacation"];
+
+if true
+{
+ testcommand;
+}
+
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if false # true
+{
+ vacation :subject "XXX" "dsfgsdfgsdfg";
+}
+
+if true
+{
+ testcommand;
+}
\ No newline at end of file
Index: libksieve/ksieveui/vacation/tests/data/vacation-deactivate.siv
===================================================================
--- /dev/null
+++ libksieve/ksieveui/vacation/tests/data/vacation-deactivate.siv
@@ -0,0 +1,9 @@
+require ["vacation"];
+
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if false # true
+{
+ vacation :subject "XXX" "dsfgsdfgsdfg";
+}
\ No newline at end of file
Index: libksieve/ksieveui/vacation/tests/data/vacation-multiple.siv
===================================================================
--- /dev/null
+++ libksieve/ksieveui/vacation/tests/data/vacation-multiple.siv
@@ -0,0 +1,16 @@
+require ["vacation"];
+
+if false
+{
+ testcommand;
+}
+
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+vacation :subject "XXX" "dsfgsdfgsdfg";
+
+if false
+{
+ testcommand;
+}
Index: libksieve/ksieveui/vacation/tests/data/vacation-notfound.siv
===================================================================
--- /dev/null
+++ libksieve/ksieveui/vacation/tests/data/vacation-notfound.siv
@@ -0,0 +1,15 @@
+#blabla
+
+testcommand;
+
+if true {
+ testcmd2;
+}
+
+if false {
+ testcmd3;
+}
+
+if true {
+ testcmd4;
+}
\ No newline at end of file
Index: libksieve/ksieveui/vacation/tests/data/vacation-simple.siv
===================================================================
--- /dev/null
+++ libksieve/ksieveui/vacation/tests/data/vacation-simple.siv
@@ -0,0 +1,6 @@
+require ["vacation"];
+
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+vacation :subject "XXX" "dsfgsdfgsdfg";
\ No newline at end of file
Index: libksieve/ksieveui/vacation/tests/main.cpp
===================================================================
--- libksieve/ksieveui/vacation/tests/main.cpp
+++ libksieve/ksieveui/vacation/tests/main.cpp
@@ -20,6 +20,7 @@
#include <KCmdLineArgs>
#include "vacation/multiimapvacationdialog.h"
+#include <vacation/multiimapvacationmanager.h>
#include <QDebug>
@@ -30,7 +31,8 @@
KApplication app;
app.setQuitOnLastWindowClosed( false );
- KSieveUi::MultiImapVacationDialog dlg;
+ KSieveUi::MultiImapVacationManager manager;
+ KSieveUi::MultiImapVacationDialog dlg(&manager);
dlg.show();
app.exec();
Index: libksieve/ksieveui/vacation/tests/vacationutilstest.h
===================================================================
--- libksieve/ksieveui/vacation/tests/vacationutilstest.h
+++ libksieve/ksieveui/vacation/tests/vacationutilstest.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013, 2014 Montel Laurent <montel@kde.org>
+ Copyright (c) 2015 Sandro Knauß <knauss@kolabsys.com>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2, as
@@ -15,19 +15,27 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef PARSEUSERJOBTEST_H
-#define PARSEUSERJOBTEST_H
+#ifndef VACATIONUTILSTEST_H
+#define VACATIONUTILSTEST_H
#include <QObject>
-class ParseUserTest : public QObject
+
+namespace KSieveUi {
+class VacationUtilsTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
- void testParseEmptyUserJob();
- void testParseUserTwoActiveScriptJob();
- void testParseUserNoActiveScriptJob();
- void testParseUserDuplicateActiveScriptJob();
- void testParseUserErrorScriptJob();
+ void testParseEmptyScript();
+ void testParseOnlyComment();
+ void testParseActivate_data();
+ void testParseActivate();
+ void testParseScript_data();
+ void testParseScript();
+ void testParseScriptComplex();
+ void testWriteScript();
+ void testWriteSimpleScript();
+ void testUpdateVacationBlock();
+ void testMergeRequireLine();
};
-
-#endif // PARSEUSERJOBTEST_H
+}
+#endif // VACATIONUTILSTEST_H
Index: libksieve/ksieveui/vacation/tests/vacationutilstest.cpp
===================================================================
--- /dev/null
+++ libksieve/ksieveui/vacation/tests/vacationutilstest.cpp
@@ -0,0 +1,303 @@
+/*
+ Copyright (c) 2015 Sandro Knauß <knauss@kolabsys.com>
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License, version 2, as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+#include "vacationutilstest.h"
+#include "vacation/vacationutils.h"
+
+#include <kmime/kmime_header_parsing.h>
+
+#include <QFile>
+#include <qtest_kde.h>
+#include <KDebug>
+
+using namespace KSieveUi;
+
+QTEST_KDEMAIN( VacationUtilsTest, NoGUI )
+
+void VacationUtilsTest::testParseEmptyScript()
+{
+ const QString script;
+ QCOMPARE(VacationUtils::foundVacationScript(script), false);
+}
+
+void VacationUtilsTest::testParseOnlyComment()
+{
+ QString script(QLatin1String("#comment"));
+ QCOMPARE(VacationUtils::foundVacationScript(script), false);
+ script = QLatin1String("#comment\n\n#comment\n");
+ QCOMPARE(VacationUtils::foundVacationScript(script), false);
+}
+
+void VacationUtilsTest::testParseActivate_data()
+{
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<bool>("found");
+ QTest::addColumn<bool>("active");
+
+ QTest::newRow("notfound") << QString::fromLatin1("vacation-notfound.siv") << false << false;
+ QTest::newRow("simple") << QString::fromLatin1("vacation-simple.siv") << true << true;
+ QTest::newRow("multile if") << QString::fromLatin1("vacation-multiple.siv") << true << true;
+ QTest::newRow("deactivate") << QString::fromLatin1("vacation-deactivate.siv") << true << false;
+ QTest::newRow("deactivate-multiple if") << QString::fromLatin1("vacation-deactivate-multiple.siv") << true << false;
+ QTest::newRow("deactivate-complex") << QString::fromLatin1("vacation-deactivate-complex.siv") << true << false;
+}
+
+
+void VacationUtilsTest::testParseActivate()
+{
+ QFETCH(QString, filename);
+ QFETCH(bool, found);
+ QFETCH(bool, active);
+
+ QFile file(QLatin1String(VACATIONTESTDATADIR)+filename);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QString script = QString::fromUtf8(file.readAll());
+ QCOMPARE(VacationUtils::foundVacationScript(script), found);
+
+ QString messageText;
+ QString subject;
+ int notificationInterval;
+ QStringList aliases;
+ bool sendForSpam;
+ QString domainName;
+ QDate startDate;
+ QDate endDate;
+ bool scriptActive = !active;
+
+ bool ret = VacationUtils::parseScript(script, scriptActive, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate);
+ QCOMPARE(ret, found);
+ QCOMPARE(scriptActive, active);
+}
+
+void VacationUtilsTest::testParseScript_data()
+{
+ QTest::addColumn<QString>("activate");
+ QTest::addColumn<QString>("deactivate");
+
+ QTest::newRow("simple") << QString::fromLatin1("vacation-simple.siv") << QString::fromLatin1("vacation-deactivate.siv");
+ QTest::newRow("complex") << QString::fromLatin1("vacation-complex.siv") << QString::fromLatin1("vacation-deactivate-complex.siv");
+}
+
+
+void VacationUtilsTest::testParseScript()
+{
+ QFETCH(QString, activate);
+ QFETCH(QString, deactivate);
+ QFile fileA(QLatin1String(VACATIONTESTDATADIR) + activate);
+ QVERIFY(fileA.open(QIODevice::ReadOnly));
+ QString scriptA = QString::fromUtf8(fileA.readAll());
+ QFile fileD(QLatin1String(VACATIONTESTDATADIR) + deactivate);
+ QVERIFY(fileD.open(QIODevice::ReadOnly));
+ QString scriptD = QString::fromUtf8(fileD.readAll());
+
+ QString messageTextA, messageTextD;
+ QString subjectA, subjectD;
+ int notificationIntervalA, notificationIntervalD;
+ QStringList aliasesA, aliasesD;
+ bool sendForSpamA, sendForSpamD;
+ QString domainNameA, domainNameD;
+ QDate startDateA, startDateD;
+ QDate endDateA, endDateD;
+ bool scriptActiveA, scriptActiveD;
+ VacationUtils::parseScript(scriptA, scriptActiveA, messageTextA, subjectA, notificationIntervalA, aliasesA, sendForSpamA, domainNameA, startDateA, endDateA);
+ VacationUtils::parseScript(scriptD, scriptActiveD, messageTextD, subjectD, notificationIntervalD, aliasesD, sendForSpamD, domainNameD, startDateD, endDateD);
+ QCOMPARE(scriptActiveA, true);
+ QCOMPARE(scriptActiveD, false);
+ QCOMPARE(messageTextD, messageTextA);
+ QCOMPARE(subjectD, subjectA);
+ QCOMPARE(notificationIntervalD, notificationIntervalA);
+ QCOMPARE(aliasesD, aliasesA);
+ QCOMPARE(sendForSpamD, sendForSpamA);
+ QCOMPARE(domainNameD, domainNameA);
+ QCOMPARE(startDateD, startDateA);
+ QCOMPARE(endDateD, endDateA);
+}
+
+void VacationUtilsTest::testParseScriptComplex()
+{
+ QFile file(QLatin1String(VACATIONTESTDATADIR "vacation-complex.siv"));
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QString script = QString::fromUtf8(file.readAll());
+
+ QString messageText;
+ QString subject;
+ int notificationInterval;
+ QStringList aliases;
+ bool sendForSpam;
+ QString domainName;
+ QDate startDate;
+ QDate endDate;
+ bool scriptActive;
+ VacationUtils::parseScript(script, scriptActive, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate);
+ QCOMPARE(scriptActive, true);
+ QCOMPARE(messageText, QLatin1String("dsfgsdfgsdfg"));
+ QCOMPARE(subject, QLatin1String("XXX"));
+ QCOMPARE(notificationInterval, 7);
+ QCOMPARE(aliases, QStringList() << QLatin1String("test@test.de"));
+ QCOMPARE(sendForSpam, false);
+ QCOMPARE(domainName, QString());
+ QCOMPARE(startDate, QDate(2015, 01, 02));
+ QCOMPARE(endDate, QDate(2015, 03, 04));
+}
+
+void VacationUtilsTest::testWriteScript()
+{
+ QString messageText(QLatin1String("dsfgsdfgsdfg"));
+ QString subject(QLatin1String("XXX"));
+ int notificationInterval(7);
+ QStringList aliases = QStringList() << QLatin1String("test@test.de");
+ QList<KMime::Types::AddrSpec> addesses;
+ bool sendForSpam(false);
+ QString domainName(QLatin1String("example.org"));
+ QDate startDate(2015, 01, 02);
+ QDate endDate(2015, 03, 04);
+ bool scriptActive(true);
+
+ QString messageTextA;
+ QString subjectA;
+ int notificationIntervalA;
+ QStringList aliasesA;
+ bool sendForSpamA;
+ QString domainNameA;
+ QDate startDateA;
+ QDate endDateA;
+ bool scriptActiveA;
+
+ foreach(const QString &alias, aliases) {
+ KMime::Types::Mailbox a;
+ a.fromUnicodeString(alias);
+ addesses.append(a.addrSpec());
+ }
+
+ QString script = VacationUtils::composeScript(messageText, scriptActive, subject, notificationInterval, addesses, sendForSpam, domainName, startDate, endDate);
+ bool ret = VacationUtils::parseScript(script, scriptActiveA, messageTextA, subjectA, notificationIntervalA, aliasesA, sendForSpamA, domainNameA, startDateA, endDateA);
+ QCOMPARE(ret, true);
+ QCOMPARE(scriptActiveA, scriptActive);
+ QCOMPARE(messageTextA, messageText);
+ QCOMPARE(subjectA, subject);
+ QCOMPARE(notificationIntervalA, notificationInterval);
+ QCOMPARE(aliasesA, aliases);
+ QCOMPARE(sendForSpamA, sendForSpam);
+ QCOMPARE(domainNameA, domainName);
+ QCOMPARE(startDateA, startDate);
+ QCOMPARE(endDateA, endDate);
+
+ scriptActive = false;
+ script = VacationUtils::composeScript(messageText, scriptActive, subject, notificationInterval, addesses, sendForSpam, domainName, startDate, endDate);
+ ret = VacationUtils::parseScript(script, scriptActiveA, messageTextA, subjectA, notificationIntervalA, aliasesA, sendForSpamA, domainNameA, startDateA, endDateA);
+ QCOMPARE(ret, true);
+ QCOMPARE(scriptActiveA, scriptActive);
+ QCOMPARE(messageTextA, messageText);
+ QCOMPARE(subjectA, subject);
+ QCOMPARE(notificationIntervalA, notificationInterval);
+ QCOMPARE(aliasesA, aliases);
+ QCOMPARE(sendForSpamA, sendForSpam);
+ QCOMPARE(domainNameA, domainName);
+ QCOMPARE(startDateA, startDate);
+ QCOMPARE(endDateA, endDate);
+}
+
+
+void VacationUtilsTest::testWriteSimpleScript()
+{
+ QString messageText(QLatin1String("dsfgsdfgsdfg"));
+ QString subject(QLatin1String("XXX"));
+ int notificationInterval(7);
+ bool scriptActive(true);
+
+ QString messageTextA;
+ QString subjectA;
+ int notificationIntervalA;
+ QStringList aliasesA;
+ bool sendForSpamA;
+ QString domainNameA;
+ QDate startDateA;
+ QDate endDateA;
+ bool scriptActiveA;
+
+ QString script = VacationUtils::composeScript(messageText, scriptActive, subject, notificationInterval, QList<KMime::Types::AddrSpec>(), true, QString(), QDate(), QDate());
+ bool ret = VacationUtils::parseScript(script, scriptActiveA, messageTextA, subjectA, notificationIntervalA, aliasesA, sendForSpamA, domainNameA, startDateA, endDateA);
+ QCOMPARE(ret, true);
+ QCOMPARE(scriptActiveA, scriptActive);
+ QCOMPARE(messageTextA, messageText);
+ QCOMPARE(subjectA, subject);
+ QCOMPARE(notificationIntervalA, notificationInterval);
+
+ scriptActive = false;
+ script = VacationUtils::composeScript(messageText, scriptActive, subject, notificationInterval, QList<KMime::Types::AddrSpec>(), true, QString(), QDate(), QDate());
+ ret = VacationUtils::parseScript(script, scriptActiveA, messageTextA, subjectA, notificationIntervalA, aliasesA, sendForSpamA, domainNameA, startDateA, endDateA);
+ QCOMPARE(ret, true);
+ QCOMPARE(scriptActiveA, scriptActive);
+ QCOMPARE(messageTextA, messageText);
+ QCOMPARE(subjectA, subject);
+ QCOMPARE(notificationIntervalA, notificationInterval);
+}
+
+void VacationUtilsTest::testUpdateVacationBlock()
+{
+ QFile fileA(QLatin1String(VACATIONTESTDATADIR "vacation-simple.siv"));
+ QVERIFY(fileA.open(QIODevice::ReadOnly));
+ QString scriptA = QString::fromUtf8(fileA.readAll());
+
+ QFile fileB(QLatin1String(VACATIONTESTDATADIR "vacation-deactivate.siv"));
+ QVERIFY(fileB.open(QIODevice::ReadOnly));
+ QString scriptB = QString::fromUtf8(fileB.readAll());
+
+ const QString attend = QLatin1String("if true\n{\ntestcmd;\n}\n");
+ const QString require = QLatin1String("require [\"date\", \"test\"];");
+ const QString scriptAattend = scriptA + QLatin1String("\n") + attend;
+ const QString scriptBattend = scriptB + QLatin1String("\n") + attend;
+
+ QStringList linesA = scriptA.split(QLatin1Char('\n'));
+ QStringList header;
+ for(int i=0; i<5;i++ ){
+ header.append(linesA.at(i));
+ }
+
+ QStringList vacation;
+ for(int i=5; i<linesA.count(); i++ ){
+ vacation.append(linesA.at(i));
+ }
+
+ QCOMPARE(VacationUtils::updateVacationBlock(scriptA, QString()), scriptA);
+ QCOMPARE(VacationUtils::updateVacationBlock(QString(), scriptB), scriptB);
+ QCOMPARE(VacationUtils::updateVacationBlock(scriptA, scriptB), scriptB);
+ QCOMPARE(VacationUtils::updateVacationBlock(scriptB, scriptA), scriptA);
+ QCOMPARE(VacationUtils::updateVacationBlock(scriptAattend, scriptB), scriptBattend);
+ QCOMPARE(VacationUtils::updateVacationBlock(scriptBattend, scriptA), scriptAattend);
+ QCOMPARE(VacationUtils::updateVacationBlock(scriptA, attend), header.join(QLatin1String("\n")));
+ QStringList output = vacation;
+ output << attend;
+ QCOMPARE(VacationUtils::updateVacationBlock(attend, scriptA), output.join(QLatin1String("\n")));
+ output.insert(0,require);
+ QCOMPARE(VacationUtils::updateVacationBlock(require+ QLatin1String("\n") + attend, scriptA), output.join(QLatin1String("\n")));
+}
+
+void VacationUtilsTest::testMergeRequireLine()
+{
+ QString sEmpty=QLatin1String("require;");
+ QString sOne=QLatin1String("require \"test\";");
+ QString sList1=QLatin1String("require [\"test\"];");
+ QString sList2=QLatin1String("require [\"test\", \"test2\"];");
+ QString sList3=QLatin1String("require [\"test3\",\n \"test4\"];\ntestcmd;");
+
+ QCOMPARE(VacationUtils::mergeRequireLine(sEmpty, sOne), sOne);
+ QCOMPARE(VacationUtils::mergeRequireLine(sOne, sEmpty), sOne);
+ QCOMPARE(VacationUtils::mergeRequireLine(sOne, sList1), sOne);
+ QCOMPARE(VacationUtils::mergeRequireLine(sOne, sList2), sList2);
+ QCOMPARE(VacationUtils::mergeRequireLine(sOne, sList3), QLatin1String("require [\"test\", \"test3\", \"test4\"];") );
+ QCOMPARE(VacationUtils::mergeRequireLine(sList3, sOne), QLatin1String("require [\"test\", \"test3\", \"test4\"];\ntestcmd;") );
+}
Index: libksieve/ksieveui/vacation/vacation.cpp
===================================================================
--- libksieve/ksieveui/vacation/vacation.cpp
+++ libksieve/ksieveui/vacation/vacation.cpp
@@ -115,18 +115,20 @@
QString domainName = VacationUtils::defaultDomainName();
QDate startDate = VacationUtils::defaultStartDate();
QDate endDate = VacationUtils::defaultEndDate();
+ bool sActive = true;
+
if ( !success ) active = false; // default to inactive
- if ( !mCheckOnly && ( !success || !KSieveUi::VacationUtils::parseScript( script, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate ) ) )
+ if ( !mCheckOnly && ( !success || !KSieveUi::VacationUtils::parseScript( script, sActive, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate ) ) )
KMessageBox::information( 0, i18n("Someone (probably you) changed the "
"vacation script on the server.\n"
"KMail is no longer able to determine "
"the parameters for the autoreplies.\n"
"Default values will be used." ) );
- mWasActive = active;
+ mWasActive = active && sActive;
if ( mDialog ) {
- mDialog->setActivateVacation( active );
+ mDialog->setActivateVacation( active && sActive );
mDialog->setSubject(subject);
mDialog->setMessageText( messageText );
mDialog->setNotificationInterval( notificationInterval );
@@ -161,7 +163,8 @@
void Vacation::slotDialogOk() {
kDebug();
// compose a new script:
- const QString script = VacationUtils::composeScript( mDialog->messageText(),
+ const bool active = mDialog->activateVacation();
+ const QString script = VacationUtils::composeScript( mDialog->messageText(), active,
mDialog->subject(),
mDialog->notificationInterval(),
mDialog->mailAliases(),
@@ -169,7 +172,6 @@
mDialog->domainName(),
mDialog->startDate(),
mDialog->endDate() );
- const bool active = mDialog->activateVacation();
emit scriptActive( active, mServerName);
kDebug() << "script:" << endl << script;
Index: libksieve/ksieveui/vacation/vacationcheckjob.h
===================================================================
--- libksieve/ksieveui/vacation/vacationcheckjob.h
+++ libksieve/ksieveui/vacation/vacationcheckjob.h
@@ -19,6 +19,7 @@
#define VACATIONCHECKJOB_H
#include <QObject>
+#include <QStringList>
#include <KUrl>
namespace KManageSieve {
@@ -26,23 +27,46 @@
}
namespace KSieveUi {
+class ParseUserScriptJob;
class VacationCheckJob : public QObject
{
Q_OBJECT
public:
explicit VacationCheckJob(const KUrl &url, const QString &serverName, QObject *parent=0);
~VacationCheckJob();
+ void setKep14Support(bool kep14Support);
+ void start();
+ void kill();
+ bool noScriptFound();
+ QString script();
+ QStringList sieveCapabilities();
+ QString serverName();
Q_SIGNALS:
- void scriptActive(bool active, const QString &serverName);
+ void scriptActive(VacationCheckJob* job, const QString &sscriptName, bool active);
private slots:
void slotGetResult(KManageSieve::SieveJob *job, bool success, const QString &script, bool active);
+ void slotGotActiveScripts(ParseUserScriptJob *job);
+ void slotGotList(KManageSieve::SieveJob *job, bool success, const QStringList &availableScripts, const QString &activeScript);
+ void emitError(const QString &errorMessage);
+ void searchVacationScript();
+ void getNextScript();
+ bool isVacationScipt(const QString &script) const;
+ bool isLastScript() const;
private:
QString mServerName;
KUrl mUrl;
KManageSieve::SieveJob * mSieveJob;
+ ParseUserScriptJob *mParseJob;
+ bool mKep14Support;
+ QStringList mAvailableScripts;
+ QStringList mActiveScripts;
+ int mScriptPos;
+ bool mNoScriptFound;
+ QString mScript;
+ QStringList mSieveCapabilities;
};
}
Index: libksieve/ksieveui/vacation/vacationcheckjob.cpp
===================================================================
--- libksieve/ksieveui/vacation/vacationcheckjob.cpp
+++ libksieve/ksieveui/vacation/vacationcheckjob.cpp
@@ -16,32 +16,196 @@
*/
#include "vacationcheckjob.h"
+#include "vacationutils.h"
+#include <managescriptsjob/parseuserscriptjob.h>
+#include <util/util.h>
#include <kmanagesieve/sievejob.h>
+#include <KDebug>
+
using namespace KSieveUi;
VacationCheckJob::VacationCheckJob(const KUrl &url, const QString &serverName, QObject *parent)
: QObject(parent),
mServerName(serverName),
mUrl(url)
+ , mKep14Support(false)
+ , mSieveJob(0)
+ , mParseJob(0)
+ , mNoScriptFound(0)
{
- mSieveJob = KManageSieve::SieveJob::get( mUrl );
- mSieveJob->setInteractive( false );
- connect( mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
- SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool)) );
}
VacationCheckJob::~VacationCheckJob()
{
+ kill();
+}
+
+void VacationCheckJob::kill()
+{
if ( mSieveJob )
mSieveJob->kill();
mSieveJob = 0;
+
+ if (mParseJob) {
+ mParseJob->kill();
+ }
+ mParseJob = 0;
+}
+
+
+void VacationCheckJob::setKep14Support(bool kep14Support)
+{
+ mKep14Support = kep14Support;
}
-void VacationCheckJob::slotGetResult(KManageSieve::SieveJob */*job*/, bool success, const QString &/*script*/, bool active)
+void VacationCheckJob::start()
{
+ if (mKep14Support) {
+ KUrl url = mUrl;
+ url.setFileName(QLatin1String("USER"));
+ mParseJob = new ParseUserScriptJob(url);
+ connect(mParseJob, SIGNAL(finished(ParseUserScriptJob*)), SLOT(slotGotActiveScripts(ParseUserScriptJob*)));
+ mParseJob->start();
+ mSieveJob = KManageSieve::SieveJob::list(url);
+ connect(mSieveJob, SIGNAL(gotList(KManageSieve::SieveJob*,bool,QStringList,QString)),
+ this, SLOT(slotGotList(KManageSieve::SieveJob*,bool,QStringList,QString)));
+ } else {
+ mSieveJob = KManageSieve::SieveJob::get(mUrl);
+ mSieveJob->setInteractive(false);
+ connect(mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
+ SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool)));
+ }
+}
+
+void VacationCheckJob::slotGetResult(KManageSieve::SieveJob */*job*/, bool success, const QString &script, bool active)
+{
+ mScript = script;
+ mSieveCapabilities = mSieveJob->sieveCapabilities();
mSieveJob = 0;
- if ( !success )
- active = false; // default to inactive
- emit scriptActive( active, mServerName );
+
+ if (mKep14Support) {
+ if (isVacationScipt(script)) {
+ const QString &scriptName = mAvailableScripts[mScriptPos-1];
+ emit scriptActive(this, scriptName, mActiveScripts.contains(scriptName) && VacationUtils::vacationScriptActive(script));
+ kDebug() << "vacation script found :)";
+ } else if (isLastScript()) {
+ mNoScriptFound = true;
+ emit scriptActive(this, QString(), false);
+ kDebug() << "no vacation script found :(";
+ } else {
+ getNextScript();
+ }
+ } else {
+ if ( !success ) {
+ active = false; // default to inactive
+ mNoScriptFound = true;
+ }
+ if (active) {
+ mActiveScripts << mUrl.fileName();
+ }
+ emit scriptActive(this, mUrl.fileName(), active);
+ }
}
+
+void VacationCheckJob::slotGotActiveScripts(ParseUserScriptJob *job)
+{
+ mParseJob = 0;
+ if (!job->error().isEmpty()) {
+ emitError(QLatin1String("ParseUserScriptJob failed:")+job->error());
+ return;
+ }
+ mActiveScripts = job->activeScriptList();
+
+ if (!mSieveJob) {
+ searchVacationScript();
+ }
+}
+
+void VacationCheckJob::slotGotList(KManageSieve::SieveJob *job, bool success, const QStringList &availableScripts, const QString &activeScript)
+{
+ mSieveJob = 0;
+ if (!success) {
+ emitError(QLatin1String("SieveJob list failed."));
+ return;
+ }
+
+ mAvailableScripts = availableScripts;
+
+ if (!mParseJob) {
+ searchVacationScript();
+ }
+}
+
+void VacationCheckJob::emitError(const QString &errorMessage)
+{
+ qWarning() << errorMessage;
+ //TODO: emit error
+}
+
+void VacationCheckJob::searchVacationScript()
+{
+ QStringList scriptList = mActiveScripts;
+
+ // Reorder script list
+ foreach(const QString &script, mAvailableScripts) {
+ if (!scriptList.contains(script)) {
+ scriptList.append(script);
+ }
+ }
+
+ mAvailableScripts = scriptList;
+ mScriptPos = 0;
+ getNextScript();
+}
+
+void VacationCheckJob::getNextScript()
+{
+ if (isLastScript()) {
+ //TODO: no script found
+ mNoScriptFound = true;
+ emit scriptActive(this, QString(), false);
+ kDebug() << "no vacation script found :(";
+ }
+ KUrl url = mUrl;
+ url.setFileName(mAvailableScripts[mScriptPos]);
+ mScriptPos += 1;
+ if (Util::isKep14ProtectedName(url.fileName())) {
+ getNextScript();
+ }
+ mSieveJob = KManageSieve::SieveJob::get(url);
+ mSieveJob->setInteractive(false);
+ connect(mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
+ SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool)));
+}
+
+bool VacationCheckJob::isLastScript() const
+{
+ return mScriptPos >= mAvailableScripts.count();
+}
+
+bool VacationCheckJob::isVacationScipt(const QString &script) const
+{
+ return KSieveUi::VacationUtils::foundVacationScript(script);
+}
+
+bool VacationCheckJob::noScriptFound()
+{
+ return mNoScriptFound;
+}
+
+QString VacationCheckJob::serverName()
+{
+ return mServerName;
+}
+
+QString VacationCheckJob::script()
+{
+ return mScript;
+}
+
+QStringList VacationCheckJob::sieveCapabilities()
+{
+ return mSieveCapabilities;
+}
+
Index: libksieve/ksieveui/vacation/vacationcreatescriptjob.h
===================================================================
--- libksieve/ksieveui/vacation/vacationcreatescriptjob.h
+++ libksieve/ksieveui/vacation/vacationcreatescriptjob.h
@@ -29,6 +29,8 @@
}
namespace KSieveUi {
+class ParseUserScriptJob;
+class GenerateGlobalScriptJob;
class KSIEVEUI_EXPORT VacationCreateScriptJob : public QObject
{
Q_OBJECT
@@ -37,28 +39,39 @@
~VacationCreateScriptJob();
void start();
+ void kill();
void setServerUrl(const KUrl &url);
void setScript(const QString &script);
void setServerName(const QString &servername);
+ const QString &serverName() const;
void setStatus(bool activate, bool wasActive);
+ void setKep14Support(bool kep14Support);
Q_SIGNALS:
void result(bool);
void scriptActive(bool activated, const QString &serverName);
private slots:
- void slotPutActiveResult(KManageSieve::SieveJob *job, bool success);
- void slotPutInactiveResult(KManageSieve::SieveJob *job, bool success);
+ void slotPutResult(KManageSieve::SieveJob *job, bool success);
+ void slotGetScript(KManageSieve::SieveJob *job, bool success, const QString &oldScript, bool active);
+ void slotGotActiveScripts(ParseUserScriptJob *job);
+ void slotGenerateDone(const QString &error=QString());
private:
- void handlePutResult(KManageSieve::SieveJob *, bool success, bool activated);
+ void handleResult();
KUrl mUrl;
QString mScript;
QString mServerName;
bool mActivate;
- bool mWasActive;
+ bool mScriptActive;
+ bool mKep14Support;
+ bool mUserJobRunning;
+ bool mScriptJobRunning;
+ bool mSuccess;
KManageSieve::SieveJob *mSieveJob;
+ ParseUserScriptJob *mParseUserJob;
+ GenerateGlobalScriptJob *mCreateJob;
};
}
Index: libksieve/ksieveui/vacation/vacationcreatescriptjob.cpp
===================================================================
--- libksieve/ksieveui/vacation/vacationcreatescriptjob.cpp
+++ libksieve/ksieveui/vacation/vacationcreatescriptjob.cpp
@@ -16,6 +16,9 @@
*/
#include "vacationcreatescriptjob.h"
+#include "vacationutils.h"
+#include <managescriptsjob/parseuserscriptjob.h>
+#include <managescriptsjob/generateglobalscriptjob.h>
#include <kmanagesieve/sievejob.h>
#include <KMessageBox>
@@ -27,21 +30,46 @@
VacationCreateScriptJob::VacationCreateScriptJob(QObject *parent)
: QObject(parent),
mActivate(false),
- mWasActive(false),
- mSieveJob(0)
+ mScriptActive(false)
+ , mKep14Support(false)
+ , mUserJobRunning(false)
+ , mScriptJobRunning(false)
+ , mSuccess(true)
+ , mSieveJob(0)
+ , mParseUserJob(0)
+ , mCreateJob(0)
{
}
VacationCreateScriptJob::~VacationCreateScriptJob()
{
+ kill();
+}
+
+void VacationCreateScriptJob::kill()
+{
+ if (mSieveJob) {
+ mSieveJob->kill();
+ }
+ mSieveJob = 0;
+
+ if (mParseUserJob) {
+ mParseUserJob->kill();
+ }
+ mParseUserJob = 0;
+ if (mCreateJob) {
+ mCreateJob->kill();
+ }
+ mParseUserJob = 0;
}
+
void VacationCreateScriptJob::setStatus(bool activate, bool wasActive)
{
mActivate = activate;
- mWasActive = wasActive;
+ mScriptActive = wasActive;
}
void VacationCreateScriptJob::setServerName(const QString &servername)
@@ -49,20 +77,14 @@
mServerName = servername;
}
-void VacationCreateScriptJob::start()
+const QString &VacationCreateScriptJob::serverName() const
{
- if (mUrl.isEmpty()) {
- qDebug()<<" server url is empty";
- deleteLater();
- return;
- }
- mSieveJob = KManageSieve::SieveJob::put( mUrl, mScript, mActivate, mWasActive );
- if ( mActivate )
- connect( mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
- SLOT(slotPutActiveResult(KManageSieve::SieveJob*,bool)) );
- else
- connect( mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
- SLOT(slotPutInactiveResult(KManageSieve::SieveJob*,bool)) );
+ return mServerName;
+}
+
+void VacationCreateScriptJob::setKep14Support(bool kep14Support)
+{
+ mKep14Support = kep14Support;
}
void VacationCreateScriptJob::setServerUrl(const KUrl &url)
@@ -75,28 +97,104 @@
mScript = script;
}
-void VacationCreateScriptJob::slotPutActiveResult( KManageSieve::SieveJob * job, bool success )
+void VacationCreateScriptJob::start()
+{
+ if (mUrl.isEmpty()) {
+ qDebug()<<" server url is empty";
+ deleteLater();
+ return;
+ }
+
+ mUserJobRunning = false;
+ mScriptJobRunning = true;
+ mSieveJob = KManageSieve::SieveJob::get(mUrl);
+ mSieveJob->setInteractive(false);
+ connect(mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
+ SLOT(slotGetScript(KManageSieve::SieveJob*,bool,QString,bool)));
+
+ if (mKep14Support && mActivate && !mScriptActive) {
+ mUserJobRunning = true;
+ KUrl url = mUrl;
+ url.setFileName(QLatin1String("USER"));
+ mParseUserJob = new ParseUserScriptJob(url, this);
+ connect(mParseUserJob, SIGNAL(finished(ParseUserScriptJob*)), SLOT(slotGotActiveScripts(ParseUserScriptJob*)));
+ mParseUserJob->start();
+ }
+}
+
+void VacationCreateScriptJob::slotGetScript(KManageSieve::SieveJob *job, bool success, const QString &oldScript, bool active)
{
- handlePutResult( job, success, true );
+ mSieveJob = 0;
+ QString script = mScript;
+ if (success || !oldScript.trimmed().isEmpty()) {
+ script = VacationUtils::mergeRequireLine(oldScript, mScript);
+ script = VacationUtils::updateVacationBlock(oldScript,mScript);
+ }
+ if (mKep14Support) {
+ mSieveJob = KManageSieve::SieveJob::put( mUrl, mScript, false, false );
+ } else {
+ mSieveJob = KManageSieve::SieveJob::put( mUrl, mScript, mActivate, false ); //Never deactivate
+ }
+ connect( mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
+ SLOT(slotPutResult(KManageSieve::SieveJob*,bool)) );
}
-void VacationCreateScriptJob::slotPutInactiveResult( KManageSieve::SieveJob * job, bool success )
+void VacationCreateScriptJob::slotPutResult( KManageSieve::SieveJob * job, bool success )
{
- handlePutResult( job, success, false );
+ mSieveJob = 0;
+ mScriptJobRunning = false;
+ if (!success) {
+ mSuccess = false;
+ }
+ handleResult();
}
-void VacationCreateScriptJob::handlePutResult( KManageSieve::SieveJob *, bool success, bool activated )
+void VacationCreateScriptJob::handleResult()
{
- if ( success )
- KMessageBox::information( 0, activated
+ if (mUserJobRunning || mScriptJobRunning) { // Not both jobs are done
+ return;
+ }
+
+ if ( mSuccess )
+ KMessageBox::information( 0, mActivate
? i18n("Sieve script installed successfully on the server \'%1\'.\n"
"Out of Office reply is now active.", mServerName)
: i18n("Sieve script installed successfully on the server \'%1\'.\n"
"Out of Office reply has been deactivated.", mServerName) );
- kDebug() << "( ???," << success << ", ? )";
- mSieveJob = 0; // job deletes itself after returning from this slot!
- Q_EMIT result( success );
- Q_EMIT scriptActive( activated, mServerName );
+ kDebug() << "( ???," << mSuccess << ", ? )";
+ Q_EMIT result( mSuccess );
+ Q_EMIT scriptActive( mActivate, mServerName );
deleteLater();
}
+
+void VacationCreateScriptJob::slotGotActiveScripts(ParseUserScriptJob *job)
+{
+ mParseUserJob = 0;
+ if (!job->error().isEmpty()) {
+ slotGenerateDone(job->error());
+ return;
+ }
+
+ QStringList list = job->activeScriptList();
+
+ if (!list.contains(mUrl.fileName())) {
+ list.prepend(mUrl.fileName());
+ mCreateJob = new GenerateGlobalScriptJob(mUrl, this);
+ mCreateJob->addUserActiveScripts(list);
+ connect( mCreateJob, SIGNAL(success()), SLOT(slotGenerateDone()));
+ connect( mCreateJob, SIGNAL(error(QString)), SLOT(slotGenerateDone(QString)));
+ mCreateJob->start();
+ }
+}
+
+void VacationCreateScriptJob::slotGenerateDone(const QString &error)
+{
+ mCreateJob = 0;
+ mUserJobRunning = false;
+ if (!error.isEmpty()) {
+ qWarning() << error;
+ mSuccess = false;
+ }
+ handleResult();
+}
Index: libksieve/ksieveui/vacation/vacationmanager.h
===================================================================
--- libksieve/ksieveui/vacation/vacationmanager.h
+++ libksieve/ksieveui/vacation/vacationmanager.h
@@ -41,17 +41,19 @@
void slotEditVacation(const QString &serverName);
Q_SIGNALS:
- void updateVacationScriptStatus(bool, const QString&);
+ void updateVacationScriptStatus(bool active, const QString &serverName);
void editVacation();
private slots:
void slotDialogCanceled();
void slotDialogOk();
+ void slotUpdateVacationScriptStatus(bool active, const QString &serverName);
private:
QPointer<KSieveUi::MultiImapVacationDialog> mMultiImapVacationDialog;
QPointer<KSieveUi::MultiImapVacationManager> mCheckVacation;
QWidget *mWidget;
+ bool mQuestionAsked;
};
}
Index: libksieve/ksieveui/vacation/vacationmanager.cpp
===================================================================
--- libksieve/ksieveui/vacation/vacationmanager.cpp
+++ libksieve/ksieveui/vacation/vacationmanager.cpp
@@ -30,38 +30,53 @@
VacationManager::VacationManager(QWidget *parent)
: QObject(parent),
mWidget(parent)
+ , mMultiImapVacationDialog(0)
+ , mQuestionAsked(false)
{
+ mCheckVacation = new KSieveUi::MultiImapVacationManager( this );
+ connect( mCheckVacation, SIGNAL(scriptActive(bool,QString)), SIGNAL(updateVacationScriptStatus(bool,QString)) );
+ connect( mCheckVacation, SIGNAL(scriptActive(bool,QString)), SLOT(slotUpdateVacationScriptStatus(bool,QString)) );
}
VacationManager::~VacationManager()
{
+ mCheckVacation = 0;
+ mMultiImapVacationDialog = 0;
}
void VacationManager::checkVacation()
{
- delete mCheckVacation;
-
- mCheckVacation = new KSieveUi::MultiImapVacationManager( this );
- connect( mCheckVacation, SIGNAL(scriptActive(bool,QString)), SIGNAL(updateVacationScriptStatus(bool,QString)) );
- connect( mCheckVacation, SIGNAL(requestEditVacation()), SIGNAL(editVacation()) );
mCheckVacation->checkVacation();
}
+void VacationManager::slotUpdateVacationScriptStatus(bool active, const QString &serverName)
+{
+ if (active) {
+ if (!mQuestionAsked) {
+ mQuestionAsked = true;
+ if ( KMessageBox::questionYesNo( 0, i18n( "There is still an active out-of-office reply configured.\n"
+ "Do you want to edit it?"), i18n("Out-of-office reply still active"),
+ KGuiItem( i18n( "Edit"), QLatin1String("document-properties") ),
+ KGuiItem( i18n("Ignore"), QLatin1String("dialog-cancel") ) )
+ == KMessageBox::Yes ) {
+ slotEditVacation(serverName);
+ }
+ }
+ }
+}
+
+
void VacationManager::slotEditVacation(const QString &serverName)
{
if ( mMultiImapVacationDialog ) {
- mMultiImapVacationDialog->show();
mMultiImapVacationDialog->raise();
mMultiImapVacationDialog->activateWindow();
- if (!serverName.isEmpty()) {
- mMultiImapVacationDialog->switchToServerNamePage(serverName);
- }
- return;
+ } else {
+ mMultiImapVacationDialog = new KSieveUi::MultiImapVacationDialog(mCheckVacation, mWidget);
+ connect( mMultiImapVacationDialog, SIGNAL(okClicked()), SLOT(slotDialogOk()) );
+ connect( mMultiImapVacationDialog, SIGNAL(cancelClicked()), SLOT(slotDialogCanceled()) );
}
- mMultiImapVacationDialog = new KSieveUi::MultiImapVacationDialog(mWidget);
- connect( mMultiImapVacationDialog, SIGNAL(okClicked()), SLOT(slotDialogOk()) );
- connect( mMultiImapVacationDialog, SIGNAL(cancelClicked()), SLOT(slotDialogCanceled()) );
mMultiImapVacationDialog->show();
if (!serverName.isEmpty()) {
mMultiImapVacationDialog->switchToServerNamePage(serverName);
@@ -80,6 +95,7 @@
QList<KSieveUi::VacationCreateScriptJob *> listJob = mMultiImapVacationDialog->listCreateJob();
Q_FOREACH (KSieveUi::VacationCreateScriptJob *job, listJob) {
connect(job, SIGNAL(scriptActive(bool,QString)), SIGNAL(updateVacationScriptStatus(bool,QString)));
+ job->setKep14Support(mCheckVacation->kep14Support(job->serverName()));
job->start();
}
mMultiImapVacationDialog->delayedDestruct();
Index: libksieve/ksieveui/vacation/vacationpagewidget.h
===================================================================
--- libksieve/ksieveui/vacation/vacationpagewidget.h
+++ libksieve/ksieveui/vacation/vacationpagewidget.h
@@ -29,6 +29,8 @@
class VacationEditWidget;
class VacationWarningWidget;
class VacationCreateScriptJob;
+class MultiImapVacationManager;
+class ParseUserScriptJob;
class VacationPageWidget : public QWidget
{
Q_OBJECT
@@ -40,11 +42,15 @@
void setServerName(const QString &serverName);
KSieveUi::VacationCreateScriptJob *writeScript();
void setDefault();
+ void setVacationManager(MultiImapVacationManager *vacationManager);
private slots:
- void slotGetResult(KManageSieve::SieveJob *job, bool success, const QString &script, bool active);
+ void slotGetResult(const QString &serverName, const QStringList &sieveCapabilities, const QString &scriptName, const QString &script, bool active);
private:
+
+ void fillWithDefaults();
+
enum PageType {
Script = 0,
ScriptNotSupported = 1
@@ -56,7 +62,7 @@
QStackedWidget *mStackWidget;
VacationEditWidget *mVacationEditWidget;
VacationWarningWidget *mVacationWarningWidget;
- KManageSieve::SieveJob *mSieveJob;
+ MultiImapVacationManager *mVacationManager;
bool mWasActive;
};
}
Index: libksieve/ksieveui/vacation/vacationpagewidget.cpp
===================================================================
--- libksieve/ksieveui/vacation/vacationpagewidget.cpp
+++ libksieve/ksieveui/vacation/vacationpagewidget.cpp
@@ -20,6 +20,8 @@
#include "vacationwarningwidget.h"
#include "vacationcreatescriptjob.h"
#include "vacationutils.h"
+#include "multiimapvacationmanager.h"
+#include <managescriptsjob/parseuserscriptjob.h>
#include "sieve-vacation.h"
#include <kmime/kmime_header_parsing.h>
@@ -37,7 +39,6 @@
VacationPageWidget::VacationPageWidget(QWidget *parent)
: QWidget(parent),
mPageScript(Script),
- mSieveJob(0),
mWasActive(false)
{
QVBoxLayout *lay = new QVBoxLayout;
@@ -79,18 +80,20 @@
VacationPageWidget::~VacationPageWidget()
{
- if ( mSieveJob )
- mSieveJob->kill();
- mSieveJob = 0;
}
void VacationPageWidget::setServerUrl(const KUrl &url)
{
mUrl = url;
mVacationEditWidget->setEnabled(false);
- mSieveJob = KManageSieve::SieveJob::get( url );
- connect( mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
- SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool)) );
+}
+
+void VacationPageWidget::setVacationManager(MultiImapVacationManager *vacationManager)
+{
+ mVacationManager = vacationManager;
+ connect(mVacationManager, SIGNAL(scriptAvailable(QString,QStringList,QString,QString,bool)),
+ SLOT(slotGetResult(QString,QStringList,QString,QString,bool)));
+ mVacationManager->checkVacation(mServerName, mUrl);
}
void VacationPageWidget::setServerName(const QString &serverName)
@@ -98,24 +101,28 @@
mServerName = serverName;
}
-void VacationPageWidget::slotGetResult( KManageSieve::SieveJob * job, bool success, const QString & script, bool active )
+void VacationPageWidget::slotGetResult(const QString &serverName, const QStringList &sieveCapabilities, const QString &scriptName, const QString &script, bool active)
{
- kDebug() << success
- << ", ?," << active << ")" << endl
+ if (serverName != mServerName) {
+ return;
+ }
+
+ kDebug() << serverName << sieveCapabilities << endl
+ << scriptName << "(" << active << ")" << endl
<< "script:" << endl
<< script;
- mSieveJob = 0; // job deletes itself after returning from this slot!
if ( mUrl.protocol() == QLatin1String("sieve") &&
- !job->sieveCapabilities().contains(QLatin1String("vacation")) ) {
+ !sieveCapabilities.contains(QLatin1String("vacation")) ) {
mStackWidget->setCurrentIndex(ScriptNotSupported);
return;
}
+ mUrl.setFileName(scriptName);
+
// Whether the server supports the "date" extension
- const bool supportsSieveDate = mUrl.protocol() == QLatin1String("sieve") && job->sieveCapabilities().contains(QLatin1String("date"));
+ const bool supportsSieveDate = mUrl.protocol() == QLatin1String("sieve") && sieveCapabilities.contains(QLatin1String("date"));
- mVacationEditWidget->setEnabled(true);
QString messageText = VacationUtils::defaultMessageText();
QString subject = VacationUtils::defaultSubject();
int notificationInterval = VacationUtils::defaultNotificationInterval();
@@ -124,14 +131,17 @@
QString domainName = VacationUtils::defaultDomainName();
QDate startDate = VacationUtils::defaultStartDate();
QDate endDate = VacationUtils::defaultEndDate();
- if ( !success )
- active = false; // default to inactive
+ bool scriptActive = true;
- if ( ( !success || !KSieveUi::VacationUtils::parseScript( script, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate ) ) )
+ const bool bParse = KSieveUi::VacationUtils::parseScript(script, scriptActive, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate);
+
+ if (!bParse) {
mVacationWarningWidget->setVisible(true);
+ }
mWasActive = active;
- mVacationEditWidget->setActivateVacation( active );
+ mVacationEditWidget->setEnabled(true);
+ mVacationEditWidget->setActivateVacation( active && scriptActive );
mVacationEditWidget->setMessageText( messageText );
mVacationEditWidget->setSubject( subject );
mVacationEditWidget->setNotificationInterval( notificationInterval );
@@ -149,13 +159,16 @@
//emit scriptActive( mWasActive, mServerName );
}
+
+
KSieveUi::VacationCreateScriptJob *VacationPageWidget::writeScript()
{
if (mPageScript == Script) {
KSieveUi::VacationCreateScriptJob *createJob = new KSieveUi::VacationCreateScriptJob;
createJob->setServerUrl(mUrl);
createJob->setServerName(mServerName);
- const QString script = VacationUtils::composeScript( mVacationEditWidget->messageText(),
+ const bool active = mVacationEditWidget->activateVacation();
+ const QString script = VacationUtils::composeScript( mVacationEditWidget->messageText(), active,
mVacationEditWidget->subject(),
mVacationEditWidget->notificationInterval(),
mVacationEditWidget->mailAliases(),
@@ -163,7 +176,6 @@
mVacationEditWidget->domainName(),
mVacationEditWidget->startDate(),
mVacationEditWidget->endDate() );
- const bool active = mVacationEditWidget->activateVacation();
createJob->setStatus(active, mWasActive);
//Q_EMIT scriptActive( active, mServerName);
createJob->setScript(script);
Index: libksieve/ksieveui/vacation/vacationscriptextractor.h
===================================================================
--- libksieve/ksieveui/vacation/vacationscriptextractor.h
+++ libksieve/ksieveui/vacation/vacationscriptextractor.h
@@ -80,14 +80,14 @@
#undef FOREACH
#endif
#define FOREACH for ( std::vector<KSieve::ScriptBuilder*>::const_iterator it = mBuilders.begin(), end = mBuilders.end() ; it != end ; ++it ) (*it)->
- void commandStart( const QString & identifier ) { FOREACH commandStart( identifier ); }
- void commandEnd() { FOREACH commandEnd(); }
+ void commandStart( const QString & identifier, int lineNumber ) { FOREACH commandStart( identifier, lineNumber ); }
+ void commandEnd(int lineNumber) { FOREACH commandEnd(lineNumber); }
void testStart( const QString & identifier ) { FOREACH testStart( identifier ); }
void testEnd() { FOREACH testEnd(); }
void testListStart() { FOREACH testListStart(); }
void testListEnd() { FOREACH testListEnd(); }
- void blockStart() { FOREACH blockStart(); }
- void blockEnd() { FOREACH blockEnd(); }
+ void blockStart(int lineNumber) { FOREACH blockStart(lineNumber); }
+ void blockEnd(int lineNumber) { FOREACH blockEnd(lineNumber); }
void hashComment( const QString & comment ) { FOREACH hashComment( comment ); }
void bracketComment( const QString & comment ) { FOREACH bracketComment( comment ); }
void lineFeed() { FOREACH lineFeed(); }
@@ -143,9 +143,11 @@
unsigned int mState;
int mNestingDepth;
+ int mLineNumber;
+
public:
GenericInformationExtractor( const std::vector<StateNode> & nodes )
- : KSieve::ScriptBuilder(), mNodes( nodes ), mState( 0 ), mNestingDepth( 0 ) {}
+ : KSieve::ScriptBuilder(), mNodes( nodes ), mState( 0 ), mNestingDepth( 0 ), mLineNumber(0) {}
const std::map<QString,QString> & results() const { return mResults; }
@@ -180,17 +182,17 @@
doProcess( method, string );
}
}
- void commandStart( const QString & identifier ) { kDebug() ; process( CommandStart, identifier ); }
- void commandEnd() { kDebug() ; process( CommandEnd ); }
- void testStart( const QString & identifier ) { kDebug() ; process( TestStart, identifier ); }
+ void commandStart( const QString & identifier, int lineNumber ) { kDebug() << identifier ; process( CommandStart, identifier ); }
+ void commandEnd(int lineNumber) { kDebug() ; process( CommandEnd ); }
+ void testStart( const QString & identifier ) { kDebug() << identifier ; process( TestStart, identifier ); }
void testEnd() { kDebug() ; process( TestEnd ); }
void testListStart() { kDebug() ; process( TestListStart ); }
void testListEnd() { kDebug() ; process( TestListEnd ); }
- void blockStart() { kDebug() ; process( BlockStart ); ++mNestingDepth; }
- void blockEnd() { kDebug() ; --mNestingDepth; process( BlockEnd ); }
+ void blockStart(int lineNumber) { kDebug() ; process( BlockStart ); ++mNestingDepth; }
+ void blockEnd(int lineNumber) { kDebug() ; --mNestingDepth; process( BlockEnd ); }
void hashComment( const QString & ) { kDebug() ; }
void bracketComment( const QString & ) { kDebug() ; }
- void lineFeed() { kDebug() ; }
+ void lineFeed() { kDebug() << ++mLineNumber; }
void error( const KSieve::Error & ) {
kDebug() ;
mState = 0;
@@ -208,34 +210,39 @@
typedef GenericInformationExtractor GIE;
static const GenericInformationExtractor::StateNode spamNodes[] = {
{ 0, GIE::CommandStart, "if", 1, 0, 0 }, // 0
- { 0, GIE::TestStart, "header", 2, 0, 0 }, // 1
- { 0, GIE::TaggedArgument, "contains", 3, 0, 0 }, // 2
+ { 0, GIE::TestStart, "allof", 2, 3, 0 }, // 1
+ { 0, GIE::TestListStart, 0, 3, 0, 0 }, // 2
+ { 0, GIE::TestStart, "not", 4, 3, 0 }, // 3
+ { 0, GIE::TestStart, "header", 5, 3, 0 }, // 4
+ { 0, GIE::TaggedArgument, "contains", 6, 0, 0 }, // 5
// accept both string and string-list:
- { 0, GIE::StringArgument, "x-spam-flag", 9, 4, "x-spam-flag" }, // 3
- { 0, GIE::StringListArgumentStart, 0, 5, 0, 0 }, // 4
- { 0, GIE::StringListEntry, "x-spam-flag", 6, 7, "x-spam-flag" }, // 5
- { 0, GIE::StringListEntry, 0, 6, 8, 0 }, // 6
- { 0, GIE::StringListArgumentEnd, 0, 0, 5, 0 }, // 7
- { 0, GIE::StringListArgumentEnd, 0, 9, 0, 0 }, // 8
+ { 0, GIE::StringArgument, "x-spam-flag", 12, 7, "x-spam-flag" }, // 6
+ { 0, GIE::StringListArgumentStart, 0, 8, 0, 0 }, // 7
+ { 0, GIE::StringListEntry, "x-spam-flag", 9, 10, "x-spam-flag" }, // 8
+ { 0, GIE::StringListEntry, 0, 9, 11, 0 }, // 9
+ { 0, GIE::StringListArgumentEnd, 0, 0, 8, 0 }, // 10
+ { 0, GIE::StringListArgumentEnd, 0, 12, 0, 0 }, // 11
// accept both string and string-list:
- { 0, GIE::StringArgument, "yes", 15, 10, "spam-flag-yes" }, // 9
- { 0, GIE::StringListArgumentStart, 0, 11, 0, 0 }, // 10
- { 0, GIE::StringListEntry, "yes", 12, 13, "spam-flag-yes" }, // 11
- { 0, GIE::StringListEntry, 0, 12, 14, 0 }, // 12
- { 0, GIE::StringListArgumentEnd, 0, 0, 11, 0 }, // 13
- { 0, GIE::StringListArgumentEnd, 0, 15, 0, 0 }, // 14
+ { 0, GIE::StringArgument, "yes", 18, 13, "spam-flag-yes" }, // 12
+ { 0, GIE::StringListArgumentStart, 0, 14, 0, 0 }, // 13
+ { 0, GIE::StringListEntry, "yes", 15, 16, "spam-flag-yes" }, // 14
+ { 0, GIE::StringListEntry, 0, 15, 17, 0 }, // 15
+ { 0, GIE::StringListArgumentEnd, 0, 0, 14, 0 }, // 16
+ { 0, GIE::StringListArgumentEnd, 0, 18, 0, 0 }, // 17
- { 0, GIE::TestEnd, 0, 16, 0, 0 }, // 15
+ { 0, GIE::TestEnd, 0, 21, 20, 0 }, // 18
+ { 0, GIE::Any, 0, 21, 0, 0 }, // 19
+ { 0, GIE::TestListEnd, 0, 21, 19, 0 }, // 20
// block of command, find "stop", take nested if's into account:
- { 0, GIE::BlockStart, 0, 17, 0, 0 }, // 16
- { 1, GIE::CommandStart, "stop", 20, 19, "stop" }, // 17
- { -1, GIE::Any, 0, 17, 0, 0 }, // 18
- { 0, GIE::BlockEnd, 0, 0, 18, 0 }, // 19
+ { 0, GIE::BlockStart, 0, 22, 18, 0 }, // 21
+ { 1, GIE::CommandStart, "vacation", 24, 22, "vacation" }, // 22
+ { 1, GIE::Any, 0, 24, 0, 0 }, // 23
+ { 0, GIE::BlockEnd, 0, 25, 23, 0 }, // 24
- { -1, GIE::Any, 0, 20, 20, 0 }, // 20 end state
+ { -1, GIE::Any, 0, 25, 25, 0 }, // 25 end state
};
static const unsigned int numSpamNodes = sizeof spamNodes / sizeof *spamNodes ;
@@ -250,7 +257,7 @@
bool found() const {
return mResults.count( QLatin1String("x-spam-flag") ) &&
mResults.count( QLatin1String("spam-flag-yes") ) &&
- mResults.count( QLatin1String("stop") ) ;
+ mResults.count( QLatin1String("vacation") ) ;
}
};
@@ -259,39 +266,40 @@
// 'if not address :domain :contains ["from"] ["mydomain.org"] { keep; stop; }'
static const GenericInformationExtractor::StateNode domainNodes[] = {
{ 0, GIE::CommandStart, "if", 1, 0, 0 }, // 0
- { 0, GIE::TestStart, "not", 2, 0, 0, }, // 1
- { 0, GIE::TestStart, "address", 3, 0, 0 }, // 2
+ { 0, GIE::TestStart, "allof", 2, 3, 0 }, // 1
+ { 0, GIE::TestListStart, 0, 3, 0, 0 }, // 2
+ { 0, GIE::TestStart, "address", 4, 3, 0 }, // 3
// :domain and :contains in arbitrary order:
- { 0, GIE::TaggedArgument, "domain", 4, 5, 0 }, // 3
- { 0, GIE::TaggedArgument, "contains", 7, 0, 0 }, // 4
- { 0, GIE::TaggedArgument, "contains", 6, 0, 0 }, // 5
- { 0, GIE::TaggedArgument, "domain", 7, 0, 0 }, // 6
+ { 0, GIE::TaggedArgument, "domain", 5, 6, 0 }, // 4
+ { 0, GIE::TaggedArgument, "contains", 8, 0, 0 }, // 5
+ { 0, GIE::TaggedArgument, "contains", 7, 0, 0 }, // 6
+ { 0, GIE::TaggedArgument, "domain", 8, 0, 0 }, // 7
// accept both string and string-list:
- { 0, GIE::StringArgument, "from", 13, 8, "from" }, // 7
- { 0, GIE::StringListArgumentStart, 0, 9, 0, 0 }, // 8
- { 0, GIE::StringListEntry, "from", 10, 11, "from" }, // 9
- { 0, GIE::StringListEntry, 0, 10, 12, 0 }, // 10
- { 0, GIE::StringListArgumentEnd, 0, 0, 9, 0 }, // 11
- { 0, GIE::StringListArgumentEnd, 0, 13, 0, 0 }, // 12
+ { 0, GIE::StringArgument, "from", 14, 9, "from" }, // 8
+ { 0, GIE::StringListArgumentStart, 0, 10, 0, 0 }, // 9
+ { 0, GIE::StringListEntry, "from", 11, 12, "from" }, // 10
+ { 0, GIE::StringListEntry, 0, 11, 13, 0 }, // 11
+ { 0, GIE::StringListArgumentEnd, 0, 0, 10, 0 }, // 12
+ { 0, GIE::StringListArgumentEnd, 0, 14, 0, 0 }, // 13
// string: save, string-list: save last
- { 0, GIE::StringArgument, 0, 17, 14, "domainName" }, // 13
- { 0, GIE::StringListArgumentStart, 0, 15, 0, 0 }, // 14
- { 0, GIE::StringListEntry, 0, 15, 16, "domainName" }, // 15
- { 0, GIE::StringListArgumentEnd, 0, 17, 0, 0 }, // 16
+ { 0, GIE::StringArgument, 0, 18, 15, "domainName" }, // 14
+ { 0, GIE::StringListArgumentStart, 0, 16, 0, 0 }, // 15
+ { 0, GIE::StringListEntry, 0, 16, 17, "domainName" }, // 16
+ { 0, GIE::StringListArgumentEnd, 0, 18, 0, 0 }, // 17
- { 0, GIE::TestEnd, 0, 18, 0, 0 }, // 17
- { 0, GIE::TestEnd, 0, 19, 0, 0 }, // 18
+ { 0, GIE::TestEnd, 0, 18, 20, 0 }, // 18
+ { 0, GIE::Any, 0, 18, 0, 0 }, // 19
// block of commands, find "stop", take nested if's into account:
- { 0, GIE::BlockStart, 0, 20, 0, 0 }, // 19
- { 1, GIE::CommandStart, "stop", 23, 22, "stop" }, // 20
- { -1, GIE::Any, 0, 20, 0, 0 }, // 21
- { 0, GIE::BlockEnd, 0, 0, 21, 0 }, // 22
+ { 0, GIE::BlockStart, 0, 21, 19, 0 }, // 20
+ { 1, GIE::CommandStart, "vacation", 23, 21, "vacation" }, // 21
+ { 1, GIE::Any, 0, 23, 0, 0 }, // 22
+ { 0, GIE::BlockEnd, 0, 24, 22, 0 }, // 23
- { -1, GIE::Any, 0, 23, 23, 0 } // 23 end state
+ { -1, GIE::Any, 0, 24, 24, 0 } // 24 end state
};
static const unsigned int numDomainNodes = sizeof domainNodes / sizeof *domainNodes ;
@@ -304,7 +312,7 @@
}
QString domainName() /*not const, since map::op[] isn't const*/ {
- return mResults.count( QLatin1String("stop") ) && mResults.count( QLatin1String("from") )
+ return mResults.count( QLatin1String("vacation") ) && mResults.count( QLatin1String("from") )
? mResults[QLatin1String("domainName")] : QString();
}
};
@@ -313,42 +321,44 @@
// currentfate :value "le" date "YYYY-MM-DD) { keep; stop; }
static const GenericInformationExtractor::StateNode datesNodes[] = {
{ 0, GIE::CommandStart, "if", 1, 0, 0 }, // 0
- { 0, GIE::TestStart, "not", 2, 0, 0 }, // 1
- { 0, GIE::TestStart, "allof", 3, 0, 0 }, // 2
+ { 0, GIE::TestStart, "allof", 2, 0, 0 }, // 1
// handle startDate and endDate in arbitrary order
- { 0, GIE::TestListStart, 0, 4, 0, 0 }, // 3
- { 0, GIE::TestStart, "currentdate", 5, 0, 0 }, // 4
- { 0, GIE::TaggedArgument, "value", 6, 0, 0 }, // 5
- { 0, GIE::StringArgument, "ge", 7, 9, 0 }, // 6
- { 0, GIE::StringArgument, "date", 8, 0, 0 }, // 7
- { 0, GIE::StringArgument, 0, 12, 0, "startDate" }, // 8
- { 0, GIE::StringArgument, "le", 10, 0, 0 }, // 9
- { 0, GIE::StringArgument, "date", 11, 0, 0 }, // 10
- { 0, GIE::StringArgument, 0, 12, 0, "endDate" }, // 11
- { 0, GIE::TestEnd, 0, 13, 0, 0 }, // 12
-
- { 0, GIE::TestStart, "currentdate", 14, 0, 0 }, // 13
- { 0, GIE::TaggedArgument, "value", 15, 0, 0 }, // 14
- { 0, GIE::StringArgument, "le", 16, 18, 0 }, // 15
- { 0, GIE::StringArgument, "date", 17, 0, 0 }, // 16
- { 0, GIE::StringArgument, 0, 21, 0, "endDate" }, // 17
- { 0, GIE::StringArgument, "ge", 19, 0, 0 }, // 18
- { 0, GIE::StringArgument, "date", 20, 0, 0 }, // 19
- { 0, GIE::StringArgument, 0, 21, 0, "startDate" }, // 20
- { 0, GIE::TestEnd, 0, 22, 0, 0 }, // 21
- { 0, GIE::TestListEnd, 0, 23, 0, 0 }, // 22
-
- { 0, GIE::TestEnd, 0, 24, 0, 0 }, // 23
- { 0, GIE::TestEnd, 0, 25, 0, 0 }, // 24
+ { 0, GIE::TestListStart, 0, 3, 0, 0 }, // 2
+ { 0, GIE::TestStart, "currentdate", 4, 3, 0 }, // 3
+ { 0, GIE::TaggedArgument, "value", 5, 4, 0 }, // 4
+ { 0, GIE::StringArgument, "ge", 6, 8, 0 }, // 5
+ { 0, GIE::StringArgument, "date", 7, 0, 0 }, // 6
+ { 0, GIE::StringArgument, 0, 11, 0, "startDate" }, // 7
+ { 0, GIE::StringArgument, "le", 9, 0, 0 }, // 8
+ { 0, GIE::StringArgument, "date", 10, 0, 0 }, // 9
+ { 0, GIE::StringArgument, 0, 11, 0, "endDate" }, // 10
+ { 0, GIE::TestEnd, 0, 12, 0, 0 }, // 11
+
+ { 0, GIE::TestStart, "currentdate", 13, 12, 0 }, // 12
+ { 0, GIE::TaggedArgument, "value", 14, 13, 0 }, // 13
+ { 0, GIE::StringArgument, "le", 15, 17, 0 }, // 14
+ { 0, GIE::StringArgument, "date", 16, 0, 0 }, // 15
+ { 0, GIE::StringArgument, 0, 20, 0, "endDate" }, // 16
+ { 0, GIE::StringArgument, "ge", 18, 0, 0 }, // 17
+ { 0, GIE::StringArgument, "date", 19, 0, 0 }, // 18
+ { 0, GIE::StringArgument, 0, 20, 0, "startDate" }, // 19
+ { 0, GIE::TestEnd, 0, 24, 0, 0 }, // 20
+ { 0, GIE::TestStart, 0, 23, 22, 0 }, // 21
+ { -1, GIE::Any, 0, 24, 0, 0 }, // 22
+ { 0, GIE::TestEnd, 0, 24, 22, 0 }, // 23
+ { 0, GIE::TestListEnd, 0, 25, 21, 0 }, // 24
+
+ { 0, GIE::TestEnd, 0, 26, 0, 0 }, // 25
// block of commands, find "stop", take nested if's into account:
- { 0, GIE::BlockStart, 0, 26, 0, 0 }, // 25
- { 1, GIE::CommandStart, "stop", 29, 28, "stop" }, // 26
- { -1, GIE::Any, 0, 26, 0, 0 }, // 27
- { 0, GIE::BlockEnd, 0, 0, 27, 0 }, // 28
+ { 0, GIE::BlockStart, 0, 28, 25, 0 }, // 26
+ { -1, GIE::Any, 0, 28, 0, 0 }, // 27
+ { 1, GIE::CommandStart, "vacation", 30, 27, "vacation" }, // 28
+ { -1, GIE::Any, 0, 30, 0, 0 }, // 29
+ { 0, GIE::BlockEnd, 0, 31, 29, 0 }, // 30
- { -1, GIE::Any, 0, 27, 27, 0 } // 29 end state
+ { -1, GIE::Any, 0, 31, 31, 0 } // 31 end state
};
static const unsigned int numDatesNodes = sizeof datesNodes / sizeof *datesNodes;
@@ -387,34 +397,42 @@
// command itself:
VacationCommand,
// tagged args:
- Days, Addresses, Subject
+ Days, Addresses, Subject,
+ VacationEnd,
+ IfBlock
};
public:
VacationDataExtractor();
virtual ~VacationDataExtractor();
+ bool commandFound() const { return mContext == VacationEnd; }
+ bool active() const { return mActive; }
int notificationInterval() const { return mNotificationInterval; }
const QString & messageText() const { return mMessageText; }
const QStringList & aliases() const { return mAliases; }
+ const QString &ifComment() const { return mIfComment; }
const QString &subject() const
{
return mSubject;
}
+ int lineStart() const {return mLineStart;}
+ int lineEnd() const {return mLineEnd;}
+
private:
- void commandStart( const QString & identifier );
+ void commandStart( const QString & identifier, int lineNumber );
- void commandEnd();
+ void commandEnd(int lineNumber);
- void testStart( const QString & ) {}
+ void testStart( const QString &);
void testEnd() {}
void testListStart() {}
void testListEnd() {}
- void blockStart() {}
- void blockEnd() {}
- void hashComment( const QString & ) {}
- void bracketComment( const QString & ) {}
+ void blockStart(int lineNumber);
+ void blockEnd(int lineNumber);
+ void hashComment( const QString & );
+ void bracketComment( const QString &c ) {}
void lineFeed() {}
void error( const KSieve::Error & e );
void finished();
@@ -435,10 +453,65 @@
QString mMessageText;
QString mSubject;
QStringList mAliases;
+ bool mActive;
+ bool mInIfBlock;
+ int mBlockLevel;
+ QString mIfComment;
+ int mLineStart;
+ int mLineEnd;
void reset();
};
+class RequireExtractor : public KSieve::ScriptBuilder {
+ enum Context {
+ None = 0,
+ // command itself:
+ RequireCommand,
+ EndState
+ };
+public:
+ RequireExtractor();
+ virtual ~RequireExtractor();
+
+ bool commandFound() const { return mContext == EndState; }
+ const QStringList &requirements() const { return mRequirements; }
+
+ int lineStart() const {return mLineStart;}
+ int lineEnd() const {return mLineEnd;}
+
+private:
+ void commandStart( const QString & identifier, int lineNumber );
+
+ void commandEnd(int lineNumber);
+
+ void testStart( const QString &) {}
+ void testEnd() {}
+ void testListStart() {}
+ void testListEnd() {}
+ void blockStart(int lineNumber){};
+ void blockEnd(int lineNumber){};
+ void hashComment( const QString & ) {}
+ void bracketComment( const QString & ) {}
+ void lineFeed() {}
+ void error( const KSieve::Error & e );
+ void finished();
+
+ void taggedArgument( const QString & tag ) {}
+ void numberArgument( unsigned long number, char ) {}
+
+ void stringArgument( const QString & string, bool, const QString & );
+
+ void stringListArgumentStart(){}
+ void stringListEntry( const QString & string, bool, const QString & );
+ void stringListArgumentEnd(){}
+
+private:
+ Context mContext;
+ QStringList mRequirements;
+ int mLineStart;
+ int mLineEnd;
+};
}
Index: libksieve/ksieveui/vacation/vacationscriptextractor.cpp
===================================================================
--- libksieve/ksieveui/vacation/vacationscriptextractor.cpp
+++ libksieve/ksieveui/vacation/vacationscriptextractor.cpp
@@ -22,6 +22,11 @@
: KSieve::ScriptBuilder(),
mContext( None ),
mNotificationInterval( 0 )
+ , mActive(true)
+ , mInIfBlock(false)
+ , mBlockLevel(0)
+ , mLineStart(0)
+ , mLineEnd(0)
{
kDebug();
}
@@ -31,17 +36,29 @@
}
-void VacationDataExtractor::commandStart( const QString & identifier ) {
+void VacationDataExtractor::commandStart( const QString & identifier, int lineNumber ) {
kDebug() << "( \"" << identifier <<"\" )";
+ if (identifier == QLatin1String("if") && mContext == None) {
+ mContext = IfBlock;
+ mLineStart = lineNumber;
+ mInIfBlock = true;
+ }
if ( identifier != QLatin1String("vacation") )
return;
+
+ if (mContext != IfBlock) {
+ mLineStart = lineNumber;
+ }
+
reset();
mContext = VacationCommand;
}
-void VacationDataExtractor::commandEnd() {
- kDebug();
- mContext = None;
+void VacationDataExtractor::commandEnd(int lineNumber) {
+ if ( mContext != None && mContext != IfBlock && mContext != VacationEnd) {
+ mContext = VacationEnd;
+ mLineEnd = lineNumber;
+ }
}
void VacationDataExtractor::error( const KSieve::Error & e )
@@ -54,6 +71,42 @@
}
+void VacationDataExtractor::testStart(const QString &test)
+{
+ if (mContext == IfBlock) {
+ if (test == QLatin1String("true") || test == QLatin1String("false")) {
+ mActive = (test == QLatin1String("true"));
+ mIfComment = QString();
+ kDebug() << "set active level to" << mActive;
+ }
+ }
+}
+
+void VacationDataExtractor::hashComment(const QString &comment)
+{
+ if (mContext == IfBlock) {
+ mIfComment += comment;
+ }
+}
+
+
+void VacationDataExtractor::blockStart(int lineNumber)
+{
+ mBlockLevel++;
+}
+
+void VacationDataExtractor::blockEnd(int lineNumber)
+{
+ mBlockLevel--;
+ if(mBlockLevel == 0 && !commandFound()) { //We are in main level again, and didn't found vacation in block
+ mActive = true;
+ mIfComment = QString();
+ } else if (mInIfBlock && mBlockLevel == 0 && commandFound()) {
+ mLineEnd = lineNumber;
+ mInIfBlock = false;
+ }
+}
+
void VacationDataExtractor::taggedArgument( const QString & tag )
{
kDebug() << "( \"" << tag <<"\" )";
@@ -123,3 +176,53 @@
mAliases.clear();
mMessageText.clear();
}
+
+RequireExtractor::RequireExtractor()
+ : KSieve::ScriptBuilder()
+ , mContext( None )
+ , mLineStart(0)
+ , mLineEnd(0)
+{
+
+}
+
+RequireExtractor::~RequireExtractor()
+{
+
+}
+
+void RequireExtractor::commandStart(const QString &identifier, int lineNumber)
+{
+ if (identifier == QLatin1String("require") && mContext == None) {
+ mContext = RequireCommand;
+ mLineStart = lineNumber;
+ }
+}
+
+void RequireExtractor::commandEnd(int lineNumber)
+{
+ if (mContext == RequireCommand) {
+ mContext = EndState;
+ mLineEnd = lineNumber;
+ }
+}
+
+void RequireExtractor::error(const KSieve::Error &e)
+{
+ kDebug() << e.asString() << "@" << e.line() << "," << e.column();
+}
+
+void RequireExtractor::finished()
+{
+
+}
+
+void RequireExtractor::stringArgument(const QString &string, bool, const QString &)
+{
+ mRequirements << string;
+}
+
+void RequireExtractor::stringListEntry(const QString &string, bool, const QString &)
+{
+ mRequirements << string;
+}
\ No newline at end of file
Index: libksieve/ksieveui/vacation/vacationutils.h
===================================================================
--- libksieve/ksieveui/vacation/vacationutils.h
+++ libksieve/ksieveui/vacation/vacationutils.h
@@ -40,17 +40,27 @@
QDate defaultStartDate();
QDate defaultEndDate();
-QString composeScript( const QString & messageText, const QString &subject,
+QString composeScript( const QString & messageText, bool active, const QString &subject,
int notificationInterval,
const KMime::Types::AddrSpecList & aliases,
bool sendForSpam, const QString & excludeDomain,
const QDate & startDate, const QDate & endDate );
-bool parseScript( const QString & script, QString & messageText,
+bool parseScript( const QString & script, bool &active, QString & messageText,
QString &subject,
int & notificationInterval, QStringList & aliases,
bool & sendForSpam, QString & domainName,
QDate & startDate, QDate & endDate );
+//returns if a vacation script is found in the sieve script
+bool foundVacationScript(const QString &script);
+
+// returns if the vacation script is active
+bool vacationScriptActive(const QString &script);
+
+QString mergeRequireLine(const QString &script1, const QString script2);
+
+QString updateVacationBlock(const QString &oldScript, const QString &newScript);
+
}
}
Index: libksieve/ksieveui/vacation/vacationutils.cpp
===================================================================
--- libksieve/ksieveui/vacation/vacationutils.cpp
+++ libksieve/ksieveui/vacation/vacationutils.cpp
@@ -98,13 +98,14 @@
}
-bool KSieveUi::VacationUtils::parseScript( const QString &script, QString &messageText,
+bool KSieveUi::VacationUtils::parseScript( const QString &script, bool &active, QString &messageText,
QString &subject,
int & notificationInterval, QStringList &aliases,
bool & sendForSpam, QString &domainName,
QDate & startDate, QDate & endDate )
{
if ( script.trimmed().isEmpty() ) {
+ active = false;
messageText = VacationUtils::defaultMessageText();
subject = VacationUtils::defaultSubject();
notificationInterval = VacationUtils::defaultNotificationInterval();
@@ -125,26 +126,72 @@
SpamDataExtractor sdx;
DomainRestrictionDataExtractor drdx;
DateExtractor dx;
- KSieveExt::MultiScriptBuilder tsb( &vdx, &sdx, &drdx, &dx );
+ KSieveExt::MultiScriptBuilder tsb( &vdx , &sdx, &drdx, &dx );
parser.setScriptBuilder( &tsb );
- if ( !parser.parse() )
+ parser.parse();
+ if ( !parser.parse() || !vdx.commandFound() ) {
+ active = false;
return false;
+ }
+ active = vdx.active();
messageText = vdx.messageText().trimmed();
if (!vdx.subject().isEmpty()) {
subject = vdx.subject().trimmed();
}
notificationInterval = vdx.notificationInterval();
aliases = vdx.aliases();
- if ( !VacationSettings::allowOutOfOfficeUploadButNoSettings() ) {
- sendForSpam = !sdx.found();
- domainName = drdx.domainName();
+
+ if (!active && !vdx.ifComment().isEmpty()) {
+ const QByteArray newScript = QString::fromAscii("if ").toUtf8() + vdx.ifComment().toUtf8() + QString::fromLatin1("{vacation;}").toUtf8();
+ tsb = KSieveExt::MultiScriptBuilder( &sdx, &drdx, &dx );
+ KSieve::Parser parser( newScript.begin(),
+ newScript.begin() + newScript.length() );
+ parser.setScriptBuilder( &tsb );
+ if ( !parser.parse() ) {
+ return false;
+ }
}
+
+ sendForSpam = !sdx.found();
+ domainName = drdx.domainName();
startDate = dx.startDate();
endDate = dx.endDate();
return true;
}
-QString KSieveUi::VacationUtils::composeScript( const QString & messageText,
+bool KSieveUi::VacationUtils::foundVacationScript(const QString &script)
+{
+ const QByteArray scriptUTF8 = script.trimmed().toUtf8();
+ kDebug() << "scriptUtf8 = \"" + scriptUTF8 +"\"";
+
+ if (scriptUTF8.isEmpty()) {
+ return false;
+ }
+
+ KSieve::Parser parser( scriptUTF8.begin(),
+ scriptUTF8.begin() + scriptUTF8.length() );
+ VacationDataExtractor vdx;
+ parser.setScriptBuilder(&vdx);
+ return parser.parse() && vdx.commandFound();
+}
+
+bool KSieveUi::VacationUtils::vacationScriptActive(const QString &script)
+{
+ const QByteArray scriptUTF8 = script.trimmed().toUtf8();
+ kDebug() << "scriptUtf8 = \"" + scriptUTF8 +"\"";
+
+ if (scriptUTF8.isEmpty()) {
+ return false;
+ }
+
+ KSieve::Parser parser( scriptUTF8.begin(),
+ scriptUTF8.begin() + scriptUTF8.length() );
+ VacationDataExtractor vdx;
+ parser.setScriptBuilder(&vdx);
+ return parser.parse() && vdx.commandFound() && vdx.active();
+}
+
+QString composeOldScript( const QString & messageText,
const QString &subject,
int notificationInterval,
const AddrSpecList & addrSpecs,
@@ -194,8 +241,198 @@
}
script += QString::fromLatin1("text:\n");
- script += dotstuff( messageText.isEmpty() ? VacationUtils::defaultMessageText() : messageText );
+ script += dotstuff( messageText.isEmpty() ? KSieveUi::VacationUtils::defaultMessageText() : messageText );
script += QString::fromLatin1( "\n.\n;\n" );
return script;
}
+QString KSieveUi::VacationUtils::composeScript( const QString & messageText, bool active,
+ const QString &subject,
+ int notificationInterval,
+ const AddrSpecList & addrSpecs,
+ bool sendForSpam, const QString & domain,
+ const QDate & startDate, const QDate & endDate )
+{
+ QStringList condition;
+
+ if (startDate.isValid()) {
+ condition.append(QString::fromLatin1("currentdate :value \"ge\" \"date\" \"%1\"")
+ .arg(startDate.toString(Qt::ISODate)));
+ }
+
+ if (endDate.isValid()) {
+ condition.append(QString::fromLatin1("currentdate :value \"le\" \"date\" \"%1\"")
+ .arg(endDate.toString(Qt::ISODate)));
+ }
+
+ if (!sendForSpam) {
+ condition.append(QString::fromLatin1("not header :contains \"X-Spam-Flag\" \"YES\""));
+ }
+
+ if (!domain.isEmpty()) {
+ condition.append(QString::fromLatin1("address :domain :contains \"from\" \"%1\"").arg( domain ));
+ }
+
+ QString addressesArgument;
+ QStringList aliases;
+ if ( !addrSpecs.empty() ) {
+ addressesArgument += QLatin1String(":addresses [ ");
+ QStringList sl;
+ AddrSpecList::const_iterator end = addrSpecs.constEnd();
+ for ( AddrSpecList::const_iterator it = addrSpecs.begin() ; it != end; ++it ) {
+ sl.push_back( QLatin1Char('"') + (*it).asString().replace( QLatin1Char('\\'), QLatin1String("\\\\") ).replace( QLatin1Char('"'), QLatin1String("\\\"") ) + QLatin1Char('"') );
+ aliases.push_back( (*it).asString() );
+ }
+ addressesArgument += sl.join( QLatin1String(", ") ) + QLatin1String(" ] ");
+ }
+
+ QString vacation(QLatin1String("vacation "));
+ vacation += addressesArgument;
+ if ( notificationInterval > 0 )
+ vacation += QString::fromLatin1(":days %1 ").arg(notificationInterval);
+
+ if (!subject.trimmed().isEmpty()) {
+ vacation += QString::fromLatin1(":subject \"%1\" ").arg(stringReplace(subject).trimmed());
+ }
+
+ vacation += QString::fromLatin1("text:\n");
+ vacation += dotstuff( messageText.isEmpty() ? VacationUtils::defaultMessageText() : messageText );
+ vacation += QString::fromLatin1( "\n.\n;" );
+
+ QString script;
+
+ if ( startDate.isValid() || endDate.isValid() ) {
+ script = QString::fromLatin1("require [\"vacation\", \"relational\", \"date\"];\n\n" );
+ } else {
+ script = QString::fromLatin1("require \"vacation\";\n\n" );
+ }
+
+ if (condition.count() == 0) {
+ if (active) {
+ script += vacation;
+ } else {
+ script += QString::fromLatin1("if false\n{\n\t");
+ script += vacation;
+ script += QLatin1String("\n}");
+ }
+ } else {
+ if (active) {
+ script += QString::fromLatin1("if allof(%1)\n{\n\t").arg(condition.join(QLatin1String(", ")));
+ } else {
+ script += QString::fromLatin1("if false # allof(%1)\n{\n\t").arg(condition.join(QLatin1String(", ")));
+ }
+ script += vacation;
+ script += QLatin1String("\n}");
+ }
+
+ script += QLatin1String("\n");
+
+ return script;
+}
+
+
+QString KSieveUi::VacationUtils::mergeRequireLine(const QString &script, const QString scriptUpdate)
+{
+ const QByteArray scriptUTF8 = script.trimmed().toUtf8();
+ const QByteArray scriptUpdateUTF8 = scriptUpdate.trimmed().toUtf8();
+
+ if (scriptUTF8.isEmpty()) {
+ return scriptUpdate;
+ }
+
+ if (scriptUpdateUTF8.isEmpty()) {
+ return script;
+ }
+
+ KSieve::Parser parser( scriptUTF8.begin(),
+ scriptUTF8.begin() + scriptUTF8.length() );
+ KSieve::Parser parserUpdate( scriptUpdateUTF8.begin(),
+ scriptUpdateUTF8.begin() + scriptUpdateUTF8.length() );
+ RequireExtractor rx, rxUpdate;
+ parser.setScriptBuilder(&rx);
+ parserUpdate.setScriptBuilder(&rxUpdate);
+
+ int insert(0);
+ QStringList lines = script.split(QLatin1Char('\n'));
+ QSet<QString> requirements;
+
+ if (parser.parse() && rx.commandFound()) {
+ insert = rx.lineStart();
+ const int endOld(rx.lineEnd());
+ for (int i=insert; i<=endOld; i++) {
+ lines.removeAt(insert);
+ }
+ requirements = rx.requirements().toSet();
+ }
+
+ if (parserUpdate.parse() && rxUpdate.commandFound()) {
+ requirements += rxUpdate.requirements().toSet();
+ }
+
+ if (requirements.count() > 1) {
+ QStringList req = requirements.toList();
+ req.sort();
+ lines.insert(insert, QString::fromLatin1("require [\"%1\"];").arg(req.join(QLatin1String("\", \""))));
+ } else if (requirements.count() == 1) {
+ lines.insert(insert, QString::fromLatin1("require \"%1\";").arg(requirements.toList().first()));
+ }
+
+ return lines.join(QLatin1String("\n"));
+}
+
+QString KSieveUi::VacationUtils::updateVacationBlock(const QString &oldScript, const QString &newScript)
+{
+ const QByteArray oldScriptUTF8 = oldScript.trimmed().toUtf8();
+ const QByteArray newScriptUTF8 = newScript.trimmed().toUtf8();
+
+ if (oldScriptUTF8.isEmpty()) {
+ return newScript;
+ }
+
+ if (newScriptUTF8.isEmpty()) {
+ return oldScript;
+ }
+
+ KSieve::Parser parserOld( oldScriptUTF8.begin(),
+ oldScriptUTF8.begin() + oldScriptUTF8.length() );
+ KSieve::Parser parserNew( newScriptUTF8.begin(),
+ newScriptUTF8.begin() + newScriptUTF8.length() );
+ VacationDataExtractor vdxOld, vdxNew;
+ RequireExtractor rx;
+ KSieveExt::MultiScriptBuilder tsb( &vdxOld , &rx );
+ parserOld.setScriptBuilder(&tsb);
+ parserNew.setScriptBuilder(&vdxNew);
+
+ int startOld(0);
+
+ int startNew(vdxNew.lineStart());
+ int endNew(vdxNew.lineEnd());
+
+ QStringList lines = oldScript.split(QLatin1Char('\n'));
+
+ QString script;
+ if (parserOld.parse() && vdxOld.commandFound()) {
+ startOld = vdxOld.lineStart();
+ const int endOld(vdxOld.lineEnd());
+ for (int i=startOld; i<=endOld; i++) {
+ lines.removeAt(startOld);
+ }
+ } else {
+ if (rx.commandFound()) { // after require
+ startOld = rx.lineEnd() + 1;
+ } else {
+ startOld = 0;
+ }
+ }
+
+ if (parserNew.parse() && vdxNew.commandFound()) {
+ const int startNew(vdxNew.lineStart());
+ const int endNew(vdxNew.lineEnd());
+ QStringList linesNew = newScript.split(QLatin1Char('\n'));
+ for(int i=endNew;i>=startNew;i--) {
+ lines.insert(startOld, linesNew.at(i));
+ }
+ }
+
+ return lines.join(QLatin1String("\n"));
+}
Index: libksieve/ksieveui/widgets/managesievewidget.h
===================================================================
--- libksieve/ksieveui/widgets/managesievewidget.h
+++ libksieve/ksieveui/widgets/managesievewidget.h
@@ -35,6 +35,7 @@
namespace KSieveUi {
class ManageSieveTreeView;
+class ParseUserScriptJob;
class KSIEVEUI_EXPORT ManageSieveWidget : public QWidget
{
Q_OBJECT
@@ -65,6 +66,7 @@
void slotDoubleClicked(QTreeWidgetItem *item);
void slotSystemNetworkStatusChanged(Solid::Networking::Status status);
void slotCheckNetworkStatus();
+ void setActiveScripts(ParseUserScriptJob *job);
public Q_SLOTS:
void slotGotList(KManageSieve::SieveJob *job, bool success, const QStringList &listScript, const QString &activeScript);
@@ -91,8 +93,6 @@
bool isFileNameItem(QTreeWidgetItem *item) const;
bool itemIsActived(QTreeWidgetItem *item) const;
void changeActiveScript(QTreeWidgetItem *item, bool activate);
- bool isProtectedName(const QString &name);
-
// Maps top-level items to their child which has the radio button selection
QMap<QTreeWidgetItem*,QTreeWidgetItem*> mSelectedItems;
Index: libksieve/ksieveui/widgets/managesievewidget.cpp
===================================================================
--- libksieve/ksieveui/widgets/managesievewidget.cpp
+++ libksieve/ksieveui/widgets/managesievewidget.cpp
@@ -21,6 +21,9 @@
#include <kmanagesieve/sievejob.h>
+#include <managescriptsjob/parseuserscriptjob.h>
+#include <managescriptsjob/generateglobalscriptjob.h>
+#include <util/util.h>
#include <KInputDialog>
#include <KStandardGuiItem>
@@ -31,8 +34,11 @@
#include <QMenu>
#include <QTimer>
#include <QDebug>
+#include <qmetatype.h>
using namespace KSieveUi;
+Q_DECLARE_METATYPE(QTreeWidgetItem*)
+
ManageSieveWidget::ManageSieveWidget(QWidget *parent)
: QWidget(parent),
mClearAll( false ),
@@ -174,7 +180,7 @@
if ( !ok || name.isEmpty() )
return;
- if (isProtectedName(name.toLower())) {
+ if (Util::isKep14ProtectedName(name)) {
KMessageBox::error(this, i18n("You cannot use protected name."), i18n("New Script"));
return;
}
@@ -245,11 +251,27 @@
KUrl u = mUrls[item];
if ( u.isEmpty() )
return;
+
+ if (item->data(0, SIEVE_SERVER_MODE).toInt() == Kep14EditorMode) {
+ QStringList activeScripts;
+ for(int i=0; i < item->childCount(); i++) {
+ QTreeWidgetItem *j = item->child(i);
+ if (itemIsActived(j)) {
+ activeScripts << j->text(0);
+ }
+ }
+ GenerateGlobalScriptJob *job = new GenerateGlobalScriptJob(u);
+ job->addUserActiveScripts(activeScripts);
+ connect( job, SIGNAL(success()), SLOT(slotRefresh()));
+ connect( job, SIGNAL(error(QString)), SLOT(slotRefresh()));
+ job->start();
+ return;
+ }
+
QTreeWidgetItem* selected = mSelectedItems[item];
if ( !selected )
return;
u.setFileName( selected->text(0) );
-
KManageSieve::SieveJob * job;
if ( activate )
job = KManageSieve::SieveJob::activate( u );
@@ -311,16 +333,6 @@
Q_EMIT scriptDeleted(u);
}
-bool ManageSieveWidget::isProtectedName(const QString &name)
-{
- if (name == QLatin1String("master") ||
- name == QLatin1String("user") ||
- name == QLatin1String("management")) {
- return true;
- }
- return false;
-}
-
void ManageSieveWidget::slotRefresh()
{
mBlockSignal = true;
@@ -342,9 +354,7 @@
qDebug()<<"void ManageSieveWidget::slotGotList(KManageSieve::SieveJob *job, bool success, const QStringList &listScript, const QString &activeScript) success: "<<success<<" listScript"<<listScript;
if (mClearAll)
return;
- qDebug()<<" After mClear All";
QTreeWidgetItem * parent = mJobs[job];
- qDebug()<<" parent "<<parent;
if ( !parent )
return;
(static_cast<SieveTreeWidgetItem*>(parent))->stopAnimation();
@@ -364,8 +374,7 @@
mBlockSignal = true; // don't trigger slotItemChanged
Q_FOREACH (const QString &script, listScript) {
//Hide protected name.
- const QString lowerScript(script.toLower());
- if (isProtectedName(lowerScript))
+ if (Util::isKep14ProtectedName(script))
continue;
QTreeWidgetItem* item = new QTreeWidgetItem( parent );
item->setFlags(item->flags() & (Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable));
@@ -379,20 +388,60 @@
}
mBlockSignal = false;
- qDebug()<<" LOAD";
- const bool hasIncludeCapability = job->sieveCapabilities().contains(QLatin1String("include"));
- const bool hasUserActiveScript = (activeScript.toLower() == QLatin1String("USER"));
- QStringList mUserActiveScriptList;
- if (hasUserActiveScript && hasIncludeCapability) {
- //TODO parse file.
+ const bool hasKep14EditorMode = Util::hasKep14Support(job->sieveCapabilities(), listScript, activeScript);
+ if (hasKep14EditorMode) {
+ KUrl u = mUrls[parent];
+ u.setFileName(QLatin1String("USER"));
+ ParseUserScriptJob *parseJob = new ParseUserScriptJob(u);
+ parseJob->setProperty(QLatin1String("parentItem").latin1(), QVariant::fromValue<QTreeWidgetItem*>(parent));
+ connect(parseJob, SIGNAL(finished(ParseUserScriptJob*)), SLOT(setActiveScripts(ParseUserScriptJob*)));
+ parseJob->start();
+ (static_cast<SieveTreeWidgetItem*>(parent))->startAnimation();
}
parent->setData( 0, SIEVE_SERVER_CAPABILITIES, job->sieveCapabilities() );
parent->setData( 0, SIEVE_SERVER_ERROR, false );
- parent->setData( 0, SIEVE_SERVER_MODE, hasIncludeCapability ? Kep14EditorMode : NormalEditorMode);
+ parent->setData( 0, SIEVE_SERVER_MODE, hasKep14EditorMode ? Kep14EditorMode : NormalEditorMode);
mTreeView->expandItem( parent );
}
+void ManageSieveWidget::setActiveScripts(ParseUserScriptJob *job)
+{
+ QTreeWidgetItem * parent = job->property(QLatin1String("parentItem").latin1()).value<QTreeWidgetItem*>();
+ if ( !parent ) {
+ return;
+ }
+ (static_cast<SieveTreeWidgetItem*>(parent))->stopAnimation();
+
+ if (!job->error().isEmpty()) {
+ qWarning() << job->error();
+ return;
+ }
+
+ mBlockSignal = true; // don't trigger slotItemChanged
+ const QStringList activeScriptList = job->activeScriptList();
+ QStringList scriptOrder = activeScriptList;
+ QMap<QString, QTreeWidgetItem*> scriptMap;
+
+ const int children = parent->childCount();
+ for(int i=0; i < children; i++) {
+ QTreeWidgetItem *item = parent->takeChild(0);
+ scriptMap.insert(item->text(0), item);
+ const bool isActive = activeScriptList.contains(item->text(0));
+ item->setCheckState(0, isActive ? Qt::Checked : Qt::Unchecked);
+ if (!isActive) {
+ scriptOrder << item->text(0);
+ }
+ }
+
+ foreach(const QString &scriptName, scriptOrder) {
+ parent->addChild(scriptMap[scriptName]);
+ }
+
+ mBlockSignal = false;
+}
+
+
void ManageSieveWidget::slotDoubleClicked( QTreeWidgetItem * item )
{
if ( !isFileNameItem( item ) )
Index: libksieve/parser/lexer.cpp
===================================================================
--- libksieve/parser/lexer.cpp
+++ libksieve/parser/lexer.cpp
@@ -161,7 +161,7 @@
#endif
static QString removeCRLF( const QString & s ) {
const bool CRLF = s.endsWith( QLatin1String("\r\n") );
- const bool LF = !CRLF && s.endsWith( '\n' );
+ const bool LF = !CRLF && s.endsWith( QLatin1Char('\n') );
const int e = CRLF ? 2 : LF ? 1 : 0 ; // what to chop off at the end
@@ -255,7 +255,7 @@
case ')':
case ';':
case ',': // Special
- result = *mState.cursor++;
+ result = QLatin1Char(*mState.cursor++);
return Special;
case '0':
case '1':
@@ -401,7 +401,7 @@
}
if ( reallySave ) {
QString tmp = QString::fromUtf8( commentStart, commentLength );
- result += tmp.remove( '\r' ); // get rid of CR in CRLF pairs
+ result += tmp.remove( QLatin1Char('\r') ); // get rid of CR in CRLF pairs
}
}
@@ -505,7 +505,7 @@
assert( isdigit( *mState.cursor ) );
while ( !atEnd() && isdigit( *mState.cursor ) )
- result += *mState.cursor++;
+ result += QLatin1Char(*mState.cursor++);
if ( atEnd() || isDelim( *mState.cursor ) )
return true;
@@ -517,7 +517,7 @@
case 'm':
case 'K':
case 'k':
- result += *mState.cursor++;
+ result += QLatin1Char(*mState.cursor++);
break;
default:
makeIllegalCharError();
@@ -589,21 +589,21 @@
}
const QString line = removeCRLF( QString::fromUtf8( oldBeginOfLine, lineLength ) );
lines.push_back( removeDotStuff( line ) );
- if ( line == "." )
+ if ( line == QLatin1String(".") )
break;
} else {
lines.push_back( QString() );
}
}
- if ( lines.back() != "." ) {
+ if ( lines.back() != QLatin1String(".") ) {
makeError( Error::PrematureEndOfMultiLine, mlBeginLine, mlBeginCol );
return false;
}
assert( !lines.empty() );
lines.erase( --lines.end() ); // don't include the lone dot.
- result = lines.join("\n");
+ result = lines.join(QLatin1String("\n"));
return true;
}
@@ -630,7 +630,7 @@
case '\n':
if ( !eatCRLF() )
return false;
- result += '\n';
+ result += QLatin1Char('\n');
break;
case '\\':
++mState.cursor;
@@ -639,7 +639,7 @@
// else fall through:
default:
if ( !is8Bit( *mState.cursor ) )
- result += *mState.cursor++;
+ result += QLatin1Char(*mState.cursor++);
else { // probably UTF-8
const char * const eightBitBegin = mState.cursor;
skipTo8BitEnd();
Index: libksieve/parser/parser.cpp
===================================================================
--- libksieve/parser/parser.cpp
+++ libksieve/parser/parser.cpp
@@ -42,6 +42,8 @@
#include <limits.h> // ULONG_MAX
#include <ctype.h> // isdigit
+#include <KDebug>
+
namespace KSieve {
//
@@ -130,7 +132,7 @@
return isStringToken() ||
token() == Lexer::Number ||
token() == Lexer::Tag ||
- ( token() == Lexer::Special && mTokenValue == "[" );
+ ( token() == Lexer::Special && mTokenValue == QLatin1String("[")) ;
}
bool Parser::Impl::obtainToken() {
@@ -218,8 +220,9 @@
if ( !obtainToken() || token() != Lexer::Identifier )
return false;
- if ( scriptBuilder() )
- scriptBuilder()->commandStart( tokenValue() );
+ if ( scriptBuilder() ) {
+ scriptBuilder()->commandStart( tokenValue(), lexer.line() );
+ }
consumeToken();
//
@@ -251,7 +254,7 @@
return false;
}
- if ( token() == Lexer::Special && tokenValue() == "(" ) { // test-list
+ if ( token() == Lexer::Special && tokenValue() == QLatin1String ("(")) { // test-list
if ( !parseTestList() ) {
assert( error() );
return false;
@@ -280,9 +283,9 @@
return false;
}
- if ( tokenValue() == ";" )
+ if ( tokenValue() == QLatin1String (";"))
consumeToken();
- else if ( tokenValue() == "{" ) { // block
+ else if ( tokenValue() == QLatin1String ("{")) { // block
if ( !parseBlock() )
return false; // it's an error since we saw '{'
} else {
@@ -290,8 +293,9 @@
return false;
}
- if ( scriptBuilder() )
- scriptBuilder()->commandEnd();
+ if ( scriptBuilder() ) {
+ scriptBuilder()->commandEnd(lexer.line());
+ }
return true;
}
@@ -334,7 +338,7 @@
scriptBuilder()->stringArgument( tokenValue(), token() == Lexer::MultiLineString, QString() );
consumeToken();
return true;
- } else if ( token() == Lexer::Special && tokenValue() == "[" ) {
+ } else if ( token() == Lexer::Special && tokenValue() == QLatin1String("[")) {
if ( !parseStringList() ) {
assert( error() );
return false;
@@ -352,7 +356,7 @@
if ( !obtainToken() || atEnd() )
return false;
- if ( token() != Lexer::Special || tokenValue() != "(" )
+ if ( token() != Lexer::Special || tokenValue() != QLatin1String("("))
return false;
if ( scriptBuilder() )
scriptBuilder()->testListStart();
@@ -462,7 +466,7 @@
if ( atEnd() ) // a test w/o nested tests
goto TestEnd;
- if ( token() == Lexer::Special && tokenValue() == "(" ) { // test-list
+ if ( token() == Lexer::Special && tokenValue() == QLatin1String("(")) { // test-list
if ( !parseTestList() ) {
assert( error() );
return false;
@@ -488,10 +492,10 @@
if ( !obtainToken() || atEnd() )
return false;
- if ( token() != Lexer::Special || tokenValue() != "{" )
+ if ( token() != Lexer::Special || tokenValue() != QLatin1String("{"))
return false;
if ( scriptBuilder() )
- scriptBuilder()->blockStart();
+ scriptBuilder()->blockStart(lexer.line());
consumeToken();
if ( !obtainToken() )
@@ -517,12 +521,12 @@
return false;
}
- if ( token() != Lexer::Special || tokenValue() != "}" ) {
+ if ( token() != Lexer::Special || tokenValue() != QLatin1String("}")) {
makeError( Error::NonCommandInCommandList );
return false;
}
if ( scriptBuilder() )
- scriptBuilder()->blockEnd();
+ scriptBuilder()->blockEnd(lexer.line());
consumeToken();
return true;
}
@@ -538,7 +542,7 @@
if ( !obtainToken() || atEnd() )
return false;
- if ( token() != Lexer::Special || tokenValue() != "[" )
+ if ( token() != Lexer::Special || tokenValue() != QLatin1String("[") )
return false;
if ( scriptBuilder() )
@@ -619,7 +623,7 @@
int i = 0;
const QByteArray s = tokenValue().toLatin1();
for ( const int len = s.length() ; i < len && isdigit( s[i] ) ; ++i ) {
- const unsigned long digitValue = s[i] - '0' ;
+ const unsigned long digitValue = s[i] - QLatin1Char('0').toLatin1() ;
if ( willOverflowULong( result, digitValue ) ) {
makeError( Error::NumberOutOfRange );
return false;
Index: libksieve/tests/parsertest.cpp
===================================================================
--- libksieve/tests/parsertest.cpp
+++ libksieve/tests/parsertest.cpp
@@ -400,12 +400,12 @@
const QString txt = "number" + ( quantifier ? QString(" quantifier=\"%1\"").arg( quantifier ) : QString() ) ;
write( txt.toLatin1(), QString::number( number ) );
}
- void commandStart( const QString & identifier ) {
+ void commandStart( const QString & identifier, int lineNumber) {
write( "<command>" );
++indent;
write( "identifier", identifier );
}
- void commandEnd() {
+ void commandEnd(int lineNumber) {
--indent;
write( "</command>" );
}
@@ -426,11 +426,11 @@
--indent;
write( "</testlist>" );
}
- void blockStart() {
+ void blockStart(int lineNumber) {
write( "<block>" );
++indent;
}
- void blockEnd() {
+ void blockEnd(int lineNumber) {
--indent;
write( "</block>" );
}
@@ -515,12 +515,12 @@
checkEquals( QString::number( number ) + ( quantifier ? quantifier : ' ' ) );
++mNextResponse;
}
- void commandStart( const QString & identifier ) {
+ void commandStart( const QString & identifier, int lineNumber ) {
checkIs( CommandStart );
checkEquals( identifier );
++mNextResponse;
}
- void commandEnd() {
+ void commandEnd(int lineNumber) {
checkIs( CommandEnd );
++mNextResponse;
}
@@ -541,11 +541,11 @@
checkIs( TestListEnd );
++mNextResponse;
}
- void blockStart() {
+ void blockStart(int lineNumber) {
checkIs( BlockStart );
++mNextResponse;
}
- void blockEnd() {
+ void blockEnd(int lineNumber) {
checkIs( BlockEnd );
++mNextResponse;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 5, 5:14 PM (5 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10179219
Default Alt Text
D31.id61.diff (132 KB)
Attached To
Mode
D31: Support KEP:14 in sieveeditor
Attached
Detach File
Event Timeline
Log In to Comment