def windows_check_if_files_in_use(self, paths): ''' Raises an EACCES IOError if any of the files in the folder of book_id are opened in another program on windows. ''' if iswindows: for path in paths: spath = os.path.join(self.library_path, *path.split('/')) wam = None if os.path.exists(spath): try: wam = WindowsAtomicFolderMove(spath) finally: if wam is not None: wam.close_handles()
def windows_check_if_files_in_use(self, paths): ''' Raises an EACCES IOError if any of the files in the folder of book_id are opened in another program on windows. ''' if iswindows: for path in paths: spath = os.path.join(self.library_path, *path.split('/')) wam = None if os.path.exists(spath): try: wam = WindowsAtomicFolderMove(spath) finally: if wam is not None: wam.close_handles()
def update_path(self, book_id, title, author, path_field, formats_field): path = self.construct_path_name(book_id, title, author) current_path = path_field.for_book(book_id) formats = formats_field.for_book(book_id, default_value=()) fname = self.construct_file_name(book_id, title, author) # Check if the metadata used to construct paths has changed changed = False for fmt in formats: name = formats_field.format_fname(book_id, fmt) if name and name != fname: changed = True break if path == current_path and not changed: return spath = os.path.join(self.library_path, *current_path.split('/')) tpath = os.path.join(self.library_path, *path.split('/')) source_ok = current_path and os.path.exists(spath) wam = WindowsAtomicFolderMove( spath) if iswindows and source_ok else None try: if not os.path.exists(tpath): os.makedirs(tpath) if source_ok: # Migrate existing files dest = os.path.join(tpath, 'cover.jpg') self.copy_cover_to(current_path, dest, windows_atomic_move=wam, use_hardlink=True) for fmt in formats: dest = os.path.join(tpath, fname + '.' + fmt.lower()) self.copy_format_to(book_id, fmt, formats_field.format_fname( book_id, fmt), current_path, dest, windows_atomic_move=wam, use_hardlink=True) # Update db to reflect new file locations for fmt in formats: formats_field.table.set_fname(book_id, fmt, fname, self) path_field.table.set_path(book_id, path, self) # Delete not needed directories if source_ok: if os.path.exists(spath) and not samefile(spath, tpath): if wam is not None: wam.delete_originals() self.rmtree(spath, permanent=True) parent = os.path.dirname(spath) if len(os.listdir(parent)) == 0: self.rmtree(parent, permanent=True) finally: if wam is not None: wam.close_handles() curpath = self.library_path c1, c2 = current_path.split('/'), path.split('/') if not self.is_case_sensitive and len(c1) == len(c2): # 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 attempts to fix this # by checking each segment. If they are different because of case, # then rename the segment. Note that the code above correctly # handles files in the directories, so no need to do them here. for oldseg, newseg in zip(c1, c2): if oldseg.lower() == newseg.lower() and oldseg != newseg: try: os.rename(os.path.join(curpath, oldseg), os.path.join(curpath, newseg)) except: break # Fail silently since nothing catastrophic has happened curpath = os.path.join(curpath, newseg)
def update_path(self, book_id, title, author, path_field, formats_field): path = self.construct_path_name(book_id, title, author) current_path = path_field.for_book(book_id) formats = formats_field.for_book(book_id, default_value=()) fname = self.construct_file_name(book_id, title, author) # Check if the metadata used to construct paths has changed changed = False for fmt in formats: name = formats_field.format_fname(book_id, fmt) if name and name != fname: changed = True break if path == current_path and not changed: return spath = os.path.join(self.library_path, *current_path.split('/')) tpath = os.path.join(self.library_path, *path.split('/')) source_ok = current_path and os.path.exists(spath) wam = WindowsAtomicFolderMove(spath) if iswindows and source_ok else None try: if not os.path.exists(tpath): os.makedirs(tpath) if source_ok: # Migrate existing files dest = os.path.join(tpath, 'cover.jpg') self.copy_cover_to(current_path, dest, windows_atomic_move=wam, use_hardlink=True) for fmt in formats: dest = os.path.join(tpath, fname+'.'+fmt.lower()) self.copy_format_to(book_id, fmt, formats_field.format_fname(book_id, fmt), current_path, dest, windows_atomic_move=wam, use_hardlink=True) # Update db to reflect new file locations for fmt in formats: formats_field.table.set_fname(book_id, fmt, fname, self) path_field.table.set_path(book_id, path, self) # Delete not needed directories if source_ok: if os.path.exists(spath) and not samefile(spath, tpath): if wam is not None: wam.delete_originals() self.rmtree(spath, permanent=True) parent = os.path.dirname(spath) if len(os.listdir(parent)) == 0: self.rmtree(parent, permanent=True) finally: if wam is not None: wam.close_handles() curpath = self.library_path c1, c2 = current_path.split('/'), path.split('/') if not self.is_case_sensitive and len(c1) == len(c2): # 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 attempts to fix this # by checking each segment. If they are different because of case, # then rename the segment. Note that the code above correctly # handles files in the directories, so no need to do them here. for oldseg, newseg in zip(c1, c2): if oldseg.lower() == newseg.lower() and oldseg != newseg: try: os.rename(os.path.join(curpath, oldseg), os.path.join(curpath, newseg)) except: break # Fail silently since nothing catastrophic has happened curpath = os.path.join(curpath, newseg)