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): '''