1 /*
2 SPDX-FileCopyrightText: 2014-2021 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "followupremindermanager.h"
8 #include "followupreminderagent_debug.h"
9 #include "followupreminderinfo.h"
10 #include "followupremindernoanswerdialog.h"
11 #include "followupreminderutil.h"
12 #include "jobs/followupreminderfinishtaskjob.h"
13 #include "jobs/followupreminderjob.h"
14
15 #include <Akonadi/KMime/SpecialMailCollections>
16
17 #include <KConfig>
18 #include <KConfigGroup>
19 #include <KLocalizedString>
20 #include <KNotification>
21 #include <QRegularExpression>
22 using namespace FollowUpReminder;
23
FollowUpReminderManager(QObject * parent)24 FollowUpReminderManager::FollowUpReminderManager(QObject *parent)
25 : QObject(parent)
26 {
27 mConfig = KSharedConfig::openConfig();
28 }
29
~FollowUpReminderManager()30 FollowUpReminderManager::~FollowUpReminderManager()
31 {
32 qDeleteAll(mFollowUpReminderInfoList);
33 mFollowUpReminderInfoList.clear();
34 }
35
load(bool forceReloadConfig)36 void FollowUpReminderManager::load(bool forceReloadConfig)
37 {
38 if (forceReloadConfig) {
39 mConfig->reparseConfiguration();
40 }
41 const QStringList itemList = mConfig->groupList().filter(QRegularExpression(QStringLiteral("FollowupReminderItem \\d+")));
42 const int numberOfItems = itemList.count();
43 QList<FollowUpReminder::FollowUpReminderInfo *> noAnswerList;
44 for (int i = 0; i < numberOfItems; ++i) {
45 KConfigGroup group = mConfig->group(itemList.at(i));
46
47 auto info = new FollowUpReminderInfo(group);
48 if (info->isValid()) {
49 if (!info->answerWasReceived()) {
50 mFollowUpReminderInfoList.append(info);
51 if (!mInitialize) {
52 auto noAnswerInfo = new FollowUpReminderInfo(*info);
53 noAnswerList.append(noAnswerInfo);
54 } else {
55 delete info;
56 }
57 } else {
58 delete info;
59 }
60 } else {
61 delete info;
62 }
63 }
64 if (!noAnswerList.isEmpty()) {
65 mInitialize = true;
66 if (!mNoAnswerDialog.data()) {
67 mNoAnswerDialog = new FollowUpReminderNoAnswerDialog;
68 connect(mNoAnswerDialog.data(),
69 &FollowUpReminderNoAnswerDialog::needToReparseConfiguration,
70 this,
71 &FollowUpReminderManager::slotReparseConfiguration);
72 }
73 mNoAnswerDialog->setInfo(noAnswerList);
74 mNoAnswerDialog->wakeUp();
75 }
76 }
77
addReminder(FollowUpReminder::FollowUpReminderInfo * info)78 void FollowUpReminderManager::addReminder(FollowUpReminder::FollowUpReminderInfo *info)
79 {
80 if (info->isValid()) {
81 FollowUpReminderUtil::writeFollowupReminderInfo(FollowUpReminderUtil::defaultConfig(), info, true);
82 } else {
83 delete info;
84 }
85 }
86
slotReparseConfiguration()87 void FollowUpReminderManager::slotReparseConfiguration()
88 {
89 load(true);
90 }
91
checkFollowUp(const Akonadi::Item & item,const Akonadi::Collection & col)92 void FollowUpReminderManager::checkFollowUp(const Akonadi::Item &item, const Akonadi::Collection &col)
93 {
94 if (mFollowUpReminderInfoList.isEmpty()) {
95 return;
96 }
97
98 const Akonadi::SpecialMailCollections::Type type = Akonadi::SpecialMailCollections::self()->specialCollectionType(col);
99 switch (type) {
100 case Akonadi::SpecialMailCollections::Trash:
101 case Akonadi::SpecialMailCollections::Outbox:
102 case Akonadi::SpecialMailCollections::Drafts:
103 case Akonadi::SpecialMailCollections::Templates:
104 case Akonadi::SpecialMailCollections::SentMail:
105 return;
106 default:
107 break;
108 }
109
110 auto job = new FollowUpReminderJob(this);
111 connect(job, &FollowUpReminderJob::finished, this, &FollowUpReminderManager::slotCheckFollowUpFinished);
112 job->setItem(item);
113 job->start();
114 }
115
slotCheckFollowUpFinished(const QString & messageId,Akonadi::Item::Id id)116 void FollowUpReminderManager::slotCheckFollowUpFinished(const QString &messageId, Akonadi::Item::Id id)
117 {
118 for (FollowUpReminderInfo *info : std::as_const(mFollowUpReminderInfoList)) {
119 qCDebug(FOLLOWUPREMINDERAGENT_LOG) << "FollowUpReminderManager::slotCheckFollowUpFinished info:" << info;
120 if (!info) {
121 continue;
122 }
123 if (info->messageId() == messageId) {
124 info->setAnswerMessageItemId(id);
125 info->setAnswerWasReceived(true);
126 answerReceived(info->to());
127 if (info->todoId() != -1) {
128 auto job = new FollowUpReminderFinishTaskJob(info->todoId(), this);
129 connect(job, &FollowUpReminderFinishTaskJob::finishTaskDone, this, &FollowUpReminderManager::slotFinishTaskDone);
130 connect(job, &FollowUpReminderFinishTaskJob::finishTaskFailed, this, &FollowUpReminderManager::slotFinishTaskFailed);
131 job->start();
132 }
133 // Save item
134 FollowUpReminder::FollowUpReminderUtil::writeFollowupReminderInfo(FollowUpReminder::FollowUpReminderUtil::defaultConfig(), info, true);
135 break;
136 }
137 }
138 }
139
slotFinishTaskDone()140 void FollowUpReminderManager::slotFinishTaskDone()
141 {
142 qCDebug(FOLLOWUPREMINDERAGENT_LOG) << " Task Done";
143 // TODO
144 }
145
slotFinishTaskFailed()146 void FollowUpReminderManager::slotFinishTaskFailed()
147 {
148 qCDebug(FOLLOWUPREMINDERAGENT_LOG) << " Task Failed";
149 // TODO
150 }
151
answerReceived(const QString & from)152 void FollowUpReminderManager::answerReceived(const QString &from)
153 {
154 KNotification::event(QStringLiteral("mailreceived"),
155 QString(),
156 i18n("Answer from %1 received", from),
157 QStringLiteral("kmail"),
158 nullptr,
159 KNotification::CloseOnTimeout,
160 QStringLiteral("akonadi_followupreminder_agent"));
161 }
162
printDebugInfo() const163 QString FollowUpReminderManager::printDebugInfo() const
164 {
165 QString infoStr;
166 if (mFollowUpReminderInfoList.isEmpty()) {
167 infoStr = QStringLiteral("No mail");
168 } else {
169 for (FollowUpReminder::FollowUpReminderInfo *info : std::as_const(mFollowUpReminderInfoList)) {
170 if (!infoStr.isEmpty()) {
171 infoStr += QLatin1Char('\n');
172 }
173 infoStr += infoToStr(info);
174 }
175 }
176 return infoStr;
177 }
178
infoToStr(FollowUpReminder::FollowUpReminderInfo * info) const179 QString FollowUpReminderManager::infoToStr(FollowUpReminder::FollowUpReminderInfo *info) const
180 {
181 QString infoStr = QStringLiteral("****************************************");
182 infoStr += QStringLiteral("Akonadi Item id :%1\n").arg(info->originalMessageItemId());
183 infoStr += QStringLiteral("MessageId :%1\n").arg(info->messageId());
184 infoStr += QStringLiteral("Subject :%1\n").arg(info->subject());
185 infoStr += QStringLiteral("To :%1\n").arg(info->to());
186 infoStr += QStringLiteral("Dead Line :%1\n").arg(info->followUpReminderDate().toString());
187 infoStr += QStringLiteral("Answer received :%1\n").arg(info->answerWasReceived() ? QStringLiteral("true") : QStringLiteral("false"));
188 infoStr += QStringLiteral("****************************************\n");
189 return infoStr;
190 }
191