diff --git a/core/opds_import.py b/core/opds_import.py index 03a46929c..90b51ea0d 100644 --- a/core/opds_import.py +++ b/core/opds_import.py @@ -1958,20 +1958,29 @@ def _get_feeds(self) -> Iterable[tuple[str, bytes]]: return reversed(feeds) def run_once(self, progress: TimestampData) -> TimestampData: + """ + Import all books in a feed. + + :param progress: A TimestampData object indicating the start time of the run. + :return: A new TimestampData object with an achievements field + containing details of the operation. + """ feeds = self._get_feeds() total_imported = 0 total_failures = 0 + failure_summary = [] for link, feed in feeds: self.log.info("Importing next feed: %s", link) imported_editions, failures = self.import_one_feed(feed) total_imported += len(imported_editions) total_failures += len(failures) + for failure_id, failure_details in failures.items(): + failure_summary.append(f"ISBN: {failure_id}: {failure_details}") self._db.commit() - - achievements = "Items imported: %d. Failures: %d." % ( - total_imported, - total_failures, + achievements = ( + "Items imported: %d. Failures: %d.\nFailed IDs and details:\n%s" + % (total_imported, total_failures, "\n".join(failure_summary)) ) return TimestampData(achievements=achievements) diff --git a/tests/core/test_opds_import.py b/tests/core/test_opds_import.py index 3e1c2626d..5710dd04a 100644 --- a/tests/core/test_opds_import.py +++ b/tests/core/test_opds_import.py @@ -1948,7 +1948,7 @@ def test_import_one_feed(self, opds_importer_fixture: OPDSImporterFixture): collection=collection, ) assert "Utter failure!" in failure.exception - + print(failures) # Both failures were reported in the return value from # import_one_feed assert 2 == len(failures) @@ -1992,7 +1992,9 @@ def import_one_feed(self, feed): assert ["last page", "second page", "first page"] == monitor.imports # Every page of the import had two successes and one failure. - assert "Items imported: 6. Failures: 3." == progress.achievements + assert ( + "Items imported: 6. Failures: 3.\nFailed IDs and details:\nISBN: identifier: Failure\nISBN: identifier: Failure\nISBN: identifier: Failure" + ) == progress.achievements # The TimestampData returned by run_once does not include any # timing information; that's provided by run().