|
|
@ -11,6 +11,7 @@ import sys |
|
|
|
# TODO Find config file from XDG |
|
|
|
# TODO Signature file |
|
|
|
# TODO Write ~/.mail/[mailbox]/color file if required by sth? |
|
|
|
# TODO Write in .config or .cache /mel |
|
|
|
# TODO Fix IMAPS with mbsync |
|
|
|
|
|
|
|
configPath = os.path.join(os.path.expanduser('~'), '.config', 'mel', 'accounts.conf') |
|
|
@ -26,6 +27,17 @@ SERVER_DEFAULTS = { |
|
|
|
"smtp": {"port": 587, "starttls": True}, |
|
|
|
} |
|
|
|
SERVER_ITEMS = {"host", "port", "user", "pass", "starttls"} |
|
|
|
ACCOUNT_DEFAULTS = { |
|
|
|
"color": "#FFFFFF", |
|
|
|
"color16": "0", |
|
|
|
# "colormutt": "white", |
|
|
|
"inboxfolder": "INBOX", |
|
|
|
"archivefolder": "Archive", |
|
|
|
"draftsfolder": "Drafts", |
|
|
|
"sentfolder": "Sent", |
|
|
|
"spamfolder": "Spam", |
|
|
|
"trashfolder": "Trash", |
|
|
|
} |
|
|
|
|
|
|
|
# Reading sections |
|
|
|
accounts = dict() |
|
|
@ -59,6 +71,14 @@ for name in config.sections(): |
|
|
|
continue |
|
|
|
data[key] = section[key] |
|
|
|
|
|
|
|
for k, v in config['DEFAULT'].items(): |
|
|
|
if k not in data: |
|
|
|
data[k] = v |
|
|
|
|
|
|
|
for k, v in ACCOUNT_DEFAULTS.items(): |
|
|
|
if k not in data: |
|
|
|
data[k] = v |
|
|
|
|
|
|
|
mails.add(section["from"]) |
|
|
|
if "alternatives" in section: |
|
|
|
for alt in section["alternatives"].split(";"): |
|
|
@ -163,8 +183,8 @@ for name, account in accounts.items(): |
|
|
|
secconf += "\nCertificateFile {certificate}".format(**account) |
|
|
|
imappassEscaped = account["imappass"].replace("\\", "\\\\") |
|
|
|
mbsyncStr += MBSYNC_ACCOUNT.format(**account, secconf=secconf, imappassEscaped=imappassEscaped) |
|
|
|
msbsyncFilepath = os.path.join(os.path.expanduser('~'), '.mbsyncrc') |
|
|
|
with open(msbsyncFilepath, 'w') as f: |
|
|
|
mbsyncFilepath = os.path.join(os.path.expanduser('~'), '.mbsyncrc') |
|
|
|
with open(mbsyncFilepath, 'w') as f: |
|
|
|
f.write(mbsyncStr) |
|
|
|
|
|
|
|
# msmtp |
|
|
@ -188,8 +208,8 @@ tls on |
|
|
|
msmtpStr = MSMTP_BEGIN |
|
|
|
for name, account in accounts.items(): |
|
|
|
msmtpStr += MSMTP_ACCOUNT.format(**account) |
|
|
|
msbsyncFilepath = os.path.join(os.path.expanduser('~'), '.msmtprc') |
|
|
|
with open(msbsyncFilepath, 'w') as f: |
|
|
|
mbsyncFilepath = os.path.join(os.path.expanduser('~'), '.msmtprc') |
|
|
|
with open(mbsyncFilepath, 'w') as f: |
|
|
|
f.write(msmtpStr) |
|
|
|
|
|
|
|
|
|
|
@ -221,7 +241,90 @@ other_email = mails.copy() |
|
|
|
other_email.remove(general["main"]["from"]) |
|
|
|
other_email = ";".join(other_email) |
|
|
|
notmuchStr = NOTMUCH_BEGIN.format(**general, other_email=other_email) |
|
|
|
msbsyncFilepath = os.path.join(os.path.expanduser('~'), '.notmuchrc') |
|
|
|
with open(msbsyncFilepath, 'w') as f: |
|
|
|
mbsyncFilepath = os.path.join(os.path.expanduser('~'), '.notmuchrc') |
|
|
|
with open(mbsyncFilepath, 'w') as f: |
|
|
|
f.write(notmuchStr) |
|
|
|
|
|
|
|
# mutt (temp) |
|
|
|
|
|
|
|
## mailboxes |
|
|
|
MAILBOXES_BEGIN = "mailboxes" |
|
|
|
|
|
|
|
mailboxesStr = MAILBOXES_BEGIN |
|
|
|
for name, account in accounts.items(): |
|
|
|
lines = "-" * (20 - len(name)) |
|
|
|
mailboxesStr += f' "+{name}{lines}"' |
|
|
|
for root, dirs, files in os.walk(account['storage']): |
|
|
|
if "cur" not in dirs or "new" not in dirs or "tmp" not in dirs: |
|
|
|
continue |
|
|
|
assert root.startswith(storageFull) |
|
|
|
path = root[len(storageFull)+1:] |
|
|
|
mailboxesStr += f' "+{path}"' |
|
|
|
mailboxesStr += "\n" |
|
|
|
mailboxesFilepath = os.path.join(os.path.expanduser('~'), '.mutt/mailboxes') |
|
|
|
with open(mailboxesFilepath, 'w') as f: |
|
|
|
f.write(mailboxesStr) |
|
|
|
|
|
|
|
## accounts |
|
|
|
# TODO html mails |
|
|
|
|
|
|
|
MUTT_ACCOUNT = """set from = "{from}" |
|
|
|
set sendmail = "/usr/bin/msmtp -a {account}" |
|
|
|
set realname = "{name}" |
|
|
|
set spoolfile = "+{account}/{inboxfolder}" |
|
|
|
set mbox = "+{account}/{archivefolder}" |
|
|
|
set postponed = "+{account}/{draftsfolder}" |
|
|
|
set record = "+{account}/{sentfolder}" |
|
|
|
set trash = "+{account}/{trashfolder}" |
|
|
|
set signature = "~/.mutt/accounts/{account}.sig" |
|
|
|
set content_type = "text/plain" |
|
|
|
set sig_dashes = yes |
|
|
|
|
|
|
|
color status {colormutt} default |
|
|
|
|
|
|
|
macro index D \\ |
|
|
|
"<clear-flag>N<save-message>+{account}/{trashfolder}<enter>" \\ |
|
|
|
"move message to the trash" |
|
|
|
|
|
|
|
macro index S \\ |
|
|
|
"<clear-flag>N<save-message>+{account}/{spamfolder}<enter>" \\ |
|
|
|
"mark message as spam" |
|
|
|
# vim: syntax=muttrc |
|
|
|
""" |
|
|
|
|
|
|
|
for name, account in accounts.items(): |
|
|
|
muttStr = MUTT_ACCOUNT.format(**account) |
|
|
|
|
|
|
|
# Config |
|
|
|
muttFilepath = os.path.join(os.path.expanduser('~'), f'.mutt/accounts/{name}') |
|
|
|
with open(muttFilepath, 'w') as f: |
|
|
|
f.write(muttStr) |
|
|
|
|
|
|
|
# Signature |
|
|
|
sigStr = account.get("sig", account.get("name", "")) |
|
|
|
sigFilepath = os.path.join(os.path.expanduser('~'), f'.mutt/accounts/{name}.sig') |
|
|
|
with open(sigFilepath, 'w') as f: |
|
|
|
f.write(sigStr) |
|
|
|
|
|
|
|
MUTT_SELECTOR = """ |
|
|
|
set folder = "{storage}" |
|
|
|
source ~/.mutt/mailboxes |
|
|
|
|
|
|
|
source ~/.mutt/accounts/{main[account]} |
|
|
|
|
|
|
|
{hooks} |
|
|
|
|
|
|
|
source ~/.mutt/custom |
|
|
|
|
|
|
|
# vim: syntax=muttrc |
|
|
|
""" |
|
|
|
|
|
|
|
selectStr = "" |
|
|
|
hooks = "" |
|
|
|
for name, account in accounts.items(): |
|
|
|
hooks += f"folder-hook {name}/* source ~/.mutt/accounts/{name}\n" |
|
|
|
selectStr += MUTT_SELECTOR.format(**general, hooks=hooks) |
|
|
|
selectFilepath = os.path.join(os.path.expanduser('~'), '.mutt/muttrc') |
|
|
|
with open(selectFilepath, 'w') as f: |
|
|
|
f.write(selectStr) |
|
|
|
|