def test_tv_search_one(self): book = API_functions.request_book("The Handmaid's Tale") result = API_functions.request_tv_show(book["name"], book["author_name_clean"], 0) # since this is a tv show that exists, we can assert that there will be 1 result self.assertTrue(result["total_results"] == 1)
def test_tv_search_zero(self): book = API_functions.request_book("The Way Of Kings") result = API_functions.request_tv_show(book["name"], book["author_name_clean"], 0) # since this is a tv show that does not exist, we can assert that there will be 0 results self.assertTrue(result["total_results"] == 0)
def test_movie_search_one(self): book = API_functions.request_book("The Great Gatsby") result = API_functions.request_movie(book["name"], book["author_name_clean"], 0) # since this is a movie that exists, we can assert that there will be 1 result self.assertTrue(result["total_results"] == 1)
def test_movie_search_zero(self): book = API_functions.request_book("I Let you go") result = API_functions.request_movie(book["name"], book["author_name_clean"], 0) # since this is a movie that does not exist, we can assert that there will be 0 results self.assertTrue(result["total_results"] == 0)
def test_validate_writer(self): book = API_functions.request_book("The Handmaid's Tale") result = API_functions.request_tv_show(book["name"], book["author_name_clean"], 0) validate = data_functions.validate_writer(result["credits"], book["author_name_clean"]) # since the writer of the book is credited as a writer in the tv show, we can assert # validate writer will return true self.assertTrue(validate)
def api_book_title(): # get the title of the book to search for from the url search_term = request.args.get('title') # Goodreads API functions gr_result = API_functions.request_book( search_term) # use function in API_functions.py # if no book is found, return a json file stating so if gr_result["total"] == 0: return jsonify({"total_results": 0, "message": "No book found."}) # TheMovieDB functions movie_result = {} # empty dictionary tv_result = {} # empty dictionary if gr_result["total"] != 0: # only continue if there is a book found # search for movie # use function in API_functions.py movie_result = API_functions.request_movie( gr_result["name_split"], gr_result["author_name_clean"], 0) if movie_result[ "total_results"] == 0: # if no movie is found, return no result for movie movie_result = {"total_results": 0} # search for TV show # use function in API_functions.py tv_result = API_functions.request_tv_show( gr_result["name_split"], gr_result["author_name_clean"], 0) if tv_result[ "total_results"] == 0: # if no tv show is found, return no result for tv show tv_result = {"total_results": 0} final_data = { "book": gr_result, "movie": movie_result, "tv_show": tv_result } return jsonify(final_data)
def get_random_book(): """This function uses the 'books_with_movies.json' file to find a random book to search for. Args: None. Raises: None. Returns: search_term: A random book title to search adaptations for. """ books_list = json_functions.read_data("app_files/static/books_with_movies.json") matched = 0 search_term = "" while matched != 1: # keep changing the random number until an actual book and tv show match is found rand_num = random.randint(0, 487) for item in books_list: if item["num"] == rand_num: search_term = item["title"] movie_result = API_functions.request_movie(search_term, item["author"], 0) # use function in API_functions.py tv_result = API_functions.request_tv_show(search_term, item["author"], 0) # match book author to movie or tv show credits if (movie_result["total_results"] != 0 and validate_writer(API_functions.request_movie_credits(movie_result["id"]), item["author"])) \ or (tv_result["total_results"] != 0 and validate_writer(API_functions.request_tv_credits(tv_result["id"]), item["author"])): search_term = item["title"] matched = 1 else: matched = 0 return search_term
def test_book_search_zero(self): result = API_functions.request_book("poaskk oewrof kl") # since this is not a title for any book that exists in Goodreads, we can assert that the total result is 0 self.assertTrue(result["total"] == 0)
def test_book_search_zero_one(self): result = API_functions.request_book( "Harry Potter and the Goblet of Fire") # since this is a book that exists, we can assert that the total result is 1 self.assertTrue(result["total"] == 1)
def search_for_adaptation(): """This method is called when navigating to the root '/' of the website with a POST request. If there is an 'random' argument in the url and it is set to '1', then a random book is requested by using the get_random_book() method from data_functions import. Else, this method uses the user input search request. Using this input, a search is made to the Goodreads API to find a matching book. With the matching book, a matching movie and tv show is located. Once the three searches (book, movie, tv show) are complete, 'index.html' is again rendered with updated data. The 'status_msg' and 'status_num' variables are used to indicate the current status of the search. 0 = no error, 1 = no book found, 2 = no movie found, 3 = no tv show found, 4 = no adaptation found. If a matching adaptation is found for the book, then the search term is appended to the previous_search deque. Args: None. Raises: None. Returns: render_template using the 'index.html' and populating it with found book, movie, and tv show data or a status message, if required. """ book_id = 0 # variables for status results; 0 for no error, 1 for no book found, 2 for no movie found, # 3 for no tv show found, 4 for no tv show and movie found status_msg = "" status_num = 0 # if the Random Book button is chosen, then select a random book from the list # try to match the book with a movie or tv show until one is found if request.args.get('random') == "1": search_term = data_functions.get_random_book() else: # if search input is used, then get the search term search_term = request.form['search'] # get search term from input box # Goodreads API functions gr_result = API_functions.request_book(search_term) # use function in API_functions.py # if no book is found, generate status code if gr_result["total"] == 0: status_msg = "No matching book found for {0}. Try another.".format(search_term) status_num = 1 # TheMovieDB functions movie_result = {} # empty dictionary tv_result = {} # empty dictionary if status_num == 0: # only continue if there is a book found # search for movie # use function in API_functions.py movie_result = API_functions.request_movie(gr_result["name_split"], gr_result["author_name_clean"], 0) if movie_result["total_results"] != 0: # if a movie is found, save some of its data movie_id = movie_result["id"] # save movie ID else: # if no movie is found, generate status message status_msg = "No movie found. Try another." status_num = 2 # search for TV show # use function in API_functions.py tv_result = API_functions.request_tv_show(gr_result["name_split"], gr_result["author_name_clean"], 0) if tv_result["total_results"] != 0: # if a tv show is found, save some of its data tv_id = tv_result["id"] # save tv ID else: # if no tv show is found, generate status message status_msg = "No TV Show found. Try another." status_num = 3 if movie_result["total_results"] == 0 and tv_result["total_results"] == 0: # if no movie and tv show found, generate status message. # in the case they are found, but not based on the book, generate the same message status_msg = "No adaptation found for {0}. Try another.".format(search_term) status_num = 4 if previous_searches.count( gr_result["name_split"]) == 0 and status_num != 4: # only add if book name is not in deque if len(previous_searches) == 5: # keep the deque at only five most recent searches previous_searches.pop() # remove one if there is already five previous_searches.appendleft(gr_result["name_split"]) # add recent search to beginning of deque # render the page again with updated information, pass all data to render_template method return render_template("index.html", book_id=book_id, book_data=gr_result, movie_data=movie_result, tv_data=tv_result, app_name=app_name, search=search_term, status_msg=status_msg, status_num=status_num, previous_searches=previous_searches)
def gr_result(): """This function is called after the user is redirected to the 'gr_result' route. After the user is authenticated using Goodreads OAuth, the cookies previous set are retrieved and used as the current session to the user. Using Goodreads API methods, the users Goodreads ID is retrieved and used to search for the users Read books by using the 'get_users_books' method from API_functions import. After the books and adaptations list is obtained, it is rendered using the 'gr_result.html' page. The status message number 6 is used in case the users Read books have no adaptations. Args: None. Raises: None. Returns: render_template using the 'gr_result.html' and populating it with the book and adaptations results from the users Goodreads Read list """ status_msg = "" status_num = 0 user_id = 0 users_books = [] # Get a real consumer key & secret from: https://www.goodreads.com/api/keys if request.args.get("authorize") == "1": # if user authorized the connection try: # use cookies to get session tokens session = goodreads.get_auth_session(request.cookies.get('rt'), request.cookies.get('rts')) # get the current session except (KeyError, AttributeError) as e: return redirect(url_for('gr_init')) # redirect to gr_init to try again # session information access_token = session.access_token access_token_secret = session.access_token_secret consumer = oauth.Consumer(key=CONSUMER_KEY, secret=CONSUMER_SECRET) token = oauth.Token(access_token, access_token_secret) client = oauth.Client(consumer, token) url = 'http://www.goodreads.com' response, content = client.request('%s/api/auth_user' % url, 'GET') # get the users goodreads ID if response['status'] != '200': raise Exception('Cannot fetch resource: %s' % response['status']) userxml = xml.dom.minidom.parseString(content) user_id = userxml.getElementsByTagName('user')[0].attributes['id'].value # variable for user ID from Goodreads users_books = API_functions.get_users_books(user_id, client) # use page to paginate results if len(users_books) == 1: # check if adaptations were found for any books on users read list status_num = 6 status_msg = "No adaptations found on your books list." else: # if user did not authorize connection, generate a message status_msg = "Goodreads authentication required." status_num = 6 # number to identify an authentication requirement return render_template("gr_result.html", search=None, app_name=app_name, user_id=user_id, status_msg=status_msg, status_num=status_num, users_books=users_books, previous_searches=previous_searches)
# script just to get name of book and rating from a list of books with movies from Goodreads # will be used for random book search and also based on rating # will be used for auto suggestion when searching # only saving books with adaptation result page = 1 books = [] num = 0 for full in range(15): print(page) URL = "https://www.goodreads.com/list/show/429.The_BOOK_was_BETTER_than_the_MOVIE?page={0}".format(page) r = requests.get(URL) text = BeautifulSoup(r.content, 'html5lib') for item in text.findAll('tr', attrs={'itemtype': 'http://schema.org/Book'}): search_term = item.find('div', attrs={'data-resource-type': 'Book'}).a['title'] movie_result = API_functions.request_movie(search_term, 0) # use function in API_functions.py tv_result = API_functions.request_tv_show(search_term, 0) if (movie_result["total_results"] != 0 and data_functions.validate_writer(API_functions.request_movie_credits(movie_result["id"]), item.find('span', attrs={'itemprop': 'author'}).find('span', attrs={ 'itemprop': 'name'}).text.replace(" ", ""),)) \ or (tv_result["total_results"] != 0 and data_functions.validate_writer(API_functions.request_tv_credits(tv_result["id"]), item.find('span', attrs={'itemprop': 'author'}).find('span', attrs={ 'itemprop': 'name'}).text.replace( " ", ""),)): books.append({'num': num, 'title': item.find('div', attrs={'data-resource-type': 'Book'}).a['title'], 'author': item.find('span', attrs={'itemprop': 'author'}).find('span', attrs={ 'itemprop': 'name'}).text.replace(" ", ""),