diff --git a/app/database.py b/app/database.py index 43f552a..6878171 100644 --- a/app/database.py +++ b/app/database.py @@ -62,7 +62,7 @@ class TrackedSeries(Base): rating = Column(String, nullable=True) # MangaBaka aggregated mu_rating = Column(Float, nullable=True) # MangaUpdates bayesian rating (0-10) mu_rating_votes = Column(Integer, nullable=True) - user_rating = Column(Float, nullable=True) # User's personal rating (0-10, integers) + user_rating = Column(Float, nullable=True) # User's personal rating (0-10, 0.5 increments) # ── Chapter / release tracking ──────────────────────────────────── total_chapters = Column(String, nullable=True) # MB chapter count — unreliable per dev; last-resort fallback only diff --git a/app/main.py b/app/main.py index 7331eba..445b205 100644 --- a/app/main.py +++ b/app/main.py @@ -430,9 +430,14 @@ def komga_import(req: KomgaImportRequest, background_tasks: BackgroundTasks): @app.get("/api/komga/import/progress") def komga_import_progress(): - """Poll this endpoint during a Komga import to show live progress.""" - with _komga_import_lock: - return dict(_komga_import_progress) + """Poll this endpoint during a Komga import to show live progress. + + Deliberately does NOT acquire _komga_import_lock — the running import holds + that lock for its full duration, so taking it here would block every poll + until the import finished, defeating live progress. Reading the plain dict + is atomic enough for progress display. + """ + return dict(_komga_import_progress) def _schedule_mu_lookup(background_tasks: BackgroundTasks, series_id: int, title: str): @@ -482,7 +487,7 @@ def _do_lookup(): series.genres = json.dumps(merged) # Authors - mu_authors = [a.get("name") for a in mu_data.get("authors", []) if a.get("name")] + mu_authors = [a.get("author_name") for a in mu_data.get("authors", []) if a.get("author_name")] if mu_authors and not series.authors: series.authors = json.dumps(mu_authors) diff --git a/app/scheduler.py b/app/scheduler.py index 0d24bc3..34f563e 100644 --- a/app/scheduler.py +++ b/app/scheduler.py @@ -339,7 +339,7 @@ def _maybe_notify_poll_failure(db: "Session", series: TrackedSeries): return # Only fire at exact powers of 2 of the threshold to avoid spamming ratio = failures // threshold - if ratio & (ratio - 1) != 0: + if (ratio & (ratio - 1)) != 0: return user_key, app_token, pushover_enabled = get_pushover_creds(db) if not pushover_enabled or not user_key or not app_token: @@ -1496,15 +1496,15 @@ def _poll_komga(db: Session, series_list: list[TrackedSeries]): except KomgaAuthError: logger.error("Komga: API key is invalid — check Settings") - # Mark all remaining Komga series as failed before breaking - for s in series_list: - _mark_poll_failure(s, "API key invalid", db) + # Global failure — mark only the current series; don't taint series + # already polled successfully this run. The rest are simply left for + # the next cycle rather than recorded as failures they never hit. + _mark_poll_failure(series, "API key invalid", db) db.commit() break except KomgaConnectionError as e: logger.error(f"Komga: server unreachable — {e}") - for s in series_list: - _mark_poll_failure(s, f"Server unreachable: {e}", db) + _mark_poll_failure(series, f"Server unreachable: {e}", db) db.commit() break except KomgaNotFound: