# Script to add a new item to the log from datetime import datetime from dotenv import load_dotenv import json import logging import os import re import requests from urllib.request import urlopen logging.basicConfig(filename='./logs/run.log', encoding='utf-8', level=logging.DEBUG) load_dotenv() TMDB_API_KEY = os.getenv('TMDB_API_KEY') TVDB_API_KEY = os.getenv('TVDB_API_KEY') OPENLIBRARY_API_KEY = os.getenv('OPENLIBRARY_API_KEY') if "" == TMDB_API_KEY: logging.error("TMDB API key not found") if "" == TVDB_API_KEY: logging.error("TVDB API key not found") if "" == OPENLIBRARY_API_KEY: logging.error("OpenLibrary API key not found") def add_item_to_log(item_id, media_type, log): """Add a film, book, TV series or TV episode to a log""" logging.info(f"Processing {item_id}…") item = import_by_id(item_id, media_type) if log in ['log', 'current']: if 'log' == log: date_watched = '' while re.search('[0-9]{4}-[0-9]{2}-[0-9]{2}', date_watched) is None: date_watched = input("Enter date watched [YYYY-MM-DD, t for today]:") if 't' == date_watched: date_watched = datetime.today().strftime('%Y-%m-%d') item['date_watched'] = date_watched elif 'current' == log: date_started = '' while re.search('[0-9]{4}-[0-9]{2}-[0-9]{2}', date_started) is None: date_started = input("Enter date started [YYYY-MM-DD, t for today]:") if 't' == date_started: date_started = datetime.today().strftime('%Y-%m-%d') item['date_started'] = date_started is_rewatch = '' while is_rewatch not in ['y', 'n']: is_rewatch = input("Is this a rewatch? [y/n]:") if 'y' == is_rewatch: item['is_rewatch'] = True item['added_by_id'] = item_id comments = input("Enter comments (optional):") if '' != comments: item['comments'] = comments # Validation step correct = '' print(f"{media_type} data to add:\n") print(json.dumps(item, indent=4)) if 'y' != input("\nDoes this look correct? [y]: "): return # Save changes logging.info(f"Adding {media_type} to {log}…") with open(f"./data/{media_type}/{log}.json", "r") as log_file: log_items = json.load(log_file) log_items.insert(0, item) with open(f"./data/{media_type}/{log}.json", "w") as log_file: json.dump(log_items, log_file, indent=4) logging.info(f"Added {media_type} {item_id} to {log}") def import_by_id(import_id, media_type): if media_type in ['films', 'tv-series']: return import_from_imdb_by_id(import_id, media_type) elif media_type in ['tv-episodes']: return #import_from_tvdb_by_id(import_id, media_type) elif media_type in ['books']: return #import_from_openlibrary_by_id(import_id, media_type) def import_from_imdb_by_id(imdb_id, media_type): """Retrieve a film, TV show or TV episode from TMDB using an IMDB ID""" api_url = f"https://api.themoviedb.org/3/find/{imdb_id}" # Sending API request response = requests.get( api_url, params={ 'external_source': 'imdb_id' }, headers={'Authorization': f"Bearer {TMDB_API_KEY}"} ) # Process the response if (200 == response.status_code): logging.info(response.status_code) elif (429 == response.status_code): time.sleep(2) import_from_imdb_by_id(imdb_id, media_type) return else: logging.error(response.text) if ('films' == media_type): results_key = 'movie_results' elif ('tv-episodes' == media_type): results_key = 'TODO' elif ('tv-series' == media_type): results_key = 'tv_results' response_data = json.loads(response.text)[results_key] if 1 == len(response_data): item = response_data[0] elif 0 == len(response_data): logging.error(f"Returned no results for {imdb_id}") return elif 1 < len(response_data): logging.warning(f"Returned more than one {media_type} for ID {imdb_id}") print(f"Returned more than one {media_type} for ID {imdb_id}:\n") print(json.dumps(response_data, indent=4)) idx = input("\nEnter the index of the result to use: ") try: item = response_data[int(idx)] except: logging.error("Index invalid!") print("Index invalid!") # Modify the returned result to add additional data return cleanup_result(item) def cleanup_result(item): """Process a film or TV episode returned by the TMDB API by removing unnecessary fields and adding others""" for field_name in ['adult', 'backdrop_path', 'episode_type', 'genre_ids', 'media_type', 'origin_country', 'popularity', 'production_code', 'runtime', 'still_path', 'video', 'vote_average', 'vote_count']: if field_name in item: del item[field_name] # TODO - select automatically title_key = 'name' if f"original_{title_key}" in item and 'original_language' in item: if item[f"original_{title_key}"] == item[title_key] and item['original_language'] == 'en': del item[f"original_{title_key}"], item['original_language'] if 'date_added' not in item: item['date_added'] = datetime.today().strftime('%Y-%m-%d') return item def main(): media_type = '' while media_type not in ['films', 'tv-episodes', 'tv-series', 'books']: media_type = input("Select media type [films|tv-episodes|tv-series|books]:") if 'films' == media_type: log = '' while log not in ['log', 'wishlist']: log = input ("Enter log to update [log|wishlist]:") imdb_id = '' while re.search("tt[0-9]+", imdb_id) is None: imdb_id = input("Enter IMDB ID:") add_item_to_log(imdb_id, media_type, log) elif 'books' == media_type: log = '' while log not in ['log', 'current', 'wishlist']: log = input ("Enter log to update [log|current|wishlist]:") isbn = '' while re.search("[0-9]+", isbn) is None: isbn = input("Enter ISBN:") elif 'tv-episodes' == media_type: imdb_id = '' while re.search("tt[0-9]+", imdb_id) is None: imdb_id = input("Enter IMDB ID:") add_item_to_log(imdb_id, media_type, 'log') elif 'tv-series' == media_type: log = '' while log not in ['log', 'current', 'wishlist']: log = input ("Enter log to update [log|current|wishlist]:") imdb_id = '' while re.search("tt[0-9]+", imdb_id) is None: imdb_id = input("Enter IMDB ID:") add_item_to_log(imdb_id, media_type, log) if __name__ == "__main__": main()