File indexing completed on 2024-05-19 05:17:42

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 "listjob.h"
0021 
0022 #include "job_p.h"
0023 #include "message_p.h"
0024 #include "rfccodecs.h"
0025 #include "session_p.h"
0026 
0027 static const int _kimap_mailBoxDescriptorId = qRegisterMetaType<KIMAP2::MailBoxDescriptor>();
0028 
0029 namespace KIMAP2
0030 {
0031 class ListJobPrivate : public JobPrivate
0032 {
0033 public:
0034     ListJobPrivate(ListJob *job, Session *session, const QString &name) : JobPrivate(session, name), q(job), option(ListJob::NoOption) { }
0035     ~ListJobPrivate() { }
0036 
0037     ListJob *const q;
0038 
0039     ListJob::Option option;
0040     QList<MailBoxDescriptor> namespaces;
0041     QByteArray command;
0042 };
0043 }
0044 
0045 using namespace KIMAP2;
0046 
0047 ListJob::ListJob(Session *session)
0048     : Job(*new ListJobPrivate(this, session, "List"))
0049 {
0050 }
0051 
0052 ListJob::~ListJob()
0053 {
0054 }
0055 
0056 void ListJob::setOption(Option option)
0057 {
0058     Q_D(ListJob);
0059     d->option = option;
0060 }
0061 
0062 ListJob::Option ListJob::option() const
0063 {
0064     Q_D(const ListJob);
0065     return d->option;
0066 }
0067 
0068 void ListJob::setQueriedNamespaces(const QList<MailBoxDescriptor> &namespaces)
0069 {
0070     Q_D(ListJob);
0071     d->namespaces = namespaces;
0072 }
0073 
0074 QList<MailBoxDescriptor> ListJob::queriedNamespaces() const
0075 {
0076     Q_D(const ListJob);
0077     return d->namespaces;
0078 }
0079 
0080 void ListJob::doStart()
0081 {
0082     Q_D(ListJob);
0083 
0084     switch (d->option) {
0085         break;
0086     case IncludeUnsubscribed:
0087         d->command = "LIST";
0088         break;
0089     case IncludeFolderRoleFlags:
0090         d->command = "XLIST";
0091         break;
0092     case NoOption:
0093     default:
0094         d->command = "LSUB";
0095     }
0096 
0097     if (d->namespaces.isEmpty()) {
0098         d->sendCommand(d->command, "\"\" *");
0099     } else {
0100         foreach (const MailBoxDescriptor &descriptor, d->namespaces) {
0101             QString parameters = QStringLiteral("\"\" \"%1\"");
0102 
0103             if (descriptor.name.endsWith(descriptor.separator)) {
0104                 QString name = encodeImapFolderName(descriptor.name);
0105                 name.chop(1);
0106                 d->sendCommand(d->command,
0107                         parameters.arg(name).toUtf8());
0108             }
0109 
0110             d->sendCommand(d->command,
0111                     parameters.arg(descriptor.name + QLatin1Char('*')).toUtf8());
0112         }
0113     }
0114 }
0115 
0116 void ListJob::handleResponse(const Message &response)
0117 {
0118     Q_D(ListJob);
0119 
0120     if (handleErrorReplies(response) == NotHandled) {
0121         if (response.content.size() >= 5 && response.content[1].toString() == d->command) {
0122             QList<QByteArray> flags = response.content[2].toList();
0123             for (QList<QByteArray>::iterator it = flags.begin(), itEnd = flags.end(); it != itEnd; ++it) {
0124                 *it = it->toLower();
0125             }
0126             QByteArray separator = response.content[3].toString();
0127             if (separator.isEmpty()) {
0128                 // Defaults to / for servers reporting an empty list
0129                 // it's supposedly not a problem as servers doing that
0130                 // only do it for mailboxes with no child.
0131                 separator = "/"; //krazy:exclude=doublequote_chars since a QByteArray
0132             }
0133             Q_ASSERT(separator.size() == 1);
0134             QByteArray fullName;
0135             for (int i = 4; i < response.content.size(); i++) {
0136                 fullName += response.content[i].toString() + ' ';
0137             }
0138             fullName.chop(1);
0139 
0140             fullName = decodeImapFolderName(fullName);
0141 
0142             MailBoxDescriptor mailBoxDescriptor;
0143             mailBoxDescriptor.separator = QLatin1Char(separator[0]);
0144             mailBoxDescriptor.name = QString::fromUtf8(fullName);
0145             convertInboxName(mailBoxDescriptor);
0146 
0147             emit resultReceived(mailBoxDescriptor, flags);
0148         }
0149     }
0150 }
0151 
0152 void ListJob::convertInboxName(KIMAP2::MailBoxDescriptor &descriptor)
0153 {
0154     //Inbox must be case sensitive, according to the RFC, so make it always uppercase
0155     QStringList pathParts = descriptor.name.split(descriptor.separator);
0156     if (!pathParts.isEmpty() &&
0157             pathParts[0].compare(QLatin1String("INBOX"), Qt::CaseInsensitive) == 0) {
0158         pathParts.removeAt(0);
0159         descriptor.name = QStringLiteral("INBOX");
0160         if (!pathParts.isEmpty()) {
0161             descriptor.name += descriptor.separator + pathParts.join(descriptor.separator);
0162         }
0163     }
0164 }
0165 #include "moc_listjob.cpp"