Rename everything on rename authors

This commit is contained in:
Ozzieisaacs 2021-11-11 18:46:32 +04:00
parent add502d236
commit baba205bce
2 changed files with 80 additions and 23 deletions

View File

@ -114,7 +114,7 @@ def search_objects_add(db_book_object, db_type, input_elements):
type_elements = c_elements.value
else:
type_elements = c_elements.name
if inp_element.lower() == type_elements.lower(): # Lowercase check
if inp_element == type_elements:
found = True
break
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):
# handle author(s)
# renamed = False
input_authors = author_name.split('&')
input_authors = list(map(lambda it: it.strip().replace(',', '|'), input_authors))
# Remove duplicates in authors list
@ -717,6 +718,20 @@ def handle_author_on_edit(book, author_name, update_stored=True):
if input_authors == ['']:
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')
# 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:
book.author_sort = sort_authors
change = True
return input_authors, change
return input_authors, change, renamed
@editbook.route("/admin/book/<int:book_id>", methods=['GET', 'POST'])
@ -773,7 +788,7 @@ def edit_book(book_id):
# handle 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:
edited_books_id = book.id
modif_date = True
@ -783,7 +798,8 @@ def edit_book(book_id):
error = False
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 "cover_url" in to_save:
@ -1145,7 +1161,7 @@ def edit_list_book(param):
elif param == 'title':
sort = book.sort
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}),
mimetype='application/json')
elif param =='sort':
@ -1157,8 +1173,8 @@ def edit_list_book(param):
ret = Response(json.dumps({'success': True, 'newValue': book.comments[0].text}),
mimetype='application/json')
elif param =='authors':
input_authors, __ = 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])
input_authors, __, renamed = handle_author_on_edit(book, vals['value'], vals.get('checkA', None) == "true")
helper.update_dir_structure(book.id, config.config_calibre_dir, input_authors[0], renamed_author=renamed)
ret = Response(json.dumps({'success': True,
'newValue': ' & '.join([author.replace('|',',') for author in input_authors])}),
mimetype='application/json')
@ -1267,7 +1283,7 @@ def table_xchange_author_title():
author_names.append(authr.name.replace('|', ','))
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:
edited_books_id = book.id
modif_date = True
@ -1276,7 +1292,8 @@ def table_xchange_author_title():
gdriveutils.updateGdriveCalibreFromLocal()
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:
book.last_modified = datetime.utcnow()
try:

View File

@ -334,9 +334,22 @@ def delete_book_file(book, calibrepath, book_format=None):
id=book.id,
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
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
localbook = calibre_db.get_book(book_id)
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
if 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:
new_authordir = get_valid_filename(localbook.authors[0].name)
new_titledir = get_valid_filename(localbook.title) + " (" + str(book_id) + ")"
if titledir != new_titledir or authordir != new_authordir or orignal_filepath:
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:
if orignal_filepath:
if not os.path.isdir(new_path):
os.makedirs(new_path)
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)
# Check new path is not valid path
else:
# Check new path is not valid path
if not os.path.exists(new_path):
# move original path to 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)),
os.path.normcase(os.path.join(new_path + dir_name[len(path):], 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:
log.error("Rename title from: %s to %s: %s", path, new_path, ex)
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
try:
for file_format in localbook.data:
shutil.move(os.path.normcase(
os.path.join(new_path, file_format.name + '.' + file_format.format.lower())),
os.path.normcase(os.path.join(new_path, new_name + '.' + file_format.format.lower())))
file_format.name = new_name
if not orignal_filepath and len(os.listdir(os.path.dirname(path))) == 0:
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(
os.path.join(all_new_path, file_format.name + '.' + file_format.format.lower())),
os.path.normcase(os.path.join(all_new_path, all_new_name + '.' + file_format.format.lower())))
file_format.name = all_new_name
if not renamed_author and not orignal_filepath and len(os.listdir(os.path.dirname(path))) == 0:
shutil.rmtree(os.path.dirname(path))
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)
return _("Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s",
src=new_path, dest=new_name, error=str(ex))
@ -528,11 +558,21 @@ def valid_email(email):
# ################################# 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:
# ToDo: rename author on gdrive
return update_dir_structure_gdrive(book_id, first_author)
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):