handle shutdown properly

This commit is contained in:
Valentin Boettcher 2024-11-17 13:08:43 -05:00
parent b953412360
commit 721d1b005e
No known key found for this signature in database
GPG key ID: E034E12B7AF56ACE

View file

@ -9,7 +9,6 @@ import signal
import shutil import shutil
import subprocess import subprocess
import urllib.request import urllib.request
from asyncio import wait_for
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from .imap import ( from .imap import (
@ -93,16 +92,20 @@ async def wait_for_new_message(imap_client, kindle_dir, latest_path):
imap_client, persistent_max_uid imap_client, persistent_max_uid
) )
while True: idle_task = None
try:
LOGGER.debug("waiting for new message")
idle_task = await imap_client.idle_start(timeout=float("inf")) try:
msg = await imap_client.wait_server_push() while True:
imap_client.idle_done() try:
await wait_for(idle_task, timeout=float("inf")) LOGGER.debug("waiting for new message")
except TimeoutError:
continue idle_task = await imap_client.idle_start(timeout=float("inf"))
msg = await imap_client.wait_server_push()
imap_client.idle_done()
await asyncio.wait_for(idle_task, timeout=10)
except TimeoutError:
continue
for message in msg: for message in msg:
if message.endswith(b"EXISTS"): if message.endswith(b"EXISTS"):
@ -143,6 +146,15 @@ async def wait_for_new_message(imap_client, kindle_dir, latest_path):
await remove_message(imap_client, persistent_max_uid) await remove_message(imap_client, persistent_max_uid)
except asyncio.CancelledError:
LOGGER.info("exiting monitor")
if idle_task is not None:
imap_client.idle_done()
await asyncio.wait_for(idle_task, timeout=5)
await imap_client.logout()
LOGGER.info("logged out")
def parse_args_and_configure_logging(): def parse_args_and_configure_logging():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
@ -204,26 +216,23 @@ def parse_args_and_configure_logging():
def main(): def main():
"""The entry point for the command line script.""" """The entry point for the command line script."""
options = parse_args_and_configure_logging() options = parse_args_and_configure_logging()
loop = asyncio.get_event_loop()
LOGGER.info("logging in") LOGGER.info("logging in")
try: with asyncio.Runner() as runner:
client = loop.run_until_complete( try:
make_client(options.server, options.user, options.password, options.mailbox) client = runner.run(
make_client(
options.server, options.user, options.password, options.mailbox
)
)
except Exception as e:
LOGGER.error(f"Failed to connect to the server: {e}")
sys.exit(1)
LOGGER.info("starting monitor")
runner.run(
wait_for_new_message(client, options.kindle_dir, options.latest_path)
) )
except Exception as e:
LOGGER.error(f"Failed to connect to the server: {e}")
sys.exit(1)
LOGGER.info("starting monitor")
signal.signal(
signal.SIGINT,
lambda _, _1: loop.run_until_complete(client.logout()) and sys.exit(0),
)
loop.run_until_complete(
wait_for_new_message(client, options.kindle_dir, options.latest_path)
)
loop.run_until_complete(client.logout())