#!/usr/bin/python from argparse import ArgumentParser from pathlib import Path MAILBOX_SUBDIRS = {"cur", "new", "tmp"} def get_mailbox_from_dir(path: Path, mailboxes: list[Path]) -> None: """ Add mailboxes in a directory to a list. All directories below path are evaluated to have necessary subdirectories (see MAILBOX_SUBDIRS) to be counted as a mailbox directory. Parameters ---------- path: Path The path to search in for mailbox directories mailboxes: list[Path] A list of paths to add mailboxes to """ for current_path in path.iterdir(): if current_path.is_dir() and current_path.name not in MAILBOX_SUBDIRS: subdirs = list(current_path.iterdir()) if ( MAILBOX_SUBDIRS & set(subdir.name for subdir in subdirs) and current_path not in mailboxes ): mailboxes.append(current_path) for subdir in subdirs: if subdir.name not in MAILBOX_SUBDIRS: get_mailbox_from_dir( path=current_path, mailboxes=mailboxes, ) def write_file(contents: str, output: Path) -> None: """Write a string to a file Parameters ---------- contents: str The string to write output: Path The file path to write to """ with open(output, "w") as f: print(contents, file=f) def main(path: Path, output: Path) -> None: """Find mailbox directories in account directories and write them to file. The directories below path are considered to be account directories, containing mailboxes. The output is written to output and is compatible with mutt's mailboxes directive. Parameters ---------- path: Path A directory below which directories are assumed to be account directories which contain mailboxes output: Path A file to which to write output to Raises ------ RuntimeError If path does not exist or if path is not a directory or if path does not contain any directories """ if not path.exists(): raise RuntimeError(f"The input path '{path}' does not exist!") if not path.is_dir(): raise RuntimeError(f"The input path '{path}' is not a directory!") accounts = [subdir for subdir in path.iterdir() if subdir.is_dir()] if len(accounts) == 0: raise RuntimeError( f"The path '{path}' does not contain any account directories!" ) file_string = "" for account_dir in accounts: mailboxes: list[Path] = [] mailboxes_string = "mailboxes " get_mailbox_from_dir(path=account_dir, mailboxes=mailboxes) for mailbox in mailboxes: mailbox_dir = str(mailbox).replace( str(account_dir.parent) + '/', '', ) mailboxes_string += f" '+{mailbox_dir}'" if mailboxes: file_string += mailboxes_string + "\n" write_file(contents=file_string, output=output) if __name__ == "__main__": parser = ArgumentParser( description=""" Create 'mailboxes' entries for one or more directories. Each provided directory is """ ) parser.add_argument( "-o", "--output", default=Path("mailboxes.rc"), help="a file to write the mailboxes to (mailboxes.rc by default)", type=Path, ) parser.add_argument( "path", default=Path("~/.local/state/mail/"), help="a directory to search in for mailbox directories", nargs="?", type=Path, ) namespace = parser.parse_args() main(output=namespace.output, path=namespace.path)