Add Goodreads series and group them on the about page

This commit is contained in:
SirBlob committed 2026-11-01 20:57:37 -05:00
1 parent 737700a9a8
commit 2318cdeaac
11 files changed
+651 -12

No files matched your search

+38
View File
@@ -6,13 +6,16 @@ from textual.containers import Horizontal, VerticalScroll
from textual.widgets import DataTable, Static
import books
import goodreads_series
from tui.content_pane import ContentPane
from tui.dialogs import ConfirmDialog, FormDialog, FormField
from tui.series_picker import SeriesPicker
def book_details(book: dict) -> str:
rows = [
("Shelf", book.get("shelf")),
("Series", " ".join(filter(None, [(book.get("series") or {}).get("name"), (book.get("series") or {}).get("position")]))),
("Your rating", f"{book['rating']}/10" if book.get("rating") is not None else None),
("Goodreads", f"{book['averageRating']} from {book.get('ratingCount') or 0:,} ratings" if book.get("averageRating") else None),
("Pages", book.get("pages")),
@@ -31,6 +34,7 @@ def book_details(book: dict) -> str:
class BooksPane(ContentPane):
BINDINGS = [
Binding("a", "add", "Add"),
Binding("S", "add_series", "Add series"),
Binding("e", "rate", "Rate"),
Binding("s", "shelf", "Shelf"),
Binding("d", "delete", "Delete"),
@@ -160,3 +164,37 @@ class BooksPane(ContentPane):
self.app.call_from_thread(lambda: self.reload(self.selected_key()))
summary = f"Refreshed {len(all_books) - failures} of {len(all_books)} books"
self.app.call_from_thread(self.notify, summary)
def action_add_series(self):
fields = [FormField("link", "Goodreads series link", placeholder="https://www.goodreads.com/series/92037-wings-of-fire", required=True)]
self.app.push_screen(FormDialog("Add books from a series", fields, "Load series"), self.load_series)
def load_series(self, values: dict | None):
if values:
self.run_in_background("Reading the series from Goodreads...", lambda: goodreads_series.scrape_series(values["link"]), self.pick_series_books)
def pick_series_books(self, series: dict):
def picked(choices: dict[str, str] | None):
if not choices:
return
self.notify(f"Adding {len(choices)} books from {series['name']}...")
self.add_series_books(series, choices)
self.app.push_screen(SeriesPicker(series, books.library_shelves()), picked)
@work(thread=True, exclusive=True, group="series")
def add_series_books(self, series: dict, choices: dict[str, str]):
added = 0
for entry in series["books"]:
shelf = choices.get(entry["goodreadsId"])
if not shelf:
continue
try:
book = books.add_series_book(series, entry, shelf)
except (OSError, ValueError) as error:
self.app.call_from_thread(self.notify, f"{entry['title']}: {error}", title="Skipped", severity="warning")
continue
added += 1
self.app.call_from_thread(self.notify, f"Saved {book['title']} ({shelf})")
self.app.call_from_thread(lambda: self.reload(self.selected_key()))
self.app.call_from_thread(self.notify, f"Saved {added} of {len(choices)} books from {series['name']}")