File indexing completed on 2024-05-12 05:17:25
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 "storejob.h" 0021 0022 #include "kimap_debug.h" 0023 0024 #include "job_p.h" 0025 #include "message_p.h" 0026 #include "session_p.h" 0027 0028 namespace KIMAP2 0029 { 0030 class StoreJobPrivate : public JobPrivate 0031 { 0032 public: 0033 StoreJobPrivate(Session *session, const QString &name) : JobPrivate(session, name) { } 0034 ~StoreJobPrivate() { } 0035 0036 QByteArray addFlags(const QByteArray ¶m, const MessageFlags &flags) 0037 { 0038 QByteArray parameters; 0039 switch (mode) { 0040 case StoreJob::SetFlags: 0041 parameters += param; 0042 break; 0043 case StoreJob::AppendFlags: 0044 parameters += "+" + param; 0045 break; 0046 case StoreJob::RemoveFlags: 0047 parameters += "-" + param; 0048 break; 0049 } 0050 0051 parameters += " ("; 0052 foreach (const QByteArray &flag, flags) { 0053 parameters += flag + ' '; 0054 } 0055 if (!flags.isEmpty()) { 0056 parameters.chop(1); 0057 } 0058 parameters += ')'; 0059 0060 return parameters; 0061 } 0062 0063 ImapSet set; 0064 bool uidBased; 0065 StoreJob::StoreMode mode; 0066 MessageFlags flags; 0067 MessageFlags gmLabels; 0068 0069 QMap<int, MessageFlags> resultingFlags; 0070 }; 0071 } 0072 0073 using namespace KIMAP2; 0074 0075 StoreJob::StoreJob(Session *session) 0076 : Job(*new StoreJobPrivate(session, "Store")) 0077 { 0078 Q_D(StoreJob); 0079 d->uidBased = false; 0080 d->mode = SetFlags; 0081 } 0082 0083 StoreJob::~StoreJob() 0084 { 0085 } 0086 0087 void StoreJob::setSequenceSet(const ImapSet &set) 0088 { 0089 Q_D(StoreJob); 0090 d->set = set; 0091 } 0092 0093 ImapSet StoreJob::sequenceSet() const 0094 { 0095 Q_D(const StoreJob); 0096 return d->set; 0097 } 0098 0099 void StoreJob::setUidBased(bool uidBased) 0100 { 0101 Q_D(StoreJob); 0102 d->uidBased = uidBased; 0103 } 0104 0105 bool StoreJob::isUidBased() const 0106 { 0107 Q_D(const StoreJob); 0108 return d->uidBased; 0109 } 0110 0111 void StoreJob::setFlags(const MessageFlags &flags) 0112 { 0113 Q_D(StoreJob); 0114 d->flags = flags; 0115 } 0116 0117 MessageFlags StoreJob::flags() const 0118 { 0119 Q_D(const StoreJob); 0120 return d->flags; 0121 } 0122 0123 void StoreJob::setGMLabels(const MessageFlags &gmLabels) 0124 { 0125 Q_D(StoreJob); 0126 d->gmLabels = gmLabels; 0127 } 0128 0129 MessageFlags StoreJob::gmLabels() const 0130 { 0131 Q_D(const StoreJob); 0132 return d->gmLabels; 0133 } 0134 0135 void StoreJob::setMode(StoreMode mode) 0136 { 0137 Q_D(StoreJob); 0138 d->mode = mode; 0139 } 0140 0141 StoreJob::StoreMode StoreJob::mode() const 0142 { 0143 Q_D(const StoreJob); 0144 return d->mode; 0145 } 0146 0147 QMap<int, MessageFlags> StoreJob::resultingFlags() const 0148 { 0149 Q_D(const StoreJob); 0150 return d->resultingFlags; 0151 } 0152 0153 void StoreJob::doStart() 0154 { 0155 Q_D(StoreJob); 0156 0157 if (d->set.isEmpty()) { 0158 qCWarning(KIMAP2_LOG) << "Empty uid set passed to store job"; 0159 setError(KJob::UserDefinedError); 0160 setErrorText(QStringLiteral("Empty uid set passed to store job")); 0161 emitResult(); 0162 return; 0163 } 0164 0165 d->set.optimize(); 0166 QByteArray parameters = d->set.toImapSequenceSet() + ' '; 0167 0168 if (!d->flags.isEmpty() || d->mode == SetFlags) { 0169 parameters += d->addFlags("FLAGS", d->flags); 0170 } 0171 if (!d->gmLabels.isEmpty()) { 0172 if (!d->flags.isEmpty()) { 0173 parameters += ' '; 0174 } 0175 parameters += d->addFlags("X-GM-LABELS", d->gmLabels); 0176 } 0177 0178 qCDebug(KIMAP2_LOG) << parameters; 0179 0180 QByteArray command = "STORE"; 0181 if (d->uidBased) { 0182 command = "UID " + command; 0183 } 0184 0185 d->sendCommand(command, parameters); 0186 } 0187 0188 void StoreJob::handleResponse(const Message &response) 0189 { 0190 Q_D(StoreJob); 0191 0192 if (handleErrorReplies(response) == NotHandled) { 0193 if (response.content.size() == 4 && 0194 response.content[2].toString() == "FETCH" && 0195 response.content[3].type() == Message::Part::List) { 0196 0197 int id = response.content[1].toString().toInt(); 0198 qint64 uid = 0; 0199 bool uidFound = false; 0200 QList<QByteArray> resultingFlags; 0201 0202 QList<QByteArray> content = response.content[3].toList(); 0203 0204 for (QList<QByteArray>::ConstIterator it = content.constBegin(); 0205 it != content.constEnd(); ++it) { 0206 QByteArray str = *it; 0207 ++it; 0208 0209 if (str == "FLAGS") { 0210 if ((*it).startsWith('(') && (*it).endsWith(')')) { 0211 QByteArray str = *it; 0212 str.chop(1); 0213 str.remove(0, 1); 0214 resultingFlags = str.split(' '); 0215 } else { 0216 resultingFlags << *it; 0217 } 0218 } else if (str == "UID") { 0219 uid = it->toLongLong(&uidFound); 0220 } 0221 } 0222 0223 if (!d->uidBased) { 0224 d->resultingFlags[id] = resultingFlags; 0225 } else if (uidFound) { 0226 d->resultingFlags[uid] = resultingFlags; 0227 } else { 0228 qCWarning(KIMAP2_LOG) << "We asked for UID but the server didn't give it back, resultingFlags not stored."; 0229 } 0230 } 0231 } 0232 }