From 1845c11990967695c16cf2be5750dc68be882015 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 20 Jul 2025 13:25:47 +0530 Subject: [PATCH] Fix attempt to add directories whose names end with a known ebook extension These will fail anyway, so dont return them when iterating a folder to scan for books. --- src/calibre/db/adding.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/calibre/db/adding.py b/src/calibre/db/adding.py index 11a8fa65a6..4ab8b1f02d 100644 --- a/src/calibre/db/adding.py +++ b/src/calibre/db/adding.py @@ -8,8 +8,9 @@ import os import re import time from collections import defaultdict -from contextlib import contextmanager +from contextlib import contextmanager, suppress from functools import partial +from operator import attrgetter from calibre import prints from calibre.constants import filesystem_encoding, ismacos, iswindows @@ -109,6 +110,22 @@ def listdir(root, sort_by_mtime=False): yield path +def list_only_files_in_dir(root, sort_by_mtime=False): + def files_iter(): + for x in os.scandir(root): + with suppress(OSError): + if x.is_file(follow_symlinks=True): + yield x + items = files_iter() + if sort_by_mtime: + def safe_mtime(x: os.DirEntry): + with suppress(OSError): + return x.stat(follow_symlinks=True).st_mtime_ns + return 0 + items = sorted(items, key=safe_mtime) + yield from map(attrgetter('name'), items) + + def allow_path(path, ext, compiled_rules): ans = filter_filename(compiled_rules, os.path.basename(path)) if ans is None: @@ -138,7 +155,7 @@ def run_import_plugins(formats): return ans -def find_books_in_directory(dirpath, single_book_per_directory, compiled_rules=(), listdir_impl=listdir): +def find_books_in_directory(dirpath, single_book_per_directory, compiled_rules=(), listdir_impl=list_only_files_in_dir): dirpath = make_long_path_useable(os.path.abspath(dirpath)) if single_book_per_directory: formats = {} @@ -231,7 +248,7 @@ def recursive_import(db, root, single_book_per_directory=True, def cdb_find_in_dir(dirpath, single_book_per_directory, compiled_rules): return find_books_in_directory(dirpath, single_book_per_directory=single_book_per_directory, - compiled_rules=compiled_rules, listdir_impl=partial(listdir, sort_by_mtime=True)) + compiled_rules=compiled_rules, listdir_impl=partial(list_only_files_in_dir, sort_by_mtime=True)) def cdb_recursive_find(root, single_book_per_directory=True, compiled_rules=()):