Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
idIMAP4 Help required
#1
Hi

I'm after a bit of help with idIMAP4.

I'm reading an IMAP folder using the UIDRetrieveAllEnvelopes method, a week later I want to get all the new emails that have arrived since the last read.

Currently I'm calling UIDRetrieveAllEnvelopes a second time and then looking at the messages with a greater UID than the max retrieved previously.

Up to now this has worked OK, but today I came across an IMAP folder with > 100,000 emails in it and so even UIDRetrieveAllEnvelopes take a very long time.

I feel that there should be a faster way to get all the new emails, but I can't see how - am I missing some methods that might help here. Obviously I can't just go on the Mailbox count as I've no idea what the user might have done in some other IMAP app e.g deleted emails etc between my apps reads.

Thanks

David
Reply
#2
Seems that simply getting the UID of the last email and counting down seem to do the job, though it astounds me that there's nothing like an IMAP query language that's universally supported.
Reply
#3
Server protocols such as IMAP4 are designed to be very light on the server so as not to overload them. In addition to this, IMAP4 is an extremely poorly designed protocol. Among the worst of the standard protocols by far. It doesn't follow even standard command mechanisms. Prior to IMAP4, POP3 was the only non standard one. With IMAP4 they had a chance to correct it, instead they made it worse.
Reply
#4
(03-27-2018, 10:22 PM)david_navigator Wrote: I'm reading an IMAP folder using the UIDRetrieveAllEnvelopes method, a week later I want to get all the new emails that have arrived since the last read.

TIdIMAP4 has SearchMailBox() and UIDSearchMailBox() methods that you can use for that purpose.  The MsgNo or UID of the matching emails will be in the TIdIMAP4.MailBox.SearchResults property.  You can then retrieve those emails as needed.

But, for true mailbox synchronization, simply searching for new emails is not enough.  You also need to look for deleted/moved emails, too.

(03-27-2018, 10:22 PM)david_navigator Wrote: Currently I'm calling UIDRetrieveAllEnvelopes a second time and then looking at the messages with a greater UID than the max retrieved previously.

That will break if UIDs get regenerated between sessions.

You need to check the TIdIMAP4.MailBox.UIDValidity property after selecting a mailbox.  If the UIDValidity does not change values between sessions, you know any UIDs you have previously saved for that mailbox are still valid (though the corresponding emails could have been deleted/moved in the meantime, of course).  But, if the UIDValidity does change value, you need to update your saved UIDs.

The UIDValidity does not change often, but it can change nonetheless, so you should account for it if you save UIDs between sessions.

(03-27-2018, 10:22 PM)david_navigator Wrote: Up to now this has worked OK, but today I came across an IMAP folder with > 100,000 emails in it and so even UIDRetrieveAllEnvelopes take a very long time.

I would imagine so.  That is a lot of data for it to download and parse.

(03-27-2018, 10:22 PM)david_navigator Wrote: I feel that there should be a faster way to get all the new emails, but I can't see how - am I missing some methods that might help here.

Yes. With the SearchMailBox() and UIDSearchMailBox() methods, you can search by many criteria, including dates and flags (like New, Unseen, etc).

Note: unfortunately, you can't currently search for everything that IMAP allows you to search for.  The search methods do not allow for the level of flexibility that the IMAP SEARCH command supports.

Another option is the ExamineMailBox() method (which reports the same info as the SelectMailBox() method, but keeps the mailbox read-only), followed by either:

- a "FETCH 1:* (UID FLAGS)" command (unfortunately, it cannot be sent with any of the existing retrieval methods, so you have to send it manually), which will report all of the UIDs and Flags in the mailbox.

- a "UID SEARCH 1:*" command (unfortunately, it cannot be sent with the UIDSearchMailBox() method, so you have to send it manually), which will report all of the UIDs in the mailbox.

Then you can compare the reported UIDs (and in the case of FETCH, the flags) to the ones you have previously saved, to know which emails have been added, deleted, moved, altered, etc, and then you can retrieve/update your local copies as needed.

See RFC 4549: Synchronization Operations for Disconnected IMAP4 Clients for more details about what you should do when synchronizing with an IMAP server between sessions.

(03-28-2018, 03:32 PM)david_navigator Wrote: Seems that simply getting the UID of the last email and counting down seem to do the job

Sure, if:

- you are only interested in looking for new emails that have been added since the last check.

- you don't care about the state of any emails you have previously retrieved.

- the UIDs have not been changed since your last session.

(03-28-2018, 03:32 PM)david_navigator Wrote: though it astounds me that there's nothing like an IMAP query language that's universally supported.

IMAP has a standardized SEARCH command.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)