diff options
author | Anton Khirnov <anton@khirnov.net> | 2021-01-16 10:31:16 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2021-01-16 10:31:16 +0100 |
commit | f0b24807e42ad95395a3885775cb1ee3322571a6 (patch) | |
tree | e5340c93471d8eb7a27f4810d57adb86af64b110 | |
parent | 44bb1b83488ea6acf4b0f9f1deb6384c7dfa98fa (diff) |
helper: rewrite mailto_to_envelope/parse_mailto to Envelope.from_mailto
-rw-r--r-- | alot/commands/globals.py | 4 | ||||
-rw-r--r-- | alot/db/envelope.py | 34 | ||||
-rw-r--r-- | alot/helper.py | 41 |
3 files changed, 35 insertions, 44 deletions
diff --git a/alot/commands/globals.py b/alot/commands/globals.py index c2128135..97f82c99 100644 --- a/alot/commands/globals.py +++ b/alot/commands/globals.py @@ -24,7 +24,6 @@ from .. import commands from .. import buffers from .. import helper from ..helper import split_commandstring -from ..helper import mailto_to_envelope from ..completion.commandline import CommandLineCompleter from ..completion.contacts import ContactsCompleter from ..completion.accounts import AccountCompleter @@ -38,7 +37,6 @@ from ..utils import argparse as cargparse MODE = 'global' - @registerCommand(MODE, 'exit', help="shut down cleanly") class ExitCommand(Command): """Shut down cleanly.""" @@ -906,7 +904,7 @@ class ComposeCommand(Command): if self.envelope is None: if self.rest: if self.rest.startswith('mailto'): - self.envelope = mailto_to_envelope(self.rest) + self.envelope = Envelope.from_mailto(self.rest) else: self.envelope = Envelope() self.envelope.add('To', self.rest) diff --git a/alot/db/envelope.py b/alot/db/envelope.py index 314be03c..d5b84b3e 100644 --- a/alot/db/envelope.py +++ b/alot/db/envelope.py @@ -12,6 +12,8 @@ from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication import email.charset as charset +from urllib.parse import unquote + import gpg from .attachment import Attachment @@ -347,3 +349,35 @@ class Envelope: del self['Attach'] self.body = raw[headerEndPos:].strip() + + _MAILTO_PREFIX = 'mailto:' + _MAILTO_SAFE_HEADERS = ('Subject', 'Cc', 'Keywords') + + @classmethod + def from_mailto(cls, mailto): + if not mailto.startswith(cls._MAILTO_PREFIX): + raise ValueError('Invalid mailto string: %s' % mailto) + mailto = mailto[len(cls._MAILTO_PREFIX):] + + headers = {} + body = '' + + to, _, hfields = mailto.partition('?') + to = unquote(to) + if to: + headers['To'] = [to] + + for hfield in hfields.split('&'): + key, _, value = hfield.partition('=') + + key = key.capitalize() + value = unquote(value) + if not value: + continue + + if key == 'Body': + body = value + elif key in cls._MAILTO_SAFE_HEADERS: + headers[key] = [value] + + return cls(headers = headers, bodytext = body) diff --git a/alot/helper.py b/alot/helper.py index eb6c1969..b7c4f5a1 100644 --- a/alot/helper.py +++ b/alot/helper.py @@ -439,47 +439,6 @@ def parse_mailcap_nametemplate(tmplate='%s'): template_suffix = tmplate return (template_prefix, template_suffix) - -def parse_mailto(mailto_str): - """ - Interpret mailto-string - - :param mailto_str: the string to interpret. Must conform to :rfc:2368. - :type mailto_str: str - :return: the header fields and the body found in the mailto link as a tuple - of length two - :rtype: tuple(dict(str->list(str)), str) - """ - if mailto_str.startswith('mailto:'): - import urllib.parse - to_str, parms_str = mailto_str[7:].partition('?')[::2] - headers = {} - body = '' - - to = urllib.parse.unquote(to_str) - if to: - headers['To'] = [to] - - for s in parms_str.split('&'): - key, value = s.partition('=')[::2] - key = key.capitalize() - if key == 'Body': - body = urllib.parse.unquote(value) - elif value: - headers[key] = [urllib.parse.unquote(value)] - return (headers, body) - else: - return (None, None) - - -def mailto_to_envelope(mailto_str): - """ - Interpret mailto-string into a :class:`alot.db.envelope.Envelope` - """ - from alot.db.envelope import Envelope - headers, body = parse_mailto(mailto_str) - return Envelope(bodytext=body, headers=headers) - def get_xdg_env(env_name, fallback): """ Used for XDG_* env variables to return fallback if unset *or* empty """ env = os.environ.get(env_name) |