From 2a50706faba9e53f44d06af3ec2ad4d1d7d44def Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Thu, 12 Aug 2010 12:02:49 +0100 Subject: [PATCH 1/2] Ensure case changes are taken into account for folders in case-insensitive file systems --- src/calibre/library/database2.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 6a259a655f..b82d7ef08b 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -433,6 +433,27 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): parent = os.path.dirname(spath) if len(os.listdir(parent)) == 0: self.rmtree(parent, permanent=True) + curpath = self.library_path + if not self.is_case_sensitive: + # On case-insensitive systems, title and author renames that only + # change case don't cause any changes to the directories in the file + # system. This can lead to having the directory names not match the + # title/author, which leads to trouble when libraries are copied to + # a case-sensitive system. The following code fixes this by checking + # each segment. If they are different (must be because of case), + # then rename the segment to some temp file name, then rename it + # back to the correct name. Note that the code above correctly + # handles files in the directories, so no need to do them here. + for oldseg,newseg in zip(current_path.split('/'), path.split('/')): + if oldseg != newseg: + while True: + # need a temp name in the current segment for renames + tempname = 'TEMP.%f'%time.time() + if not os.path.exists(os.path.join(curpath, tempname)): + break + os.rename(os.path.join(curpath, oldseg), tempname) + os.rename(tempname, os.path.join(curpath, newseg)) + curpath = os.path.join(curpath, newseg) def add_listener(self, listener): ''' From 10554d0d4dc8c50e04da45666e2fe1c83a4f1289 Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Thu, 12 Aug 2010 12:17:44 +0100 Subject: [PATCH 2/2] Real name changes (not simplly change of case) raised an exception. Fix that. --- src/calibre/library/database2.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index b82d7ef08b..7c630a4043 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -440,12 +440,12 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): # system. This can lead to having the directory names not match the # title/author, which leads to trouble when libraries are copied to # a case-sensitive system. The following code fixes this by checking - # each segment. If they are different (must be because of case), - # then rename the segment to some temp file name, then rename it - # back to the correct name. Note that the code above correctly - # handles files in the directories, so no need to do them here. + # each segment. If they are different because of case, then rename + # the segment to some temp file name, then rename it back to the + # correct name. Note that the code above correctly handles files in + # the directories, so no need to do them here. for oldseg,newseg in zip(current_path.split('/'), path.split('/')): - if oldseg != newseg: + if oldseg.lower() == newseg.lower() and oldseg != newseg: while True: # need a temp name in the current segment for renames tempname = 'TEMP.%f'%time.time()