File indexing completed on 2024-05-12 05:17:14

0001 /*
0002     SPDX-FileCopyrightText: 2009 Kevin Ottens <ervin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "idlejob.h"
0008 
0009 #include <KLocalizedString>
0010 #include <QTimer>
0011 
0012 #include "job_p.h"
0013 #include "response_p.h"
0014 #include "session_p.h"
0015 
0016 namespace KIMAP
0017 {
0018 class IdleJobPrivate : public JobPrivate
0019 {
0020 public:
0021     IdleJobPrivate(IdleJob *job, Session *session, const QString &name)
0022         : JobPrivate(session, name)
0023         , q(job)
0024     {
0025     }
0026     ~IdleJobPrivate()
0027     {
0028     }
0029 
0030     void emitStats()
0031     {
0032         emitStatsTimer.stop();
0033 
0034         Q_EMIT q->mailBoxStats(q, m_session->selectedMailBox(), messageCount, recentCount);
0035 
0036         lastMessageCount = messageCount;
0037         lastRecentCount = recentCount;
0038 
0039         messageCount = -1;
0040         recentCount = -1;
0041     }
0042 
0043     void resetTimeout()
0044     {
0045         sessionInternal()->setSocketTimeout(originalSocketTimeout);
0046     }
0047 
0048     IdleJob *const q;
0049 
0050     QTimer emitStatsTimer;
0051 
0052     int messageCount = -1;
0053     int recentCount = -1;
0054 
0055     int lastMessageCount = -1;
0056     int lastRecentCount = -1;
0057 
0058     int originalSocketTimeout = -1;
0059 };
0060 }
0061 
0062 using namespace KIMAP;
0063 
0064 IdleJob::IdleJob(Session *session)
0065     : Job(*new IdleJobPrivate(this, session, i18nc("name of the idle job", "Idle")))
0066 {
0067     Q_D(IdleJob);
0068     connect(&d->emitStatsTimer, &QTimer::timeout, this, [d]() {
0069         d->emitStats();
0070     });
0071 
0072     connect(this, &KJob::result, this, [d]() {
0073         d->resetTimeout();
0074     });
0075 }
0076 
0077 IdleJob::~IdleJob()
0078 {
0079 }
0080 
0081 void KIMAP::IdleJob::stop()
0082 {
0083     Q_D(IdleJob);
0084     d->sessionInternal()->setSocketTimeout(d->originalSocketTimeout);
0085     d->sessionInternal()->sendData("DONE");
0086 }
0087 
0088 void IdleJob::doStart()
0089 {
0090     Q_D(IdleJob);
0091     d->originalSocketTimeout = d->sessionInternal()->socketTimeout();
0092     d->sessionInternal()->setSocketTimeout(-1);
0093     d->tags << d->sessionInternal()->sendCommand("IDLE");
0094 }
0095 
0096 void IdleJob::handleResponse(const Response &response)
0097 {
0098     Q_D(IdleJob);
0099 
0100     // We can predict it'll be handled by handleErrorReplies() so Q_EMIT
0101     // pending signals now (if needed) so that result() will really be
0102     // the last emitted signal.
0103     if (!response.content.isEmpty() && d->tags.size() == 1 && d->tags.contains(response.content.first().toString())
0104         && (d->messageCount >= 0 || d->recentCount >= 0)) {
0105         d->emitStats();
0106     }
0107 
0108     if (handleErrorReplies(response) == NotHandled) {
0109         if (!response.content.isEmpty() && response.content[0].toString() == "+") {
0110             // Got the continuation all is fine
0111             return;
0112 
0113         } else if (response.content.size() > 2) {
0114             const QByteArray ba = response.content[2].toString();
0115             if (ba == "EXISTS") {
0116                 if (d->messageCount >= 0) {
0117                     d->emitStats();
0118                 }
0119 
0120                 d->messageCount = response.content[1].toString().toInt();
0121             } else if (ba == "RECENT") {
0122                 if (d->recentCount >= 0) {
0123                     d->emitStats();
0124                 }
0125 
0126                 d->recentCount = response.content[1].toString().toInt();
0127             } else if (ba == "FETCH") {
0128                 const qint64 uid = response.content[1].toString().toLongLong();
0129                 Q_EMIT mailBoxMessageFlagsChanged(this, uid);
0130             }
0131         }
0132 
0133         if (d->messageCount >= 0 && d->recentCount >= 0) {
0134             d->emitStats();
0135         } else if (d->messageCount >= 0 || d->recentCount >= 0) {
0136             d->emitStatsTimer.start(200);
0137         }
0138     }
0139 }
0140 
0141 QString KIMAP::IdleJob::lastMailBox() const
0142 {
0143     Q_D(const IdleJob);
0144     return d->m_session->selectedMailBox();
0145 }
0146 
0147 int KIMAP::IdleJob::lastMessageCount() const
0148 {
0149     Q_D(const IdleJob);
0150     return d->lastMessageCount;
0151 }
0152 
0153 int KIMAP::IdleJob::lastRecentCount() const
0154 {
0155     Q_D(const IdleJob);
0156     return d->lastRecentCount;
0157 }
0158 
0159 #include "moc_idlejob.cpp"