44 lines
1.3 KiB
Bash
Executable File
44 lines
1.3 KiB
Bash
Executable File
#!/usr/bin/env python3
|
|
# ~/.local/bin/maildir2vcf
|
|
import email, os, sys, pathlib, fileinput
|
|
|
|
MAILDIR = pathlib.Path.home()/ "Mail" # ← change if your mail sits elsewhere
|
|
OUTDIR = pathlib.Path.home()/ ".contacts_mail"
|
|
OUTDIR.mkdir(exist_ok=True)
|
|
|
|
seen = set() # de-duplicate on lower-case e-mail
|
|
|
|
def vcard(name, mail):
|
|
safe_name = name.replace(";", " ").strip() or "No Name"
|
|
safe_mail = mail.strip().lower()
|
|
if safe_mail in seen: # already exported
|
|
return
|
|
seen.add(safe_mail)
|
|
fn = OUTDIR/f"{safe_mail}.vcf"
|
|
fn.write_text(f"""\
|
|
BEGIN:VCARD
|
|
VERSION:3.0
|
|
FN:{safe_name}
|
|
EMAIL:{safe_mail}
|
|
END:VCARD
|
|
""")
|
|
|
|
def addresses_from_msg(path):
|
|
with open(path, "rb") as f:
|
|
msg = email.message_from_binary_file(f)
|
|
for hdr in ("From", "To", "Cc", "Bcc"):
|
|
for addr in email.utils.getaddresses(msg.get_all(hdr, [])):
|
|
name, mail = addr
|
|
if "@" in mail:
|
|
vcard(name, mail)
|
|
|
|
# walk cur/ + new/ (typical Maildir layout)
|
|
for sub in ("cur", "new"):
|
|
for root, _, files in os.walk(MAILDIR/sub):
|
|
for file in files:
|
|
if file.startswith("."):
|
|
continue
|
|
addresses_from_msg(pathlib.Path(root)/file)
|
|
|
|
print("Exported", len(seen), "unique addresses →", OUTDIR)
|