7#include "vacationutils.h"
8#include "vacationscriptextractor.h"
9#include <KIdentityManagementCore/Identity>
10#include <KIdentityManagementCore/IdentityManager>
11#include <ksievecore/sieve-vacation.h>
13#include <KLocalizedString>
16#include <QRegularExpression>
19using namespace KSieveCore;
33 s.
replace(reg, QStringLiteral(
" "));
37QString VacationUtils::defaultSubject()
42QString KSieveCore::VacationUtils::mailAction(KSieveCore::VacationUtils::MailAction action)
48 return i18n(
"Discard");
50 return i18n(
"Redirect to");
52 return i18n(
"Copy to");
58KSieveCore::VacationUtils::MailAction KSieveCore::VacationUtils::defaultMailAction()
60 return KSieveCore::VacationUtils::Keep;
63QString KSieveCore::VacationUtils::defaultMessageText()
66 "I am out of office till %1.\n"
68 "In urgent cases, please contact Mrs. \"vacation replacement\"\n"
70 "email: \"email address of vacation replacement\"\n"
71 "phone: +49 711 1111 11\n"
72 "fax.: +49 711 1111 12\n"
75 "-- \"enter your name and email address here\"\n",
79int VacationUtils::defaultNotificationInterval()
88 KIdentityManagementCore::IdentityManager::ConstIterator
end(manager->end());
89 for (KIdentityManagementCore::IdentityManager::ConstIterator it = manager->begin(); it != end; ++it) {
90 if (!(*it).primaryEmailAddress().isEmpty()) {
96 for (
const QString &email : lstEmails) {
106bool VacationUtils::defaultSendForSpam()
108 return KSieveCore::VacationSettings::outOfOfficeReactToSpam();
111QString VacationUtils::defaultDomainName()
113 return KSieveCore::VacationSettings::outOfOfficeDomain();
116QDate VacationUtils::defaultStartDate()
121QDate VacationUtils::defaultEndDate()
123 return defaultStartDate().
addDays(7);
126VacationUtils::Vacation VacationUtils::parseScript(
const QString &script)
128 KSieveCore::VacationUtils::Vacation vacation;
130 vacation.valid =
false;
131 vacation.active =
false;
132 vacation.mailAction = VacationUtils::defaultMailAction();
133 vacation.messageText = VacationUtils::defaultMessageText();
134 vacation.subject = VacationUtils::defaultSubject();
135 vacation.notificationInterval = VacationUtils::defaultNotificationInterval();
136 vacation.aliases = VacationUtils::defaultMailAliases();
137 vacation.sendForSpam = VacationUtils::defaultSendForSpam();
138 vacation.reactOndomainName = VacationUtils::defaultDomainName();
146 qCDebug(LIBKSIEVECORE_LOG) <<
"scriptUtf8 = \"" + scriptUTF8 +
"\"";
148 VacationDataExtractor vdx;
149 SpamDataExtractor sdx;
150 DomainRestrictionDataExtractor drdx;
152 KSieveExt::MultiScriptBuilder tsb(&vdx, &sdx, &drdx, &dx);
153 parser.setScriptBuilder(&tsb);
154 if (!parser.parse() || !vdx.commandFound()) {
155 vacation.active =
false;
156 vacation.valid =
false;
159 vacation.valid =
true;
160 vacation.active = vdx.active();
161 vacation.mailAction = vdx.mailAction();
162 vacation.mailActionRecipient = vdx.mailActionRecipient();
163 vacation.messageText = vdx.messageText().
trimmed();
164 if (!vdx.subject().
isEmpty()) {
165 vacation.subject = vdx.subject().
trimmed();
167 vacation.notificationInterval = vdx.notificationInterval();
170 for (
const QString &alias : lstAliases) {
173 vacation.aliases.
append(a.addrSpec());
176 if (!vacation.active && !vdx.ifComment().
isEmpty()) {
177 const QByteArray newScript = QByteArrayLiteral(
"if ") + vdx.ifComment().
toUtf8() + QByteArrayLiteral(
"{vacation;}");
178 tsb = KSieveExt::MultiScriptBuilder(&sdx, &drdx, &dx);
180 activeScriptParser.setScriptBuilder(&tsb);
181 if (!activeScriptParser.parse()) {
182 vacation.valid =
false;
187 vacation.sendForSpam = !sdx.found();
188 vacation.reactOndomainName = drdx.domainName();
189 vacation.startDate = dx.startDate();
190 vacation.startTime = dx.startTime();
191 vacation.endDate = dx.endDate();
192 vacation.endTime = dx.endTime();
197QString KSieveCore::VacationUtils::composeScript(
const Vacation &vacation)
202 require << QStringLiteral(
"vacation");
204 if (vacation.startDate.isValid() || vacation.endDate.isValid()) {
205 require << QStringLiteral(
"date");
206 require << QStringLiteral(
"relational");
209 if (vacation.startDate.isValid()) {
210 if (vacation.startTime.isValid()) {
212 condition.
append(QStringLiteral(
"currentdate :value \"ge\" \"iso8601\" \"%1\"").arg(
start.toString(
Qt::ISODate)));
214 condition.
append(QStringLiteral(
"currentdate :value \"ge\" \"date\" \"%1\"").arg(vacation.startDate.toString(
Qt::ISODate)));
218 if (vacation.endDate.isValid()) {
219 if (vacation.endTime.isValid()) {
220 const QDateTime end(vacation.endDate, vacation.endTime);
221 condition.
append(QStringLiteral(
"currentdate :value \"le\" \"iso8601\" \"%1\"").arg(
end.toString(
Qt::ISODate)));
223 condition.
append(QStringLiteral(
"currentdate :value \"le\" \"date\" \"%1\"").arg(vacation.endDate.toString(
Qt::ISODate)));
227 if (!vacation.sendForSpam) {
228 condition.
append(QStringLiteral(
"not header :contains \"X-Spam-Flag\" \"YES\""));
231 if (!vacation.reactOndomainName.isEmpty()) {
232 condition.
append(QStringLiteral(
"address :domain :contains \"from\" \"%1\"").arg(vacation.reactOndomainName));
237 if (!vacation.aliases.empty()) {
238 addressesArgument += QStringLiteral(
":addresses [ ");
240 sl.
reserve(vacation.aliases.count());
251 QString sVacation(QStringLiteral(
"vacation "));
252 sVacation += addressesArgument;
253 if (vacation.notificationInterval > 0) {
254 sVacation += QStringLiteral(
":days %1 ").arg(vacation.notificationInterval);
257 if (!vacation.subject.trimmed().isEmpty()) {
258 sVacation += QStringLiteral(
":subject \"%1\" ").arg(stringReplace(vacation.subject).
trimmed());
261 sVacation += QStringLiteral(
"text:\n");
262 sVacation += dotstuff(vacation.messageText.isEmpty() ? VacationUtils::defaultMessageText() : vacation.messageText);
263 sVacation += QStringLiteral(
"\n.\n;");
265 switch (vacation.mailAction) {
266 case VacationUtils::Keep:
268 case VacationUtils::Discard:
269 sVacation += QStringLiteral(
"\ndiscard;");
271 case VacationUtils::Sendto:
274 case VacationUtils::CopyTo:
275 require << QStringLiteral(
"copy");
280 QString script = QStringLiteral(
"require [\"%1\"];\n\n").
arg(require.
join(QStringLiteral(
"\", \"")));
283 if (vacation.active) {
286 script += QStringLiteral(
"if false\n{\n\t");
288 script += QStringLiteral(
"\n}");
291 if (vacation.active) {
292 script += QStringLiteral(
"if allof(%1)\n{\n\t").
arg(condition.
join(QStringLiteral(
", ")));
294 script += QStringLiteral(
"if false # allof(%1)\n{\n\t").
arg(condition.
join(QStringLiteral(
", ")));
297 script += QStringLiteral(
"\n}");
300 script += QStringLiteral(
"\n");
305QString KSieveCore::VacationUtils::mergeRequireLine(
const QString &script,
const QString &scriptUpdate)
313 if (scriptUpdateUTF8.
isEmpty()) {
320 RequireExtractor rxUpdate;
321 parser.setScriptBuilder(&rx);
322 parserUpdate.setScriptBuilder(&rxUpdate);
328 if (parser.parse() && rx.commandFound()) {
330 const int endOld(rx.lineEnd());
331 for (
int i = insert; i <= endOld; ++i) {
334 const auto requirementsSet = rx.requirements();
335 requirements =
QSet<QString>(requirementsSet.begin(), requirementsSet.end());
338 if (parserUpdate.parse() && rxUpdate.commandFound()) {
339 const auto requirementsSet = rxUpdate.requirements();
340 requirements +=
QSet<QString>(requirementsSet.begin(), requirementsSet.end());
343 const int requirementscount = requirements.
count();
344 if (requirementscount > 1) {
347 lines.
insert(insert, QStringLiteral(
"require [\"%1\"];").arg(req.
join(QStringLiteral(
"\", \""))));
348 }
else if (requirementscount == 1) {
355QString KSieveCore::VacationUtils::updateVacationBlock(
const QString &oldScript,
const QString &newScript)
369 VacationDataExtractor vdxOld;
370 VacationDataExtractor vdxNew;
372 KSieveExt::MultiScriptBuilder tsb(&vdxOld, &rx);
373 parserOld.setScriptBuilder(&tsb);
374 parserNew.setScriptBuilder(&vdxNew);
380 if (parserOld.parse() && vdxOld.commandFound()) {
381 startOld = vdxOld.lineStart();
382 const int endOld(vdxOld.lineEnd());
383 for (
int i = startOld; i <= endOld; ++i) {
387 if (rx.commandFound()) {
388 startOld = rx.lineEnd() + 1;
394 if (parserNew.parse() && vdxNew.commandFound()) {
395 const int startNew(vdxNew.lineStart());
396 const int endNew(vdxNew.lineEnd());
398 for (
int i = endNew; i >= startNew; --i) {
399 lines.
insert(startOld, linesNew.
at(i));
static IdentityManager * self()
void fromUnicodeString(QStringView s)
Parser for the Sieve grammar.
Q_SCRIPTABLE Q_NOREPLY void start()
QString i18n(const char *text, const TYPE &arg...)
bool insert(Part *part, qint64 *insertId=nullptr)
char * toString(const EngineQuery &query)
const QList< QKeySequence > & end()
const QList< QKeySequence > & replace()
bool isEmpty() const const
qsizetype length() const const
QDate addDays(qint64 ndays) const const
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
const T & constFirst() const const
iterator insert(const_iterator before, parameter_type value)
bool isEmpty() const const
void push_back(parameter_type value)
void removeAt(qsizetype i)
void reserve(qsizetype size)
qsizetype count() const const
QList< T > values() const const
QString arg(Args &&... args) const const
bool isEmpty() const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QByteArray toUtf8() const const
QString trimmed() const const
QString join(QChar separator) const const
void sort(Qt::CaseSensitivity cs)