IMAP: Extra local messages are now deleted.

* When a message on the server is deleted, it will now be deleted
  locally, too.
This commit is contained in:
Axel Dörfler
2016-01-14 21:03:46 +01:00
parent 618cc43b64
commit aeaf68cf4b
3 changed files with 53 additions and 6 deletions
@@ -370,8 +370,7 @@ public:
fTotalBytes += entries[i].size;
fUIDsToFetch.push_back(entries[i].uid);
} else {
fFolder->UpdateMessageFlags(entries[i].uid,
entries[i].flags);
fFolder->SyncMessageFlags(entries[i].uid, entries[i].flags);
}
}
@@ -379,6 +378,8 @@ public:
fLastIndex = from - 1;
if (from == 1) {
fFolder->MessageEntriesFetched();
if (fUIDsToFetch.size() > 0) {
// Add pending command to fetch the message headers
WorkerCommand* command = new FetchHeadersCommand(*fFolder,
@@ -178,6 +178,7 @@ IMAPFolder::SetUIDValidity(uint32 uidValidity)
if (fUIDValidity == uidValidity)
return;
// TODO: delete all mails that have the same UID validity value we had
fUIDValidity = uidValidity;
BNode node(&fRef);
@@ -221,8 +222,11 @@ IMAPFolder::MessageFlags(uint32 uid)
}
/*! Synchronizes the message flags/state from the server with the local
one.
*/
void
IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
IMAPFolder::SyncMessageFlags(uint32 uid, uint32 mailboxFlags)
{
if (uid > LastUID())
return;
@@ -233,7 +237,8 @@ IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
while (true) {
status_t status = GetMessageEntryRef(uid, ref);
if (status == B_ENTRY_NOT_FOUND) {
// The message does not exist anymore locally, delete it on the server
// The message does not exist anymore locally, delete it on the
// server
// TODO: copy it to the trash directory first!
fProtocol.UpdateMessageFlags(*this, uid, IMAP::kDeleted);
return;
@@ -247,6 +252,7 @@ IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
break;
}
fSynchronizedUIDsSet.insert(uid);
uint32 previousFlags = MessageFlags(uid);
uint32 currentFlags = previousFlags;
@@ -279,6 +285,21 @@ IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
}
void
IMAPFolder::MessageEntriesFetched()
{
// Delete all local messages that weren't synchronized with the server
UIDToRefMap::const_iterator iterator = fRefMap.begin();
for (; iterator != fRefMap.end(); iterator++) {
uint32 uid = iterator->first;
if (fSynchronizedUIDsSet.find(uid) == fSynchronizedUIDsSet.end())
_DeleteLocalMessage(uid);
}
fSynchronizedUIDsSet.clear();
}
/*! Stores the given \a stream into a temporary file using the provided
BFile object. A new file will be created, and the \a ref object will
point to it. The file will remain open when this method exits without
@@ -416,6 +437,9 @@ IMAPFolder::StoringBodyFailed(const entry_ref& ref, uint32 uid, status_t error)
void
IMAPFolder::DeleteMessage(uint32 uid)
{
// TODO: move message to trash (server side)
_DeleteLocalMessage(uid);
}
@@ -471,7 +495,6 @@ IMAPFolder::_InitializeFolderState()
// _WriteUniqueID(node, uid);
// }
//
fRefMap.insert(std::make_pair(uid, ref));
}
fInitializing = false;
@@ -519,6 +542,22 @@ IMAPFolder::_GetMessageEntryRef(uint32 uid, entry_ref& ref) const
}
status_t
IMAPFolder::_DeleteLocalMessage(uint32 uid)
{
entry_ref ref;
status_t status = GetMessageEntryRef(uid, ref);
if (status != B_OK)
return status;
fRefMap.erase(uid);
fFlagsMap.erase(uid);
BEntry entry(&ref);
return entry.Remove();
}
void
IMAPFolder::_IMAPToMailFlags(uint32 flags, BMessage& attributes)
{
@@ -7,6 +7,8 @@
#include <hash_map>
#include <hash_set>
#include <sys/stat.h>
#include <Entry.h>
@@ -69,8 +71,9 @@ public:
uint32& uid) const;
uint32 MessageFlags(uint32 uid);
void UpdateMessageFlags(uint32 uid,
void SyncMessageFlags(uint32 uid,
uint32 mailboxFlags);
void MessageEntriesFetched();
status_t StoreMessage(uint32 fetchFlags, BDataIO& stream,
size_t& length, entry_ref& ref,
@@ -101,6 +104,7 @@ private:
uint32 uid, status_t status);
status_t _GetMessageEntryRef(uint32 uid,
entry_ref& ref) const;
status_t _DeleteLocalMessage(uint32 uid);
void _IMAPToMailFlags(uint32 flags,
BMessage& attributes);
@@ -130,10 +134,12 @@ private:
typedef __gnu_cxx::hash_map<uint32, uint32> UIDToFlagsMap;
typedef __gnu_cxx::hash_map<uint32, entry_ref> UIDToRefMap;
typedef __gnu_cxx::hash_map<uint32, MessengerList> MessengerMap;
typedef __gnu_cxx::hash_set<uint32> UIDSet;
#else
typedef std::hash_map<uint32, uint32> UIDToFlagsMap;
typedef std::hash_map<uint32, entry_ref> UIDToRefMap;
typedef std::hash_map<uint32, MessengerList> MessengerMap;
typedef std::hash_set<uint32> UIDSet;
#endif
IMAPProtocol& fProtocol;
@@ -147,6 +153,7 @@ private:
bool fInitializing;
UIDToRefMap fRefMap;
UIDToFlagsMap fFlagsMap;
UIDSet fSynchronizedUIDsSet;
MessengerMap fPendingBodies;
};