Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hook to process message before display/reply? #571

Closed
larskotthoff opened this issue Oct 10, 2018 · 28 comments
Closed

Hook to process message before display/reply? #571

larskotthoff opened this issue Oct 10, 2018 · 28 comments

Comments

@larskotthoff
Copy link
Contributor

One of my email providers inserts a warning into the body of the email if certain conditions are met. This is annoying and completely useless, and worse shows up in the quoted text when I reply.

It would be great to have a hook before astroid reads a mail that allows to pipe it through a script. I could remove the warning as if it never existed this way, without having to change mails on the server.

@gauteh
Copy link
Member

gauteh commented Oct 11, 2018 via email

@larskotthoff
Copy link
Contributor Author

Thanks, I'll have a look at that. It would be great if you could include something that allows this to hook in before a reply.

@larskotthoff
Copy link
Contributor Author

It looks like if I return the plain/text part of a mail from a plugin all the newlines are gone. This happens even if I return the text part verbatim without changes:

  def do_filter_part(self, text, html, mime_type, is_patch):
    if mime_type == 'text/plain':
      return text

Is this a bug or am I missing something?

@larskotthoff
Copy link
Contributor Author

Also, is there a way to modify the headers?

@gauteh
Copy link
Member

gauteh commented Oct 12, 2018 via email

@larskotthoff
Copy link
Contributor Author

Thanks, I was looking through the code and came to the same conclusion. I'm starting to think that I really want a plugin interface that allows to process the raw message.

@gauteh
Copy link
Member

gauteh commented Oct 12, 2018 via email

@larskotthoff
Copy link
Contributor Author

Ok, I've had a go at implementing a plugin that returns a modified stream of the raw message (i.e. instead of astroid reading the message directly, it gets a stream from the plugin which is passed the file name). I can't get the plugin function to be called though -- the check whether there's a pointer to the function fails (pointer is NULL, https://github.com/larskotthoff/astroid/blob/master/src/plugin/astroid_activatable.c#L175). I did add it to the interface (https://github.com/larskotthoff/astroid/blob/master/src/plugin/astroid_activatable.h#L31), so I'm not sure what's going on.

It would be great if you could have a look please -- full code at https://github.com/larskotthoff/astroid, diff at larskotthoff@501384f. The python plugin has a function "do_process(self, fname)".

@gauteh
Copy link
Member

gauteh commented Oct 16, 2018 via email

@gauteh
Copy link
Member

gauteh commented Oct 16, 2018

@larskotthoff
Copy link
Contributor Author

Thanks, I've verified that the plugin is loaded by putting in print statements like in the example plugins. The problem is almost certainly caused by the introspection, but I can't figure out where. Below is a small example plugin to demonstrate.

import gi
gi.require_version ('Astroid', '0.2')
gi.require_version ('Gtk', '3.0')
gi.require_version ('GMime', '2.6')

from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Astroid
from gi.repository import GMime

import email
import os
import mimetypes

from email.policy import default

class FooPlugin(GObject.Object, Astroid.Activatable):
  def do_activate(self):
    print('Foo: activated', __file__)

  def do_deactivate(self):
    print('Foo: deactivated')

  def do_process(self, fname):
    print("Processing " + fname)
    with open(fname, 'rb') as fp:
      msg = email.message_from_binary_file(fp, policy = default)
      for pt in msg.walk():
        if pt.get_content_type() == 'text/plain':
            pt.set_content("Lorem ipsum")

      return GMime.StreamMem.new_with_buffer(msg.as_bytes())

@larskotthoff
Copy link
Contributor Author

And of course I discover the problem as soon as I've posted this -- the transfer annotation needs to be "full"...

@gauteh
Copy link
Member

gauteh commented Oct 17, 2018 via email

@larskotthoff
Copy link
Contributor Author

Ah, good question -- it looks like there's lots of stray WebKit processes now. I'll have a look at that.

Regarding HTML to text; my plugin is adding an alternative text/plain part to the email if it's HTML-only, which I believe should work fine in all cases without a context flag. That said, there seems to be a bug either in the Python email processing library or astroid that doesn't delineate the new part correctly -- when I open an email, it shows the text and that there's an HTML part, but when I open the HTML part it is merged with the text part into one email that doesn't show separate parts anymore.

@gauteh
Copy link
Member

gauteh commented Oct 17, 2018 via email

@larskotthoff
Copy link
Contributor Author

From my reading of the documentation, the python email library should take care of automatically converting it to multipart/alternative when I add the text/plain as an alternative.

I'll definitely make a skeleton version of the plugin available once I've worked everything out.

@gauteh
Copy link
Member

gauteh commented Oct 17, 2018 via email

@larskotthoff
Copy link
Contributor Author

Ok, figured out the weirdness with the alternative part -- I was adding it as an alternative to the entire multipart/related message instead of just the HTML part.

As far as I can tell, the memory management should work correctly. I've tried to check this using https://stackoverflow.com/questions/24453266/check-if-a-gobject-was-correctly-freed but that fails even without the plugin (i.e. the refcount to stream at the end isn't 0). When I try to free it explicitly I get a core dump because of a double free though.

@gauteh
Copy link
Member

gauteh commented Oct 18, 2018 via email

@gauteh
Copy link
Member

gauteh commented Oct 19, 2018 via email

@larskotthoff
Copy link
Contributor Author

This could be useful yes. I've noticed a bug with encodings in my current plugin; when saving in the external editor non-ASCII characters get mangled up in the view in Astroid. Not sure what the problem is yet.

There's also a bunch of other functionality that I want to implement. I'll focus on that first before coming back to separating processing for viewing and quoting.

@gauteh
Copy link
Member

gauteh commented Oct 19, 2018 via email

@larskotthoff
Copy link
Contributor Author

I've looked into this further, but I can't track down the bug. Somewhere the encoding is messed up, but I don't see where -- there are temporary files written and read in ~/.cache/astroid/ and /tmp/astroid-*, and processing the former (though not the latter) in the plugin causes the problem. For now I'm simply checking the path of the file to load in the plugin and if it's in ~/.cache/astroid/ I don't to the processing.

No idea what's going on, as all reading/writing and processing is using the exact same code, but the issue only occur in some cases.

@gauteh
Copy link
Member

gauteh commented Oct 20, 2018 via email

@gauteh
Copy link
Member

gauteh commented Oct 20, 2018 via email

@gauteh
Copy link
Member

gauteh commented Oct 20, 2018 via email

@larskotthoff
Copy link
Contributor Author

Thanks, it sounds like the reason is that the file in ~/.cache isn't a complete email. Is there an easy way of checking whether one of the temporary files is processed to avoid the processing (other than hard-coding the ~/.config path)? As far as I can see this would require adding a flag to a bunch of functions throughout and that seems rather heavy-handed to me.

#578 looks good, but I don't think it'll help with this since the problem is the other temporary file.

@gauteh
Copy link
Member

gauteh commented Oct 20, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants