diff --git a/libksieve/ksieveui/vacation/tests/main.cpp b/libksieve/ksieveui/vacation/tests/main.cpp index 9320f1911c..2b8a6dcc48 100644 --- a/libksieve/ksieveui/vacation/tests/main.cpp +++ b/libksieve/ksieveui/vacation/tests/main.cpp @@ -1,40 +1,40 @@ /* Copyright (c) 2013, 2014 Montel Laurent 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 #include #include #include "vacation/multiimapvacationdialog.h" #include #include int main( int argc, char** argv ) { KCmdLineArgs::init(argc, argv, "vacationmultiscripttest", 0, ki18n("VacationMultiScriptTest_Gui"), "1.0", ki18n("Test for dialog when server has multiscript")); KApplication app; - app.setQuitOnLastWindowClosed( false ); + app.setQuitOnLastWindowClosed( true ); KSieveUi::MultiImapVacationManager manager; KSieveUi::MultiImapVacationDialog dlg(&manager); dlg.show(); app.exec(); return 0; } diff --git a/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp b/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp index 61b581d4e7..800bb66f28 100644 --- a/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp +++ b/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp @@ -1,279 +1,278 @@ /* Copyright (c) 2015 Sandro Knauß 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 #include #include #include using namespace KSieveUi; QTEST_KDEMAIN( VacationUtilsTest, NoGUI ) void testAliases(KMime::Types::AddrSpecList l1, KMime::Types::AddrSpecList l2) { QCOMPARE(l1.count(),l2.count()); for (int i=0; i < l1.count(); i++) { QCOMPARE(l1.at(i).asString(),l2.at(i).asString()); } } void testAliases(KMime::Types::AddrSpecList l1, QStringList l2) { QCOMPARE(l1.count(),l2.count()); for (int i=0;i < l1.count(); i++) { QCOMPARE(l1.at(i).asString(),l2.at(i)); } } void VacationUtilsTest::testParseEmptyScript() { const QString script; - QCOMPARE(VacationUtils::foundVacationScript(script), false); + QCOMPARE(VacationUtils::parseScript(script).isValid(), false); } void VacationUtilsTest::testParseOnlyComment() { QString script(QLatin1String("#comment")); - QCOMPARE(VacationUtils::foundVacationScript(script), false); + QCOMPARE(VacationUtils::parseScript(script).isValid(), false); script = QLatin1String("#comment\n\n#comment\n"); - QCOMPARE(VacationUtils::foundVacationScript(script), false); + QCOMPARE(VacationUtils::parseScript(script).isValid(), false); } void VacationUtilsTest::testParseActivate_data() { QTest::addColumn("filename"); QTest::addColumn("found"); QTest::addColumn("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); VacationUtils::Vacation vacation = VacationUtils::parseScript(script); QCOMPARE(vacation.isValid(), found); QCOMPARE(vacation.active, active); } void VacationUtilsTest::testParseScript_data() { QTest::addColumn("activate"); QTest::addColumn("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()); VacationUtils::Vacation vacationA = VacationUtils::parseScript(scriptA); VacationUtils::Vacation vacationD = VacationUtils::parseScript(scriptD); QCOMPARE(vacationA.active, true); QCOMPARE(vacationD.active, false); QCOMPARE(vacationD.messageText, vacationA.messageText); QCOMPARE(vacationD.subject, vacationA.subject); QCOMPARE(vacationD.notificationInterval, vacationA.notificationInterval); testAliases(vacationD.aliases, vacationA.aliases); QCOMPARE(vacationD.sendForSpam, vacationA.sendForSpam); QCOMPARE(vacationD.excludeDomain, vacationA.excludeDomain); QCOMPARE(vacationD.startDate, vacationA.startDate); QCOMPARE(vacationD.endDate, vacationA.endDate); } void VacationUtilsTest::testParseScriptComplex() { QFile file(QLatin1String(VACATIONTESTDATADIR "vacation-complex.siv")); QVERIFY(file.open(QIODevice::ReadOnly)); QString script = QString::fromUtf8(file.readAll()); VacationUtils::Vacation vacation = VacationUtils::parseScript(script); QCOMPARE(vacation.active, true); QCOMPARE(vacation.messageText, QLatin1String("dsfgsdfgsdfg")); QCOMPARE(vacation.subject, QLatin1String("XXX")); QCOMPARE(vacation.notificationInterval, 7); testAliases(vacation.aliases, QStringList() << QLatin1String("test@test.de")); QCOMPARE(vacation.sendForSpam, false); QCOMPARE(vacation.excludeDomain, QString()); QCOMPARE(vacation.startDate, QDate(2015, 01, 02)); QCOMPARE(vacation.endDate, QDate(2015, 03, 04)); } void VacationUtilsTest::testWriteScript() { VacationUtils::Vacation vacation, vacationA; QStringList aliases = QStringList() << QLatin1String("test@test.de"); vacation.valid = true; vacation.messageText = QLatin1String("dsfgsdfgsdfg"); vacation.subject = QLatin1String("XXX"); vacation.notificationInterval = 7; vacation.sendForSpam = false; vacation.excludeDomain = QLatin1String("example.org"); vacation.startDate = QDate(2015, 01, 02); vacation.endDate = QDate(2015, 03, 04); vacation.active = true; foreach(const QString &alias, aliases) { KMime::Types::Mailbox a; a.fromUnicodeString(alias); vacation.aliases.append(a.addrSpec()); } QString script = VacationUtils::composeScript(vacation); vacationA = VacationUtils::parseScript(script); QCOMPARE(vacationA.isValid(), true); QCOMPARE(vacationA.active, vacation.active); QCOMPARE(vacationA.messageText, vacation.messageText); QCOMPARE(vacationA.subject, vacation.subject); QCOMPARE(vacationA.notificationInterval, vacation.notificationInterval); kDebug() << "huih"; testAliases(vacationA.aliases, vacation.aliases); QCOMPARE(vacationA.sendForSpam, vacation.sendForSpam); QCOMPARE(vacationA.excludeDomain, vacation.excludeDomain); QCOMPARE(vacationA.startDate, vacation.startDate); QCOMPARE(vacationA.endDate, vacation.endDate); vacation.active = false; script = VacationUtils::composeScript(vacation); vacationA = VacationUtils::parseScript(script); QCOMPARE(vacationA.isValid(), true); QCOMPARE(vacationA.active, vacation.active); QCOMPARE(vacationA.messageText, vacation.messageText); QCOMPARE(vacationA.subject, vacation.subject); QCOMPARE(vacationA.notificationInterval, vacation.notificationInterval); testAliases(vacationA.aliases, vacation.aliases); QCOMPARE(vacationA.sendForSpam, vacation.sendForSpam); QCOMPARE(vacationA.excludeDomain, vacation.excludeDomain); QCOMPARE(vacationA.startDate, vacation.startDate); QCOMPARE(vacationA.endDate, vacation.endDate); } void VacationUtilsTest::testWriteSimpleScript() { VacationUtils::Vacation vacation; vacation.valid = true; vacation.messageText = QLatin1String("dsfgsdfgsdfg"); vacation.subject = QLatin1String("XXX"); vacation.notificationInterval = 7; vacation.active = true; vacation.sendForSpam = true; QString script = VacationUtils::composeScript(vacation); VacationUtils::Vacation vacationA = VacationUtils::parseScript(script); QCOMPARE(vacation.isValid(), true); QCOMPARE(vacationA.active, vacation.active); QCOMPARE(vacationA.messageText, vacation.messageText); QCOMPARE(vacationA.subject, vacation.subject); QCOMPARE(vacationA.notificationInterval, vacation.notificationInterval); vacation.active = false; script = VacationUtils::composeScript(vacation); vacationA = VacationUtils::parseScript(script); QCOMPARE(vacation.isValid(), true); QCOMPARE(vacationA.active, vacation.active); QCOMPARE(vacationA.messageText, vacation.messageText); QCOMPARE(vacationA.subject, vacation.subject); QCOMPARE(vacationA.notificationInterval, vacation.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 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 "vacationcheckjob.h" #include "vacationutils.h" #include #include #include #include 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) { } 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::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 (mKep14Support) { - if (isVacationScipt(script)) { + VacationUtils::Vacation vacation = VacationUtils::parseScript(script); + if (vacation.isValid()) { const QString &scriptName = mAvailableScripts[mScriptPos-1]; - emit scriptActive(this, scriptName, mActiveScripts.contains(scriptName) && VacationUtils::vacationScriptActive(script)); + emit scriptActive(this, scriptName, mActiveScripts.contains(scriptName) && vacation.active); 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; } diff --git a/libksieve/ksieveui/vacation/vacationcheckjob.h b/libksieve/ksieveui/vacation/vacationcheckjob.h index 4596d9ac77..3eaa8cefd0 100644 --- a/libksieve/ksieveui/vacation/vacationcheckjob.h +++ b/libksieve/ksieveui/vacation/vacationcheckjob.h @@ -1,73 +1,72 @@ /* Copyright (c) 2013, 2014 Montel Laurent 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 */ #ifndef VACATIONCHECKJOB_H #define VACATIONCHECKJOB_H #include #include #include namespace KManageSieve { class SieveJob; } 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(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; }; } #endif // VACATIONCHECKJOB_H diff --git a/libksieve/ksieveui/vacation/vacationpagewidget.cpp b/libksieve/ksieveui/vacation/vacationpagewidget.cpp index 638760d67e..8530620caa 100644 --- a/libksieve/ksieveui/vacation/vacationpagewidget.cpp +++ b/libksieve/ksieveui/vacation/vacationpagewidget.cpp @@ -1,185 +1,185 @@ /* Copyright (c) 2013, 2014 Montel Laurent 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 "vacationpagewidget.h" #include "vacationeditwidget.h" #include "vacationwarningwidget.h" #include "vacationcreatescriptjob.h" #include "vacationutils.h" #include "multiimapvacationmanager.h" #include #include "sieve-vacation.h" #include #include #include #include #include #include #include using namespace KSieveUi; VacationPageWidget::VacationPageWidget(QWidget *parent) : QWidget(parent), mPageScript(Script), mWasActive(false) { QVBoxLayout *lay = new QVBoxLayout; lay->setMargin(0); mStackWidget = new QStackedWidget; lay->addWidget(mStackWidget); //Main Page QWidget *mainPage = new QWidget; QVBoxLayout *vbox = new QVBoxLayout; mainPage->setLayout(vbox); mVacationWarningWidget = new VacationWarningWidget; vbox->addWidget(mVacationWarningWidget); mVacationEditWidget = new VacationEditWidget; vbox->addWidget(mVacationEditWidget); mStackWidget->addWidget(mainPage); QWidget *w = new QWidget; vbox = new QVBoxLayout; QLabel *lab = new QLabel(i18n( "Your server did not list \"vacation\" in " "its list of supported Sieve extensions;" "without it, KMail cannot install out-of-" "office replies for you." "Please contact your system administrator." ) ); vbox->addWidget(lab); vbox->setAlignment(lab, Qt::AlignVCenter); lab->setWordWrap(true); w->setLayout(vbox); mStackWidget->addWidget(w); mStackWidget->setCurrentIndex(Script); setLayout(lay); } VacationPageWidget::~VacationPageWidget() { } void VacationPageWidget::setServerUrl(const KUrl &url) { mUrl = url; mVacationEditWidget->setEnabled(false); } 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) { mServerName = serverName; } void VacationPageWidget::slotGetResult(const QString &serverName, const QStringList &sieveCapabilities, const QString &scriptName, const QString &script, bool active) { if (serverName != mServerName) { return; } kDebug() << serverName << sieveCapabilities << endl << scriptName << "(" << active << ")" << endl << "script:" << endl << script; if ( mUrl.protocol() == QLatin1String("sieve") && !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") && sieveCapabilities.contains(QLatin1String("date")); KSieveUi::VacationUtils::Vacation vacation = KSieveUi::VacationUtils::parseScript(script); - if (!vacation.isValid() && !script.timmed().isEmpty() ) { + if (!vacation.isValid() && !script.trimmed().isEmpty() ) { mVacationWarningWidget->setVisible(true); } mWasActive = active; mVacationEditWidget->setEnabled(true); mVacationEditWidget->setActivateVacation( active && vacation.active ); mVacationEditWidget->setMessageText( vacation.messageText ); mVacationEditWidget->setSubject( vacation.subject ); mVacationEditWidget->setNotificationInterval( vacation.notificationInterval ); mVacationEditWidget->setMailAliases( vacation.aliases ); mVacationEditWidget->setSendForSpam( vacation.sendForSpam ); mVacationEditWidget->setDomainName( vacation.excludeDomain ); mVacationEditWidget->enableDomainAndSendForSpam( !VacationSettings::allowOutOfOfficeUploadButNoSettings() ); mVacationEditWidget->enableDates( supportsSieveDate ); if ( supportsSieveDate ) { mVacationEditWidget->setStartDate( vacation.startDate ); mVacationEditWidget->setEndDate( vacation.endDate ); } //emit scriptActive( mWasActive, mServerName ); } KSieveUi::VacationCreateScriptJob *VacationPageWidget::writeScript() { if (mPageScript == Script) { KSieveUi::VacationCreateScriptJob *createJob = new KSieveUi::VacationCreateScriptJob; createJob->setServerUrl(mUrl); createJob->setServerName(mServerName); const bool active = mVacationEditWidget->activateVacation(); VacationUtils::Vacation vacation; vacation.valid = true; vacation.active = active; vacation.messageText = mVacationEditWidget->messageText(); vacation.subject = mVacationEditWidget->subject(); vacation.notificationInterval = mVacationEditWidget->notificationInterval(); vacation.aliases = mVacationEditWidget->mailAliases(); vacation.sendForSpam = mVacationEditWidget->sendForSpam(); vacation.excludeDomain = mVacationEditWidget->domainName(); vacation.startDate = mVacationEditWidget->startDate(); vacation.endDate = mVacationEditWidget->endDate(); const QString script = VacationUtils::composeScript(vacation); createJob->setStatus(active, mWasActive); //Q_EMIT scriptActive( active, mServerName); createJob->setScript(script); return createJob; } return 0; } void VacationPageWidget::setDefault() { if (mVacationEditWidget->isEnabled()) mVacationEditWidget->setDefault(); } diff --git a/libksieve/ksieveui/vacation/vacationutils.cpp b/libksieve/ksieveui/vacation/vacationutils.cpp index 9018c709f7..8c5633c074 100644 --- a/libksieve/ksieveui/vacation/vacationutils.cpp +++ b/libksieve/ksieveui/vacation/vacationutils.cpp @@ -1,422 +1,411 @@ /* Copyright (c) 2013, 2014 Montel Laurent 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 "vacationutils.h" #include "vacationscriptextractor.h" #include "sieve-vacation.h" #include #include #include #include #include #include using KMime::Types::AddrSpecList; static inline QString dotstuff( QString s ) { // krazy:exclude=passbyvalue if ( s.startsWith( QLatin1Char('.') ) ) return QLatin1Char('.') + s.replace( QLatin1String("\n."), QLatin1String("\n..") ); else return s.replace( QLatin1String("\n."), QLatin1String("\n..") ); } static inline QString stringReplace(QString s) { s = s.replace(QRegExp(QLatin1String("[\n\t]+")),QLatin1String(" ")); return s.replace(QLatin1Char('\"'),QLatin1String("\\\"")); } QString KSieveUi::VacationUtils::defaultSubject() { return i18n("Out of office till %1", QLocale().toString(QDate::currentDate().addDays(1))); } QString KSieveUi::VacationUtils::defaultMessageText() { return i18n( "I am out of office till %1.\n" "\n" "In urgent cases, please contact Mrs. \"vacation replacement\"\n" "\n" "email: \"email address of vacation replacement\"\n" "phone: +49 711 1111 11\n" "fax.: +49 711 1111 12\n" "\n" "Yours sincerely,\n" "-- \"enter your name and email address here\"\n", KGlobal::locale()->formatDate( QDate::currentDate().addDays( 1 ) ) ); } int KSieveUi::VacationUtils::defaultNotificationInterval() { return 7; // days } KMime::Types::AddrSpecList KSieveUi::VacationUtils::defaultMailAliases() { KMime::Types::AddrSpecList sl; KPIMIdentities::IdentityManager manager( true ); KPIMIdentities::IdentityManager::ConstIterator end(manager.end()); for ( KPIMIdentities::IdentityManager::ConstIterator it = manager.begin(); it != end ; ++it ) { if ( !(*it).primaryEmailAddress().isEmpty() ) { KMime::Types::Mailbox a; a.fromUnicodeString((*it).primaryEmailAddress()); sl.push_back(a.addrSpec()); } foreach(const QString &email, (*it).emailAliases()) { KMime::Types::Mailbox a; a.fromUnicodeString(email); sl.push_back(a.addrSpec()); } } return sl; } bool KSieveUi::VacationUtils::defaultSendForSpam() { return VacationSettings::outOfOfficeReactToSpam(); } QString KSieveUi::VacationUtils::defaultDomainName() { return VacationSettings::outOfOfficeDomain(); } QDate KSieveUi::VacationUtils::defaultStartDate() { return QDate::currentDate(); } QDate KSieveUi::VacationUtils::defaultEndDate() { return defaultStartDate().addDays(7); } KSieveUi::VacationUtils::Vacation KSieveUi::VacationUtils::parseScript(const QString &script) { KSieveUi::VacationUtils::Vacation vacation; if ( script.trimmed().isEmpty() ) { vacation.valid = false; vacation.active = false; vacation.messageText = VacationUtils::defaultMessageText(); vacation.subject = VacationUtils::defaultSubject(); vacation.notificationInterval = VacationUtils::defaultNotificationInterval(); vacation.aliases = VacationUtils::defaultMailAliases(); vacation.sendForSpam = VacationUtils::defaultSendForSpam(); vacation.excludeDomain = VacationUtils::defaultDomainName(); return vacation; } // The trimmed() call below prevents parsing errors. The // slave somehow omits the last \n, which results in a lone \r at // the end, leading to a parse error. const QByteArray scriptUTF8 = script.trimmed().toUtf8(); kDebug() << "scriptUtf8 = \"" + scriptUTF8 +"\""; KSieve::Parser parser( scriptUTF8.begin(), scriptUTF8.begin() + scriptUTF8.length() ); VacationDataExtractor vdx; SpamDataExtractor sdx; DomainRestrictionDataExtractor drdx; DateExtractor dx; KSieveExt::MultiScriptBuilder tsb( &vdx , &sdx, &drdx, &dx ); parser.setScriptBuilder( &tsb ); parser.parse(); if ( !parser.parse() || !vdx.commandFound() ) { vacation.active = false; vacation.valid = false; return vacation; } vacation.valid = true; vacation.active = vdx.active(); vacation.messageText = vdx.messageText().trimmed(); if (!vdx.subject().isEmpty()) { vacation.subject = vdx.subject().trimmed(); } vacation.notificationInterval = vdx.notificationInterval(); vacation.aliases = KMime::Types::AddrSpecList(); foreach(const QString &alias, vdx.aliases()) { KMime::Types::Mailbox a; a.fromUnicodeString(alias); vacation.aliases.append(a.addrSpec()); } if (!vacation.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() ) { vacation.valid = false; return vacation; } } vacation.sendForSpam = !sdx.found(); vacation.excludeDomain = drdx.domainName(); vacation.startDate = dx.startDate(); vacation.endDate = dx.endDate(); return vacation; } -bool KSieveUi::VacationUtils::foundVacationScript(const QString &script) -{ - return parseScript(script).isValid(); -} - -bool KSieveUi::VacationUtils::vacationScriptActive(const QString &script) -{ - const KSieveUi::VacationUtils::Vacation vacation = parseScript(script); - return vacation.isValid() && vacation.active; -} - QString composeOldScript( const QString & messageText, const QString &subject, int notificationInterval, const AddrSpecList & addrSpecs, bool sendForSpam, const QString & domain, const QDate & startDate, const QDate & endDate ) { 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 script; if ( startDate.isValid() && endDate.isValid() ) { script = QString::fromLatin1("require [\"vacation\", \"relational\", \"date\"];\n\n" ); } else { script = QString::fromLatin1("require \"vacation\";\n\n" ); } if ( !sendForSpam ) script += QString::fromLatin1( "if header :contains \"X-Spam-Flag\" \"YES\"" " { keep; stop; }\n" ); // FIXME? if ( !domain.isEmpty() ) // FIXME script += QString::fromLatin1( "if not address :domain :contains \"from\" \"%1\" { keep; stop; }\n" ).arg( domain ); if ( startDate.isValid() && endDate.isValid() ) { script += QString::fromLatin1( "if not allof(currentdate :value \"ge\" \"date\" \"%1\"," " currentdate :value \"le\" \"date\" \"%2\")" " { keep; stop; }\n" ).arg( startDate.toString(Qt::ISODate), endDate.toString(Qt::ISODate) ); } script += QLatin1String("vacation "); script += addressesArgument; if ( notificationInterval > 0 ) script += QString::fromLatin1(":days %1 ").arg( notificationInterval ); if (!subject.trimmed().isEmpty()) { script += QString::fromLatin1(":subject \"%1\" ").arg(stringReplace(subject).trimmed()); } script += QString::fromLatin1("text:\n"); script += dotstuff( messageText.isEmpty() ? KSieveUi::VacationUtils::defaultMessageText() : messageText ); script += QString::fromLatin1( "\n.\n;\n" ); return script; } QString KSieveUi::VacationUtils::composeScript(const Vacation &vacation) { QStringList condition; if (vacation.startDate.isValid()) { condition.append(QString::fromLatin1("currentdate :value \"ge\" \"date\" \"%1\"") .arg(vacation.startDate.toString(Qt::ISODate))); } if (vacation.endDate.isValid()) { condition.append(QString::fromLatin1("currentdate :value \"le\" \"date\" \"%1\"") .arg(vacation.endDate.toString(Qt::ISODate))); } if (!vacation.sendForSpam) { condition.append(QString::fromLatin1("not header :contains \"X-Spam-Flag\" \"YES\"")); } if (!vacation.excludeDomain.isEmpty()) { condition.append(QString::fromLatin1("address :domain :contains \"from\" \"%1\"").arg( vacation.excludeDomain )); } QString addressesArgument; QStringList aliases; if ( !vacation.aliases.empty() ) { addressesArgument += QLatin1String(":addresses [ "); QStringList sl; AddrSpecList::const_iterator end = vacation.aliases.constEnd(); for ( AddrSpecList::const_iterator it = vacation.aliases.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 sVacation(QLatin1String("vacation ")); sVacation += addressesArgument; if ( vacation.notificationInterval > 0 ) sVacation += QString::fromLatin1(":days %1 ").arg(vacation.notificationInterval); if (!vacation.subject.trimmed().isEmpty()) { sVacation += QString::fromLatin1(":subject \"%1\" ").arg(stringReplace(vacation.subject).trimmed()); } sVacation += QString::fromLatin1("text:\n"); sVacation += dotstuff( vacation.messageText.isEmpty() ? VacationUtils::defaultMessageText() : vacation.messageText ); sVacation += QString::fromLatin1( "\n.\n;" ); QString script; if ( vacation.startDate.isValid() || vacation.endDate.isValid() ) { script = QString::fromLatin1("require [\"vacation\", \"relational\", \"date\"];\n\n" ); } else { script = QString::fromLatin1("require \"vacation\";\n\n" ); } if (condition.count() == 0) { if (vacation.active) { script += sVacation; } else { script += QString::fromLatin1("if false\n{\n\t"); script += sVacation; script += QLatin1String("\n}"); } } else { if (vacation.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 += sVacation; 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 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); 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 5179eb2a0c..d326989b8d 100644 --- a/libksieve/ksieveui/vacation/vacationutils.h +++ b/libksieve/ksieveui/vacation/vacationutils.h @@ -1,69 +1,63 @@ /* Copyright (c) 2013, 2014 Montel Laurent 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 */ #ifndef VACATIONUTILS_H #define VACATIONUTILS_H #include #include #include #include namespace KSieveUi { namespace VacationUtils { QString defaultMessageText(); QString defaultSubject(); int defaultNotificationInterval(); KMime::Types::AddrSpecList defaultMailAliases(); bool defaultSendForSpam(); QString defaultDomainName(); QDate defaultStartDate(); QDate defaultEndDate(); struct Vacation { Vacation():valid(false), active(false), notificationInterval(1), sendForSpam(true) {} bool isValid() const {return valid;} bool valid; QString messageText; QString subject; bool active; int notificationInterval; KMime::Types::AddrSpecList aliases; bool sendForSpam; QString excludeDomain; QDate startDate; QDate endDate; }; QString composeScript(const Vacation &vacation); KSieveUi::VacationUtils::Vacation parseScript(const QString &script); -//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); } } #endif // VACATIONUTILS_H