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