fix(plex): a collection created on Plex keeps its editable row when the refresh read fails
The rollback dropped the new row: the next sync recreated it read-only, out of every 'add to' list, and the duplicate-name check let a retry make a second same-named collection on Plex.
This commit is contained in:
@@ -454,16 +454,25 @@ def create_collection(
|
|||||||
raise not_found("library")
|
raise not_found("library")
|
||||||
_reject_duplicate_name(db, lib.id, title)
|
_reject_duplicate_name(db, lib.id, title)
|
||||||
wrote = False
|
wrote = False
|
||||||
|
new_rk = ""
|
||||||
try:
|
try:
|
||||||
with PlexClient(db) as plex:
|
with PlexClient(db) as plex:
|
||||||
# A show collection is made as one (Plex type 2): as a movie one it stayed empty.
|
# A show collection is made as one (Plex type 2): as a movie one it stayed empty.
|
||||||
new = plex.create_collection(lib.plex_key, title, seed, 2 if seed_show else 1)
|
new = plex.create_collection(lib.plex_key, title, seed, 2 if seed_show else 1)
|
||||||
wrote = True
|
wrote = True
|
||||||
col = plex_sync.resync_collection(db, plex, lib, str(new.get("ratingKey")))
|
new_rk = str(new.get("ratingKey") or "")
|
||||||
|
col = plex_sync.resync_collection(db, plex, lib, new_rk)
|
||||||
col.editable = True
|
col.editable = True
|
||||||
db.commit()
|
db.commit()
|
||||||
except (PlexError, PlexNotConfigured) as e:
|
except (PlexError, PlexNotConfigured) as e:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
|
if wrote and new_rk:
|
||||||
|
# It is on Plex now, and only the follow-up read failed. Its row is kept, editable: the
|
||||||
|
# full sync preserves `editable` but creates a missing row read-only, so the collection
|
||||||
|
# would drop out of every "add to" list; and the duplicate-name check reads these rows,
|
||||||
|
# so a retry of the same name would make a second one on Plex.
|
||||||
|
db.add(PlexCollection(rating_key=new_rk, library_id=lib.id, title=title, editable=True))
|
||||||
|
db.commit()
|
||||||
raise _write_or_pending_error(wrote, e) from e
|
raise _write_or_pending_error(wrote, e) from e
|
||||||
return _collection_card(col)
|
return _collection_card(col)
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from app.db import get_db
|
|||||||
from app.main import app
|
from app.main import app
|
||||||
from app.models import PlexCollection, PlexItem, PlexLibrary, PlexShow, User
|
from app.models import PlexCollection, PlexItem, PlexLibrary, PlexShow, User
|
||||||
from app.plex.client import PlexError
|
from app.plex.client import PlexError
|
||||||
|
from app.plex.lookups import by_rating_key
|
||||||
from app.routes.plex import collections as coll_routes
|
from app.routes.plex import collections as coll_routes
|
||||||
|
|
||||||
|
|
||||||
@@ -355,6 +356,16 @@ def test_create_resync_failure_is_422(db, monkeypatch, override_dep):
|
|||||||
assert r.status_code == 422, r.text
|
assert r.status_code == 422, r.text
|
||||||
assert r.json()["detail"] == {"code": "refused", "reason": "collection_pending_sync"}
|
assert r.json()["detail"] == {"code": "refused", "reason": "collection_pending_sync"}
|
||||||
assert "create_collection" in stub.calls
|
assert "create_collection" in stub.calls
|
||||||
|
# It exists on Plex: its row stays, editable, until the next sync fills it in — so it is offered
|
||||||
|
# where collections are added to, and the same name is not made twice.
|
||||||
|
row = by_rating_key(db, PlexCollection, "NEW")
|
||||||
|
assert row is not None and row.editable and row.title == "Fresh Coll"
|
||||||
|
again = client.post(
|
||||||
|
"/api/plex/collections",
|
||||||
|
json={"library": "1", "title": "Fresh Coll", "item_rating_key": "m1"},
|
||||||
|
)
|
||||||
|
assert again.status_code == 409, again.text
|
||||||
|
assert stub.calls.count("create_collection") == 1
|
||||||
|
|
||||||
|
|
||||||
def test_mutation_failure_returns_422_write_failed(db, monkeypatch, override_dep):
|
def test_mutation_failure_returns_422_write_failed(db, monkeypatch, override_dep):
|
||||||
|
|||||||
Reference in New Issue
Block a user