From 41ade135aa439b5fd189a315c70bb534910e2cb7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 14 Jul 2022 13:43:40 +0530 Subject: [PATCH] API to check if a filesystem is an FAT filesystem on windows --- src/calibre/db/backend.py | 7 ++++--- src/calibre/db/cache.py | 4 ++++ src/calibre/utils/filenames.py | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index 56455f3b27..1d7dd4b730 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -16,7 +16,7 @@ import shutil import sys import time import uuid -from contextlib import suppress, closing +from contextlib import closing, suppress from functools import partial from calibre import as_unicode, force_unicode, isbytestring, prints @@ -40,8 +40,8 @@ from calibre.utils.config import from_json, prefs, to_json, tweaks from calibre.utils.date import EPOCH, parse_date, utcfromtimestamp, utcnow from calibre.utils.filenames import ( WindowsAtomicFolderMove, ascii_filename, atomic_rename, copyfile_using_links, - copytree_using_links, hardlink_file, is_case_sensitive, remove_dir_if_empty, - samefile + copytree_using_links, hardlink_file, is_case_sensitive, is_fat_filesystem, + remove_dir_if_empty, samefile ) from calibre.utils.formatter_functions import ( compile_user_template_functions, formatter_functions, @@ -470,6 +470,7 @@ class DB: if not os.path.exists(self.library_path): os.makedirs(self.library_path) self.is_case_sensitive = is_case_sensitive(self.library_path) + self.is_fat_filesystem = is_fat_filesystem(self.library_path) SchemaUpgrade(self, self.library_path, self.field_metadata) diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index bd9319ef25..96f01d483b 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -189,6 +189,10 @@ class Cache: def dbpath(self): return self.backend.dbpath + @property + def is_fat_filesystem(self): + return self.backend.is_fat_filesystem + @property def safe_read_lock(self): ''' A safe read lock is a lock that does nothing if the thread already diff --git a/src/calibre/utils/filenames.py b/src/calibre/utils/filenames.py index 283c90c43c..2fe951e9e3 100644 --- a/src/calibre/utils/filenames.py +++ b/src/calibre/utils/filenames.py @@ -604,6 +604,25 @@ if iswindows: if len(path) > 200 and os.path.isabs(path) and not path.startswith(long_path_prefix): path = long_path_prefix + os.path.normpath(path) return path + + def is_fat_filesystem(path): + try: + from calibre_extensions.winutil import filesystem_type_name + except ImportError: + return False + if not path: + return False + drive = os.path.abspath(path)[0].upper() + try: + tn = filesystem_type_name(f'{drive}:\\') + except OSError: + return False + # Values I have seen: FAT32, exFAT, NTFS + return tn.upper().startswith('FAT') else: def make_long_path_useable(path): return path + + def is_fat_filesystem(path): + # TODO: Implement for Linux and macOS + return False