Add watching status and groups for shows and movies

This commit is contained in:
SirBlob committed 2026-11-01 21:50:05 -05:00
1 parent 7ef3a29ece
commit 90705bc3e2
11 files changed
+568 -244

No files matched your search

+63 -14
View File
@@ -1,3 +1,4 @@
from rich.text import Text
from textual.app import ComposeResult
from textual.binding import Binding
from textual.widgets import DataTable
@@ -7,11 +8,19 @@ import media
from tui.content_pane import ContentPane
from tui.dialogs import ConfirmDialog, FormDialog, FormField
STATUS_STYLES = {"watching": "blue", "watched": "green"}
def rating_text(item: dict) -> str:
return f"{item['rating']}/10" if item.get("rating") is not None else "-"
class MediaPane(ContentPane):
BINDINGS = [
Binding("a", "add", "Add"),
Binding("e", "rate", "Rate"),
Binding("s", "status", "Watching"),
Binding("g", "collection", "Group"),
Binding("d", "delete", "Delete"),
Binding("r", "reload", "Reload"),
]
@@ -29,8 +38,10 @@ class MediaPane(ContentPane):
def on_mount(self):
table = self.table()
table.add_column("Status", key="status")
table.add_column("Rating", key="rating")
table.add_column("Title", key="title")
table.add_column("Group", key="collection")
table.add_column("IMDb", key="imdb")
self.reload()
@@ -39,13 +50,31 @@ class MediaPane(ContentPane):
table.clear()
for item in media.list_items(self.kind):
identifier = imdb.imdb_id(item.get("url", "")) or item.get("name", "")
table.add_row(f"{item.get('rating', '?')}/10", item.get("name", ""), identifier, key=identifier)
status = media.status_of(item)
table.add_row(
Text(status, style=STATUS_STYLES[status]),
rating_text(item),
item.get("name", ""),
item.get("collection", ""),
identifier,
key=identifier,
)
self.restore_cursor(focus_key)
def selected_item(self) -> dict | None:
identifier = self.selected_key()
return next((item for item in media.list_items(self.kind) if imdb.imdb_id(item.get("url", "")) == identifier), None)
def collection_hint(self) -> str:
names = media.collection_names(self.kind)
return f"Existing: {', '.join(names)}" if names else "e.g. Star Wars"
def action_add(self):
fields = [
FormField("link", "IMDb link or ID", placeholder="https://www.imdb.com/title/tt0816692/", required=True),
FormField("rating", "Your rating (0 to 10)", kind="rating", required=True),
FormField("status", "Status", kind="select", options=media.STATUSES, value="watched"),
FormField("rating", "Your rating (0 to 10, optional)", kind="rating"),
FormField("collection", "Group (optional, same name groups titles together)", placeholder=self.collection_hint()),
FormField("name", "Name (looked up on OMDb when empty)"),
]
self.app.push_screen(FormDialog(f"Add a {self.label}", fields, "Add"), self.add_item)
@@ -57,31 +86,51 @@ class MediaPane(ContentPane):
def added(item: dict):
self.reload(identifier)
self.notify(f"Added {item['name']} ({item['rating']}/10)")
self.notify(f"Added {item['name']} ({media.status_of(item)})")
self.run_in_background(
f"Adding {identifier or values['link']}...",
lambda: media.add_item(self.kind, values["link"], values["rating"], values["name"]),
lambda: media.add_item(self.kind, values["link"], values["rating"], values["name"], values["status"], values["collection"]),
added,
)
def action_rate(self):
identifier = self.selected_key()
if not identifier:
item = self.selected_item()
if not item:
return
current = next((item for item in media.list_items(self.kind) if imdb.imdb_id(item.get("url", "")) == identifier), {})
fields = [FormField("rating", f"Rating for {current.get('name', identifier)}", kind="rating", required=True, value=str(current.get("rating", "")))]
identifier = imdb.imdb_id(item["url"])
current = "" if item.get("rating") is None else str(item["rating"])
fields = [FormField("rating", f"Rating for {item['name']} (empty to clear)", kind="rating", value=current)]
def rated(values: dict | None):
if values:
self.run_now(
lambda: media.rate_item(self.kind, identifier, values["rating"]),
lambda item: f"Rated {item['name']} {item['rating']}/10",
identifier,
)
if values is not None:
self.run_now(lambda: media.rate_item(self.kind, identifier, values["rating"]), f"Updated {item['name']}", identifier)
self.app.push_screen(FormDialog("Change rating", fields), rated)
def action_status(self):
item = self.selected_item()
if not item:
return
identifier = imdb.imdb_id(item["url"])
next_status = "watched" if media.status_of(item) == "watching" else "watching"
self.run_now(lambda: media.set_status(self.kind, identifier, next_status), f"{item['name']} is now {next_status}", identifier)
def action_collection(self):
item = self.selected_item()
if not item:
return
identifier = imdb.imdb_id(item["url"])
fields = [FormField("collection", f"Group for {item['name']} (empty to remove)", value=item.get("collection", ""), placeholder=self.collection_hint())]
def grouped(values: dict | None):
if values is not None:
collection = values["collection"]
message = f"Added {item['name']} to {collection}" if collection else f"Removed {item['name']} from its group"
self.run_now(lambda: media.set_collection(self.kind, identifier, collection), message, identifier)
self.app.push_screen(FormDialog("Group titles", fields), grouped)
def action_delete(self):
identifier = self.selected_key()
if not identifier: