Skip to content

Commit 791926b

Browse files
fix(edit): move directory update before relationship-heavy metadata to prevent save loss
Co-authored-by: Anonymous <anonymous@example.com>
1 parent 02c8b97 commit 791926b

2 files changed

Lines changed: 28 additions & 12 deletions

File tree

cps/editbooks.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -854,14 +854,22 @@ def do_edit_book(book_id, upload_formats=None):
854854
title_author_error = None
855855
input_authors = [author.name for author in book.authors]
856856

857-
# Stage 1: Collect all metadata changes and apply them to the book object in the session
857+
# Stage 1: Apply title/author changes before touching the remaining metadata fields.
858858
if "title" in to_save:
859859
title_change = handle_title_on_edit(book, to_save["title"])
860860

861861
if not upload_formats:
862862
new_input_authors, author_change = handle_author_on_edit(book, to_save["authors"])
863863
if author_change:
864864
input_authors = new_input_authors
865+
# Keep the filesystem path in sync before staging relationship-heavy metadata.
866+
if title_change or author_change:
867+
title_author_error = helper.update_dir_structure(book.id, config.get_book_path(), input_authors[0])
868+
if title_author_error:
869+
flash(title_author_error, category="error")
870+
calibre_db.session.rollback()
871+
return render_edit_book(book_id)
872+
modify_date = True
865873
modify_date |= edit_book_ratings(to_save, book)
866874
else:
867875
to_save, edit_error = upload_book_formats(upload_formats, book, book_id, book.has_cover)
@@ -890,6 +898,7 @@ def do_edit_book(book_id, upload_formats=None):
890898
edit_error = True
891899
flash(error, category="error")
892900

901+
# Stage 2: Apply the remaining metadata changes to the database session.
893902
modify_date |= edit_book_series_index(to_save.get("series_index"), book)
894903
modify_date |= edit_book_comments(Markup(to_save.get('comments')).unescape(), book)
895904

@@ -929,16 +938,7 @@ def do_edit_book(book_id, upload_formats=None):
929938
else:
930939
book.pubdate = db.Books.DEFAULT_PUBDATE
931940

932-
# Stage 2: Perform filesystem operations if necessary
933-
if title_change or author_change:
934-
title_author_error = helper.update_dir_structure(book.id, config.get_book_path(), input_authors[0])
935-
if title_author_error:
936-
flash(title_author_error, category="error")
937-
calibre_db.session.rollback()
938-
return render_edit_book(book_id)
939-
modify_date = True
940-
941-
# Stage 3: Commit all changes to the database
941+
# Stage 3: Commit all changes to the database.
942942
if modify_date:
943943
book.last_modified = datetime.now(timezone.utc)
944944
kobo_sync_status.remove_synced_book(book.id, all=True)
@@ -1023,7 +1023,7 @@ def do_edit_book(book_id, upload_formats=None):
10231023
except Exception as e:
10241024
log.error_or_exception(f"Failed to write metadata change log for book {book.id}: {e}")
10251025

1026-
# Stage 4: Post-commit operations (like cloud sync)
1026+
# Stage 4: Post-commit operations.
10271027
if config.config_use_google_drive:
10281028
gdriveutils.updateGdriveCalibreFromLocal()
10291029

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from pathlib import Path
2+
3+
4+
REPO_ROOT = Path(__file__).resolve().parents[2]
5+
6+
7+
def test_directory_update_happens_before_comments_and_tags_are_staged():
8+
source = (REPO_ROOT / "cps/editbooks.py").read_text(encoding="utf-8")
9+
function_body = source[source.index("def do_edit_book") : source.index("def merge_metadata")]
10+
11+
directory_update = function_body.index("helper.update_dir_structure")
12+
comments_update = function_body.index("edit_book_comments")
13+
tags_update = function_body.index("edit_book_tags")
14+
15+
assert directory_update < comments_update
16+
assert directory_update < tags_update

0 commit comments

Comments
 (0)