Compare commits

...

5 Commits

6 changed files with 290 additions and 85 deletions

View File

@ -1,46 +1,4 @@
[ [
{
"publishers": [
"PAN MACMILLAN"
],
"physical_format": "paperback",
"title": "Permanent Record",
"covers": [
10118259
],
"isbn_13": "9781529035667",
"full_title": "Permanent Record",
"isbn_10": "152903566X",
"publish_date": "Sep 14, 2019",
"authors": [
{
"id": "OL7618561A",
"name": "Edward Snowden"
}
],
"work": {
"id": "OL20080323W",
"title": "Permanent Record",
"subjects": [
"Snowden, edward j., 1983-",
"Government information",
"Whistle blowing",
"Leaks (Disclosure of information)",
"Officials and employees",
"United States",
"United States. National Security Agency",
"Biography",
"nyt:combined-print-and-e-book-nonfiction=2019-10-06",
"New York Times bestseller",
"New York Times reviewed",
"Electronic surveillance"
]
},
"ol_id": "OL28181327M",
"date_added": "2019-09-14",
"date_started": "2024-02-20",
"added_by_id": "9781529035667"
},
{ {
"publishers": [ "publishers": [
"O'Reilly Media" "O'Reilly Media"
@ -175,4 +133,4 @@
"date_added": "2024-01-02", "date_added": "2024-01-02",
"date_started": "2023-12-25" "date_started": "2023-12-25"
} }
] ]

View File

@ -1,5 +1,48 @@
[ [
{ {
"publishers": [
"PAN MACMILLAN"
],
"physical_format": "paperback",
"title": "Permanent Record",
"covers": [
10118259
],
"isbn_13": "9781529035667",
"full_title": "Permanent Record",
"isbn_10": "152903566X",
"publish_date": "Sep 14, 2019",
"authors": [
{
"id": "OL7618561A",
"name": "Edward Snowden"
}
],
"work": {
"id": "OL20080323W",
"title": "Permanent Record",
"subjects": [
"Snowden, edward j., 1983-",
"Government information",
"Whistle blowing",
"Leaks (Disclosure of information)",
"Officials and employees",
"United States",
"United States. National Security Agency",
"Biography",
"nyt:combined-print-and-e-book-nonfiction=2019-10-06",
"New York Times bestseller",
"New York Times reviewed",
"Electronic surveillance"
]
},
"ol_id": "OL28181327M",
"date_added": "2019-09-14",
"date_started": "2024-02-20",
"date_finished": "2024-03-11",
"added_by_id": "9781529035667"
},
{
"description": { "description": {
"type": "/type/text", "type": "/type/text",
"value": "\"Most of us have been educated from birth to compete, judge, demand, and diagnose--to think and communicate in terms of what is 'right' and 'wrong' with people. At best, communicating and thinking this way can create misunderstanding and frustration. At its worst, it can lead to anger, depression, and even emotional or physical violence. [This book] uses stories, role-plays, and real-world examples to introduce the Nonviolent Communication (NVC) process. Far more than simple techniques, you'll learn to transform the thinking, language, and moralistic judgments that prevent the quality of relationships you've always wanted. Start to more easily resolve conflicts, get what you want without demands, hear the needs of others, strengthen your personal and professional relationships, and live your fullest potential. With Nonviolent Communication, you'll learn to: significantly improve your relationships with family, friends, and co-workers; stay peaceful in the face of judgment, criticism, and anger; speak, think, and listen in ways that inspire compassion and understanding; break patterns of thinking that lead to stress, depression, guilt, and shame; discover common ground with anyone, anytime, anywhere.\"--Book cover." "value": "\"Most of us have been educated from birth to compete, judge, demand, and diagnose--to think and communicate in terms of what is 'right' and 'wrong' with people. At best, communicating and thinking this way can create misunderstanding and frustration. At its worst, it can lead to anger, depression, and even emotional or physical violence. [This book] uses stories, role-plays, and real-world examples to introduce the Nonviolent Communication (NVC) process. Far more than simple techniques, you'll learn to transform the thinking, language, and moralistic judgments that prevent the quality of relationships you've always wanted. Start to more easily resolve conflicts, get what you want without demands, hear the needs of others, strengthen your personal and professional relationships, and live your fullest potential. With Nonviolent Communication, you'll learn to: significantly improve your relationships with family, friends, and co-workers; stay peaceful in the face of judgment, criticism, and anger; speak, think, and listen in ways that inspire compassion and understanding; break patterns of thinking that lead to stress, depression, guilt, and shame; discover common ground with anyone, anytime, anywhere.\"--Book cover."

View File

@ -1,10 +1,34 @@
[ [
{
"ol_id": "OL23279299W",
"title": "Soldier box",
"authors": [
{
"ol_id": "OL8830255A",
"name": "Joe Glenton"
}
],
"subjects": [
"Afghan War, 2001-",
"Desertions",
"Military deserters",
"Biography",
"Conscientious objectors",
"Soldiers",
"Political activity",
"British Participation",
"Personal narratives",
"Afghan war, 2001-2021"
],
"date_added": "2024-03-06"
},
{ {
"ol_id": "OL25856221W", "ol_id": "OL25856221W",
"title": "Johnny Viable", "title": "Johnny Viable",
"subjects": [ "subjects": [
"Art" "Art"
] ],
"date_added": "2024-02-25"
}, },
{ {
"ol_id": "OL27719403W", "ol_id": "OL27719403W",
@ -14,7 +38,8 @@
"Ecology", "Ecology",
"Forest ecology", "Forest ecology",
"Wald\u00f6kosystem" "Wald\u00f6kosystem"
] ],
"date_added": "2024-02-15"
}, },
{ {
"ol_id": "OL25815646W", "ol_id": "OL25815646W",
@ -30,7 +55,8 @@
"Sens et sensations", "Sens et sensations",
"Physiologie", "Physiologie",
"nyt:paperback-nonfiction=2023-09-17" "nyt:paperback-nonfiction=2023-09-17"
] ],
"date_added": "2024-02-15"
}, },
{ {
"ol_id": "OL21164374W", "ol_id": "OL21164374W",

View File

@ -1,4 +1,101 @@
[ [
{
"belongs_to_collection": null,
"genres": [
{
"id": 878,
"name": "Science Fiction"
},
{
"id": 10749,
"name": "Romance"
},
{
"id": 35,
"name": "Comedy"
}
],
"imdb_id": "tt14230458",
"overview": "Brought back to life by an unorthodox scientist, a young woman runs off with a debauched lawyer on a whirlwind adventure across the continents. Free from the prejudices of her times, she grows steadfast in her purpose to stand for equality and liberation.",
"poster_path": "/kCGlIMHnOm8JPXq3rXM6c5wMxcT.jpg",
"production_countries": [
{
"iso_3166_1": "IE",
"name": "Ireland"
},
{
"iso_3166_1": "GB",
"name": "United Kingdom"
},
{
"iso_3166_1": "US",
"name": "United States of America"
}
],
"release_date": "2023-12-07",
"spoken_languages": [
{
"english_name": "English",
"iso_639_1": "en",
"name": "English"
},
{
"english_name": "French",
"iso_639_1": "fr",
"name": "Fran\u00e7ais"
},
{
"english_name": "Portuguese",
"iso_639_1": "pt",
"name": "Portugu\u00eas"
}
],
"title": "Poor Things",
"tmdb_id": 792307,
"date_added": "2024-03-12",
"date_finished": "2024-03-09",
"added_by_id": "792307"
},
{
"belongs_to_collection": {
"id": 726871,
"name": "Dune Collection",
"poster_path": "/wcVafar6Efk3YgFvh8oZQ4yHL6H.jpg",
"backdrop_path": "/ygVSGv86R0BTOKJIb8RQ1sFxs4q.jpg"
},
"genres": [
{
"id": 878,
"name": "Science Fiction"
},
{
"id": 12,
"name": "Adventure"
}
],
"imdb_id": "tt15239678",
"overview": "Follow the mythic journey of Paul Atreides as he unites with Chani and the Fremen while on a path of revenge against the conspirators who destroyed his family. Facing a choice between the love of his life and the fate of the known universe, Paul endeavors to prevent a terrible future only he can foresee.",
"poster_path": "/8b8R8l88Qje9dn9OE8PY05Nxl1X.jpg",
"production_countries": [
{
"iso_3166_1": "US",
"name": "United States of America"
}
],
"release_date": "2024-02-27",
"spoken_languages": [
{
"english_name": "English",
"iso_639_1": "en",
"name": "English"
}
],
"title": "Dune: Part Two",
"tmdb_id": 693134,
"date_added": "2024-03-12",
"date_finished": "2024-03-09",
"added_by_id": "693134"
},
{ {
"belongs_to_collection": null, "belongs_to_collection": null,
"genres": [ "genres": [
@ -16158,4 +16255,4 @@
"date_finished": null, "date_finished": null,
"is_repeat": false "is_repeat": false
} }
] ]

View File

@ -1,4 +1,35 @@
[ [
{
"belongs_to_collection": null,
"genres": [
{
"id": 99,
"name": "Documentary"
}
],
"imdb_id": "tt0318202",
"original_language": "fr",
"original_title": "\u00catre et avoir",
"overview": "The documentary's title translates as \"to be and to have\", the two auxiliary verbs in the French language. It is about a primary school in the commune of Saint-\u00c9tienne-sur-Usson, Puy-de-D\u00f4me, France, the population of which is just over 200. The school has one small class of mixed ages (from four to twelve years), with a dedicated teacher, Georges Lopez, who shows patience and respect for the children as we follow their story through a single school year.",
"poster_path": "/mqB5QPNCmbF8DgsZqmyGQAGktUE.jpg",
"production_countries": [
{
"iso_3166_1": "FR",
"name": "France"
}
],
"release_date": "2002-08-28",
"spoken_languages": [
{
"english_name": "French",
"iso_639_1": "fr",
"name": "Fran\u00e7ais"
}
],
"title": "To Be and to Have",
"tmdb_id": 5168,
"date_added": "2024-03-06"
},
{ {
"belongs_to_collection": null, "belongs_to_collection": null,
"genres": [ "genres": [

View File

@ -54,17 +54,28 @@ if "" == TMDB_API_KEY:
logger.error("TMDB API key not found") logger.error("TMDB API key not found")
def return_if_exists(item_id, media_type, log) -> dict | None: def return_if_exists(item_id: str, media_type: str, log: str) -> dict | None:
"""Returns an item if it exists in the requested log""" """Returns an item if it exists in the requested log"""
logger.info(f"Checking for '{item_id}' in '{log}'") logger.info(f"Checking for '{item_id}' in '{log}'")
with open(f"./data/{media_type}/{log}.json", "r", encoding="utf-8") as log_file: with open(f"./data/{media_type}/{log}.json", "r", encoding="utf-8") as log_file:
log_items = json.load(log_file) log_items = json.load(log_file)
id_key = "id"
if "books" == media_type:
if re.search("OL[0-9]+[MW]", item_id) is not None:
id_key = "ol_id"
elif re.search("[0-9]{13}", item_id) is not None:
id_key = "isbn_13"
elif re.search("[0-9]{10}", item_id) is not None:
id_key = "isbn_10"
else:
raise Exception("Invalid ID for book")
existing_items = [ existing_items = [
log_item log_item
for log_item in log_items for log_item in log_items
if "id" in log_item and log_item["id"] == item_id if id_key in log_item and log_item[id_key] == item_id
] ]
if len(existing_items) > 0: if len(existing_items) > 0:
logger.info(f"Found item in '{log}'") logger.info(f"Found item in '{log}'")
@ -72,18 +83,38 @@ def return_if_exists(item_id, media_type, log) -> dict | None:
logger.info(f"'{item_id}' not found in '{log}'") logger.info(f"'{item_id}' not found in '{log}'")
def delete_existing(item_id, media_type, log) -> None: def delete_existing(item_id: str, media_type: str, log: str) -> None:
"""Deletes an item from a log if it matches the ID""" """Deletes an item from a log if it matches the ID"""
logger.info(f"Deleting '{item_id}' from '{log}'") logger.info(f"Deleting '{item_id}' from '{log}'")
with open(f"./data/{media_type}/{log}.json", "r", encoding="utf-8") as log_file: with open(f"./data/{media_type}/{log}.json", "r", encoding="utf-8") as log_file:
log_items = json.load(log_file) log_items = json.load(log_file)
id_key = "id"
if "books" == media_type:
if re.search("OL[0-9]+[MW]", item_id) is not None:
id_key = "ol_id"
elif re.search("[0-9]{13}", item_id) is not None:
id_key = "isbn_13"
elif re.search("[0-9]{10}", item_id) is not None:
id_key = "isbn_10"
else:
raise Exception("Invalid ID for book")
elif media_type in ["films", "tv-episodes"]:
if re.search("tt[0-9]+", item_id) is not None:
id_key = "isbn_id"
elif re.search("[0-9]+", item_id) is not None:
id_key = "tmdb_id"
else:
raise Exception("Invalid ID for film")
old_len = len(log_items) old_len = len(log_items)
log_items = [ log_items = [
log_item log_item
for log_item in log_items for log_item in log_items
if "id" not in log_item or ("id" in log_item and log_item["id"] != item_id) if id_key not in log_item
or (id_key in log_item and log_item[id_key] != item_id)
] ]
if len(log_items) < (old_len - 1): if len(log_items) < (old_len - 1):
raise Exception("More than one deletion made, discarding…") raise Exception("More than one deletion made, discarding…")
@ -93,7 +124,9 @@ def delete_existing(item_id, media_type, log) -> None:
logger.info(f"'{item_id}' deleted from '{log}'") logger.info(f"'{item_id}' deleted from '{log}'")
def check_for_existing(item_id, media_type, log) -> dict[dict, str]: def check_for_existing(
item_id, media_type, log
) -> tuple[dict[dict, str] | None, str | None]:
""" """
Check for an existing item in the current log, and pull the Check for an existing item in the current log, and pull the
`date_added` etc. and mark it as a repeat if so. `date_added` etc. and mark it as a repeat if so.
@ -127,14 +160,14 @@ def check_for_existing(item_id, media_type, log) -> dict[dict, str]:
return None, None return None, None
def add_item_to_log(item_id, media_type, log) -> None: def add_item_to_log(item_id: str, media_type: str, log: str) -> None:
"""Add a film, book, TV series or TV episode to a log""" """Add a film, book, TV series or TV episode to a log"""
logger.info(f"Processing {item_id}") logger.info(f"Processing {item_id}")
item = None item: dict | None = None
log_to_delete = None log_to_delete = None
if "tv-episodes" != media_type and ("books" != media_type and "wishlist" != log): if media_type not in ["tv-episodes", "books"]:
item, log_to_delete = check_for_existing(item_id, media_type, log) item, log_to_delete = check_for_existing(item_id, media_type, log)
if item is None: if item is None:
@ -142,10 +175,21 @@ def add_item_to_log(item_id, media_type, log) -> None:
if item is None: if item is None:
raise Exception("No item found") raise Exception("No item found")
if "books" == media_type and "wishlist" != log: if "books" == media_type:
item, log_to_delete = check_for_existing(item['work']['ol_id'], media_type, log) new_item, log_to_delete = check_for_existing(
if item is None: item["work"]["ol_id"], media_type, log
item, log_to_delete = check_for_existing(item['ol_id'], media_type, log) )
if new_item is None:
new_item, log_to_delete = check_for_existing(item["ol_id"], media_type, log)
if new_item is None:
new_item, log_to_delete = check_for_existing(
item["isbn_13"], media_type, log
)
if new_item is None:
new_item, log_to_delete = check_for_existing(
item["isbn_10"], media_type, log
)
item = new_item if new_item is not None else item
if log in ["log", "current"]: if log in ["log", "current"]:
if "date_started" not in item and media_type in ["books", "tv-series", "games"]: if "date_started" not in item and media_type in ["books", "tv-series", "games"]:
@ -202,7 +246,7 @@ def add_item_to_log(item_id, media_type, log) -> None:
delete_existing(item_id, media_type, log_to_delete) delete_existing(item_id, media_type, log_to_delete)
def import_by_id(import_id, media_type, log) -> dict: def import_by_id(import_id, media_type, log) -> dict | None:
"""Import from the appropriate API by unique ID""" """Import from the appropriate API by unique ID"""
if media_type in ["films", "tv-series"]: if media_type in ["films", "tv-series"]:
@ -230,8 +274,12 @@ def import_from_tmdb_by_external_id(external_id, media_type) -> dict:
response = requests.get( response = requests.get(
api_url, api_url,
headers={"Authorization": f"Bearer {TMDB_API_KEY}"}, headers={"Authorization": f"Bearer {TMDB_API_KEY}"},
params={"external_source": "imdb_id" if re.search("tt[0-9]+", external_id) else "tvdb_id"}, params={
timeout=15 "external_source": (
"imdb_id" if re.search("tt[0-9]+", external_id) else "tvdb_id"
)
},
timeout=15,
) )
# Process the response # Process the response
@ -254,7 +302,7 @@ def import_from_tmdb_by_external_id(external_id, media_type) -> dict:
key = "movie_results" key = "movie_results"
response_data = json.loads(response.text)[key][0] response_data = json.loads(response.text)[key][0]
if response_data == None: if response_data is None:
raise Exception(f"Nothing found for TVDB ID {external_id}!") raise Exception(f"Nothing found for TVDB ID {external_id}!")
# Modify the returned result to add additional data # Modify the returned result to add additional data
@ -289,7 +337,7 @@ def import_from_tmdb_by_id(tmdb_id, media_type) -> dict:
return cleanup_result(response_data, media_type) return cleanup_result(response_data, media_type)
def import_from_openlibrary_by_isbn(isbn, media_type) -> dict: def import_from_openlibrary_by_isbn(isbn, media_type) -> dict | None:
"""Retrieve a film, TV show or TV episode from TMDB using an IMDB ID""" """Retrieve a film, TV show or TV episode from TMDB using an IMDB ID"""
logging.info(f"Importing '{isbn}'") logging.info(f"Importing '{isbn}'")
@ -337,18 +385,19 @@ def import_from_openlibrary_by_isbn(isbn, media_type) -> dict:
return cleanup_result(item, media_type) return cleanup_result(item, media_type)
def import_from_openlibrary_by_ol_key(key) -> dict: def import_from_openlibrary_by_ol_key(key) -> dict | None:
"""Retrieves an item (author or work, NOT edition) from OpenLibrary using an OL key""" """Retrieves an item (author or work, NOT edition) from OpenLibrary using an OL key"""
if (len(key.split("/")) == 1): if len(key.split("/")) == 1:
key = f"/works/{key}" key = f"/works/{key}"
logger.info(f"Retrieving {key}") logger.info(f"Retrieving {key}")
_, mode, ol_id = key.split("/") _, mode, ol_id = key.split("/")
cached_authors = []
if "authors" == mode: if "authors" == mode:
with open( with open(
f"./scripts/caching/authors.json", "r", encoding="utf-8" "./scripts/caching/authors.json", "r", encoding="utf-8"
) as authors_cache: ) as authors_cache:
cached_authors = json.load(authors_cache) cached_authors = json.load(authors_cache)
@ -396,7 +445,7 @@ def import_from_openlibrary_by_ol_key(key) -> dict:
logger.info(f"Caching author '{author['name']}'") logger.info(f"Caching author '{author['name']}'")
cached_authors.append(author) cached_authors.append(author)
with open( with open(
f"./scripts/caching/authors.json", "w", encoding="utf-8" "./scripts/caching/authors.json", "w", encoding="utf-8"
) as authors_cache: ) as authors_cache:
json.dump(cached_authors, authors_cache, indent=4) json.dump(cached_authors, authors_cache, indent=4)
logger.info(f"Author '{author['name']}' cached!") logger.info(f"Author '{author['name']}' cached!")
@ -408,7 +457,9 @@ def import_from_openlibrary_by_ol_key(key) -> dict:
if "authors" in item: if "authors" in item:
for author in item["authors"]: for author in item["authors"]:
work["authors"].append(import_from_openlibrary_by_ol_key(author["author"]["key"])) work["authors"].append(
import_from_openlibrary_by_ol_key(author["author"]["key"])
)
for result_key in ["first_publish_date", "subjects"]: for result_key in ["first_publish_date", "subjects"]:
if result_key in item: if result_key in item:
@ -429,7 +480,7 @@ def cleanup_result(item, media_type) -> dict:
for field_name in [ for field_name in [
"adult", # TMDB "adult", # TMDB
"backdrop_path", # TMDB "backdrop_path", # TMDB
"budget", # TMDB "budget", # TMDB
"copyright_date", # OpenLibrary "copyright_date", # OpenLibrary
"classifications", # OpenLibrary "classifications", # OpenLibrary
"created", # OpenLibrary "created", # OpenLibrary
@ -437,7 +488,7 @@ def cleanup_result(item, media_type) -> dict:
"episode_type", # TMDB "episode_type", # TMDB
"first_sentence", # OpenLibrary "first_sentence", # OpenLibrary
"genre_ids", # TMDB "genre_ids", # TMDB
"homepage", # TMDB "homepage", # TMDB
"identifiers", # OpenLibrary "identifiers", # OpenLibrary
"media_type", # TMDB "media_type", # TMDB
"last_modified", # OpenLibrary "last_modified", # OpenLibrary
@ -452,16 +503,16 @@ def cleanup_result(item, media_type) -> dict:
"physical_dimensions", # OpenLibrary "physical_dimensions", # OpenLibrary
"popularity", # TMDB "popularity", # TMDB
"production_code", # TMDB "production_code", # TMDB
"production_companies", # TMDB "production_companies", # TMDB
"publish_places", # OpenLibrary "publish_places", # OpenLibrary
"revenue", # TMDB "revenue", # TMDB
"revision", # OpenLibrary "revision", # OpenLibrary
"runtime", # TMDB "runtime", # TMDB
"source_records", # OpenLibrary "source_records", # OpenLibrary
"status", # TMDB "status", # TMDB
"still_path", # TMDB "still_path", # TMDB
"table_of_contents", # OpenLibrary "table_of_contents", # OpenLibrary
"tagline", # TMDB "tagline", # TMDB
"type", # OpenLibrary "type", # OpenLibrary
"uri_descriptions", # OpenLibrary "uri_descriptions", # OpenLibrary
"url", # OpenLibrary "url", # OpenLibrary
@ -487,8 +538,8 @@ def cleanup_result(item, media_type) -> dict:
del item[f"original_{title_key}"], item["original_language"] del item[f"original_{title_key}"], item["original_language"]
if "tv-episodes" == media_type: if "tv-episodes" == media_type:
item['series'] = { 'tmdb_id': item['show_id'] } item["series"] = {"tmdb_id": item["show_id"]}
del item['show_id'] del item["show_id"]
if "books" == media_type: if "books" == media_type:
_, _, item["ol_id"] = item["key"].split("/") _, _, item["ol_id"] = item["key"].split("/")
@ -515,7 +566,7 @@ def cleanup_result(item, media_type) -> dict:
f"translation_of '{item['translation_of']}' \ f"translation_of '{item['translation_of']}' \
is different to work title '{item['work']['title']}'" is different to work title '{item['work']['title']}'"
) )
if 'y' != input("Accept change? [y|n]: "): if "y" != input("Accept change? [y|n]: "):
raise Exception( raise Exception(
f"translation_of '{item['translation_of']}' \ f"translation_of '{item['translation_of']}' \
is different to work title '{item['work']['title']}'" is different to work title '{item['work']['title']}'"
@ -546,8 +597,8 @@ def main() -> None:
try: try:
item_id = "" item_id = ""
log = ""
if "films" == media_type: if "films" == media_type:
log = ""
while log not in ["log", "wishlist"]: while log not in ["log", "wishlist"]:
log = input("Enter log to update [log|wishlist]: ") log = input("Enter log to update [log|wishlist]: ")
@ -555,7 +606,6 @@ def main() -> None:
item_id = input("Enter TMDB ID: ") item_id = input("Enter TMDB ID: ")
elif "books" == media_type: elif "books" == media_type:
log = ""
while log not in ["log", "current", "wishlist"]: while log not in ["log", "current", "wishlist"]:
log = input("Enter log to update [log|current|wishlist]: ") log = input("Enter log to update [log|current|wishlist]: ")
@ -566,19 +616,19 @@ def main() -> None:
item_id = "".join(re.findall(r"\d+", input("Enter ISBN: "))) item_id = "".join(re.findall(r"\d+", input("Enter ISBN: ")))
elif "tv-episodes" == media_type: elif "tv-episodes" == media_type:
log = "log"
while re.search("(tt)?[0-9]+", item_id) is None: while re.search("(tt)?[0-9]+", item_id) is None:
item_id = input("Enter TVDB or IMDB ID: ") item_id = input("Enter TVDB or IMDB ID: ")
elif "tv-series" == media_type: elif "tv-series" == media_type:
log = ""
while log not in ["log", "current", "wishlist"]: while log not in ["log", "current", "wishlist"]:
log = input("Enter log to update [log|current|wishlist]: ") log = input("Enter log to update [log|current|wishlist]: ")
while re.search("[0-9]+", item_id) is None: while re.search("[0-9]+", item_id) is None:
item_id = input("Enter TMDB ID: ") item_id = input("Enter TMDB ID: ")
add_item_to_log(re.search("(OL|tt)?[0-9]+[WMA]?", item_id)[0], media_type, log) item_id_parsed = re.search("(OL|tt)?[0-9]+[WMA]?", item_id)
if item_id_parsed is not None:
add_item_to_log(item_id_parsed[0], media_type, log)
except Exception: except Exception:
logger.exception("Exception occurred") logger.exception("Exception occurred")