diff options
author | Patrick Totzke <patricktotzke@gmail.com> | 2011-12-21 17:16:20 +0000 |
---|---|---|
committer | Patrick Totzke <patricktotzke@gmail.com> | 2011-12-21 17:16:20 +0000 |
commit | fdd9a551e4812649229346d74985939569a880e1 (patch) | |
tree | e152a3eb3bc7a7d0a4fe4cc6cceba93ac0c11c5f /alot | |
parent | d29cf21992cf80785c75b405b11920492d4ff5fe (diff) | |
parent | 742a0e3d101bc96c2a1ae1481243093bed297809 (diff) |
Merge branch 'issue-157-popen' into testing
Diffstat (limited to 'alot')
-rw-r--r-- | alot/account.py | 8 | ||||
-rw-r--r-- | alot/commands/thread.py | 17 | ||||
-rw-r--r-- | alot/helper.py | 54 | ||||
-rw-r--r-- | alot/message.py | 4 |
4 files changed, 43 insertions, 40 deletions
diff --git a/alot/account.py b/alot/account.py index 1b7d35e2..6eb9f099 100644 --- a/alot/account.py +++ b/alot/account.py @@ -4,10 +4,10 @@ import time import re import email import os +import shlex from ConfigParser import SafeConfigParser from urlparse import urlparse -from helper import cmd_output import helper @@ -140,7 +140,8 @@ class SendmailAccount(Account): def send_mail(self, mail): mail['Date'] = email.utils.formatdate(time.time(), True) - out, err = helper.pipe_to_command(self.cmd, mail.as_string()) + cmdlist = shlex.split(self.cmd.encode('utf-8', errors='ignore')) + out, err, retval = helper.call_cmd(cmdlist, stdin=mail.as_string()) if err: return err + '. sendmail_cmd set to: %s' % self.cmd self.store_sent_mail(mail) @@ -320,7 +321,8 @@ class MatchSdtoutAddressbook(AddressBook): return self.lookup('\'\'') def lookup(self, prefix): - resultstring = cmd_output('%s %s' % (self.command, prefix)) + cmdlist = shlex.split(self.command.encode('utf-8', errors='ignore')) + resultstring, errmsg, retval = helper.call_cmd(cmdlist + [prefix]) if not resultstring: return [] lines = resultstring.replace('\t', ' ' * 4).splitlines() diff --git a/alot/commands/thread.py b/alot/commands/thread.py index 2d155d86..b7159cc1 100644 --- a/alot/commands/thread.py +++ b/alot/commands/thread.py @@ -3,6 +3,7 @@ import logging import tempfile from twisted.internet.defer import inlineCallbacks import mimetypes +import shlex from alot.commands import Command, registerCommand from alot.commands.globals import ExternalCommand @@ -242,7 +243,7 @@ class ToggleHeaderCommand(Command): @registerCommand(MODE, 'pipeto', arguments=[ - (['cmd'], {'help':'shellcommand to pipe to'}), + (['cmd'], {'nargs':'?', 'help':'shellcommand to pipe to'}), (['--all'], {'action': 'store_true', 'help':'pass all messages'}), (['--decode'], {'action': 'store_true', 'help':'use only decoded body lines'}), @@ -253,14 +254,13 @@ class ToggleHeaderCommand(Command): ) class PipeCommand(Command): """pipe message(s) to stdin of a shellcommand""" - #TODO: make cmd a list #TODO: use raw arg from print command here def __init__(self, cmd, all=False, ids=False, separately=False, decode=True, noop_msg='no command specified', confirm_msg='', done_msg='done', **kwargs): """ :param cmd: shellcommand to open - :type cmd: str + :type cmd: list of str :param all: pipe all, not only selected message :type all: bool :param ids: only write message ids, not the message source @@ -276,7 +276,7 @@ class PipeCommand(Command): :type done_msg: str """ Command.__init__(self, **kwargs) - self.cmd = cmd + self.cmdlist = cmd self.whole_thread = all self.separately = separately self.ids = ids @@ -288,7 +288,7 @@ class PipeCommand(Command): @inlineCallbacks def apply(self, ui): # abort if command unset - if not self.cmd: + if not self.cmdlist: ui.notify(self.noop_msg, priority='error') return @@ -327,7 +327,7 @@ class PipeCommand(Command): # do teh monkey for mail in mailstrings: ui.logger.debug("%s" % mail) - out, err = helper.pipe_to_command(self.cmd, mail) + out, err, retval = helper.call_cmd(self.cmdlist, stdin=mail) if err: ui.notify(err, priority='error') return @@ -356,6 +356,7 @@ class PrintCommand(PipeCommand): """ # get print command cmd = settings.config.get('general', 'print_cmd', fallback='') + cmdlist = shlex.split(cmd.encode('utf-8', errors='ignore')) # set up notification strings if all: @@ -368,7 +369,7 @@ class PrintCommand(PipeCommand): # no print cmd set noop_msg = 'no print command specified. Set "print_cmd" in the '\ 'global section.' - PipeCommand.__init__(self, cmd, all=all, + PipeCommand.__init__(self, cmdlist, all=all, separately=separately, decode=not raw, noop_msg=noop_msg, confirm_msg=confirm_msg, @@ -377,7 +378,7 @@ class PrintCommand(PipeCommand): @registerCommand(MODE, 'save', arguments=[ (['--all'], {'action': 'store_true', 'help':'save all attachments'}), - (['path'], {'nargs':'?', 'help':'path to save to'})]) + (['path'], {'help':'path to save to'})]) class SaveAttachmentCommand(Command): """save attachment(s)""" def __init__(self, all=False, path=None, **kwargs): diff --git a/alot/helper.py b/alot/helper.py index c4e6d7fa..bad48213 100644 --- a/alot/helper.py +++ b/alot/helper.py @@ -213,39 +213,37 @@ def pretty_datetime(d): return string -def cmd_output(command_line): - args = shlex.split(command_line.encode('utf-8', errors='ignore')) +def call_cmd(cmdlist, stdin=None): + """ + get a shell commands output, error message and return value + + :param cmdlist: shellcommand to call, already splitted into a list accepted + by :meth:`subprocess.Popen` + :type cmdlist: list of str + :param stdin: string to pipe to the process + :type stdin: str + :return: triple of stdout, error msg, return value of the shell command + :rtype: str, str, int + """ + + out, err, ret = '', '', 0 try: - output = subprocess.check_output(args) - output = string_decode(output, urwid.util.detected_encoding) - except subprocess.CalledProcessError: - return None - except OSError: - return None - return output - - -def pipe_to_command(cmd, stdin): - # remove quotes which have been put around the whole command - cmd = cmd.strip() - stdin = stdin + '\n' - if cmd[0] == '"' and cmd[-1] == '"': - cmd = cmd[1:-1] - args = shlex.split(cmd.encode('utf-8', errors='ignore')) - try: - proc = subprocess.Popen(args, stdin=subprocess.PIPE, + if stdin: + proc = subprocess.Popen(cmdlist, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = proc.communicate(stdin) - except OSError, e: - return '', str(e) - if proc.poll(): # returncode is not 0 - e = 'return value != 0' - if err.strip(): - e = e + ': %s' % err - return '', e + ret = proc.poll() else: - return out, err + out = subprocess.check_output(cmdlist) + # todo: get error msg. rval + except (subprocess.CalledProcessError, OSError), e: + err = str(e) + ret = -1 + + out = string_decode(out, urwid.util.detected_encoding) + err = string_decode(err, urwid.util.detected_encoding) + return out, err, ret def mimewrap(path, filename=None, ctype=None): diff --git a/alot/message.py b/alot/message.py index e71d4043..e3ad3940 100644 --- a/alot/message.py +++ b/alot/message.py @@ -3,6 +3,7 @@ import email import tempfile import re import mimetypes +import shlex from datetime import datetime from email.header import Header import email.charset as charset @@ -276,7 +277,8 @@ def extract_body(mail, types=None): tmpfile.close() #create and call external command cmd = handler % tmpfile.name - rendered_payload = helper.cmd_output(cmd) + cmdlist = shlex.split(cmd.encode('utf-8', errors='ignore')) + rendered_payload, errmsg, retval = helper.call_cmd(cmdlist) #remove tempfile os.unlink(tmpfile.name) if rendered_payload: # handler had output |