File indexing completed on 2024-05-12 05:17:24
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 "namespacejob.h" 0021 0022 #include "kimap_debug.h" 0023 0024 #include "job_p.h" 0025 #include "listjob.h" 0026 #include "message_p.h" 0027 #include "rfccodecs.h" 0028 #include "session_p.h" 0029 0030 static QList<QByteArray> parseParenthesizedList(const QByteArray &data) 0031 { 0032 QList<QByteArray> result; 0033 if (data.isEmpty()) { 0034 return result; 0035 } 0036 if (data.at(0) != '(') { 0037 return result; 0038 } 0039 bool parsingString = false; 0040 int start = 0; 0041 for (int pos = 1; pos < data.size(); pos++) { 0042 //Match unescaped quotes 0043 if (data.at(pos) == '\"' && data.at(pos - 1) != '\\') { 0044 if (parsingString) { 0045 parsingString = false; 0046 result << data.mid(start, pos - start); 0047 } else { 0048 parsingString = true; 0049 start = pos + 1; 0050 } 0051 } 0052 } 0053 return result; 0054 } 0055 0056 namespace KIMAP2 0057 { 0058 class NamespaceJobPrivate : public JobPrivate 0059 { 0060 public: 0061 NamespaceJobPrivate(Session *session, const QString &name) : JobPrivate(session, name) { } 0062 ~NamespaceJobPrivate() { } 0063 0064 QList<MailBoxDescriptor> processNamespaceList(const QList<QByteArray> &namespaceList) 0065 { 0066 QList<MailBoxDescriptor> result; 0067 0068 foreach (const QByteArray &namespaceItem, namespaceList) { 0069 QList<QByteArray> parts = parseParenthesizedList(namespaceItem); 0070 if (parts.size() < 2) { 0071 qWarning() << "Not enough parts in namespace item " << namespaceItem; 0072 continue; 0073 } 0074 MailBoxDescriptor descriptor; 0075 descriptor.name = QString::fromUtf8(decodeImapFolderName(parts[0])); 0076 descriptor.separator = QLatin1Char(parts[1][0]); 0077 0078 result << descriptor; 0079 } 0080 0081 return result; 0082 } 0083 0084 QList<MailBoxDescriptor> personalNamespaces; 0085 QList<MailBoxDescriptor> userNamespaces; 0086 QList<MailBoxDescriptor> sharedNamespaces; 0087 }; 0088 } 0089 0090 using namespace KIMAP2; 0091 0092 NamespaceJob::NamespaceJob(Session *session) 0093 : Job(*new NamespaceJobPrivate(session, "Namespace")) 0094 { 0095 } 0096 0097 NamespaceJob::~NamespaceJob() 0098 { 0099 } 0100 0101 QList<MailBoxDescriptor> NamespaceJob::personalNamespaces() const 0102 { 0103 Q_D(const NamespaceJob); 0104 return d->personalNamespaces; 0105 } 0106 0107 QList<MailBoxDescriptor> NamespaceJob::userNamespaces() const 0108 { 0109 Q_D(const NamespaceJob); 0110 return d->userNamespaces; 0111 } 0112 0113 QList<MailBoxDescriptor> NamespaceJob::sharedNamespaces() const 0114 { 0115 Q_D(const NamespaceJob); 0116 return d->sharedNamespaces; 0117 } 0118 0119 bool NamespaceJob::containsEmptyNamespace() const 0120 { 0121 Q_D(const NamespaceJob); 0122 QList<MailBoxDescriptor> completeList = d->personalNamespaces 0123 + d->userNamespaces 0124 + d->sharedNamespaces; 0125 0126 foreach (const MailBoxDescriptor &descriptor, completeList) { 0127 if (descriptor.name.isEmpty()) { 0128 return true; 0129 } 0130 } 0131 0132 return false; 0133 } 0134 0135 void NamespaceJob::doStart() 0136 { 0137 Q_D(NamespaceJob); 0138 d->sendCommand("NAMESPACE", {}); 0139 } 0140 0141 void NamespaceJob::handleResponse(const Message &response) 0142 { 0143 Q_D(NamespaceJob); 0144 if (handleErrorReplies(response) == NotHandled) { 0145 if (response.content.size() >= 5 && 0146 response.content[1].toString() == "NAMESPACE") { 0147 // Personal namespaces 0148 d->personalNamespaces = d->processNamespaceList(response.content[2].toList()); 0149 0150 // User namespaces 0151 d->userNamespaces = d->processNamespaceList(response.content[3].toList()); 0152 0153 // Shared namespaces 0154 d->sharedNamespaces = d->processNamespaceList(response.content[4].toList()); 0155 } 0156 } 0157 }