def get_last_book_of_series(series_name, series_id, date, timeframe): """ Given a series name, date of search, and timeframe, returns a dictionary containing the info of the last book published in that series in the timeframe provided. If API error, returns a dictionary with key 'status' and value 'error'.""" payload = {"key": goodreads_key, "id": series_id} response = requests.get("https://www.goodreads.com/series/show/", params=payload) if response.status_code == 200: tree = ET.fromstring(response.content) series_length = tree.find("series").find("primary_work_count").text series_works = list(tree.find("series").find("series_works")) by_user_position = {} for work in series_works: user_position = work.find("user_position").text by_user_position[user_position] = work title = 'untitled' published = None while ('untitled' in title.lower() and published is None) and series_length >= "1": work = by_user_position.get(series_length) if work is None: last_position = max(by_user_position.keys()) work = by_user_position[last_position] work_info = get_info_for_work(work) title = work_info["title"] published = work_info["published"] cover = work_info["cover"] series_length = str(int(series_length) - 1) if published is None: published = get_pub_date_with_title(title) if published == "error": return {"status": "error"} result = ("Title: <i>{}</i>".format(title), "Publication date: {}".format(published), cover) pdate = convert_string_to_datetime(published) if (not timeframe) and not (pdate <= date): while series_length >= "1": work = by_user_position[series_length] work = by_user_position[series_length] work_info = get_info_for_work(work) title2 = work_info["title"] published2 = work_info["published"] cover = work_info["cover"] if published2 is None: published2 = get_pub_date_with_title(title) pdate2 = convert_string_to_datetime(published2) if pdate2 <= date: result = ("Title: <i>{}</i>".format(title2), "Publication date: {}".format(published2), cover) break series_length = str(int(series_length) - 1) if timeframe and not (date <= pdate <= date + timeframe): if pdate < date: result = (None, None, "http://sendmeglobal.net/images/404.png") else: while series_length >= "1": work = by_user_position[series_length] work_info = get_info_for_work(work) title2 = work_info["title"] published2 = work_info["published"] cover = work_info["cover"] if published2 is None: published2 = get_pub_date_with_title(title) pdate2 = convert_string_to_datetime(published2) if pdate2 < date: result = (None, None, "http://sendmeglobal.net/images/404.png") break elif pdate <= pdate2 <= date + timeframe: result = ("Title: <i>{}</i>".format(title2), "Publication date: {}".format(published2), cover) break series_length = str(int(series_length) - 1) if series_length == "0": result = (None, None, "http://sendmeglobal.net/images/404.png") return {'status': 'ok', 'results': result} else: return {'status': 'error'}
def test_convert_datetime_year_mon_day(self): """Tests to see if function converts string of format year-month-day properly""" self.assertEqual(convert_string_to_datetime("2016-02-02"), datetime(year=2016, month=2, day=2))
def search_json(): """ Returns search results based off author or series inputted""" author = request.form.get("author") series_id = request.form.get("series") timeframe = int(request.form.get("timeframe")) tf_str = timeframes[timeframe] date = request.form.get("date") date_str = " ".join(date.split()[1:]) py_date = datetime.strptime(date_str, "%b %d %Y") td = timedelta(days=timeframe) if author: payload = { "q": "inauthor:" + author, "langRestrict": "en", "orderBy": "newest", "printType": "books", "key": google_books_key } response = requests.get("https://www.googleapis.com/books/v1/volumes", params=payload) if response.status_code == 200: results = response.json() next_book = results["items"][0]["volumeInfo"] next_book_cover = no_cover_img if results["items"][0]["volumeInfo"].get("imageLinks"): next_book_cover = results["items"][0]["volumeInfo"][ "imageLinks"]["thumbnail"] next_book_id = results["items"][0]["id"] published_date = get_pub_date_with_book_id(next_book_id) if published_date == "error": return jsonify({"status": "error"}) pdate = convert_string_to_datetime(published_date) result = ("Title: <i>{}</i>".format(next_book["title"]), "Publication date: {}".format(published_date), next_book_cover) if (not td) and not (pdate <= py_date): for work in results["items"][1:]: date2 = get_pub_date_with_book_id(work["id"]) pdate2 = convert_string_to_datetime(date2) next_book_cover2 = no_cover_img if work["volumeInfo"].get("imageLinks"): next_book_cover2 = work["volumeInfo"]["imageLinks"][ "thumbnail"] if (pdate2 <= py_date): result = ("Title: <i>{}</i>".format( work["volumeInfo"]["title"]), "Publication date: {}".format(date2), next_book_cover2) break if td and not (py_date <= pdate <= py_date + td): if pdate < py_date: result = (None, None, no_results_img) else: for work in results["items"][1:]: date2 = get_pub_date_with_book_id(work["id"]) pdate2 = convert_string_to_datetime(date2) next_book_cover2 = no_cover_img if work["volumeInfo"].get("imageLinks"): next_book_cover2 = work["volumeInfo"][ "imageLinks"]["thumbnail"] if pdate2 < py_date: result = (None, None, no_results_img) break elif py_date <= pdate2 <= py_date + td: result = ("Title: <i>{}</i>".format( work["volumeInfo"]["title"]), "Publication date: {}".format(date2), next_book_cover2) break if "search_history" in session: search = (date, tf_str, author, result) # this looks redundant, but if I try to modify the session value directly # it doesn't update, so it has to be like this s_history = session["search_history"] s_history.append(search) session["search_history"] = s_history return jsonify({"status": "ok", "results": result}) return jsonify({"status": "error"}) else: # if series is being searched series = Series.query.get(series_id) results = get_last_book_of_series(series.series_name, series.goodreads_id, py_date, td) if "search_history" in session: search = (date, tf_str, series.series_name, results["results"]) # this looks redundant, but if I try to modify the session value directly # it doesn't update, so it has to be like this s_history = session["search_history"] s_history.append(search) session["search_history"] = s_history return jsonify(results)
def test_convert_datetime_year(self): """ Makes sure function turns a string with year-only into a datetime object""" self.assertEqual(convert_string_to_datetime("2016"), datetime(year=2016, month=1, day=1))