1
0
mirror of https://github.com/Mailu/Mailu.git synced 2025-06-06 23:36:26 +02:00
Mailu/optional/fetchmail/fetchmail.py

114 lines
3.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
2016-04-28 20:07:38 +02:00
import time
import os
2022-11-13 17:15:50 +01:00
from pathlib import Path
from pwd import getpwnam
2016-04-28 20:07:38 +02:00
import tempfile
2016-09-10 12:27:43 +02:00
import shlex
import subprocess
import requests
2022-11-13 17:15:50 +01:00
from socrate import system
import sys
import traceback
2016-04-28 20:07:38 +02:00
2016-06-26 13:54:16 +02:00
FETCHMAIL = """
fetchmail -N \
2021-11-13 14:40:22 +00:00
--idfile /data/fetchids --uidl \
2022-11-13 17:15:50 +01:00
--pidfile /dev/shm/fetchmail.pid \
2016-06-26 13:54:16 +02:00
--sslcertck --sslcertpath /etc/ssl/certs \
-f {}
"""
2016-04-28 20:07:38 +02:00
RC_LINE = """
poll "{host}" proto {protocol} port {port}
2016-04-28 20:07:38 +02:00
user "{username}" password "{password}"
is "{user_email}"
smtphost "{smtphost}"
2022-11-13 17:15:50 +01:00
{folders}
2016-04-28 20:07:38 +02:00
{options}
2022-11-13 17:15:50 +01:00
{lmtp}
2016-04-28 20:07:38 +02:00
"""
2016-09-10 12:27:43 +02:00
def escape_rc_string(arg):
return "".join("\\x%2x" % ord(char) for char in arg)
2016-09-10 12:27:43 +02:00
2016-04-28 20:07:38 +02:00
def fetchmail(fetchmailrc):
with tempfile.NamedTemporaryFile() as handler:
handler.write(fetchmailrc.encode("utf8"))
handler.flush()
command = FETCHMAIL.format(shlex.quote(handler.name))
output = subprocess.check_output(command, shell=True)
return output
2016-04-28 20:07:38 +02:00
def run(debug):
try:
2022-11-13 17:15:50 +01:00
fetches = requests.get(f"http://{os.environ['ADMIN_ADDRESS']}/internal/fetch").json()
for fetch in fetches:
fetchmailrc = ""
options = "options antispam 501, 504, 550, 553, 554"
options += " ssl" if fetch["tls"] else ""
options += " keep" if fetch["keep"] else " fetchall"
2022-11-13 17:15:50 +01:00
folders = "folders %s" % ((','.join('"' + item + '"' for item in fetch['folders'])) if fetch['folders'] else '"INBOX"')
fetchmailrc += RC_LINE.format(
user_email=escape_rc_string(fetch["user_email"]),
protocol=fetch["protocol"],
host=escape_rc_string(fetch["host"]),
port=fetch["port"],
2022-12-08 12:46:31 +01:00
smtphost=f'{os.environ["SMTP_ADDRESS"]}' if fetch['scan'] else f'{os.environ["IMAP_ADDRESS"]}/2525',
username=escape_rc_string(fetch["username"]),
password=escape_rc_string(fetch["password"]),
2022-11-13 17:15:50 +01:00
options=options,
folders=folders,
lmtp='' if fetch['scan'] else 'lmtp',
)
if debug:
print(fetchmailrc)
try:
print(fetchmail(fetchmailrc))
error_message = ""
except subprocess.CalledProcessError as error:
error_message = error.output.decode("utf8")
# No mail is not an error
if not error_message.startswith("fetchmail: No mail"):
print(error_message)
user_info = "for %s at %s" % (fetch["user_email"], fetch["host"])
# Number of messages seen is not a error as well
if ("messages" in error_message and
"(seen " in error_message and
user_info in error_message):
print(error_message)
finally:
2022-11-14 16:47:43 +01:00
requests.post("http://{}/internal/fetch/{}".format(os.environ['ADMIN_ADDRESS'],fetch['id']),
json=error_message.split('\n')[0]
)
except Exception:
traceback.print_exc()
2016-04-28 20:07:38 +02:00
if __name__ == "__main__":
2022-11-13 17:15:50 +01:00
id_fetchmail = getpwnam('fetchmail')
Path('/data/fetchids').touch()
os.chown("/data/fetchids", id_fetchmail.pw_uid, id_fetchmail.pw_gid)
os.chown("/data/", id_fetchmail.pw_uid, id_fetchmail.pw_gid)
os.chmod("/data/fetchids", 0o700)
os.setgid(id_fetchmail.pw_gid)
os.setuid(id_fetchmail.pw_uid)
2022-12-08 12:46:31 +01:00
system.set_env()
2016-04-28 20:07:38 +02:00
while True:
delay = int(os.environ.get("FETCHMAIL_DELAY", 60))
print("Sleeping for {} seconds".format(delay))
time.sleep(delay)
if not os.environ.get("FETCHMAIL_ENABLED", 'True') in ('True', 'true'):
print("Fetchmail disabled, skipping...")
continue
run(os.environ.get("DEBUG", None) == "True")
sys.stdout.flush()