Skip to content

Commit

Permalink
Add option to remove obsolete drafts
Browse files Browse the repository at this point in the history
(cherry picked from commit 391f02c)
This is a cherry-pick from pazz#1627.
  • Loading branch information
milhnl authored and guludo committed Sep 19, 2024
1 parent 4d6b24c commit 04eae1e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 9 deletions.
59 changes: 53 additions & 6 deletions alot/commands/envelope.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,48 @@ async def apply(self, ui):
await ui.apply_command(globals.PromptCommand(cmdstring))


async def delete_previous_draft(envelope, ui):
try:
if envelope.previous_draft is None:
return
except AttributeError:
return
if settings.get('envelope_always_delete_old_drafts'):
del_old_draft = True
else:
msg = 'Do you want to delete the old draft?'
del_old_draft = (await ui.choice(msg, cancel='no',
msg_position='left'))
del_old_draft = (del_old_draft == 'yes')
if del_old_draft:
try:
message_path = envelope.previous_draft.get_filename()
except Exception as e:
logging.error(e)
ui.notify('could not get draft path:\n%s' % e,
priority='error', block=True)
return

try:
ui.dbman.remove_message(envelope.previous_draft)
await ui.apply_command(globals.FlushCommand())
except DatabaseError as e:
logging.error(e)
ui.notify('could not remove draft from db:\n%s' % e,
priority='error', block=True)
return

try:
os.unlink(message_path)
except OSError as e:
logging.error(e)
ui.notify('could not delete draft file:\n%s' % e,
priority='error', block=True)
return

envelope.previous_draft = None


@registerCommand(MODE, 'save')
class SaveCommand(Command):
"""save draft"""
Expand All @@ -138,23 +180,26 @@ async def apply(self, ui):
path = account.store_draft_mail(
mail.as_string(policy=email.policy.SMTP, maxheaderlen=sys.maxsize))

msg = 'draft saved successfully'

# add mail to index if maildir path available
if path is not None:
ui.notify(msg + ' to %s' % path)
ui.notify('draft saved successfully to %s' % path)
logging.debug('adding new mail to index')
try:
ui.dbman.add_message(path, account.draft_tags + envelope.tags)
await ui.apply_command(globals.FlushCommand())
await ui.apply_command(commands.globals.BufferCloseCommand())
except DatabaseError as e:
logging.error(str(e))
ui.notify('could not index message:\n%s' % str(e),
priority='error',
block=True)
else:
await ui.apply_command(commands.globals.BufferCloseCommand())
return

await delete_previous_draft(envelope, ui)

# strip the outside '<' and '>' characters from the id
mid = mail['Message-ID'][1:-1]
envelope.previous_draft = ui.dbman.get_message(mid)
await ui.apply_command(commands.globals.BufferCloseCommand())


@registerCommand(MODE, 'send')
Expand Down Expand Up @@ -315,6 +360,8 @@ async def apply(self, ui):
ui.dbman.add_message(path, account.sent_tags + initial_tags)
await ui.apply_command(globals.FlushCommand())

await delete_previous_draft(self.envelope, ui)


@registerCommand(MODE, 'edit', arguments=[
(['--spawn'], {'action': cargparse.BooleanAction, 'default': None,
Expand Down
8 changes: 7 additions & 1 deletion alot/commands/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,15 @@ async def apply(self, ui):
tags.difference_update({'inbox', 'sent', 'draft', 'killed', 'replied',
'signed', 'encrypted', 'unread', 'attachment'})
tags = list(tags)

draft = None
if 'draft' in self.message.get_tags():
draft = self.message

# set body text
mailcontent = self.message.get_body_text()
envelope = Envelope(bodytext=mailcontent, tags=tags)
envelope = Envelope(bodytext=mailcontent, tags=tags,
previous_draft=draft)

# copy selected headers
to_copy = ['Subject', 'From', 'To', 'Cc', 'Bcc', 'In-Reply-To',
Expand Down
3 changes: 2 additions & 1 deletion alot/db/envelope.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Envelope:
def __init__(
self, template=None, bodytext=None, headers=None, attachments=None,
sign=False, sign_key=None, encrypt=False, tags=None, replied=None,
passed=None, account=None):
passed=None, account=None, previous_draft=None):
"""
:param template: if not None, the envelope will be initialised by
:meth:`parsing <parse_template>` this string before
Expand Down Expand Up @@ -92,6 +92,7 @@ def __init__(
self.tags = tags or [] # tags to add after successful sendout
self.replied = replied # message being replied to
self.passed = passed # message being passed on
self.previous_draft = previous_draft
self.sent_time = None
self.modified_since_sent = False
self.sending = False # semaphore to avoid accidental double sendout
Expand Down
2 changes: 1 addition & 1 deletion alot/db/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def _with_notmuch_message(self, mid):
with Database(path=self.path, mode=Database.MODE.READ_ONLY,
config=self.config) as db:
try:
yield db.find_message(mid)
yield db.find(mid)
except:
errmsg = 'no message with id %s exists!' % mid
raise NonexistantObjectError(errmsg)
Expand Down
4 changes: 4 additions & 0 deletions alot/defaults/alot.rc.spec
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ auto_replyto_mailinglist = boolean(default=False)
# prefer plaintext alternatives over html content in multipart/alternative
prefer_plaintext = boolean(default=False)

# When sending an email or saving a new draft, always delete the old draft.
# If set to False, the user will be prompted every time.
envelope_always_delete_old_drafts = boolean(default=False)

# always edit the given body text alternative when editing outgoing messages in envelope mode.
# alternative, and not the html source, even if that is currently displayed.
# If unset, html content will be edited unless the current envelope shows the plaintext alternative.
Expand Down

0 comments on commit 04eae1e

Please sign in to comment.