diff options
-rw-r--r-- | alot/account.py | 37 | ||||
-rw-r--r-- | alot/commands/envelope.py | 10 | ||||
-rw-r--r-- | alot/commands/globals.py | 1 | ||||
-rw-r--r-- | alot/helper.py | 38 |
4 files changed, 28 insertions, 58 deletions
diff --git a/alot/account.py b/alot/account.py index 4112ce53..1db65a5f 100644 --- a/alot/account.py +++ b/alot/account.py @@ -4,6 +4,7 @@ # This file is released under the GNU GPL, version 3 or a later revision. # For further details see the COPYING file import abc +import asyncio import glob import logging import mailbox @@ -11,9 +12,7 @@ import operator import os import re -from .helper import call_cmd_async -from .helper import split_commandstring - +from urwid.util import detected_encoding class Address: @@ -348,20 +347,22 @@ class SendmailAccount(Account): """Pipe the given mail to the configured sendmail command. Display a short message on success or a notification on error. :param mail: the mail to send out - :type mail: :class:`email.message.Message` or string + :type mail: bytes :raises: class:`SendingMailFailed` if sending failes """ - cmdlist = split_commandstring(self.cmd) - - try: - # make sure self.mail is a string - out, err, code = await call_cmd_async(cmdlist, stdin=str(mail)) - if code != 0: - msg = 'The sendmail command {} returned with code {}{}'.format( - self.cmd, code, ':\n' + err.strip() if err else '.') - raise Exception(msg) - except Exception as e: - logging.error(str(e)) - raise SendingMailFailed(str(e)) - logging.info('sent mail successfully') - logging.info(out) + P = asyncio.subprocess.PIPE + + child = await asyncio.create_subprocess_shell(self.cmd, P, P, P) + out, err = await child.communicate(mail) + + if child.returncode != 0: + msg = 'Calling sendmail command %s failed with code %s' % \ + (self.cmd, child.returncode) + if err: + msg += '; stderr:\n %s' % \ + err.decode(detected_encoding, errors = 'backslashreplace') + raise SendingMailFailed(msg) + + if out: + logging.info('sendmail output:\n%s', + out.decode(detected_encoding, errors = 'backslashreplace')) diff --git a/alot/commands/envelope.py b/alot/commands/envelope.py index fa45f669..b138195d 100644 --- a/alot/commands/envelope.py +++ b/alot/commands/envelope.py @@ -265,8 +265,16 @@ class SendCommand(Command): clearme = ui.notify('sending..', timeout=-1) if self.envelope is not None: self.envelope.sending = True + + # FIXME XXX horrible hack, fix the type fuckery + to_send = self.mail + if isinstance(to_send, str): + to_send = to_send.encode('ascii') + else: + to_send = to_send.as_bytes() + try: - await account.send_mail(self.mail) + await account.send_mail(to_send) except SendingMailFailed as e: if self.envelope is not None: self.envelope.account = account diff --git a/alot/commands/globals.py b/alot/commands/globals.py index 3e53a450..e30192c6 100644 --- a/alot/commands/globals.py +++ b/alot/commands/globals.py @@ -251,7 +251,6 @@ class ExternalCommand(Command): ret = '' # TODO: these can probably be refactored in terms of helper.call_cmd - # and helper.call_cmd_async if self.in_thread: try: if self.shell: diff --git a/alot/helper.py b/alot/helper.py index 9ba3c411..4bdb9731 100644 --- a/alot/helper.py +++ b/alot/helper.py @@ -168,44 +168,6 @@ def call_cmd(cmdlist, stdin=None): return out, err, ret -async def call_cmd_async(cmdlist, stdin=None, env=None): - """Given a command, call that command asynchronously and return the output. - - This function only handles `OSError` when creating the subprocess, any - other exceptions raised either durring subprocess creation or while - exchanging data with the subprocess are the caller's responsibility to - handle. - - If such an `OSError` is caught, then returncode will be set to 1, and the - error value will be set to the str() value of the exception. - - :type cmdlist: list of str - :param stdin: string to pipe to the process - :type stdin: str - :return: Tuple of stdout, stderr, returncode - :rtype: tuple[str, str, int] - """ - termenc = urwid.util.detected_encoding - cmdlist = [s.encode(termenc) for s in cmdlist] - - environment = os.environ.copy() - if env is not None: - environment.update(env) - logging.debug('ENV = %s', environment) - logging.debug('CMD = %s', cmdlist) - try: - proc = await asyncio.create_subprocess_exec( - *cmdlist, - env=environment, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, - stdin=asyncio.subprocess.PIPE if stdin else None) - except OSError as e: - return ('', str(e), 1) - out, err = await proc.communicate(stdin.encode(termenc) if stdin else None) - return (out.decode(termenc), err.decode(termenc), proc.returncode) - - def guess_mimetype(blob): """ uses file magic to determine the mime-type of the given data blob. |