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

0001 /*
0002     Copyright (c) 2009 Kevin Ottens <ervin@kde.org>
0003 
0004     This library is free software; you can redistribute it and/or modify it
0005     under the terms of the GNU Library General Public License as published by
0006     the Free Software Foundation; either version 2 of the License, or (at your
0007     option) any later version.
0008 
0009     This library is distributed in the hope that it will be useful, but WITHOUT
0010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
0012     License for more details.
0013 
0014     You should have received a copy of the GNU Library General Public License
0015     along with this library; see the file COPYING.LIB.  If not, write to the
0016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0017     02110-1301, USA.
0018 */
0019 
0020 #include "idlejob.h"
0021 
0022 #include <QtCore/QTimer>
0023 
0024 #include "job_p.h"
0025 #include "message_p.h"
0026 #include "session_p.h"
0027 
0028 namespace KIMAP2
0029 {
0030 class IdleJobPrivate : public JobPrivate
0031 {
0032 public:
0033     IdleJobPrivate(IdleJob *job, Session *session, const QString &name)
0034         : JobPrivate(session, name), q(job),
0035           messageCount(-1), recentCount(-1),
0036           lastMessageCount(-1), lastRecentCount(-1),
0037           originalSocketTimeout(-1) { }
0038     ~IdleJobPrivate() { }
0039 
0040     void emitStats()
0041     {
0042         emitStatsTimer.stop();
0043 
0044         emit q->mailBoxStats(q, m_session->selectedMailBox(),
0045                              messageCount, recentCount);
0046 
0047         lastMessageCount = messageCount;
0048         lastRecentCount = recentCount;
0049 
0050         messageCount = -1;
0051         recentCount = -1;
0052     }
0053 
0054     void resetTimeout()
0055     {
0056         sessionInternal()->setSocketTimeout(originalSocketTimeout);
0057     }
0058 
0059     IdleJob *const q;
0060 
0061     QTimer emitStatsTimer;
0062 
0063     int messageCount;
0064     int recentCount;
0065 
0066     int lastMessageCount;
0067     int lastRecentCount;
0068 
0069     int originalSocketTimeout;
0070 };
0071 }
0072 
0073 using namespace KIMAP2;
0074 
0075 IdleJob::IdleJob(Session *session)
0076     : Job(*new IdleJobPrivate(this, session, "Idle"))
0077 {
0078     Q_D(IdleJob);
0079     connect(&d->emitStatsTimer, SIGNAL(timeout()),
0080             this, SLOT(emitStats()));
0081 
0082     connect(this, SIGNAL(result(KJob*)),
0083             this, SLOT(resetTimeout()));
0084 }
0085 
0086 IdleJob::~IdleJob()
0087 {
0088 }
0089 
0090 void KIMAP2::IdleJob::stop()
0091 {
0092     Q_D(IdleJob);
0093     d->sessionInternal()->setSocketTimeout(d->originalSocketTimeout);
0094     d->sessionInternal()->sendData("DONE");
0095 }
0096 
0097 void IdleJob::doStart()
0098 {
0099     Q_D(IdleJob);
0100     d->originalSocketTimeout = d->sessionInternal()->socketTimeout();
0101     d->sessionInternal()->setSocketTimeout(-1);
0102     d->sendCommand("IDLE", {});
0103 }
0104 
0105 void IdleJob::handleResponse(const Message &response)
0106 {
0107     Q_D(IdleJob);
0108 
0109     // We can predict it'll be handled by handleErrorReplies() so emit
0110     // pending signals now (if needed) so that result() will really be
0111     // the last emitted signal.
0112     if (!response.content.isEmpty() &&
0113             d->tags.size() == 1 &&
0114             d->tags.contains(response.content.first().toString()) &&
0115             (d->messageCount >= 0 || d->recentCount >= 0)) {
0116         d->emitStats();
0117     }
0118 
0119     if (handleErrorReplies(response) == NotHandled) {
0120         if (response.content.size() > 0 && response.content[0].toString() == "+") {
0121             // Got the continuation all is fine
0122             return;
0123 
0124         } else if (response.content.size() > 2) {
0125             if (response.content[2].toString() == "EXISTS") {
0126                 if (d->messageCount >= 0) {
0127                     d->emitStats();
0128                 }
0129 
0130                 d->messageCount = response.content[1].toString().toInt();
0131             } else if (response.content[2].toString() == "RECENT") {
0132                 if (d->recentCount >= 0) {
0133                     d->emitStats();
0134                 }
0135 
0136                 d->recentCount = response.content[1].toString().toInt();
0137             } else if (response.content[2].toString() == "FETCH") {
0138                 const qint64 uid = response.content[1].toString().toLongLong();
0139                 Q_EMIT mailBoxMessageFlagsChanged(this, uid);
0140             }
0141         }
0142 
0143         if (d->messageCount >= 0 && d->recentCount >= 0) {
0144             d->emitStats();
0145         } else if (d->messageCount >= 0 || d->recentCount >= 0) {
0146             d->emitStatsTimer.start(200);
0147         }
0148     }
0149 }
0150 
0151 QString KIMAP2::IdleJob::lastMailBox() const
0152 {
0153     Q_D(const IdleJob);
0154     return d->m_session->selectedMailBox();
0155 }
0156 
0157 int KIMAP2::IdleJob::lastMessageCount() const
0158 {
0159     Q_D(const IdleJob);
0160     return d->lastMessageCount;
0161 }
0162 
0163 int KIMAP2::IdleJob::lastRecentCount() const
0164 {
0165     Q_D(const IdleJob);
0166     return d->lastRecentCount;
0167 }
0168 
0169 #include "moc_idlejob.cpp"