From cf5783077d593a92a686c5ab8fe9ce96b6b13b52 Mon Sep 17 00:00:00 2001 From: ryneeverett Date: Tue, 3 Mar 2020 16:16:42 +0000 Subject: [PATCH 1/3] Add pipeto --format=mimepart option. The most notable use case is piping html to a browser without extra scripts such as those shared in #789. --- alot/commands/thread.py | 9 ++++++++- docs/source/usage/modes/thread.rst | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/alot/commands/thread.py b/alot/commands/thread.py index 433ba6a62..f02b65e4a 100644 --- a/alot/commands/thread.py +++ b/alot/commands/thread.py @@ -32,6 +32,8 @@ from ..db.utils import extract_headers from ..db.utils import clear_my_address from ..db.utils import ensure_unique_address +from ..db.utils import remove_cte +from ..db.utils import string_sanitize from ..db.envelope import Envelope from ..db.attachment import Attachment from ..db.errors import DatabaseROError @@ -632,7 +634,8 @@ def apply(self, ui): (['cmd'], {'help': 'shellcommand to pipe to', 'nargs': '+'}), (['--all'], {'action': 'store_true', 'help': 'pass all messages'}), (['--format'], {'help': 'output format', 'default': 'raw', - 'choices': ['raw', 'decoded', 'id', 'filepath']}), + 'choices': [ + 'raw', 'decoded', 'id', 'filepath', 'mimepart']}), (['--separately'], {'action': 'store_true', 'help': 'call command once for each message'}), (['--background'], {'action': 'store_true', @@ -671,6 +674,7 @@ def __init__(self, cmd, all=False, separately=False, background=False, 'decoded': message content, decoded quoted printable, 'id': message ids, separated by newlines, 'filepath': paths to message files on disk + 'mimepart': only pipe the currently selected mime part :type format: str :param add_tags: add 'Tags' header to the message :type add_tags: bool @@ -742,6 +746,9 @@ async def apply(self, ui): bodytext = msg.get_body_text() msgtext = '%s\n\n%s' % (headertext, bodytext) pipestrings.append(msgtext) + elif self.output_format == 'mimepart': + pipestrings.append(string_sanitize(remove_cte( + msg.mime_part, as_string=True))) if not self.separately: pipestrings = [separator.join(pipestrings)] diff --git a/docs/source/usage/modes/thread.rst b/docs/source/usage/modes/thread.rst index cc389d5de..62a8765a8 100644 --- a/docs/source/usage/modes/thread.rst +++ b/docs/source/usage/modes/thread.rst @@ -72,7 +72,7 @@ The following commands are available in thread mode: optional arguments :---all: pass all messages - :---format: output format; valid choices are: 'raw','decoded','id','filepath' (defaults to: 'raw') + :---format: output format; valid choices are: 'raw','decoded','id','filepath','mimepart' (defaults to: 'raw') :---separately: call command once for each message :---background: don't stop the interface :---add_tags: add 'Tags' header to the message From 19b8201df714a5cad0632c7c0d883c3e969e04a1 Mon Sep 17 00:00:00 2001 From: ryneeverett Date: Thu, 5 Mar 2020 19:29:22 +0000 Subject: [PATCH 2/3] Pipeto specific mime part format. While `pipeto --format mimepart` pipes whichever part is currently selected, the 'html' and 'plain' formats override the selected mime part (and preferences in settings). This is useful because the mime type you want displayed in alot isn't necessarily the one you want piped and also for setting keybindings to pipe specific mime types to specific applications (plain -> text editor, html -> web browser). --- alot/commands/thread.py | 7 +++++-- docs/source/usage/modes/thread.rst | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/alot/commands/thread.py b/alot/commands/thread.py index f02b65e4a..a33452df4 100644 --- a/alot/commands/thread.py +++ b/alot/commands/thread.py @@ -635,7 +635,8 @@ def apply(self, ui): (['--all'], {'action': 'store_true', 'help': 'pass all messages'}), (['--format'], {'help': 'output format', 'default': 'raw', 'choices': [ - 'raw', 'decoded', 'id', 'filepath', 'mimepart']}), + 'raw', 'decoded', 'id', 'filepath', 'mimepart', + 'plain', 'html']}), (['--separately'], {'action': 'store_true', 'help': 'call command once for each message'}), (['--background'], {'action': 'store_true', @@ -746,7 +747,9 @@ async def apply(self, ui): bodytext = msg.get_body_text() msgtext = '%s\n\n%s' % (headertext, bodytext) pipestrings.append(msgtext) - elif self.output_format == 'mimepart': + elif self.output_format in ['mimepart', 'plain', 'html']: + if self.output_format in ['plain', 'html']: + mimepart = get_body_part(mail, self.output_format) pipestrings.append(string_sanitize(remove_cte( msg.mime_part, as_string=True))) diff --git a/docs/source/usage/modes/thread.rst b/docs/source/usage/modes/thread.rst index 62a8765a8..155b50dd0 100644 --- a/docs/source/usage/modes/thread.rst +++ b/docs/source/usage/modes/thread.rst @@ -72,7 +72,7 @@ The following commands are available in thread mode: optional arguments :---all: pass all messages - :---format: output format; valid choices are: 'raw','decoded','id','filepath','mimepart' (defaults to: 'raw') + :---format: output format; valid choices are: 'raw','decoded','id','filepath','mimepart','plain','html' (defaults to: 'raw') :---separately: call command once for each message :---background: don't stop the interface :---add_tags: add 'Tags' header to the message From 48ca7670499c0c6a94c4a514af1409ba86ed0ed6 Mon Sep 17 00:00:00 2001 From: ryneeverett Date: Wed, 11 Mar 2020 15:52:18 +0000 Subject: [PATCH 3/3] Pipe focused mime part from the mime tree. When the mimetree is toggled on and a mime part is focused, pipeto should pipe the focused mime part rather than the currently selected part. This is only applicable to --format's that pipe a single part, which are decoded and mimepart. --- alot/commands/thread.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/alot/commands/thread.py b/alot/commands/thread.py index a33452df4..4da6f7f08 100644 --- a/alot/commands/thread.py +++ b/alot/commands/thread.py @@ -29,6 +29,7 @@ from ..db.utils import decode_header from ..db.utils import formataddr from ..db.utils import get_body_part +from ..db.utils import extract_body_part from ..db.utils import extract_headers from ..db.utils import clear_my_address from ..db.utils import ensure_unique_address @@ -738,20 +739,22 @@ async def apply(self, ui): else: for msg in to_print: mail = msg.get_email() + mimepart = (getattr(ui.get_deep_focus(), 'mimepart', False) + or msg.get_mime_part()) if self.add_tags: mail.add_header('Tags', ', '.join(msg.get_tags())) if self.output_format == 'raw': pipestrings.append(mail.as_string()) elif self.output_format == 'decoded': headertext = extract_headers(mail) - bodytext = msg.get_body_text() + bodytext = extract_body_part(mimepart) msgtext = '%s\n\n%s' % (headertext, bodytext) pipestrings.append(msgtext) elif self.output_format in ['mimepart', 'plain', 'html']: if self.output_format in ['plain', 'html']: mimepart = get_body_part(mail, self.output_format) pipestrings.append(string_sanitize(remove_cte( - msg.mime_part, as_string=True))) + mimepart, as_string=True))) if not self.separately: pipestrings = [separator.join(pipestrings)]