Create Interface to MimeTreeParser for Headers
Open, Needs TriagePublic

Description

To verify the DKIM status on our own (as it is not checked by your mailserver). It needs CPU power to check the DKIM status.
We end up implementing an Interface for accessing the mailheaders not directly from the KMime, instead using a interface to access all mailheaders.

Also MemoryHole would benefit also from that.

knauss created this task.Apr 21 2018, 4:31 PM

Mimetreeparser -> HeaderStyle

We need an Interface for the headers:

bool hasMailHeader(const char *header, const KMime::Message *message) const;
KMime::Headers::Base::Ptr mailHeaderAsBase(const char *header, const KMime::Message *message) const;
KMime::Headers::Generics::AddressList::Ptr mailHeaderAsAddressList(const char *header, const KMime::Message *message) const;
KMime::Headers::Generics::MailboxList::Ptr mailHeaderAsMailboxList(const char *header, const KMime::Message *message) const;
KMime::Headers::Date::Ptr dateHeader(const KMime::Message *message) const;

Implementing those methods in NodeHelper, own object or can we somehow hook into KMime::Message?

  • KMime::Message methods are not virtual :(
  • maybe via ContentPrivate - but I don't have the knowledge if this is feasible and would produce readable code

Those methods would than return the actual header the headerstyle should use.

For at least memoryhole, we need to information who was setting the header when. So we need an additional method:

QVector<QPair<KMime::Headers::Base::Ptr>, MimetreeParser::MessagePart::Ptr>> overrideHeader(const char *header) const;

where the first is the entry that is used for the other methods. An empty vector tells the header is not overwritten.

HeaderStyle -> HTML

For HeaderStyle we would also need an other plugin system for the headers itself where you can register for headers. As "base" plugins for:

  • Subject (HeaderStyleUtil::subjectString)
  • To,CC,Bcc,Sender,... everything that is a email or a list of emails (see D13039)
  • Date (different ways to print date)

as fallback just header->asUnicodeString() is called.

additional plugins would be:

  • Spamheader (see kdepim-addons/kmail/plugins/common/kmail.antispamrc for all headers)
  • X-Face
  • DKIM (not existing atm)

Memoryhole would register for Subject, Date, To and CC.

the render method would give the plugins access to:

  • overrideHeader (with this infomation, memoryhole can detect if it should override headers).
  • theme (to modify rednering for specific themes aka using theme depdend icons)
  • style (plaintext, fancy etc. are not using grantlee and we want different rendering for those styles)

For the header interface:

  • what's the KMime::Message* parameter for, shouldn't this be coming from the nodehelper context (in particular since we might want to deviate from what KMime has)?
  • the variations on the return type can probably be covered by a single version with a template argument, IIRC that's how KMime does this
  • for the overrideHeaders method, maybe rather have a method that returns the message part for a given header? assuming that's the more common access pattern, this avoids the need to allocate and search in lists just for that

For the rendering:

  • does this really need to be a plugin? the problem I see there is that the output will tie all this together anyway, ie. it will assume a way to show a sender image, a spam rating, normal mail headers etc, so all that coming from separate plugins doesn't gain us much, no? Maybe I'm misunderstanding something, but to me it looks like we either need to keep the rendering or the header access fixed, and vary the other part via plugins, not both.

For the header interface:

  • what's the KMime::Message* parameter for, shouldn't this be coming from the nodehelper context (in particular since we might want to deviate from what KMime has)?

i do not get what you mean.

  • the variations on the return type can probably be covered by a single version with a template argument, IIRC that's how KMime does this.

right this is another solution. But for example we need additional logic for some headers like (sender and resentform/resent-to to make those to Mailboxes lists, can this been done with the template approach too?

  • for the overrideHeaders method, maybe rather have a method that returns the message part for a given header? assuming that's the more common access pattern, this avoids the need to allocate and search in lists just for that

Well but what if you need the overwritten headers? for MemoryHole you want to test/show if the header was changed etc and Memory Hole has the idea of different layers.... But we could speed this by having an additional method tat return only one message part.

For the rendering:

  • does this really need to be a plugin? the problem I see there is that the output will tie all this together anyway, ie. it will assume a way to show a sender image, a spam rating, normal mail headers etc, so all that coming from separate plugins doesn't gain us much, no? Maybe I'm misunderstanding something, but to me it looks like we either need to keep the rendering or the header access fixed, and vary the other part via plugins, not both.

for the grantlee header plugin we have the DisplayExtraVariables. But those can only just be currently header->asUnicodeString() and we have no nice way to render those Headers differently. And how do you think we show implement the rendering part of MemoryHole? Just show the new Headers without any notification that those are replaced? Or create more parameters in the header map?

I see that it reduces the code of duplication we currently have in messageviewer/src/header/grantleeheaderformatter.cpp.