mirror of
https://git.hiabuto.net/C3MA/CCMA.git
synced 2026-09-06 03:20:49 +02:00
Copy directly-sent e-mails to an IMAP Sent folder, with a live folder picker
A raw SMTP send has no server-side "Sent" copy on its own (unlike IMAP drafts, which are inherently server-side) -- add an opt-in checkbox plus a configurable target folder so directly sent Mahnungen/SEPA-info-mails still show up in the account's Gesendet/Sent folder like a normal mail client would leave them. Applies only to "send" delivery; drafts already live on the server by definition. Both the Entwürfe- and Gesendet-folder fields are now editable comboboxes: a new "Ordnerliste laden" button fetches the real folder list from the IMAP server (needs working credentials first) via LIST, decoding folder names from modified UTF-7 (RFC 3501) so names like "Entwürfe" render correctly instead of as "Entw&APw-rfe". Free text still works -- ensure_imap_folder() creates the folder on first use if it doesn't exist yet, checked once per batch rather than before every single message. mail_delivery.append_to_imap_drafts() became the more general append_message(client, content, folder=, flags=), reused for both the \Draft and \Seen cases. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
6b0da82b45
commit
cc4aaef895
@@ -10,7 +10,13 @@ from email.policy import SMTP
|
||||
from email.utils import format_datetime, make_msgid
|
||||
from pathlib import Path
|
||||
|
||||
from ccma.services.mail_delivery import append_to_imap_drafts, imap_session, send_via_smtp, smtp_session
|
||||
from ccma.services.mail_delivery import (
|
||||
append_message,
|
||||
ensure_imap_folder,
|
||||
imap_session,
|
||||
send_via_smtp,
|
||||
smtp_session,
|
||||
)
|
||||
from ccma.services.sepa import DirectDebit
|
||||
from ccma.storage.repository import MemberRepository, RepositoryError
|
||||
|
||||
@@ -105,18 +111,21 @@ def generate_debit_mails(
|
||||
) -> tuple[list[GeneratedDebitMail], list[str]]:
|
||||
output: Path | None = None
|
||||
email_settings: dict | None = None
|
||||
smtp_ctx = nullcontext(None)
|
||||
imap_ctx = nullcontext(None)
|
||||
if delivery_mode == "local":
|
||||
if not output_directory:
|
||||
raise RepositoryError("Kein Zielordner für die lokale Ablage angegeben.")
|
||||
output = Path(output_directory)
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
session = nullcontext(None)
|
||||
elif delivery_mode == "send":
|
||||
email_settings = repository.get_email_settings()
|
||||
session = smtp_session(email_settings)
|
||||
smtp_ctx = smtp_session(email_settings)
|
||||
if email_settings["imap_sent_enabled"]:
|
||||
imap_ctx = imap_session(email_settings)
|
||||
elif delivery_mode == "drafts":
|
||||
email_settings = repository.get_email_settings()
|
||||
session = imap_session(email_settings)
|
||||
imap_ctx = imap_session(email_settings)
|
||||
else:
|
||||
raise RepositoryError(f"Unbekannter Versandmodus: {delivery_mode}")
|
||||
|
||||
@@ -126,9 +135,14 @@ def generate_debit_mails(
|
||||
raise RepositoryError("In den Optionen fehlt die Gläubiger-ID.")
|
||||
generated: list[GeneratedDebitMail] = []
|
||||
warnings: list[str] = []
|
||||
# One connection is opened for the whole batch (a run can cover dozens of
|
||||
# members) instead of reconnecting/re-authenticating per recipient.
|
||||
with session as client:
|
||||
# One connection (or two, for "send" with a Sent-folder copy) is opened for the
|
||||
# whole batch -- a run can cover dozens of members -- instead of reconnecting/
|
||||
# re-authenticating per recipient.
|
||||
with smtp_ctx as smtp_client, imap_ctx as imap_client:
|
||||
if delivery_mode == "drafts":
|
||||
ensure_imap_folder(imap_client, email_settings["imap_drafts_folder"])
|
||||
elif delivery_mode == "send" and imap_client is not None:
|
||||
ensure_imap_folder(imap_client, email_settings["imap_sent_folder"])
|
||||
for debit in debits:
|
||||
member = repository.get_member(debit.member_id)
|
||||
if not member.email.strip():
|
||||
@@ -156,9 +170,15 @@ def generate_debit_mails(
|
||||
export_path = _available_path(output, filename)
|
||||
export_path.write_bytes(content)
|
||||
elif delivery_mode == "send":
|
||||
send_via_smtp(client, content)
|
||||
send_via_smtp(smtp_client, content)
|
||||
if imap_client is not None:
|
||||
append_message(
|
||||
imap_client, content, folder=email_settings["imap_sent_folder"], flags=r"(\Seen)"
|
||||
)
|
||||
else:
|
||||
append_to_imap_drafts(client, content, folder=email_settings["imap_drafts_folder"])
|
||||
append_message(
|
||||
imap_client, content, folder=email_settings["imap_drafts_folder"], flags=r"(\Draft)"
|
||||
)
|
||||
try:
|
||||
archive_path.write_bytes(content)
|
||||
except OSError:
|
||||
|
||||
Reference in New Issue
Block a user