77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
import imdb
|
|
import jsonfile
|
|
|
|
ABOUT_FILE = "about.json"
|
|
MEDIA_KINDS = {
|
|
"show": {"key": "shows", "label": "TV show", "omdb_type": "series"},
|
|
"movie": {"key": "movies", "label": "movie", "omdb_type": "movie"},
|
|
}
|
|
|
|
|
|
def check_rating(rating: int) -> int:
|
|
if not 0 <= rating <= 10:
|
|
raise ValueError("Rating must be between 0 and 10")
|
|
return rating
|
|
|
|
|
|
def load_items(kind: str) -> tuple[dict, list[dict]]:
|
|
data = jsonfile.load(ABOUT_FILE)
|
|
return data, data.setdefault(MEDIA_KINDS[kind]["key"], [])
|
|
|
|
|
|
def list_items(kind: str) -> list[dict]:
|
|
_, items = load_items(kind)
|
|
return sorted(items, key=lambda item: -item.get("rating", 0))
|
|
|
|
|
|
def find_index(items: list[dict], text: str) -> int | None:
|
|
identifier = imdb.imdb_id(text)
|
|
for index, item in enumerate(items):
|
|
if identifier and imdb.imdb_id(item.get("url", "")) == identifier:
|
|
return index
|
|
if item.get("name", "").lower() == text.lower():
|
|
return index
|
|
return None
|
|
|
|
|
|
def look_up_name(kind: str, identifier: str) -> str:
|
|
details = imdb.lookup(identifier)
|
|
if not details:
|
|
raise ValueError("Could not look up the title on OMDb. Enter a name, or set OMDB_API_KEY in .env")
|
|
return details.get("Title") or identifier
|
|
|
|
|
|
def add_item(kind: str, text: str, rating: int, name: str | None = None) -> dict:
|
|
identifier = imdb.imdb_id(text)
|
|
if not identifier:
|
|
raise ValueError(f"{text} is not an IMDb link or ID")
|
|
check_rating(rating)
|
|
data, items = load_items(kind)
|
|
if find_index(items, identifier) is not None:
|
|
raise ValueError(f"{identifier} is already listed")
|
|
item = {"name": name or look_up_name(kind, identifier), "rating": rating, "url": imdb.title_url(identifier)}
|
|
items.append(item)
|
|
jsonfile.save(ABOUT_FILE, data)
|
|
return item
|
|
|
|
|
|
def remove_item(kind: str, text: str) -> dict:
|
|
data, items = load_items(kind)
|
|
index = find_index(items, text)
|
|
if index is None:
|
|
raise ValueError(f"{text} is not listed")
|
|
removed = items.pop(index)
|
|
jsonfile.save(ABOUT_FILE, data)
|
|
return removed
|
|
|
|
|
|
def rate_item(kind: str, text: str, rating: int) -> dict:
|
|
check_rating(rating)
|
|
data, items = load_items(kind)
|
|
index = find_index(items, text)
|
|
if index is None:
|
|
raise ValueError(f"{text} is not listed")
|
|
items[index]["rating"] = rating
|
|
jsonfile.save(ABOUT_FILE, data)
|
|
return items[index]
|