summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2021-01-16 10:31:16 +0100
committerAnton Khirnov <anton@khirnov.net>2021-01-16 10:31:16 +0100
commitf0b24807e42ad95395a3885775cb1ee3322571a6 (patch)
treee5340c93471d8eb7a27f4810d57adb86af64b110
parent44bb1b83488ea6acf4b0f9f1deb6384c7dfa98fa (diff)
helper: rewrite mailto_to_envelope/parse_mailto to Envelope.from_mailto
-rw-r--r--alot/commands/globals.py4
-rw-r--r--alot/db/envelope.py34
-rw-r--r--alot/helper.py41
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)