From 2b6c9088c78d1aa944eeb969f678d644b8ef1180 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 20 Nov 2021 14:59:34 +0100 Subject: commands/envelope: refactor deriving headers to be edited Split the code into its own function. Make it properly case-insensitive. Apply either the blacklist or the whitelist setting, trying to apply both makes no sense. Enforce that either a blacklist or a whitelist is configured in the settings. --- alot/commands/envelope.py | 60 +++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 23 deletions(-) (limited to 'alot/commands/envelope.py') diff --git a/alot/commands/envelope.py b/alot/commands/envelope.py index 5dce6b44..c347c3c7 100644 --- a/alot/commands/envelope.py +++ b/alot/commands/envelope.py @@ -26,7 +26,6 @@ from ..errors import GPGProblem from ..settings.const import settings from ..settings.errors import NoMatchingAccount from ..utils import argparse as cargparse -from ..utils.collections import OrderedSet MODE = 'envelope' @@ -326,21 +325,41 @@ class EditCommand(Command): self.edit_only_body = False super().__init__(**kwargs) + def _headers_to_edit(self, headers): + whitelist = settings.get('edit_headers_whitelist') + blacklist = settings.get('edit_headers_blacklist') + + # convert all header names to lowercase for uniqueness + wl = set(map(str.lower, whitelist)) + bl = set(map(str.lower, blacklist)) + kl = set(map(str.lower, headers)) + + # exactly one of wl/bl must be '*', so when operating + # in blacklist mode we convert the blacklist to whitelist + if '*' in wl: + wl = kl - bl + + # drop all non-whitelisted headers + edit_headers = headers.copy() + for k in set((k.lower() for k in edit_headers)): + if not k in wl: + del edit_headers[k] + + if not '*' in whitelist: + # any explicitly whitelisted headers that do not have a value + # are set to empty string, so they appear in the edited file + for h in whitelist: + if not h in edit_headers: + edit_headers[h] = '' + + logging.debug('editable headers: %s', edit_headers) + return edit_headers + async def apply(self, ui): ebuffer = ui.current_buffer if not self.envelope: self.envelope = ui.current_buffer.envelope - # determine editable headers - edit_headers = OrderedSet(settings.get('edit_headers_whitelist')) - if '*' in edit_headers: - edit_headers = OrderedSet(self.envelope.headers) - blacklist = set(settings.get('edit_headers_blacklist')) - if '*' in blacklist: - blacklist = set(self.envelope.headers) - edit_headers = edit_headers - blacklist - logging.info('editable headers: %s', edit_headers) - def openEnvelopeFromTmpfile(): # This parses the input from the tempfile. # we do this ourselves here because we want to be able to @@ -367,20 +386,15 @@ class EditCommand(Command): # decode header headertext = '' - for key in edit_headers: - vlist = self.envelope.get_all(key) - if len(vlist) == 0: - # ensure editable headers are present in template - vlist.append('') - else: - # remove to be edited lines from envelope + for key, val in self._headers_to_edit(self.envelope.headers).items(): + # remove to be edited lines from envelope + if key in self.envelope: del self.envelope[key] - for value in vlist: - # newlines (with surrounding spaces) by spaces in values - value = value.strip() - value = re.sub('[ \t\r\f\v]*\n[ \t\r\f\v]*', ' ', value) - headertext += '%s: %s\n' % (key, value) + # newlines (with surrounding spaces) by spaces in values + val = val.strip() + val = re.sub('[ \t\r\f\v]*\n[ \t\r\f\v]*', ' ', val) + headertext += '%s: %s\n' % (key, val) # determine editable content bodytext = self.envelope.body -- cgit v1.2.3