Add games library with IGDB, file explorer and static files script
This commit is contained in:
1 parent
a16444451a
commit
ec57bd73b3
65 files changed
+2230
-352
No files matched your search
@@ -0,0 +1,105 @@
|
||||
import igdb
|
||||
import library_api
|
||||
|
||||
STATUSES = ["played", "playing", "planning", "replayable"]
|
||||
STATUS_ORDER = {"playing": 0, "replayable": 1, "played": 2, "planning": 3}
|
||||
PROFILE_FLAGS = {"favorite": "favorite", "liked": "liked"}
|
||||
SUGGESTED_TAGS = ["Casual", "Competitive", "Love it", "Open to play", "Looking to discuss"]
|
||||
|
||||
|
||||
def check_rating(rating: int | None) -> int | None:
|
||||
if rating is not None and not 0 <= rating <= 10:
|
||||
raise ValueError("Rating must be between 0 and 10")
|
||||
return rating
|
||||
|
||||
|
||||
def check_status(status: str) -> str:
|
||||
if status not in STATUSES:
|
||||
raise ValueError(f"Status must be one of {', '.join(STATUSES)}")
|
||||
return status
|
||||
|
||||
|
||||
def list_games() -> list[dict]:
|
||||
games = library_api.fetch_library()["games"]
|
||||
rating = lambda game: game["rating"] if game.get("rating") is not None else -1
|
||||
return sorted(games, key=lambda game: (STATUS_ORDER[game["status"]], -rating(game), game["name"].lower()))
|
||||
|
||||
|
||||
def lookup(link: str | None, name: str | None) -> dict:
|
||||
return igdb.details(igdb.find_game(link or None, name or None))
|
||||
|
||||
|
||||
def add_game(link: str | None, name: str | None, status: str = "played", rating: int | None = None, image: str | None = None) -> dict:
|
||||
if not link and not name:
|
||||
raise ValueError("Enter a store link, an IGDB link or a name")
|
||||
check_status(status)
|
||||
check_rating(rating)
|
||||
found = lookup(link, name)
|
||||
identifier = found.pop("igdbId")
|
||||
if any(game["igdbId"] == identifier for game in list_games()):
|
||||
raise ValueError(f"{found['name']} is already listed")
|
||||
is_store_link = bool(link) and not igdb.IGDB_SLUG_PATTERN.search(link)
|
||||
fields = {
|
||||
**found,
|
||||
"name": name or found["name"],
|
||||
"url": link if is_store_link else None,
|
||||
"status": status,
|
||||
"rating": rating,
|
||||
}
|
||||
if image:
|
||||
fields["imageSource"] = image
|
||||
return library_api.save_game(identifier, fields)
|
||||
|
||||
|
||||
def update_game(identifier: str, fields: dict) -> dict:
|
||||
return library_api.save_game(identifier, fields)
|
||||
|
||||
|
||||
def rate_game(identifier: str, rating: int | None) -> dict:
|
||||
return update_game(identifier, {"rating": check_rating(rating)})
|
||||
|
||||
|
||||
def set_status(identifier: str, status: str) -> dict:
|
||||
return update_game(identifier, {"status": check_status(status)})
|
||||
|
||||
|
||||
def set_dates(identifier: str, started: str | None, finished: str | None) -> dict:
|
||||
return update_game(identifier, {"started": started, "finished": finished})
|
||||
|
||||
|
||||
def set_links(identifier: str, url: str | None, image: str | None) -> dict:
|
||||
fields = {"url": url}
|
||||
if image:
|
||||
fields["imageSource"] = image
|
||||
return update_game(identifier, fields)
|
||||
|
||||
|
||||
def toggle_flag(game: dict, flag: str) -> dict:
|
||||
if flag not in PROFILE_FLAGS:
|
||||
raise ValueError(f"{flag} is not one of {', '.join(PROFILE_FLAGS)}")
|
||||
return update_game(game["igdbId"], {flag: not game.get(flag, False)})
|
||||
|
||||
|
||||
def set_tags(identifier: str, tags_text: str | None, note: str | None) -> dict:
|
||||
tags = [tag.strip() for tag in (tags_text or "").split(",") if tag.strip()]
|
||||
return update_game(identifier, {"tags": tags, "note": note or None})
|
||||
|
||||
|
||||
def profile_text(game: dict) -> str:
|
||||
return ", ".join(label for flag, label in PROFILE_FLAGS.items() if game.get(flag)) or "-"
|
||||
|
||||
|
||||
def remove_game(identifier: str) -> None:
|
||||
library_api.delete_game(identifier)
|
||||
|
||||
|
||||
def refresh_game(game: dict) -> dict:
|
||||
result = igdb.game_by_id(game["igdbId"])
|
||||
if not result:
|
||||
raise ValueError(f"{game['name']} is no longer on IGDB")
|
||||
found = igdb.details(result)
|
||||
found.pop("igdbId", None)
|
||||
found.pop("name", None)
|
||||
if game.get("image"):
|
||||
found.pop("imageSource", None)
|
||||
return update_game(game["igdbId"], found)
|
||||
Reference in new issue
Block a user