Branch 'dev/sieve_kep14' - 2 commits - libksieve/ksieve libksieve/ksieveui libksieve/parser libksieve/tests
Sandro Knauß
knauss at kolabsys.com
Wed Mar 25 21:46:14 CET 2015
libksieve/ksieve/scriptbuilder.h | 8
libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp | 8
libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h | 8
libksieve/ksieveui/vacation/multiimapvacationmanager.cpp | 12
libksieve/ksieveui/vacation/multiimapvacationmanager.h | 2
libksieve/ksieveui/vacation/tests/vacationutilstest.cpp | 155 +++++++
libksieve/ksieveui/vacation/tests/vacationutilstest.h | 4
libksieve/ksieveui/vacation/vacation.cpp | 4
libksieve/ksieveui/vacation/vacationcreatescriptjob.cpp | 50 ++
libksieve/ksieveui/vacation/vacationcreatescriptjob.h | 6
libksieve/ksieveui/vacation/vacationmanager.cpp | 1
libksieve/ksieveui/vacation/vacationpagewidget.cpp | 8
libksieve/ksieveui/vacation/vacationscriptextractor.cpp | 78 +++-
libksieve/ksieveui/vacation/vacationscriptextractor.h | 154 +++++--
libksieve/ksieveui/vacation/vacationutils.cpp | 195 +++++++++-
libksieve/ksieveui/vacation/vacationutils.h | 6
libksieve/parser/parser.cpp | 16
libksieve/tests/parsertest.cpp | 16
18 files changed, 627 insertions(+), 104 deletions(-)
New commits:
commit b3c0476b3e499cca5d63281ed01e9975ac0ca1a8
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Mar 25 21:45:01 2015 +0100
Sieve: Adding write support
diff --git a/libksieve/ksieve/scriptbuilder.h b/libksieve/ksieve/scriptbuilder.h
index 9d95b36..7b08ebf 100644
--- a/libksieve/ksieve/scriptbuilder.h
+++ b/libksieve/ksieve/scriptbuilder.h
@@ -51,8 +51,8 @@ namespace KSieve {
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 @@ namespace KSieve {
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;
diff --git a/libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp b/libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp
index 0fa9c34..65c382c 100644
--- a/libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp
+++ b/libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp
@@ -50,7 +50,7 @@ void XMLPrintingScriptBuilder::numberArgument( unsigned long number, char quanti
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::commandStart( const QString &identifier )
}
}
-void XMLPrintingScriptBuilder::commandEnd()
+void XMLPrintingScriptBuilder::commandEnd(int lineNumber)
{
if (mIsAction) {
write( QLatin1String("</action>") );
@@ -96,12 +96,12 @@ void XMLPrintingScriptBuilder::testListEnd()
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>") );
}
diff --git a/libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h b/libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h
index 7435647..2e4cb52 100644
--- a/libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h
+++ b/libksieve/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h
@@ -33,14 +33,14 @@ public:
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 );
diff --git a/libksieve/ksieveui/vacation/multiimapvacationmanager.cpp b/libksieve/ksieveui/vacation/multiimapvacationmanager.cpp
index f27fdd3..6d6e12d 100644
--- a/libksieve/ksieveui/vacation/multiimapvacationmanager.cpp
+++ b/libksieve/ksieveui/vacation/multiimapvacationmanager.cpp
@@ -27,6 +27,8 @@
#include <KMessageBox>
#include <KLocalizedString>
+#include <KDebug>
+
using namespace KSieveUi;
MultiImapVacationManager::MultiImapVacationManager(QObject *parent)
: QObject(parent),
@@ -121,3 +123,13 @@ void MultiImapVacationManager::slotCheckKep14Ended(CheckKep14SupportJob *job, bo
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;
+}
diff --git a/libksieve/ksieveui/vacation/multiimapvacationmanager.h b/libksieve/ksieveui/vacation/multiimapvacationmanager.h
index aee0c83..ca46b38 100644
--- a/libksieve/ksieveui/vacation/multiimapvacationmanager.h
+++ b/libksieve/ksieveui/vacation/multiimapvacationmanager.h
@@ -39,6 +39,8 @@ public:
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 scriptAvailable(const QString &serverName, const QStringList &sieveCapabilities, const QString &scriptName, const QString &script, bool active);
diff --git a/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp b/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp
index 555841e..f0cb13d 100644
--- a/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp
+++ b/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp
@@ -245,3 +245,59 @@ void VacationUtilsTest::testWriteSimpleScript()
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;") );
+}
diff --git a/libksieve/ksieveui/vacation/tests/vacationutilstest.h b/libksieve/ksieveui/vacation/tests/vacationutilstest.h
index c2fcdc8..41e3e03 100644
--- a/libksieve/ksieveui/vacation/tests/vacationutilstest.h
+++ b/libksieve/ksieveui/vacation/tests/vacationutilstest.h
@@ -34,6 +34,8 @@ private Q_SLOTS:
void testParseScriptComplex();
void testWriteScript();
void testWriteSimpleScript();
+ void testUpdateVacationBlock();
+ void testMergeRequireLine();
};
}
#endif // VACATIONUTILSTEST_H
diff --git a/libksieve/ksieveui/vacation/vacationcreatescriptjob.cpp b/libksieve/ksieveui/vacation/vacationcreatescriptjob.cpp
index 6d31678..1ccd9c1 100644
--- a/libksieve/ksieveui/vacation/vacationcreatescriptjob.cpp
+++ b/libksieve/ksieveui/vacation/vacationcreatescriptjob.cpp
@@ -16,6 +16,7 @@
*/
#include "vacationcreatescriptjob.h"
+#include "vacationutils.h"
#include <kmanagesieve/sievejob.h>
#include <KMessageBox>
@@ -29,6 +30,7 @@ VacationCreateScriptJob::VacationCreateScriptJob(QObject *parent)
mActivate(false),
mWasActive(false),
mSieveJob(0)
+ , mKep14Support(false)
{
}
@@ -49,6 +51,26 @@ void VacationCreateScriptJob::setServerName(const QString &servername)
mServerName = servername;
}
+const QString &VacationCreateScriptJob::serverName() const
+{
+ return mServerName;
+}
+
+void VacationCreateScriptJob::setKep14Support(bool kep14Support)
+{
+ mKep14Support = kep14Support;
+}
+
+void VacationCreateScriptJob::setServerUrl(const KUrl &url)
+{
+ mUrl = url;
+}
+
+void VacationCreateScriptJob::setScript(const QString &script)
+{
+ mScript = script;
+}
+
void VacationCreateScriptJob::start()
{
if (mUrl.isEmpty()) {
@@ -56,7 +78,24 @@ void VacationCreateScriptJob::start()
deleteLater();
return;
}
- mSieveJob = KManageSieve::SieveJob::put( mUrl, mScript, mActivate, mWasActive );
+ mSieveJob = KManageSieve::SieveJob::get(mUrl);
+ mSieveJob->setInteractive(false);
+ connect(mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
+ SLOT(slotGetScript(KManageSieve::SieveJob*,bool,QString,bool)));
+}
+
+void VacationCreateScriptJob::slotGetScript(KManageSieve::SieveJob *job, bool success, const QString &oldScript, bool active)
+{
+ 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
+ }
if ( mActivate )
connect( mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)),
SLOT(slotPutActiveResult(KManageSieve::SieveJob*,bool)) );
@@ -65,15 +104,6 @@ void VacationCreateScriptJob::start()
SLOT(slotPutInactiveResult(KManageSieve::SieveJob*,bool)) );
}
-void VacationCreateScriptJob::setServerUrl(const KUrl &url)
-{
- mUrl = url;
-}
-
-void VacationCreateScriptJob::setScript(const QString &script)
-{
- mScript = script;
-}
void VacationCreateScriptJob::slotPutActiveResult( KManageSieve::SieveJob * job, bool success )
{
diff --git a/libksieve/ksieveui/vacation/vacationcreatescriptjob.h b/libksieve/ksieveui/vacation/vacationcreatescriptjob.h
index c23584e..0172d63 100644
--- a/libksieve/ksieveui/vacation/vacationcreatescriptjob.h
+++ b/libksieve/ksieveui/vacation/vacationcreatescriptjob.h
@@ -41,7 +41,11 @@ public:
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);
+ QString updateVacationBlock(QString oldScript, QString mScript);
+ QString mergeRequireLine(QString oldScript, QString mScript);
Q_SIGNALS:
void result(bool);
@@ -50,6 +54,7 @@ Q_SIGNALS:
private slots:
void slotPutActiveResult(KManageSieve::SieveJob *job, bool success);
void slotPutInactiveResult(KManageSieve::SieveJob *job, bool success);
+ void slotGetScript(KManageSieve::SieveJob *job, bool success, const QString &oldScript, bool active);
private:
void handlePutResult(KManageSieve::SieveJob *, bool success, bool activated);
@@ -58,6 +63,7 @@ private:
QString mServerName;
bool mActivate;
bool mWasActive;
+ bool mKep14Support;
KManageSieve::SieveJob *mSieveJob;
};
}
diff --git a/libksieve/ksieveui/vacation/vacationmanager.cpp b/libksieve/ksieveui/vacation/vacationmanager.cpp
index 6cad984..becf6f2 100644
--- a/libksieve/ksieveui/vacation/vacationmanager.cpp
+++ b/libksieve/ksieveui/vacation/vacationmanager.cpp
@@ -94,6 +94,7 @@ void VacationManager::slotDialogOk()
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();
diff --git a/libksieve/ksieveui/vacation/vacationpagewidget.cpp b/libksieve/ksieveui/vacation/vacationpagewidget.cpp
index 1a0aa9a..c26d0f3 100644
--- a/libksieve/ksieveui/vacation/vacationpagewidget.cpp
+++ b/libksieve/ksieveui/vacation/vacationpagewidget.cpp
@@ -118,6 +118,8 @@ void VacationPageWidget::slotGetResult(const QString &serverName, const QStringL
return;
}
+ mUrl.setFileName(scriptName);
+
// Whether the server supports the "date" extension
const bool supportsSieveDate = mUrl.protocol() == QLatin1String("sieve") && sieveCapabilities.contains(QLatin1String("date"));
@@ -137,7 +139,7 @@ void VacationPageWidget::slotGetResult(const QString &serverName, const QStringL
mVacationWarningWidget->setVisible(true);
}
- mWasActive = active && scriptActive;
+ mWasActive = active;
mVacationEditWidget->setEnabled(true);
mVacationEditWidget->setActivateVacation( active && scriptActive );
mVacationEditWidget->setMessageText( messageText );
diff --git a/libksieve/ksieveui/vacation/vacationscriptextractor.cpp b/libksieve/ksieveui/vacation/vacationscriptextractor.cpp
index 4648058..7e029d2 100644
--- a/libksieve/ksieveui/vacation/vacationscriptextractor.cpp
+++ b/libksieve/ksieveui/vacation/vacationscriptextractor.cpp
@@ -25,6 +25,8 @@ VacationDataExtractor::VacationDataExtractor()
, mActive(true)
, mInIfBlock(false)
, mBlockLevel(0)
+ , mLineStart(0)
+ , mLineEnd(0)
{
kDebug();
}
@@ -34,21 +36,28 @@ VacationDataExtractor::~VacationDataExtractor()
}
-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();
- if ( mContext != None && mContext != IfBlock ) {
+void VacationDataExtractor::commandEnd(int lineNumber) {
+ if ( mContext != None && mContext != IfBlock && mContext != VacationEnd) {
mContext = VacationEnd;
+ mLineEnd = lineNumber;
}
}
@@ -81,21 +90,20 @@ void VacationDataExtractor::hashComment(const QString &comment)
}
-void VacationDataExtractor::blockStart()
+void VacationDataExtractor::blockStart(int lineNumber)
{
- if (mContext == IfBlock) {
- mContext = None;
- }
mBlockLevel++;
}
-void VacationDataExtractor::blockEnd()
+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();
- kDebug() << "Reset active level";
+ } else if (mInIfBlock && mBlockLevel == 0 && commandFound()) {
+ mLineEnd = lineNumber;
+ mInIfBlock = false;
}
}
@@ -168,3 +176,53 @@ void VacationDataExtractor::reset()
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
diff --git a/libksieve/ksieveui/vacation/vacationscriptextractor.h b/libksieve/ksieveui/vacation/vacationscriptextractor.h
index 851221c..1812ada 100644
--- a/libksieve/ksieveui/vacation/vacationscriptextractor.h
+++ b/libksieve/ksieveui/vacation/vacationscriptextractor.h
@@ -80,14 +80,14 @@ private:
#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 @@ public:
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 @@ private:
doProcess( method, string );
}
}
- void commandStart( const QString & identifier ) { kDebug() << identifier ; process( CommandStart, identifier ); }
- void commandEnd() { kDebug() ; process( CommandEnd ); }
+ 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;
@@ -415,19 +417,22 @@ public:
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 testEnd() {}
void testListStart() {}
void testListEnd() {}
- void blockStart();
- void blockEnd();
+ void blockStart(int lineNumber);
+ void blockEnd(int lineNumber);
void hashComment( const QString & );
- void bracketComment( const QString & ) {}
+ void bracketComment( const QString &c ) {}
void lineFeed() {}
void error( const KSieve::Error & e );
void finished();
@@ -452,10 +457,61 @@ private:
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;
+};
}
diff --git a/libksieve/ksieveui/vacation/vacationutils.cpp b/libksieve/ksieveui/vacation/vacationutils.cpp
index 9c5c509..806600d 100644
--- a/libksieve/ksieveui/vacation/vacationutils.cpp
+++ b/libksieve/ksieveui/vacation/vacationutils.cpp
@@ -313,3 +313,110 @@ QString KSieveUi::VacationUtils::composeScript( const QString & messageText, boo
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"));
+}
diff --git a/libksieve/ksieveui/vacation/vacationutils.h b/libksieve/ksieveui/vacation/vacationutils.h
index a07ebfe..d6b8c6f 100644
--- a/libksieve/ksieveui/vacation/vacationutils.h
+++ b/libksieve/ksieveui/vacation/vacationutils.h
@@ -53,6 +53,10 @@ bool parseScript( const QString & script, bool &active, QString & messageText,
bool foundVacationScript(const QString & script);
+QString mergeRequireLine(const QString &script1, const QString script2);
+
+QString updateVacationBlock(const QString &oldScript, const QString &newScript);
+
}
}
diff --git a/libksieve/parser/parser.cpp b/libksieve/parser/parser.cpp
index 3562452..df9ad7c 100644
--- a/libksieve/parser/parser.cpp
+++ b/libksieve/parser/parser.cpp
@@ -42,6 +42,8 @@
#include <limits.h> // ULONG_MAX
#include <ctype.h> // isdigit
+#include <KDebug>
+
namespace KSieve {
//
@@ -218,8 +220,9 @@ bool Parser::Impl::parseCommand() {
if ( !obtainToken() || token() != Lexer::Identifier )
return false;
- if ( scriptBuilder() )
- scriptBuilder()->commandStart( tokenValue() );
+ if ( scriptBuilder() ) {
+ scriptBuilder()->commandStart( tokenValue(), lexer.line() );
+ }
consumeToken();
//
@@ -290,8 +293,9 @@ bool Parser::Impl::parseCommand() {
return false;
}
- if ( scriptBuilder() )
- scriptBuilder()->commandEnd();
+ if ( scriptBuilder() ) {
+ scriptBuilder()->commandEnd(lexer.line());
+ }
return true;
}
@@ -491,7 +495,7 @@ bool Parser::Impl::parseBlock() {
if ( token() != Lexer::Special || tokenValue() != QLatin1String("{"))
return false;
if ( scriptBuilder() )
- scriptBuilder()->blockStart();
+ scriptBuilder()->blockStart(lexer.line());
consumeToken();
if ( !obtainToken() )
@@ -522,7 +526,7 @@ bool Parser::Impl::parseBlock() {
return false;
}
if ( scriptBuilder() )
- scriptBuilder()->blockEnd();
+ scriptBuilder()->blockEnd(lexer.line());
consumeToken();
return true;
}
diff --git a/libksieve/tests/parsertest.cpp b/libksieve/tests/parsertest.cpp
index 57660c8..82eb8e1 100644
--- a/libksieve/tests/parsertest.cpp
+++ b/libksieve/tests/parsertest.cpp
@@ -400,12 +400,12 @@ public:
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 @@ public:
--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 @@ public:
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 @@ public:
checkIs( TestListEnd );
++mNextResponse;
}
- void blockStart() {
+ void blockStart(int lineNumber) {
checkIs( BlockStart );
++mNextResponse;
}
- void blockEnd() {
+ void blockEnd(int lineNumber) {
checkIs( BlockEnd );
++mNextResponse;
}
commit b774a4f30288b3d3f56fc5914c30a3b3dafc7855
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Mar 25 12:54:18 2015 +0100
Fix compose sieve script.
diff --git a/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp b/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp
index 876fcb5..555841e 100644
--- a/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp
+++ b/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp
@@ -17,6 +17,8 @@
#include "vacationutilstest.h"
#include "vacation/vacationutils.h"
+#include <kmime/kmime_header_parsing.h>
+
#include <QFile>
#include <qtest_kde.h>
#include <KDebug>
@@ -148,5 +150,98 @@ void VacationUtilsTest::testParseScriptComplex()
QCOMPARE(sendForSpam, false);
QCOMPARE(domainName, QString());
QCOMPARE(startDate, QDate(2015, 01, 02));
- QCOMPARE(endDate, QDate(2015,03,04));
-}
\ No newline at end of file
+ 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 at 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);
+}
diff --git a/libksieve/ksieveui/vacation/tests/vacationutilstest.h b/libksieve/ksieveui/vacation/tests/vacationutilstest.h
index eac4378..c2fcdc8 100644
--- a/libksieve/ksieveui/vacation/tests/vacationutilstest.h
+++ b/libksieve/ksieveui/vacation/tests/vacationutilstest.h
@@ -32,6 +32,8 @@ private Q_SLOTS:
void testParseScript_data();
void testParseScript();
void testParseScriptComplex();
+ void testWriteScript();
+ void testWriteSimpleScript();
};
}
#endif // VACATIONUTILSTEST_H
diff --git a/libksieve/ksieveui/vacation/vacation.cpp b/libksieve/ksieveui/vacation/vacation.cpp
index a886fcf..0fe799a 100644
--- a/libksieve/ksieveui/vacation/vacation.cpp
+++ b/libksieve/ksieveui/vacation/vacation.cpp
@@ -163,7 +163,8 @@ void Vacation::slotGetResult( KManageSieve::SieveJob * job, bool success,
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(),
@@ -171,7 +172,6 @@ void Vacation::slotDialogOk() {
mDialog->domainName(),
mDialog->startDate(),
mDialog->endDate() );
- const bool active = mDialog->activateVacation();
emit scriptActive( active, mServerName);
kDebug() << "script:" << endl << script;
diff --git a/libksieve/ksieveui/vacation/vacationpagewidget.cpp b/libksieve/ksieveui/vacation/vacationpagewidget.cpp
index cbdc4c0..1a0aa9a 100644
--- a/libksieve/ksieveui/vacation/vacationpagewidget.cpp
+++ b/libksieve/ksieveui/vacation/vacationpagewidget.cpp
@@ -165,7 +165,8 @@ KSieveUi::VacationCreateScriptJob *VacationPageWidget::writeScript()
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(),
@@ -173,7 +174,6 @@ KSieveUi::VacationCreateScriptJob *VacationPageWidget::writeScript()
mVacationEditWidget->domainName(),
mVacationEditWidget->startDate(),
mVacationEditWidget->endDate() );
- const bool active = mVacationEditWidget->activateVacation();
createJob->setStatus(active, mWasActive);
//Q_EMIT scriptActive( active, mServerName);
createJob->setScript(script);
diff --git a/libksieve/ksieveui/vacation/vacationscriptextractor.h b/libksieve/ksieveui/vacation/vacationscriptextractor.h
index d5f1a5d..851221c 100644
--- a/libksieve/ksieveui/vacation/vacationscriptextractor.h
+++ b/libksieve/ksieveui/vacation/vacationscriptextractor.h
@@ -230,16 +230,17 @@ static const GenericInformationExtractor::StateNode spamNodes[] = {
{ 0, GIE::StringListArgumentEnd, 0, 0, 14, 0 }, // 16
{ 0, GIE::StringListArgumentEnd, 0, 18, 0, 0 }, // 17
- { 0, GIE::TestEnd, 0, 20, 19, 0 }, // 18
- { 0, GIE::TestListEnd, 0, 20, 0, 0 }, // 19
+ { 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, 21, 18, 0 }, // 20
- { 1, GIE::CommandStart, "vacation", 24, 24, "vacation" }, // 21
- { -1, GIE::Any, 0, 21, 0, 0 }, // 22
- { 0, GIE::BlockEnd, 0, 0, 18, 0 }, // 23
+ { 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, 24, 24, 0 }, // 24 end state
+ { -1, GIE::Any, 0, 25, 25, 0 }, // 25 end state
};
static const unsigned int numSpamNodes = sizeof spamNodes / sizeof *spamNodes ;
@@ -263,39 +264,40 @@ public:
// '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 ;
@@ -308,7 +310,7 @@ public:
}
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();
}
};
@@ -321,7 +323,7 @@ static const GenericInformationExtractor::StateNode datesNodes[] = {
// handle startDate and endDate in arbitrary order
{ 0, GIE::TestListStart, 0, 3, 0, 0 }, // 2
- { 0, GIE::TestStart, "currentdate", 4, 0, 0 }, // 3
+ { 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
@@ -331,7 +333,7 @@ static const GenericInformationExtractor::StateNode datesNodes[] = {
{ 0, GIE::StringArgument, 0, 11, 0, "endDate" }, // 10
{ 0, GIE::TestEnd, 0, 12, 0, 0 }, // 11
- { 0, GIE::TestStart, "currentdate", 13, 0, 0 }, // 12
+ { 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
diff --git a/libksieve/ksieveui/vacation/vacationutils.cpp b/libksieve/ksieveui/vacation/vacationutils.cpp
index a6b69ac..9c5c509 100644
--- a/libksieve/ksieveui/vacation/vacationutils.cpp
+++ b/libksieve/ksieveui/vacation/vacationutils.cpp
@@ -128,6 +128,7 @@ bool KSieveUi::VacationUtils::parseScript( const QString &script, bool &active,
DateExtractor dx;
KSieveExt::MultiScriptBuilder tsb( &vdx , &sdx, &drdx, &dx );
parser.setScriptBuilder( &tsb );
+ parser.parse();
if ( !parser.parse() || !vdx.commandFound() ) {
active = false;
return false;
@@ -174,7 +175,7 @@ bool KSieveUi::VacationUtils::foundVacationScript(const QString &script)
return parser.parse() && vdx.commandFound();
}
-QString KSieveUi::VacationUtils::composeScript( const QString & messageText,
+QString composeOldScript( const QString & messageText,
const QString &subject,
int notificationInterval,
const AddrSpecList & addrSpecs,
@@ -224,8 +225,91 @@ QString KSieveUi::VacationUtils::composeScript( const QString & messageText,
}
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;
+}
diff --git a/libksieve/ksieveui/vacation/vacationutils.h b/libksieve/ksieveui/vacation/vacationutils.h
index 53248c8..a07ebfe 100644
--- a/libksieve/ksieveui/vacation/vacationutils.h
+++ b/libksieve/ksieveui/vacation/vacationutils.h
@@ -40,7 +40,7 @@ QString defaultDomainName();
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,
More information about the commits
mailing list