diff --git a/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp b/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp index f0cb13da82..61b581d4e7 100644 --- a/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp +++ b/libksieve/ksieveui/vacation/tests/vacationutilstest.cpp @@ -1,303 +1,279 @@ /* 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); } 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("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); - 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); + 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()); - 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); + 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()); - 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)); + 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() { - QString messageText(QLatin1String("dsfgsdfgsdfg")); - QString subject(QLatin1String("XXX")); - int notificationInterval(7); + VacationUtils::Vacation vacation, vacationA; QStringList aliases = QStringList() << QLatin1String("test@test.de"); - QList 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; + 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); - addesses.append(a.addrSpec()); + vacation.aliases.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); + 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() { - 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(), 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(), 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); + 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.0, as published by the Free Software Foundation. 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, US */ #include "vacation.h" #include "vacationutils.h" #include "vacationscriptextractor.h" #include "sieve-vacation.h" #include "util/util.h" #include "vacationdialog.h" #include #include #include #include #include #include #include #include using namespace KSieveUi; Vacation::Vacation(QObject * parent, bool checkOnly, const KUrl &url) : QObject( parent ), mSieveJob( 0 ), mDialog( 0 ), mWasActive( false ), mCheckOnly( checkOnly ) { if (url.isEmpty()) { mUrl = findURL(mServerName); } else { mUrl = url; } kDebug() << "Vacation: found url \"" << mUrl.prettyUrl() <<"\""; if ( mUrl.isEmpty() ) // nothing to do... return; mSieveJob = KManageSieve::SieveJob::get( mUrl ); if (checkOnly) { mSieveJob->setInteractive( false ); } connect( mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)), SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool)) ); } Vacation::~Vacation() { if ( mSieveJob ) mSieveJob->kill(); mSieveJob = 0; delete mDialog; mDialog = 0; kDebug() << "~Vacation()"; } KUrl Vacation::findURL(QString &serverName) const { const Akonadi::AgentInstance::List instances = Util::imapAgentInstances(); foreach ( const Akonadi::AgentInstance &instance, instances ) { if ( instance.status() == Akonadi::AgentInstance::Broken ) continue; const KUrl url = Util::findSieveUrlForAccount( instance.identifier() ); if ( !url.isEmpty() ) { serverName = instance.name(); return url; } } return KUrl(); } void Vacation::slotGetResult( KManageSieve::SieveJob * job, bool success, const QString & script, bool active ) { kDebug() << success << ", ?," << active << ")" << endl << "script:" << endl << script; mSieveJob = 0; // job deletes itself after returning from this slot! if ( !mCheckOnly && mUrl.protocol() == QLatin1String("sieve") && !job->sieveCapabilities().contains(QLatin1String("vacation")) ) { KMessageBox::sorry( 0, i18n( "Your server did not list \"vacation\" in " "its list of supported Sieve extensions;\n" "without it, KMail cannot install out-of-" "office replies for you.\n" "Please contact your system administrator." ) ); emit result( false ); return; } const bool supportsDate = job->sieveCapabilities().contains(QLatin1String("date")); if ( !mDialog && !mCheckOnly ) mDialog = new VacationDialog( i18n("Configure \"Out of Office\" Replies"), 0, false ); - QString messageText = VacationUtils::defaultMessageText(); - QString subject = VacationUtils::defaultSubject(); - int notificationInterval = VacationUtils::defaultNotificationInterval(); - QStringList aliases = VacationUtils::defaultMailAliases(); - bool sendForSpam = VacationUtils::defaultSendForSpam(); - 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, sActive, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate ) ) ) + if ( !success ) { + active = false; // default to inactive + } + + KSieveUi::VacationUtils::Vacation vacation = KSieveUi::VacationUtils::parseScript(script); + + if ( !mCheckOnly && ( !success || (!vacation.isValid() && !script.trimmed().isEmpty())) ) { 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 && sActive; + } + mWasActive = active; if ( mDialog ) { - mDialog->setActivateVacation( active && sActive ); - mDialog->setSubject(subject); - mDialog->setMessageText( messageText ); - mDialog->setNotificationInterval( notificationInterval ); - mDialog->setMailAliases( aliases.join(QLatin1String(", ")) ); - mDialog->setSendForSpam( sendForSpam ); - mDialog->setDomainName( domainName ); + mDialog->setActivateVacation( active && vacation.active ); + mDialog->setSubject(vacation.subject); + mDialog->setMessageText( vacation.messageText ); + mDialog->setNotificationInterval( vacation.notificationInterval ); + mDialog->setMailAliases( vacation.aliases ); + mDialog->setSendForSpam( vacation.sendForSpam ); + mDialog->setDomainName( vacation.excludeDomain ); mDialog->enableDomainAndSendForSpam( !VacationSettings::allowOutOfOfficeUploadButNoSettings() ); if (supportsDate) { mDialog->enableDates( supportsDate ); - mDialog->setStartDate( startDate ); - mDialog->setEndDate( endDate ); + mDialog->setStartDate( vacation.startDate ); + mDialog->setEndDate( vacation.endDate ); } connect( mDialog, SIGNAL(okClicked()), SLOT(slotDialogOk()) ); connect( mDialog, SIGNAL(cancelClicked()), SLOT(slotDialogCancel()) ); mDialog->show(); } emit scriptActive( mWasActive, mServerName ); if ( mCheckOnly && mWasActive ) { 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 ) { emit requestEditVacation(); } } } void Vacation::slotDialogOk() { kDebug(); // compose a new script: const bool active = mDialog->activateVacation(); - const QString script = VacationUtils::composeScript( mDialog->messageText(), active, - mDialog->subject(), - mDialog->notificationInterval(), - mDialog->mailAliases(), - mDialog->sendForSpam(), - mDialog->domainName(), - mDialog->startDate(), - mDialog->endDate() ); + VacationUtils::Vacation vacation; + vacation.valid = true; + vacation.active = active; + vacation.messageText = mDialog->messageText(); + vacation.subject = mDialog->subject(); + vacation.notificationInterval = mDialog->notificationInterval(); + vacation.aliases = mDialog->mailAliases(); + vacation.sendForSpam = mDialog->sendForSpam(); + vacation.excludeDomain = mDialog->domainName(); + vacation.startDate = mDialog->startDate(); + vacation.endDate = mDialog->endDate(); + const QString script = VacationUtils::composeScript(vacation); emit scriptActive( active, mServerName); kDebug() << "script:" << endl << script; // and commit the dialog's settings to the server: mSieveJob = KManageSieve::SieveJob::put( mUrl, script, active, mWasActive ); if ( active ) 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)) ); // destroy the dialog: mDialog->delayedDestruct(); mDialog = 0; } void Vacation::slotDialogCancel() { kDebug(); mDialog->delayedDestruct(); mDialog = 0; emit result( false ); } void Vacation::slotPutActiveResult( KManageSieve::SieveJob * job, bool success ) { handlePutResult( job, success, true ); } void Vacation::slotPutInactiveResult( KManageSieve::SieveJob * job, bool success ) { handlePutResult( job, success, false ); } void Vacation::handlePutResult( KManageSieve::SieveJob *, bool success, bool activated ) { if ( success ) KMessageBox::information( 0, activated ? i18n("Sieve script installed successfully on the server.\n" "Out of Office reply is now active.") : i18n("Sieve script installed successfully on the server.\n" "Out of Office reply has been deactivated.") ); kDebug() << "( ???," << success << ", ? )"; mSieveJob = 0; // job deletes itself after returning from this slot! emit result( success ); emit scriptActive( activated, mServerName ); } void Vacation::showVacationDialog() { if (mDialog) { mDialog->show(); mDialog->raise(); mDialog->activateWindow(); } } diff --git a/libksieve/ksieveui/vacation/vacationeditwidget.cpp b/libksieve/ksieveui/vacation/vacationeditwidget.cpp index 642f1f24de..56a7666675 100644 --- a/libksieve/ksieveui/vacation/vacationeditwidget.cpp +++ b/libksieve/ksieveui/vacation/vacationeditwidget.cpp @@ -1,323 +1,323 @@ /* 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 "vacationeditwidget.h" #include "vacationutils.h" #include #include #include #include #include #include #include #include #include #include #include #include using KMime::Types::AddrSpecList; using KMime::Types::AddressList; using KMime::Types::MailboxList; using KMime::HeaderParsing::parseAddressList; using namespace KSieveUi; VacationEditWidget::VacationEditWidget(QWidget *parent) : QWidget(parent) { int row = -1; QGridLayout * glay = new QGridLayout( this ); glay->setSpacing( KDialog::spacingHint() ); glay->setMargin( 0 ); glay->setColumnStretch( 1, 1 ); // explanation label: ++row; glay->addWidget( new QLabel( i18n("Configure vacation " "notifications to be sent:"), this ), row, 0, 1, 2 ); // Activate checkbox: ++row; mActiveCheck = new QCheckBox( i18n("&Activate vacation notifications"), this ); glay->addWidget( mActiveCheck, row, 0, 1, 2 ); // Message text edit: ++row; glay->setRowStretch( row, 1 ); mTextEdit = new PimCommon::RichTextEditorWidget( this ); mTextEdit->setObjectName( QLatin1String("mTextEdit") ); mTextEdit->setAcceptRichText( false ); glay->addWidget( mTextEdit, row, 0, 1, 2 ); // Subject ++row; mSubject = new KLineEdit(this); mSubject->setObjectName(QLatin1String("mSubject")); mSubject->setClearButtonShown(true); QLabel *tmpLabel = new QLabel(i18n("&Subject of the vacation mail:"), this); tmpLabel->setBuddy(mSubject); glay->addWidget(tmpLabel, row, 0); glay->addWidget(mSubject, row, 1); // From date ++row; mStartDate = new KDateComboBox( this ); mStartDate->setObjectName( QLatin1String( "mStartDate" ) ); mStartDate->setOptions( KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::DateKeywords | KDateComboBox::WarnOnInvalid ); mStartDate->setEnabled( false ); // Disable by default - we need an extension to support this QLabel *label = new QLabel( i18n("&Start:"), this ); label->setBuddy( mStartDate ); glay->addWidget( label, row, 0 ); glay->addWidget( mStartDate, row, 1 ); // End date ++row; mEndDate = new KDateComboBox( this ); mEndDate->setObjectName( QLatin1String( "mEndDate" ) ); mEndDate->setOptions( KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::DateKeywords | KDateComboBox::WarnOnInvalid ); mEndDate->setEnabled( false ); // Disable by default - we need an extension to support this label = new QLabel( i18n("&End:"), this ); label->setBuddy( mEndDate ); glay->addWidget( label, row, 0 ); glay->addWidget( mEndDate, row, 1 ); // "Resent only after" spinbox and label: ++row; int defDayInterval = 7; //default day interval mIntervalSpin = new KIntSpinBox( 1, 356, 1, defDayInterval, this ); mIntervalSpin->setObjectName( QLatin1String("mIntervalSpin") ); mIntervalSpin->setSuffix( i18np(" day", " days", defDayInterval) ); connect(mIntervalSpin, SIGNAL(valueChanged(int)), SLOT(slotIntervalSpinChanged(int)) ); label = new QLabel( i18n("&Resend notification only after:"), this ); label->setBuddy( mIntervalSpin ); glay->addWidget( label, row, 0 ); glay->addWidget( mIntervalSpin, row, 1 ); // "Send responses for these addresses" lineedit and label: ++row; mMailAliasesEdit = new KLineEdit( this ); mMailAliasesEdit->setObjectName( QLatin1String("mMailAliasesEdit") ); mMailAliasesEdit->setClearButtonShown( true ); tmpLabel = new QLabel( i18n("&Send responses for these addresses:"), this ); tmpLabel->setBuddy( mMailAliasesEdit ); glay->addWidget( tmpLabel, row, 0 ); glay->addWidget( mMailAliasesEdit, row, 1 ); // "Send responses also to SPAM mail" checkbox: ++row; mSpamCheck = new QCheckBox( i18n("Do not send vacation replies to spam messages"), this ); mSpamCheck->setObjectName( QLatin1String("mSpamCheck") ); mSpamCheck->setChecked( true ); glay->addWidget( mSpamCheck, row, 0, 1, 2 ); // domain checkbox and linedit: ++row; mDomainCheck = new QCheckBox( i18n("Only react to mail coming from domain"), this ); mDomainCheck->setObjectName( QLatin1String("mDomainCheck") ); mDomainCheck->setChecked( false ); mDomainEdit = new KLineEdit( this ); mDomainEdit->setObjectName( QLatin1String("mDomainEdit") ); mDomainEdit->setClearButtonShown( true ); mDomainEdit->setEnabled( false ); mDomainEdit->setValidator( new QRegExpValidator( QRegExp( QLatin1String("[a-zA-Z0-9+-]+(?:\\.[a-zA-Z0-9+-]+)*") ), mDomainEdit ) ); glay->addWidget( mDomainCheck, row, 0 ); glay->addWidget( mDomainEdit, row, 1 ); connect( mDomainCheck, SIGNAL(toggled(bool)), mDomainEdit, SLOT(setEnabled(bool)) ); } VacationEditWidget::~VacationEditWidget() { } bool VacationEditWidget::activateVacation() const { return mActiveCheck->isChecked(); } void VacationEditWidget::setActivateVacation( bool activate ) { mActiveCheck->setChecked( activate ); } QString VacationEditWidget::messageText() const { return mTextEdit->toPlainText().trimmed(); } void VacationEditWidget::setMessageText( const QString &text ) { mTextEdit->setPlainText( text ); const int height = ( mTextEdit->fontMetrics().lineSpacing() + 1 ) * 11; mTextEdit->setMinimumHeight( height ); } int VacationEditWidget::notificationInterval() const { return mIntervalSpin->value(); } void VacationEditWidget::setNotificationInterval( int days ) { mIntervalSpin->setValue( days ); } AddrSpecList VacationEditWidget::mailAliases() const { QByteArray text = mMailAliasesEdit->text().toLatin1(); // ### IMAA: !ok AddressList al; const char * s = text.begin(); parseAddressList( s, text.end(), al ); AddrSpecList asl; AddressList::const_iterator end(al.constEnd()); for ( AddressList::const_iterator it = al.constBegin() ; it != end; ++it ) { const MailboxList & mbl = (*it).mailboxList; for ( MailboxList::const_iterator jt = mbl.constBegin() ; jt != mbl.constEnd() ; ++jt ) asl.push_back( (*jt).addrSpec() ); } return asl; } void VacationEditWidget::setMailAliases( const AddrSpecList &aliases ) { QStringList sl; AddrSpecList::const_iterator end(aliases.constEnd()); for ( AddrSpecList::const_iterator it = aliases.constBegin() ; it != end; ++it ) sl.push_back( (*it).asString() ); mMailAliasesEdit->setText( sl.join(QLatin1String(", ")) ); } void VacationEditWidget::setMailAliases( const QString &aliases ) { mMailAliasesEdit->setText( aliases ); } void VacationEditWidget::slotIntervalSpinChanged ( int value ) { mIntervalSpin->setSuffix( i18np(" day", " days", value) ); } QString VacationEditWidget::domainName() const { return mDomainCheck->isChecked() ? mDomainEdit->text() : QString() ; } void VacationEditWidget::setDomainName( const QString &domain ) { if ( !domain.isEmpty() ) { mDomainEdit->setText( domain ); mDomainCheck->setChecked( true ); } } bool VacationEditWidget::domainCheck() const { return mDomainCheck->isChecked(); } void VacationEditWidget::setDomainCheck( bool check ) { mDomainCheck->setChecked( check ); } bool VacationEditWidget::sendForSpam() const { return !mSpamCheck->isChecked(); } void VacationEditWidget::setSendForSpam( bool enable ) { mSpamCheck->setChecked( !enable ); } QDate VacationEditWidget::endDate() { if ( mEndDate->isEnabled() ) { return mEndDate->date(); } else { return QDate(); } } void VacationEditWidget::setEndDate( const QDate &endDate ) { mEndDate->setDate( endDate ); } QDate VacationEditWidget::startDate() const { if ( mStartDate->isEnabled() ) { return mStartDate->date(); } else { return QDate(); } } void VacationEditWidget::setStartDate( const QDate &startDate ) { mStartDate->setDate( startDate ); } void VacationEditWidget::setSubject(const QString &subject) { mSubject->setText(subject); } QString VacationEditWidget::subject() const { if (mSubject->isEnabled()) { return mSubject->text(); } else { return QString(); } } void VacationEditWidget::enableDates( bool enable ) { mStartDate->setEnabled( enable ); mEndDate->setEnabled( enable ); } void VacationEditWidget::enableDomainAndSendForSpam( bool enable ) { mDomainCheck->setEnabled( enable ); mDomainEdit->setEnabled( enable && mDomainCheck->isChecked() ); mSpamCheck->setEnabled( enable ); } void VacationEditWidget::setDefault() { setActivateVacation( true ); setMessageText( VacationUtils::defaultMessageText() ); setSubject(VacationUtils::defaultSubject()); setNotificationInterval( VacationUtils::defaultNotificationInterval() ); - setMailAliases( VacationUtils::defaultMailAliases().join(QLatin1String(", ")) ); + setMailAliases( VacationUtils::defaultMailAliases() ); setSendForSpam( VacationUtils::defaultSendForSpam() ); setDomainName( VacationUtils::defaultDomainName() ); setDomainCheck( false ); } diff --git a/libksieve/ksieveui/vacation/vacationpagewidget.cpp b/libksieve/ksieveui/vacation/vacationpagewidget.cpp index c26d0f3e7e..638760d67e 100644 --- a/libksieve/ksieveui/vacation/vacationpagewidget.cpp +++ b/libksieve/ksieveui/vacation/vacationpagewidget.cpp @@ -1,191 +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")); - QString messageText = VacationUtils::defaultMessageText(); - QString subject = VacationUtils::defaultSubject(); - int notificationInterval = VacationUtils::defaultNotificationInterval(); - QStringList aliases = VacationUtils::defaultMailAliases(); - bool sendForSpam = VacationUtils::defaultSendForSpam(); - QString domainName = VacationUtils::defaultDomainName(); - QDate startDate = VacationUtils::defaultStartDate(); - QDate endDate = VacationUtils::defaultEndDate(); - bool scriptActive = true; - - const bool bParse = KSieveUi::VacationUtils::parseScript(script, scriptActive, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate); - - if (!bParse) { + KSieveUi::VacationUtils::Vacation vacation = KSieveUi::VacationUtils::parseScript(script); + + if (!vacation.isValid() && !script.timmed().isEmpty() ) { mVacationWarningWidget->setVisible(true); } mWasActive = active; mVacationEditWidget->setEnabled(true); - mVacationEditWidget->setActivateVacation( active && scriptActive ); - mVacationEditWidget->setMessageText( messageText ); - mVacationEditWidget->setSubject( subject ); - mVacationEditWidget->setNotificationInterval( notificationInterval ); - mVacationEditWidget->setMailAliases( aliases.join(QLatin1String(", ")) ); - mVacationEditWidget->setSendForSpam( sendForSpam ); - mVacationEditWidget->setDomainName( domainName ); + 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( startDate ); - mVacationEditWidget->setEndDate( endDate ); + 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(); - const QString script = VacationUtils::composeScript( mVacationEditWidget->messageText(), active, - mVacationEditWidget->subject(), - mVacationEditWidget->notificationInterval(), - mVacationEditWidget->mailAliases(), - mVacationEditWidget->sendForSpam(), - mVacationEditWidget->domainName(), - mVacationEditWidget->startDate(), - mVacationEditWidget->endDate() ); + 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 ae01e9de51..9018c709f7 100644 --- a/libksieve/ksieveui/vacation/vacationutils.cpp +++ b/libksieve/ksieveui/vacation/vacationutils.cpp @@ -1,438 +1,422 @@ /* 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 } -QStringList KSieveUi::VacationUtils::defaultMailAliases() +KMime::Types::AddrSpecList KSieveUi::VacationUtils::defaultMailAliases() { - QStringList sl; + 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() ) { - sl.push_back( (*it).primaryEmailAddress() ); + 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()); } - sl += (*it).emailAliases(); } + 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); } -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 ) +KSieveUi::VacationUtils::Vacation KSieveUi::VacationUtils::parseScript(const QString &script) { + KSieveUi::VacationUtils::Vacation vacation; if ( script.trimmed().isEmpty() ) { - active = false; - messageText = VacationUtils::defaultMessageText(); - subject = VacationUtils::defaultSubject(); - notificationInterval = VacationUtils::defaultNotificationInterval(); - aliases = VacationUtils::defaultMailAliases(); - sendForSpam = VacationUtils::defaultSendForSpam(); - domainName = VacationUtils::defaultDomainName(); - return true; + 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() ) { - active = false; - return false; + vacation.active = false; + vacation.valid = false; + return vacation; } - active = vdx.active(); - messageText = vdx.messageText().trimmed(); + vacation.valid = true; + vacation.active = vdx.active(); + vacation.messageText = vdx.messageText().trimmed(); if (!vdx.subject().isEmpty()) { - subject = vdx.subject().trimmed(); + 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()); } - notificationInterval = vdx.notificationInterval(); - aliases = vdx.aliases(); - if (!active && !vdx.ifComment().isEmpty()) { + 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() ) { - return false; + vacation.valid = false; + return vacation; } } - sendForSpam = !sdx.found(); - domainName = drdx.domainName(); - startDate = dx.startDate(); - endDate = dx.endDate(); - return true; + 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) { - 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(); + return parseScript(script).isValid(); } 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(); + 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 QString & messageText, bool active, - const QString &subject, - int notificationInterval, - const AddrSpecList & addrSpecs, - bool sendForSpam, const QString & domain, - const QDate & startDate, const QDate & endDate ) +QString KSieveUi::VacationUtils::composeScript(const Vacation &vacation) { QStringList condition; - if (startDate.isValid()) { + if (vacation.startDate.isValid()) { condition.append(QString::fromLatin1("currentdate :value \"ge\" \"date\" \"%1\"") - .arg(startDate.toString(Qt::ISODate))); + .arg(vacation.startDate.toString(Qt::ISODate))); } - if (endDate.isValid()) { + if (vacation.endDate.isValid()) { condition.append(QString::fromLatin1("currentdate :value \"le\" \"date\" \"%1\"") - .arg(endDate.toString(Qt::ISODate))); + .arg(vacation.endDate.toString(Qt::ISODate))); } - if (!sendForSpam) { + if (!vacation.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 )); + if (!vacation.excludeDomain.isEmpty()) { + condition.append(QString::fromLatin1("address :domain :contains \"from\" \"%1\"").arg( vacation.excludeDomain )); } QString addressesArgument; QStringList aliases; - if ( !addrSpecs.empty() ) { + if ( !vacation.aliases.empty() ) { addressesArgument += QLatin1String(":addresses [ "); QStringList sl; - AddrSpecList::const_iterator end = addrSpecs.constEnd(); - for ( AddrSpecList::const_iterator it = addrSpecs.begin() ; it != end; ++it ) { + 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 vacation(QLatin1String("vacation ")); - vacation += addressesArgument; - if ( notificationInterval > 0 ) - vacation += QString::fromLatin1(":days %1 ").arg(notificationInterval); + QString sVacation(QLatin1String("vacation ")); + sVacation += addressesArgument; + if ( vacation.notificationInterval > 0 ) + sVacation += QString::fromLatin1(":days %1 ").arg(vacation.notificationInterval); - if (!subject.trimmed().isEmpty()) { - vacation += QString::fromLatin1(":subject \"%1\" ").arg(stringReplace(subject).trimmed()); + if (!vacation.subject.trimmed().isEmpty()) { + sVacation += QString::fromLatin1(":subject \"%1\" ").arg(stringReplace(vacation.subject).trimmed()); } - vacation += QString::fromLatin1("text:\n"); - vacation += dotstuff( messageText.isEmpty() ? VacationUtils::defaultMessageText() : messageText ); - vacation += QString::fromLatin1( "\n.\n;" ); + sVacation += QString::fromLatin1("text:\n"); + sVacation += dotstuff( vacation.messageText.isEmpty() ? VacationUtils::defaultMessageText() : vacation.messageText ); + sVacation += QString::fromLatin1( "\n.\n;" ); QString script; - if ( startDate.isValid() || endDate.isValid() ) { + 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 (active) { - script += vacation; + if (vacation.active) { + script += sVacation; } else { script += QString::fromLatin1("if false\n{\n\t"); - script += vacation; + script += sVacation; script += QLatin1String("\n}"); } } else { - if (active) { + 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 += vacation; + 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); - 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 daed23ed6d..5179eb2a0c 100644 --- a/libksieve/ksieveui/vacation/vacationutils.h +++ b/libksieve/ksieveui/vacation/vacationutils.h @@ -1,67 +1,69 @@ /* 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 - -namespace KMime { -namespace Types { -struct AddrSpec; -typedef QList AddrSpecList; -} -} - -class QDate; +#include +#include namespace KSieveUi { namespace VacationUtils { QString defaultMessageText(); QString defaultSubject(); int defaultNotificationInterval(); -QStringList defaultMailAliases(); +KMime::Types::AddrSpecList defaultMailAliases(); bool defaultSendForSpam(); QString defaultDomainName(); QDate defaultStartDate(); QDate defaultEndDate(); -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, bool &active, QString & messageText, - QString &subject, - int & notificationInterval, QStringList & aliases, - bool & sendForSpam, QString & domainName, - QDate & startDate, QDate & endDate ); +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