def recommend_by_author(author, number, book_id): df = Recommend.get_recommend_list() # Get total number of books written by this author available_num = df['authors'].value_counts() if available_num[author] == 1: return [] # Sort the dataframe by authors and popular grade df = df.sort_values(by=['authors', 'popular'], ascending=False) counter = 0 result = [] for item in df.iterrows(): if counter == number: break # Do not recommend current reference book if item[1]['authors'] == author and item[1]['id'] != book_id: book = Book(item[1]['id']) info = book.get_info() # Return information which need for front-end temp = { 'book_id': item[1]['id'], 'author': item[1]['authors'], 'categories': item[1]['categories'], 'popular': item[1]['popular'], 'title': info.title, 'book_cover_url': info.book_cover_url } result.append(temp) counter += 1 return result
def get_read_history_by_date(user_id, year, month): # set default start date start_date = str(year) + "-" + str(month) + "-01 00:00:00" # set default finish date if month is 12: finish_date = str(year) + "-" + str(1) + "-01 00:00:00" else: finish_date = str(year) + "-" + str(month + 1) + "-01 00:00:00" # date -> timestamp start_timestamp = int( time.mktime(time.strptime(start_date, "%Y-%m-%d %H:%M:%S"))) * 1000 finish_timestamp = int( time.mktime(time.strptime(finish_date, "%Y-%m-%d %H:%M:%S"))) * 1000 collection_id = Collection.get_readcollection_id(user_id) # SQL conn = connect_sys_db() query = "SELECT book_id FROM collects WHERE collection_id = \'{collection_id}\'".format( collection_id=collection_id) db_result = read_sql(sql=query, con=conn) json_str = db_result.to_json(orient='index') ds = json.loads(json_str) result = [] for index in ds: finish_date = Collection.get_book_read_date( user_id, ds[index]['book_id']) # Compare finish time to make sure whether this book is finished in this month if start_timestamp <= finish_date < finish_timestamp: ds[index]['finish_time'] = finish_date book = Book(ds[index]['book_id']) ds[index]['book_title'] = book.get_info().title ds[index]['book_cover_url'] = book.get_info().book_cover_url result.append(ds[index]) return result
def get_read_history(user_id): collection_id = Collection.get_readcollection_id(user_id) # SQL conn = connect_sys_db() query = "SELECT book_id FROM collects WHERE collection_id = \'{collection_id}\'".format( collection_id=collection_id) db_result = read_sql(sql=query, con=conn) json_str = db_result.to_json(orient='index') ds = json.loads(json_str) result = [] for index in ds: finish_date = Collection.get_book_read_date( user_id, ds[index]['book_id']) # Add book's finish_time and title and cover_url to result ds[index]['finish_time'] = finish_date book = Book(ds[index]['book_id']) ds[index]['book_title'] = book.get_info().title ds[index]['book_cover_url'] = book.get_info().book_cover_url # Reformat result need for front-end # timeArray = time.strptime(finish_date, "%Y-%m-%d %H:%M:%S") date = datetime.datetime.fromtimestamp(int(finish_date) / 1000) target, finish_num, finish_flag = Collection.get_tag( user_id, date.year, date.month) ds[index]['tag'] = { 'target': target, 'finish_num': finish_num, 'finish_flag': finish_flag } result.append(ds[index]) return result
def recommend_by_publishedDate(publishedDate, number, book_id): df = Recommend.get_recommend_list() # Format the published_date column in the dataframe df = df[df['published_date'].str.contains(publishedDate)] # Sort by popular grade df = df.sort_values(by=['popular'], ascending=False) counter = 0 result = [] for item in df.iterrows(): if counter == number: break # Do not recommend the reference book if item[1]['id'] != book_id: book = Book(item[1]['id']) info = book.get_info() # Return information which need for front-end temp = { 'book_id': item[1]['id'], 'author': item[1]['authors'], 'categories': item[1]['categories'], 'popular': item[1]['popular'], 'title': info.title, 'book_cover_url': info.book_cover_url } result.append(temp) counter += 1 return result
def get(self): # Get page and book_id from parser args = search_parser.parse_args() page = args.get('page') rating_from = args.get('rating_from') rating_to = args.get('rating_to') category = args.get('category') # Default rating filter is 0 to 5 if rating_from is None: rating_from = 0 if rating_to is None: rating_to = 5 if rating_to < rating_from: return {'message': 'Wrong rating range'}, 201 content, category = Book.book_search_regex(args.get('search_content'), args.get('category')) page_num, last_page_num, total_result_num, all_result = Book.get_book_search_page_num( content, category, rating_from, rating_to, 15) # Index out of range if page <= 0 or page > page_num: return {'message': 'Resource not found'}, 404 result = Book.get_book_search_page(content, 15, page, page_num, last_page_num, total_result_num, all_result) return { 'total_page_num': page_num, 'current_page': page, 'total_result_num': int(total_result_num), 'result': result }, 200
def get(self, book_id): book = Book(book_id) detail = book.get_info() if detail is None: return {'message': 'Resource not found'}, 404 else: avg_rating = Review.get_book_average_rating(book_id) review_preview = Review.get_book_review_from_to(book_id, 0, 2) num_rated = Review.get_book_num_rating(book_id) return { 'book_id': int(detail.id), 'title': detail.title, 'authors': detail.authors, 'publisher': detail.publisher, 'published_date': detail.published_date, 'description': detail.description, 'ISBN13': int(detail.ISBN13), 'categories': detail.categories, 'google_rating': float(detail.google_rating), 'google_ratings_count': int(detail.google_ratings_count), 'book_cover_url': detail.book_cover_url, 'language': detail.language, 'avg_rating': avg_rating, 'num_rated': num_rated, 'review_preview': review_preview, 'read_times': int(book.get_read_times()) }, 200
def get(self): args = book_parser.parse_args() book_id = args.get('book_id') book = Book(book_id) # Get reference book's published date published_date = book.get_info().published_date result = Recommend.recommend_by_publishedDate(published_date[0:3], 6, book_id) if not result: return {'message': 'There is no more book similar with this book, try another mode'}, 200 return {'books': result}, 200
def get(self): args = book_parser.parse_args() book_id = args.get('book_id') book = Book(book_id) # Get reference book's author author = book.get_info().authors result = Recommend.recommend_by_author(author, 6, book_id) if not result: return {'message': 'There is no more book similar with this book, try another mode'}, 200 return {'books': result}, 200
def get_user_reviews(user_id): # SQL conn = connect_sys_db() query = "SELECT user_id, username, book_id, rating, review_content, review_time FROM review_rate WHERE user_id = \'{user_id}\' ORDER BY review_time DESC".format( user_id=user_id) db_result = read_sql(sql=query, con=conn) json_str = db_result.to_json(orient='index') ds = json.loads(json_str) result = [] for index in ds: # Add book's title and cover to result list book = Book(ds[index]['book_id']) ds[index]['book_title'] = book.get_info().title ds[index]['book_cover_url'] = book.get_info().book_cover_url result.append(ds[index]) return result
def post(self): # Get user_id from token token = request.headers.get('AUTH-TOKEN') token_info = jwt.decode(token, SECRET_KEY, algorithms='HS256') user_id = token_info['id'] # Get book_id from parser args = read_parser.parse_args() book_id = args.get('book_id') # Get current year and month now_year = int(datetime.datetime.now().strftime("%Y")) now_month = int(datetime.datetime.now().strftime("%m")) if args.get('year') > now_year or args.get('year') < 1900: return {'message': 'Invalid year'}, 401 if args.get('month') > 12 or args.get('month') < 1: return {'message': 'Invalid month'}, 401 if args.get('year') == now_year and args.get('month') > now_month: return {'message': 'Invalid month'}, 401 date = str(args.get('year')) + "-" + str(args.get('month')) if Collection.is_book_read(user_id, book_id): return {'message': 'This book is already been marked as read'} if not Book.is_book_exists_by_id(book_id): return {'message': 'Resource not found'}, 404 try: Collection.mark_as_read(user_id, book_id, date) except pymysql.Error as e: return {'message': e.args[1]}, 500 return {'message': 'Mark successfully'}, 200
def post(self): # Get user's id from token token = request.headers.get('AUTH-TOKEN') token_info = jwt.decode(token, SECRET_KEY, algorithms='HS256') user_id = token_info['id'] # Get book_id and content from json input info = request.json book_id = info['book_id'] rating = info['rating'] content = info['content'] if not Book.is_book_exists_by_id(book_id): return {'message': 'Resource not found'}, 404 if not Collection.is_book_read(user_id, book_id): return { 'message': 'You can only review and rate after you read the book' }, 401 # input cannot be empty string if book_id is None or rating is None or content == "": return {'message': 'Rating or review content cannot be empty'}, 401 try: if Review.new_review(user_id, book_id, rating, content): return {'message': 'Post new review successfuly'}, 200 else: return {'message': 'Review already existed'}, 401 except pymysql.Error as e: return {'message': e.args[1]}, 500
def get(self): # Get book_id and user_id from parser args = review_parser.parse_args() book_id = args.get('book_id') user_id = args.get('user_id') # If user does not exist if (not User.is_user_exists_by_id(user_id)) and (user_id != None): return {'message': 'Resource not found'}, 404 # if book does not exist if (not Book.is_book_exists_by_id(book_id)) and (book_id != None): return {'message': 'Resource not found'}, 404 # show reviews posted by certain user by only input user_id if (book_id == None and user_id != None): result = Review.get_user_reviews(user_id) return {'reviews': result}, 200 # show reviews of certain book by only input book_id elif (book_id != None and user_id == None): result = Review.get_book_review(book_id) return {'reviews': result}, 200 # show reviews posted by certain user of certain book by input both id elif (book_id != None and user_id != None): result = Review.get_book_user_review(user_id, book_id) return {'reviews': result}, 200 # book_id and user_id cannot be both empty elif (book_id == None and user_id == None): return {'message': 'book_id and user_id cannot be both empty'}, 400
def get_recent_added_books(user_id): conn = connect_sys_db() query = "SELECT book_id, max(collect_time) as latest FROM collections \ JOIN collects ON collections.id = collects.collection_id WHERE user_id = \'{user_id}\' \ AND name != 'read' GROUP BY book_id ORDER BY latest DESC".format( user_id=user_id) db_result = read_sql(sql=query, con=conn) json_str = db_result.to_json(orient='index') ds = json.loads(json_str) result = [] for index in ds: book = Book(ds[index]['book_id']) book_info = book.get_info() # Add book's title and cover_url to result ds[index]['title'] = book_info.title ds[index]['book_cover_url'] = book_info.book_cover_url result.append(ds[index]) return result
def put(self): # Get collection_id and book_id from parser token = request.headers.get('AUTH-TOKEN') token_info = jwt.decode(token, SECRET_KEY, algorithms='HS256') user_id = token_info['id'] # Get args from parser args = collection_move_parser.parse_args() new_collection_id = args.get('new_collection_id') old_collection_id = args.get('old_collection_id') book_id = args.get('book_id') if not (Collection.is_collection_exists_by_both_id( user_id, new_collection_id) and Collection.is_collection_exists_by_both_id( user_id, old_collection_id)): return {'message': 'Resource not found'}, 404 if not Book.is_book_exists_by_id(book_id): return {'message': 'Resource not found'}, 404 if not Book.is_book_exists_in_collection(old_collection_id, book_id): return {'message': 'Resource not found'}, 404 if Book.is_book_exists_in_collection(new_collection_id, book_id): return { 'message': 'This book already existed in the collection you want to move to' }, 401 if old_collection_id == Collection.get_readcollection_id( user_id ) or new_collection_id == Collection.get_readcollection_id(user_id): return { 'message': 'You cannot move in or out books in Read collection' }, 401 try: collection = Collection(old_collection_id) collection.move_book_to_another_collection(new_collection_id, book_id) return { 'message': 'Move book to another collection successfully' }, 200 except pymysql.Error as e: return {'message': e.args[1]}, 500
def get(self): # Get user_id from token token = request.headers.get('AUTH-TOKEN') token_info = jwt.decode(token, SECRET_KEY, algorithms='HS256') user_id = token_info['id'] # Get book_id from parser args = read_id_parser.parse_args() book_id = args.get('book_id') if not Book.is_book_exists_by_id(book_id): return {'message': 'Resource not found'}, 404 read_flag = Collection.is_book_read(user_id, book_id) review_flag = Review.is_review_exist_by_both_id(user_id, book_id) return {'read': read_flag, 'review': review_flag}, 200
def delete(self): # Get book_id and user_id from parser args = delete_parser.parse_args() book_id = args.get('book_id') user_id = args.get('user_id') if not Book.is_book_exists_by_id(book_id): return {'message': 'Resource not found'}, 404 if not Review.is_review_exist_by_both_id(user_id, book_id): return {'message': 'Resource not found'}, 404 try: Review.delete_review(user_id, book_id) except pymysql.Error as e: return {'message': e.args[1]}, 500 return {'message': 'Delete review successfully'}, 200
def post(self): # Get user_id from token token = request.headers.get('AUTH-TOKEN') token_info = jwt.decode(token, SECRET_KEY, algorithms='HS256') user_id = token_info['id'] # Get book_id from parser args = read_id_parser.parse_args() book_id = args.get('book_id') if not Book.is_book_exists_by_id(book_id): return {'message': 'Resource not found'}, 404 if not Collection.is_book_read(user_id, book_id): return {'message': 'This book is not been marked as read yet'} try: Collection.mark_as_unread(user_id, book_id) if Review.is_review_exist_by_both_id(user_id, book_id): Review.delete_review(user_id, book_id) except pymysql.Error as e: return {'message': e.args[1]}, 500 return {'message': 'Mark successfully'}, 200
def delete(self): # Get collection_id and book_id from parser token = request.headers.get('AUTH-TOKEN') token_info = jwt.decode(token, SECRET_KEY, algorithms='HS256') user_id = token_info['id'] # Get collection_id and book_id from parser args = collection_add_book_parser.parse_args() collection_id = args.get('collection_id') book_id = args.get('book_id') if not Collection.is_collection_exists_by_both_id( user_id, collection_id): return {'message': 'Resource not found'}, 404 if not Book.is_book_exists_by_id(book_id): return {'message': 'Resource not found'}, 404 collection = Collection(collection_id) if collection.delete_book_in_collection(args.get('book_id')): return {'message': 'Delete book successfully'}, 200 else: return {'message': 'Resource not found'}, 404
def post(self): # Get collection_id and book_id from parser token = request.headers.get('AUTH-TOKEN') token_info = jwt.decode(token, SECRET_KEY, algorithms='HS256') user_id = token_info['id'] # Get args from parser args = collection_add_book_parser.parse_args() collection_id = args.get('collection_id') book_id = args.get('book_id') # Check user is adding book to their own collections if not Collection.is_collection_exists_by_both_id( user_id, collection_id): return {'message': 'Resource not found'}, 404 # Check if book existed if not Book.is_book_exists_by_id(book_id): return {'message': 'Resource not found'}, 404 collection = Collection(collection_id) flag, message = collection.add_book_to_collection(args.get('book_id')) return {'message': message}, flag
def get(self): return {'books': Book.get_popular_book()}, 200
def get(self): return {'categories': Book.get_categories_list()}, 200