File indexing completed on 2024-05-12 05:10:48
0001 /* 0002 SPDX-FileCopyrightText: 2001, 2004 Cornelius Schumacher <schumacher@kde.org> 0003 SPDX-FileCopyrightText: 2010, 2012 Sérgio Martins <iamsergio@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "mailscheduler_p.h" 0009 #include "calendarbase.h" 0010 #include "calendarsettings.h" 0011 #include "utils_p.h" 0012 0013 #include <KCalendarCore/ICalFormat> 0014 #include <KCalendarCore/ScheduleMessage> 0015 #include <KIdentityManagementCore/Identity> 0016 #include <KIdentityManagementCore/IdentityManager> 0017 0018 #include <KLocalizedString> 0019 #include <QStandardPaths> 0020 0021 using namespace Akonadi; 0022 using namespace KIdentityManagementCore; 0023 0024 class Akonadi::MailSchedulerPrivate 0025 { 0026 public: 0027 [[nodiscard]] KIdentityManagementCore::Identity identityForIncidence(const KCalendarCore::IncidenceBase::Ptr &incidence) const; 0028 [[nodiscard]] KIdentityManagementCore::Identity identityForAddress(const QString &address) const; 0029 0030 MailClient::MailPrivacyFlags privacyFlags() const 0031 { 0032 MailClient::MailPrivacyFlags flags; 0033 flags.setFlag(MailClient::MailPrivacySign, m_sign); 0034 flags.setFlag(MailClient::MailPrivacyEncrypt, m_encrypt); 0035 return flags; 0036 } 0037 0038 KIdentityManagementCore::IdentityManager *m_identityManager = nullptr; 0039 MailClient *m_mailer = nullptr; 0040 bool m_encrypt = false; 0041 bool m_sign = false; 0042 }; 0043 0044 MailScheduler::MailScheduler(ITIPHandlerComponentFactory *factory, QObject *parent) 0045 : Scheduler(parent) 0046 , d(new MailSchedulerPrivate()) 0047 { 0048 d->m_identityManager = KIdentityManagementCore::IdentityManager::self(); 0049 d->m_mailer = new MailClient(factory, parent); 0050 0051 connect(d->m_mailer, &MailClient::finished, this, &MailScheduler::onMailerFinished); 0052 } 0053 0054 MailScheduler::~MailScheduler() 0055 { 0056 delete d->m_mailer; 0057 } 0058 0059 KIdentityManagementCore::Identity MailSchedulerPrivate::identityForIncidence(const KCalendarCore::IncidenceBase::Ptr &incidence) const 0060 { 0061 const auto organizer = incidence->organizer(); 0062 const QString organizerEmail = !organizer.isEmpty() ? organizer.email() : CalendarUtils::email(); 0063 return m_identityManager->identityForAddress(organizerEmail); 0064 } 0065 0066 KIdentityManagementCore::Identity MailSchedulerPrivate::identityForAddress(const QString &address) const 0067 { 0068 return m_identityManager->identityForAddress(address); 0069 } 0070 0071 void MailScheduler::publish(const KCalendarCore::IncidenceBase::Ptr &incidence, const QString &recipients) 0072 { 0073 Q_ASSERT(incidence); 0074 if (!incidence) { 0075 return; 0076 } 0077 0078 const QString messageText = mFormat->createScheduleMessage(incidence, KCalendarCore::iTIPPublish); 0079 d->m_mailer->mailTo(incidence, 0080 d->identityForIncidence(incidence), 0081 CalendarUtils::email(), 0082 KCalendarCore::iTIPPublish, 0083 CalendarSettings::self()->bcc(), 0084 recipients, 0085 messageText, 0086 {}, 0087 d->privacyFlags()); 0088 } 0089 0090 void MailScheduler::performTransaction(const KCalendarCore::IncidenceBase::Ptr &incidence, 0091 KCalendarCore::iTIPMethod method, 0092 const QString &recipients, 0093 const QString &sender) 0094 { 0095 Q_ASSERT(incidence); 0096 if (!incidence) { 0097 return; 0098 } 0099 const QString messageText = mFormat->createScheduleMessage(incidence, method); 0100 0101 const auto identity = sender.isEmpty() ? d->identityForIncidence(incidence) : d->identityForAddress(sender); 0102 0103 d->m_mailer->mailTo(incidence, identity, Akonadi::CalendarUtils::email(), method, CalendarSettings::self()->bcc(), recipients, messageText, {}, d->privacyFlags()); 0104 } 0105 0106 void MailScheduler::performTransaction(const KCalendarCore::IncidenceBase::Ptr &incidence, KCalendarCore::iTIPMethod method, const QString &sender) 0107 { 0108 Q_ASSERT(incidence); 0109 if (!incidence) { 0110 return; 0111 } 0112 0113 const QString messageText = mFormat->createScheduleMessage(incidence, method); 0114 const auto identity = sender.isEmpty() ? d->identityForIncidence(incidence) : d->identityForAddress(sender); 0115 0116 if (method == KCalendarCore::iTIPRequest || method == KCalendarCore::iTIPCancel || method == KCalendarCore::iTIPAdd 0117 || method == KCalendarCore::iTIPDeclineCounter) { 0118 d->m_mailer->mailAttendees(incidence, identity, method, CalendarSettings::self()->bcc(), messageText, {}, d->privacyFlags()); 0119 } else { 0120 QString subject; 0121 KCalendarCore::Incidence::Ptr inc = incidence.dynamicCast<KCalendarCore::Incidence>(); 0122 if (inc && method == KCalendarCore::iTIPCounter) { 0123 subject = i18n("Counter proposal: %1", inc->summary()); 0124 } 0125 0126 const auto from = sender.isEmpty() ? CalendarUtils::email() : sender; 0127 0128 d->m_mailer->mailOrganizer(incidence, identity, sender, method, CalendarSettings::self()->bcc(), messageText, subject, {}, d->privacyFlags()); 0129 } 0130 } 0131 0132 QString MailScheduler::freeBusyDir() const 0133 { 0134 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/korganizer/freebusy"); 0135 } 0136 0137 // TODO: AKONADI_PORT review following code 0138 void MailScheduler::acceptCounterProposal(const KCalendarCore::Incidence::Ptr &incidence, const Akonadi::CalendarBase::Ptr &calendar) 0139 { 0140 Q_ASSERT(incidence); 0141 Q_ASSERT(calendar); 0142 if (!incidence || !calendar) { 0143 return; 0144 } 0145 0146 Akonadi::Item exInc = calendar->item(incidence); 0147 if (!exInc.isValid()) { 0148 KCalendarCore::Incidence::Ptr exIncidence = calendar->incidenceFromSchedulingID(incidence->uid()); 0149 if (exIncidence) { 0150 exInc = calendar->item(exIncidence); 0151 } 0152 // exInc = exIncItem.isValid() && exIncItem.hasPayload<KCalendarCore::Incidence::Ptr>() ? 0153 // exIncItem.payload<KCalendarCore::Incidence::Ptr>() : KCalendarCore::Incidence::Ptr(); 0154 } 0155 0156 incidence->setRevision(incidence->revision() + 1); 0157 Result result = ResultSuccess; 0158 0159 if (exInc.isValid() && exInc.hasPayload<KCalendarCore::Incidence::Ptr>()) { 0160 auto exIncPtr = exInc.payload<KCalendarCore::Incidence::Ptr>(); 0161 incidence->setRevision(qMax(incidence->revision(), exIncPtr->revision() + 1)); 0162 // some stuff we don't want to change, just to be safe 0163 incidence->setSchedulingID(exIncPtr->schedulingID()); 0164 incidence->setUid(exIncPtr->uid()); 0165 0166 Q_ASSERT(exIncPtr && incidence); 0167 0168 KCalendarCore::IncidenceBase::Ptr i1 = exIncPtr; 0169 KCalendarCore::IncidenceBase::Ptr i2 = incidence; 0170 0171 if (i1->type() == i2->type()) { 0172 *i1 = *i2; 0173 } 0174 0175 exIncPtr->updated(); 0176 0177 if (!calendar->modifyIncidence(exIncPtr)) { 0178 result = ResultModifyingError; 0179 } 0180 } else { 0181 if (!calendar->addIncidence(KCalendarCore::Incidence::Ptr(incidence->clone()))) { 0182 result = ResultCreatingError; 0183 } 0184 } 0185 0186 if (result != ResultSuccess) { 0187 Q_EMIT transactionFinished(result, QStringLiteral("Error creating job")); 0188 } else { 0189 // Nothing to do here. Signal will be emitted when we hear back from the calendar. 0190 } 0191 } 0192 0193 void MailScheduler::onMailerFinished(Akonadi::MailClient::Result result, const QString &errorMsg) 0194 { 0195 if (result == MailClient::ResultSuccess) { 0196 Q_EMIT transactionFinished(ResultSuccess, QString()); 0197 } else { 0198 const QString message = i18n("Error sending e-mail: ") + errorMsg; 0199 Q_EMIT transactionFinished(ResultGenericError, message); 0200 } 0201 } 0202 0203 void MailScheduler::setEncrypt(bool encrypt) 0204 { 0205 d->m_encrypt = encrypt; 0206 } 0207 0208 void MailScheduler::setSign(bool sign) 0209 { 0210 d->m_sign = sign; 0211 } 0212 0213 #include "moc_mailscheduler_p.cpp"