#! /usr/bin/env python3 import sys import argparse import traceback from xenu_nntp.config import Config from xenu_nntp.db import Database from xenu_nntp.newsgroup import Newsgroup from xenu_nntp.mbox import MBoxReader class Importer(): def __init__(self, db: Database, newsgroup: Newsgroup, args): self.db = db self.newsgroup = newsgroup self.args = args def print_error(self, mboxfile: str, reader: MBoxReader, e: Exception): print(f"Error importing file {mboxfile} on line {reader.line} to newsgroup {self.newsgroup.name}: {e}") def import_mbox_file(self, mboxfile: str): if self.args.verbose and not self.args.quiet: print(f"Reading file {mboxfile}") reader = MBoxReader(mboxfile) for message in reader.messages(): if self.args.verbose and not self.args.quiet: print(f"Importing message {message.message_id} to newsgroup {self.newsgroup.name}") try: self.db.add(message) self.db.execute(f'insert into newsgroup_message values (%s, %s)', (self.newsgroup.id, message.id)) except Exception as e: if not self.args.quiet: self.print_error(mboxfile, reader, e) if not self.args.ignore_errors: exit(1) parser = argparse.ArgumentParser(description='Create new account') parser.add_argument('--dry-run', action='store_true', help='Do not commit to database') parser.add_argument('--quiet', action='store_true', help='Do not print errors') parser.add_argument('--verbose', action='store_true', help='Print messages when importing files and messages') parser.add_argument('--ignore-errors', action='store_true', help='Do not exit on encountering errors') parser.add_argument('--config-file', '-f', type=str, help='Specify a configuration file location') parser.add_argument('newsgroup', type=str, help='Name of newsgroup to ingest articles into') parser.add_argument('mboxfile', type=str, nargs='+', help='mbox file to ingest') args = parser.parse_args() config = Config.load(args.config_file) db = Database.from_config(config) newsgroup = db.get(Newsgroup, {'name': args.newsgroup}) importer = Importer(db, newsgroup, args) db.execute("begin transaction") for mboxfile in args.mboxfile: importer.import_mbox_file(mboxfile) if not args.dry_run: db.commit()