mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 07:13:02 +00:00 
			
		
		
		
	Rename everything on rename authors
This commit is contained in:
		| @@ -114,7 +114,7 @@ def search_objects_add(db_book_object, db_type, input_elements): | |||||||
|                 type_elements = c_elements.value |                 type_elements = c_elements.value | ||||||
|             else: |             else: | ||||||
|                 type_elements = c_elements.name |                 type_elements = c_elements.name | ||||||
|             if inp_element.lower() == type_elements.lower():    # Lowercase check |             if inp_element == type_elements: | ||||||
|                 found = True |                 found = True | ||||||
|                 break |                 break | ||||||
|         if not found: |         if not found: | ||||||
| @@ -709,6 +709,7 @@ def handle_title_on_edit(book, book_title): | |||||||
|  |  | ||||||
| def handle_author_on_edit(book, author_name, update_stored=True): | def handle_author_on_edit(book, author_name, update_stored=True): | ||||||
|     # handle author(s) |     # handle author(s) | ||||||
|  |     # renamed = False | ||||||
|     input_authors = author_name.split('&') |     input_authors = author_name.split('&') | ||||||
|     input_authors = list(map(lambda it: it.strip().replace(',', '|'), input_authors)) |     input_authors = list(map(lambda it: it.strip().replace(',', '|'), input_authors)) | ||||||
|     # Remove duplicates in authors list |     # Remove duplicates in authors list | ||||||
| @@ -717,6 +718,20 @@ def handle_author_on_edit(book, author_name, update_stored=True): | |||||||
|     if input_authors == ['']: |     if input_authors == ['']: | ||||||
|         input_authors = [_(u'Unknown')]  # prevent empty Author |         input_authors = [_(u'Unknown')]  # prevent empty Author | ||||||
|  |  | ||||||
|  |     # ToDo: Falsch es kann auch sein das der 2. Author in der Liste umbenannt wurde, | ||||||
|  |     #  man müsste für alle Authoren schauen | ||||||
|  |     renamed = list() | ||||||
|  |     for in_aut in input_authors: | ||||||
|  |         renamed_author = calibre_db.session.query(db.Authors).filter(db.Authors.name == in_aut).first() | ||||||
|  |         if renamed_author and in_aut != renamed_author.name: | ||||||
|  |             renamed.append(renamed_author.name) | ||||||
|  |             all_books = calibre_db.session.query(db.Books) \ | ||||||
|  |                 .filter(db.Books.authors.any(db.Authors.name == renamed_author.name)).all() | ||||||
|  |             sorted_renamed_author = helper.get_sorted_author(renamed_author.name) | ||||||
|  |             sorted_old_author = helper.get_sorted_author(in_aut) | ||||||
|  |             for one_book in all_books: | ||||||
|  |                 one_book.author_sort = one_book.author_sort.replace(sorted_renamed_author, sorted_old_author) | ||||||
|  |  | ||||||
|     change = modify_database_object(input_authors, book.authors, db.Authors, calibre_db.session, 'author') |     change = modify_database_object(input_authors, book.authors, db.Authors, calibre_db.session, 'author') | ||||||
|  |  | ||||||
|     # Search for each author if author is in database, if not, author name and sorted author name is generated new |     # Search for each author if author is in database, if not, author name and sorted author name is generated new | ||||||
| @@ -733,7 +748,7 @@ def handle_author_on_edit(book, author_name, update_stored=True): | |||||||
|     if book.author_sort != sort_authors and update_stored: |     if book.author_sort != sort_authors and update_stored: | ||||||
|         book.author_sort = sort_authors |         book.author_sort = sort_authors | ||||||
|         change = True |         change = True | ||||||
|     return input_authors, change |     return input_authors, change, renamed | ||||||
|  |  | ||||||
|  |  | ||||||
| @editbook.route("/admin/book/<int:book_id>", methods=['GET', 'POST']) | @editbook.route("/admin/book/<int:book_id>", methods=['GET', 'POST']) | ||||||
| @@ -773,7 +788,7 @@ def edit_book(book_id): | |||||||
|         # handle book title |         # handle book title | ||||||
|         title_change = handle_title_on_edit(book, to_save["book_title"]) |         title_change = handle_title_on_edit(book, to_save["book_title"]) | ||||||
|  |  | ||||||
|         input_authors, authorchange = handle_author_on_edit(book, to_save["author_name"]) |         input_authors, authorchange, renamed = handle_author_on_edit(book, to_save["author_name"]) | ||||||
|         if authorchange or title_change: |         if authorchange or title_change: | ||||||
|             edited_books_id = book.id |             edited_books_id = book.id | ||||||
|             modif_date = True |             modif_date = True | ||||||
| @@ -783,7 +798,8 @@ def edit_book(book_id): | |||||||
|  |  | ||||||
|         error = False |         error = False | ||||||
|         if edited_books_id: |         if edited_books_id: | ||||||
|             error = helper.update_dir_stucture(edited_books_id, config.config_calibre_dir, input_authors[0]) |             error = helper.update_dir_structure(edited_books_id, config.config_calibre_dir, input_authors[0], | ||||||
|  |                                                renamed_author=renamed) | ||||||
|  |  | ||||||
|         if not error: |         if not error: | ||||||
|             if "cover_url" in to_save: |             if "cover_url" in to_save: | ||||||
| @@ -1145,7 +1161,7 @@ def edit_list_book(param): | |||||||
|     elif param == 'title': |     elif param == 'title': | ||||||
|         sort = book.sort |         sort = book.sort | ||||||
|         handle_title_on_edit(book, vals.get('value', "")) |         handle_title_on_edit(book, vals.get('value', "")) | ||||||
|         helper.update_dir_stucture(book.id, config.config_calibre_dir) |         helper.update_dir_structure(book.id, config.config_calibre_dir) | ||||||
|         ret = Response(json.dumps({'success': True, 'newValue':  book.title}), |         ret = Response(json.dumps({'success': True, 'newValue':  book.title}), | ||||||
|                        mimetype='application/json') |                        mimetype='application/json') | ||||||
|     elif param =='sort': |     elif param =='sort': | ||||||
| @@ -1157,8 +1173,8 @@ def edit_list_book(param): | |||||||
|         ret = Response(json.dumps({'success': True, 'newValue':  book.comments[0].text}), |         ret = Response(json.dumps({'success': True, 'newValue':  book.comments[0].text}), | ||||||
|                        mimetype='application/json') |                        mimetype='application/json') | ||||||
|     elif param =='authors': |     elif param =='authors': | ||||||
|         input_authors, __ = handle_author_on_edit(book, vals['value'], vals.get('checkA', None) == "true") |         input_authors, __, renamed = handle_author_on_edit(book, vals['value'], vals.get('checkA', None) == "true") | ||||||
|         helper.update_dir_stucture(book.id, config.config_calibre_dir, input_authors[0]) |         helper.update_dir_structure(book.id, config.config_calibre_dir, input_authors[0], renamed_author=renamed) | ||||||
|         ret = Response(json.dumps({'success': True, |         ret = Response(json.dumps({'success': True, | ||||||
|                                    'newValue':  ' & '.join([author.replace('|',',') for author in input_authors])}), |                                    'newValue':  ' & '.join([author.replace('|',',') for author in input_authors])}), | ||||||
|                        mimetype='application/json') |                        mimetype='application/json') | ||||||
| @@ -1267,7 +1283,7 @@ def table_xchange_author_title(): | |||||||
|                 author_names.append(authr.name.replace('|', ',')) |                 author_names.append(authr.name.replace('|', ',')) | ||||||
|  |  | ||||||
|             title_change = handle_title_on_edit(book, " ".join(author_names)) |             title_change = handle_title_on_edit(book, " ".join(author_names)) | ||||||
|             input_authors, authorchange = handle_author_on_edit(book, authors) |             input_authors, authorchange, renamed = handle_author_on_edit(book, authors) | ||||||
|             if authorchange or title_change: |             if authorchange or title_change: | ||||||
|                 edited_books_id = book.id |                 edited_books_id = book.id | ||||||
|                 modif_date = True |                 modif_date = True | ||||||
| @@ -1276,7 +1292,8 @@ def table_xchange_author_title(): | |||||||
|                 gdriveutils.updateGdriveCalibreFromLocal() |                 gdriveutils.updateGdriveCalibreFromLocal() | ||||||
|  |  | ||||||
|             if edited_books_id: |             if edited_books_id: | ||||||
|                 helper.update_dir_stucture(edited_books_id, config.config_calibre_dir, input_authors[0]) |                 helper.update_dir_structure(edited_books_id, config.config_calibre_dir, input_authors[0], | ||||||
|  |                                            renamed_author=renamed) | ||||||
|             if modif_date: |             if modif_date: | ||||||
|                 book.last_modified = datetime.utcnow() |                 book.last_modified = datetime.utcnow() | ||||||
|             try: |             try: | ||||||
|   | |||||||
| @@ -334,9 +334,22 @@ def delete_book_file(book, calibrepath, book_format=None): | |||||||
|                    id=book.id, |                    id=book.id, | ||||||
|                    path=book.path) |                    path=book.path) | ||||||
|  |  | ||||||
|  | # was muss gemacht werden: | ||||||
|  | # Die Autorennamen müssen separiert werden und von dupletten bereinigt werden. | ||||||
|  | # Es muss geprüft werden: | ||||||
|  | # - ob es die alten Autoren mit dem letzten Buch verknüpft waren, dann müssen sie gelöscht werden | ||||||
|  | # - ob es neue Autoren sind, dann müssen sie angelegt werden -> macht modify_database_object | ||||||
|  | # - ob es bestehende Autoren sind welche umbenannt wurden -> Groß Kleinschreibung, dann muss: | ||||||
|  | # für jedes Buch und jeder Autor welcher umbenannt wurde: | ||||||
|  | #   - Autorensortierung angepasst werden | ||||||
|  | #   - Pfad im Buch angepasst werden | ||||||
|  | #   - Dateiname in Datatabelle angepasst werden, sowie die Dateien umbenannt werden | ||||||
|  | #   - Dateipfade Autor umbenannt werden | ||||||
|  | # die letzten Punkte treffen auch zu wenn es sich um einen normalen Autoränderungsvorgang handelt kann man also generell | ||||||
|  | # behandeln | ||||||
|  |  | ||||||
| # Moves files in file storage during author/title rename, or from temp dir to file storage | # Moves files in file storage during author/title rename, or from temp dir to file storage | ||||||
| def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepath, db_filename): | def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepath, db_filename, renamed_author): | ||||||
|     # get book database entry from id, if original path overwrite source with original_filepath |     # get book database entry from id, if original path overwrite source with original_filepath | ||||||
|     localbook = calibre_db.get_book(book_id) |     localbook = calibre_db.get_book(book_id) | ||||||
|     if orignal_filepath: |     if orignal_filepath: | ||||||
| @@ -352,21 +365,32 @@ def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepa | |||||||
|     # Create new titledir from database and add id |     # Create new titledir from database and add id | ||||||
|     if first_author: |     if first_author: | ||||||
|         new_authordir = get_valid_filename(first_author) |         new_authordir = get_valid_filename(first_author) | ||||||
|  |         for r in renamed_author: | ||||||
|  |             if first_author.lower() == r.lower(): | ||||||
|  |                 try: | ||||||
|  |                     new_author_path = os.path.join(calibrepath, new_authordir) | ||||||
|  |                     old_author_path = os.path.join(calibrepath, r) | ||||||
|  |                     shutil.move(os.path.normcase(old_author_path), os.path.normcase(new_author_path)) | ||||||
|  |                 except (OSError) as ex: | ||||||
|  |                     log.error("Rename author from: %s to %s: %s", r, new_authordir, ex) | ||||||
|  |                     log.debug(ex, exc_info=True) | ||||||
|  |                     return _("Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s", | ||||||
|  |                              src=old_author_path, dest=new_author_path, error=str(ex)) | ||||||
|     else: |     else: | ||||||
|         new_authordir = get_valid_filename(localbook.authors[0].name) |         new_authordir = get_valid_filename(localbook.authors[0].name) | ||||||
|     new_titledir = get_valid_filename(localbook.title) + " (" + str(book_id) + ")" |     new_titledir = get_valid_filename(localbook.title) + " (" + str(book_id) + ")" | ||||||
|  |  | ||||||
|     if titledir != new_titledir or authordir != new_authordir or orignal_filepath: |     if titledir != new_titledir or authordir != new_authordir or orignal_filepath: | ||||||
|         new_path = os.path.join(calibrepath, new_authordir, new_titledir) |         new_path = os.path.join(calibrepath, new_authordir, new_titledir) | ||||||
|         new_name = get_valid_filename(localbook.title) + ' - ' + get_valid_filename(new_authordir) |         new_name = get_valid_filename(localbook.title) + ' - ' + new_authordir | ||||||
|         try: |         try: | ||||||
|             if orignal_filepath: |             if orignal_filepath: | ||||||
|                 if not os.path.isdir(new_path): |                 if not os.path.isdir(new_path): | ||||||
|                     os.makedirs(new_path) |                     os.makedirs(new_path) | ||||||
|                 shutil.move(os.path.normcase(path), os.path.normcase(os.path.join(new_path, db_filename))) |                 shutil.move(os.path.normcase(path), os.path.normcase(os.path.join(new_path, db_filename))) | ||||||
|                 log.debug("Moving title: %s to %s/%s", path, new_path, new_name) |                 log.debug("Moving title: %s to %s/%s", path, new_path, new_name) | ||||||
|                 # Check new path is not valid path |  | ||||||
|             else: |             else: | ||||||
|  |                 # Check new path is not valid path | ||||||
|                 if not os.path.exists(new_path): |                 if not os.path.exists(new_path): | ||||||
|                     # move original path to new path |                     # move original path to new path | ||||||
|                     log.debug("Moving title: %s to %s", path, new_path) |                     log.debug("Moving title: %s to %s", path, new_path) | ||||||
| @@ -379,8 +403,6 @@ def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepa | |||||||
|                             shutil.move(os.path.normcase(os.path.join(dir_name, file)), |                             shutil.move(os.path.normcase(os.path.join(dir_name, file)), | ||||||
|                                             os.path.normcase(os.path.join(new_path + dir_name[len(path):], file))) |                                             os.path.normcase(os.path.join(new_path + dir_name[len(path):], file))) | ||||||
|                             # os.unlink(os.path.normcase(os.path.join(dir_name, file))) |                             # os.unlink(os.path.normcase(os.path.join(dir_name, file))) | ||||||
|             # change location in database to new author/title path |  | ||||||
|             localbook.path = os.path.join(new_authordir, new_titledir).replace('\\','/') |  | ||||||
|         except (OSError) as ex: |         except (OSError) as ex: | ||||||
|             log.error("Rename title from: %s to %s: %s", path, new_path, ex) |             log.error("Rename title from: %s to %s: %s", path, new_path, ex) | ||||||
|             log.debug(ex, exc_info=True) |             log.debug(ex, exc_info=True) | ||||||
| @@ -389,15 +411,23 @@ def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepa | |||||||
|  |  | ||||||
|         # Rename all files from old names to new names |         # Rename all files from old names to new names | ||||||
|         try: |         try: | ||||||
|             for file_format in localbook.data: |             all_books = calibre_db.session.query(db.Books)\ | ||||||
|  |                 .filter(db.Books.authors.any(db.Authors.name == renamed_author)).all() | ||||||
|  |             for book in all_books: | ||||||
|  |                 all_titledir = book.path.split('/')[1] | ||||||
|  |                 all_new_path = os.path.join(calibrepath, new_authordir, all_titledir) | ||||||
|  |                 all_new_name = get_valid_filename(book.title) + ' - ' + new_authordir | ||||||
|  |                 # change location in database to new author/title path | ||||||
|  |                 book.path = os.path.join(new_authordir, all_titledir).replace('\\', '/') | ||||||
|  |                 for file_format in book.data: | ||||||
|                     shutil.move(os.path.normcase( |                     shutil.move(os.path.normcase( | ||||||
|                     os.path.join(new_path, file_format.name + '.' + file_format.format.lower())), |                         os.path.join(all_new_path, file_format.name + '.' + file_format.format.lower())), | ||||||
|                     os.path.normcase(os.path.join(new_path, new_name + '.' + file_format.format.lower()))) |                         os.path.normcase(os.path.join(all_new_path, all_new_name + '.' + file_format.format.lower()))) | ||||||
|                 file_format.name = new_name |                     file_format.name = all_new_name | ||||||
|             if not orignal_filepath and len(os.listdir(os.path.dirname(path))) == 0: |             if not renamed_author and not orignal_filepath and len(os.listdir(os.path.dirname(path))) == 0: | ||||||
|                 shutil.rmtree(os.path.dirname(path)) |                 shutil.rmtree(os.path.dirname(path)) | ||||||
|         except (OSError) as ex: |         except (OSError) as ex: | ||||||
|             log.error("Rename file in path %s to %s: %s", new_path, new_name, ex) |             log.error("Rename file in path %s to %s: %s", all_new_path, all_new_name, ex) | ||||||
|             log.debug(ex, exc_info=True) |             log.debug(ex, exc_info=True) | ||||||
|             return _("Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s", |             return _("Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s", | ||||||
|                      src=new_path, dest=new_name, error=str(ex)) |                      src=new_path, dest=new_name, error=str(ex)) | ||||||
| @@ -528,11 +558,21 @@ def valid_email(email): | |||||||
| # ################################# External interface ################################# | # ################################# External interface ################################# | ||||||
|  |  | ||||||
|  |  | ||||||
| def update_dir_stucture(book_id, calibrepath, first_author=None, orignal_filepath=None, db_filename=None): | def update_dir_structure(book_id, | ||||||
|  |                         calibrepath, | ||||||
|  |                         first_author=None, | ||||||
|  |                         orignal_filepath=None, | ||||||
|  |                         db_filename=None, | ||||||
|  |                         renamed_author=False): | ||||||
|     if config.config_use_google_drive: |     if config.config_use_google_drive: | ||||||
|  |         # ToDo: rename author on gdrive | ||||||
|         return update_dir_structure_gdrive(book_id, first_author) |         return update_dir_structure_gdrive(book_id, first_author) | ||||||
|     else: |     else: | ||||||
|         return update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepath, db_filename) |         return update_dir_structure_file(book_id, | ||||||
|  |                                          calibrepath, | ||||||
|  |                                          first_author, | ||||||
|  |                                          orignal_filepath, | ||||||
|  |                                          db_filename, renamed_author) | ||||||
|  |  | ||||||
|  |  | ||||||
| def delete_book(book, calibrepath, book_format): | def delete_book(book, calibrepath, book_format): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ozzieisaacs
					Ozzieisaacs