news:201211040...@usenet.drumscum.be...
> On 2012-11-03, the following emerged from the brain of Ezekiel:
>
> 8<
>
>> Technically there's nothing that POP can do that IMAP can't. POP is
>> a very simple and basic protocol and IMAP is a super-set of that
>> protocol. There are features and capabilities that IMAP has that POP
>> doesn't but not vice-versa.
>
> Yes, POP is the simpler protocol, and that is exactly why I prefer it
> to do simple stuff.
>
Unless you're writing the actual code/implementation you're not the one who
has to deal with the protocol level details. Most likely you're going to use
something like a command-line-utility like 'mail' (man mail(1)) or simply
calling a Python class. The easy/difficulty of the underlying protocol is
going to be hidden from you.
Years ago (I looked at the file dates and scared myself) I wrote some mail
protocol classes. The underlying C++ mail classes were wrapped in a COM
object so they could easily be scripted or automated. (The class interface
is at the end of this post) - But to use the class for pop mail access the
user would simply script it like this:
var pop = new Object("MailUtils.Pop3Client");
if (pop.Connect("
mail.myserver.com", "MyUserName", "SecretPassword")){
var numEmails = pop.MessageCount();
for(i=0; i<inumEmails; i++){
var emailmsg = pop.GetPopMessage(i); // Get the message[i] object
if(emailmsg.IsSpam()){
....
emailmsg.DeleteMessage();
}
else{
var name = emailmsg.GetFromName());
var subj = emailmsg.GetSubject());
....
}
} // for(numEMails)
}
The user never sees how difficult or easy the underlying protocol is. In
this case it's a POP automation object but I also wrote an IMAP client that
has essentially the same interface. The difference being when the mail
object is created it's a "MailUtils.ImapClient" object that would get
created instead of a "MailUtils.Pop3Client".
> Yes, I could do it with IMAP too, but I don't /need/ IMAP to do it.
> That's about the reasoning.
>
> 8<
>
Okay, to each his own.
>
> I never have been a fan of the "always on" approach for email and
> communication in general. Even with IMAP I just use the polling
> approach at a 15 minute interval.
>
I have a script on my server that monitors my various email accounts and my
wife's email account. The purpose of the script is to delete spam before it
reaches the inbox. Originally it would poll every 20-minutes and check the
incoming mail. This worked but the problem was that the spam could sit in
the inbox for up to 19-minutes before the script ran and deleted it. So my
phone would beep telling me there's email which was spam. A few years back
(when I got a smartphone) I converted the server to use IMAP so the script
would wake-up immediately when the message was available and delete spam in
real-time.
> This brings us to a completely different side-topic, that of email
> being considered as "immediate" communication nowadays. The problem is
> that it isn't, and that it probably never will be. It just was never
> designed that way.
True. In most cases mail gets delivered almost immediately and it's easy for
people to assume that it's an immediate protocol. But every once in a while
I see a long delay in the delivery time but that's fairly rare these days.
But there's no guarantee of when mail will get delivered.
>
> In case of problems, email relay servers typically keep submitted
> messages queued for several *days* before a delivery failure is
> generated. This alone is reason enough to never consider email as
> "immediate" communication.
Above I was talking about delivery to a valid recipient. But in the delivery
error case I see a massive variety. Sometimes I get the message back
immediately usually if the email address is invalid. But other times I'll
get the delivery failure back several days after I've sent the email.
> Also, with IMAP's "pseudo push" mechanism (ie. the idle connection you
> mention), network time-outs (gateway, IMAP server, intermittent
> connection loss...) can delay delivery of messages significantly.
When I implemented the IMAP library 'back in the day' I found the error
checking and handling the most difficult part of the protocol. There are a
lot of different network errors that can happen and it's a balancing act
between how much of this I want to handle (and hide) down in my
implementation and how much I need to return back to the client.
For example - if a network connection times out do I immediately return an
error to the client and force them to have to deal with it. Or does my code
try and do 'the right thing' and handle the error immediately and only
return an error if it's a catastrophic failure. It's a balancing act between
how much detail/fine-control I give the client and how much of this I handle
down in my code which makes life easier for the client but hides details and
removes some of the control from the client.
One of the reasons it's was difficult handling the various error cases is
that they're generally hard to test and simulate. Something simple like
failing to connect to a server are easy:
client.Connect("
no-such-server-xyz.com"...) and stuff like dealing with the
wrong user credentials is easy. But stuff like network connections timing
out, connections dropping in the middle of a mail message, etc are much more
difficult to simulate/test to make sure that the error handling is doing the
right thing.
Anyhow - here's the class interface for the POP client that I implemented
years back. The IMAP client is nearly identical except it's a super-set and
has more interface methods than this. FYI - I commented out the GUIDS for
the object IDs (xxxxxx-43EE-xxxx) because it's a unique GUI and this library
is actually out in the wild. It makes this potentially very identifiable.
// -------------------------------------------------------------
// Interfaces
// -------------------------------------------------------------
[
object,
uuid(xxxxxxxxx-43EE-4808-8848-xxxxxxxxxxxx),
dual,
nonextensible,
helpstring("IPop3Client Interface"),
pointer_default(unique)
]
interface IPop3Client : IDispatch{
[id(1), helpstring("method Connect")] HRESULT Connect([in] BSTR
i_szServer,
[in] BSTR i_szUserName,
[in] BSTR i_szPassword,
[out, retval] BOOL* o_pBool);
[id(2), helpstring("method GetError")] HRESULT GetError([out,retval] BSTR*
o_szError);
[id(3), helpstring("method AddFilter")] HRESULT AddFilter([in] BSTR
i_szName);
[id(4), helpstring("method MessageCount")] HRESULT
MessageCount([out,retval] LONG* o_cntMessages);
[id(5), helpstring("method Quit")] HRESULT Quit([out, retval] BOOL*
o_pBool);
[id(6), helpstring("method GetPopMessage")] HRESULT GetPopMessage(LONG
i_MsgIndex, [out,retval] IPop3Msg** o_pIMsg);
};
[
object,
uuid(xxxxxxxxx-48E8-437D-A5A9-xxxxxxxxxxxx),
dual,
nonextensible,
helpstring("IPop3Msg Interface"),
pointer_default(unique)
]
interface IPop3Msg : IDispatch{
[id(1), helpstring("method DeleteMessage")] HRESULT
DeleteMessage([out,retval] BOOL* o_pStatus);
[id(2), helpstring("method WasCheckedForSpam")] HRESULT
WasCheckedForSpam([out,retval] BOOL* o_pStatus);
[id(3), helpstring("method IsSpam")] HRESULT IsSpam([out,retval] BOOL*
o_pStatus);
[id(4), helpstring("method GetSpamLevel")] HRESULT
GetSpamLevel([out,retval] LONG* o_pSpamLevel);
[id(5), helpstring("method GetScore")] HRESULT GetScore([out,retval]
DOUBLE* o_pScore);
[id(6), helpstring("method GetTo")] HRESULT GetTo([out,retval] BSTR*
o_pVal);
[id(7), helpstring("method GetFrom")] HRESULT GetFrom([out,retval] BSTR*
o_pVal);
[id(8), helpstring("method GetDate")] HRESULT GetDate([out,retval] BSTR*
o_pVal);
[id(9), helpstring("method GetFromEmail")] HRESULT
GetFromEmail([out,retval] BSTR* o_pVal);
[id(10), helpstring("method GetFromName")] HRESULT
GetFromName([out,retval] BSTR* o_pVal);
[id(11), helpstring("method GetSubject")] HRESULT GetSubject([out,retval]
BSTR* o_pVal);
[id(12), helpstring("method GetUserAgent")] HRESULT
GetUserAgent([out,retval] BSTR* o_pVal);
[id(13), helpstring("method GetSpamStatus")] HRESULT
GetSpamStatus([out,retval] BSTR* o_pVal);
};