Пример #1
0
def add_book():
    """
    This method lists a book on one of several lists, by a user. It involves the following steps:
    - add the book to the backend DB to the relevant table
    - then, reload the page with an updated table
    """
    bsdb = get_bsdb()
    data = req.get_json()
    if data.get('request') == 'my-books':  # here we list the book as being available for trade
        # isbn = req.get_json()["isbn"]
        copyquality = data["quality"]
        points = data["points"]
        book_id = data["bookId"]
        user_num = session["user_num"]
        # bsdb.user_add_book_by_isbn(isbn, user_num, copyquality)
        bsdb.user_add_book_by_id(book_id, user_num, copyquality, points)
        app.logger.info(f"Book {book_id} added by user {user_num}")
        flash("Book successfully added to your BookSwap library.", "success")

        return redirect('/my-books')
    elif data.get('request') == 'my-wishlist':
        book_id = data["bookId"]
        user_num = session["user_num"]
        bsdb.user_add_book_to_wishlist_by_id(book_id, user_num)
        return redirect('/wishlist')
Пример #2
0
def change_points():
    """
    Change_points changes the point value assigned to the UserBooks entry.
    """
    bsdb = get_bsdb()
    points = req.get_json().get('points')
    user_num = session['user_num']
    book_id = req.get_json().get('id')
    app.logger.info(
        f"UserBooks id {book_id} trying to change it to {points} points. " +
        f"Current user is {session['user_num']}")
    # Confirm that the requesting user owns the book
    try:
        if bsdb.is_user_book_owner(user_num, book_id):
            app.logger.info(f"Correct user for the book detected.")
        else:
            app.logger.warning(f"Incorrect user for the book detected.")
            flash("Wrong uesr for that book.  Log out, log in, and try again?",
                  "warning")
            return redirect(url_for('my_books'))
    except Exception:
        app.logger.error("Error checking user validity.")
        flash("We had an error trying to verify your identity. " +
              "Sorry about that.  Perhaps try again?", "warning")
        return redirect(url_for('my_books'))
    # Change the points
    try:
        bsdb.set_book_points(book_id, points)
        app.logger.info(f"Book points changed.")
        flash("Book points successfully changed.", "success")
    except Exception:
        app.logger.error(f"Error changing book points.")
        flash("We had an error trying to change your book points. " +
              "Sorry about that.  Perhaps try again?", "warning")
    return redirect(url_for('my_books'))
Пример #3
0
def search_book():
    """
    This method is POSTed a request with the fields 'isbn', 'author', and 'title', and searches for
    results on the open library API that match these fields. It returns a rendered set of divs to be inserted
    into the html as appropriate.
    """
    bsdb = get_bsdb()
    data = req.get_json()
    if data.get('request') == 'my-books':
        isbn = data["isbn"]
        author = data["author"]
        title = data["title"]
        # TODO magic number here - number of search results
        search_results = bsdb.search_books_openlibrary(title=title, author=author, isbn=isbn, num_results=5)
        copyqualities = bsdb.get_book_qualities()
        return render_template("snippets/external_search_results.html", search_results=search_results,
                               copyqualities=copyqualities, show_qualities=True, show_points=True)
    elif data.get('request') == 'my-wishlist':
        isbn = data["isbn"]
        author = data["author"]
        title = data["title"]
        # TODO magic number here - number of search results
        search_results = bsdb.search_books_openlibrary(title=title, author=author, isbn=isbn, num_results=5)
        return render_template("snippets/external_search_results.html", search_results=search_results,
                               show_qualities=False, show_points=False, show_wishlist_results=True)
Пример #4
0
def requestBook():
    bsdb = get_bsdb()
    book = req.get_json(force=True)
    app.logger.info('Request incoming for book: %s', book)
    if (book['userId'] == session['user_num']):
        flash("You tried to request your own book?  It would be easier to just pull it off the shelf and read...",
              "warning")
        app.logger.warning(
            f"User {session['user_num']} attempted to trade with themselves.  This leads to night blindness")
        success = "False"
        try:
            points_available = bsdb.get_current_user_points(session["user_num"])
        except Exception:
            points_available = 0
    else:
        try:
            points_available = bsdb.request_book(book, session['user_num'])
            success = "True"
            app.logger.info(
                f"Successfully placed trade request for user {session['user_num']} on UserBooks number "
                f"{book['userBooksId']}")
        except Exception:
            app.logger.error(
                f"Unable to place the Trade Request for user {session['user_num']} on UserBooks book number "
                f"{book['userBooksId']}")
            success = "False"
            flash("There was an error in placing the trade request.  Feel free to try again", "warning")
    return {
        "book": book,
        "points_available": points_available,
        "success": success
    }
Пример #5
0
def wishlist():
    bsdb = get_bsdb()
    wishlists = Wishlists(session['user_num'], bsdb)
    data = req.get_json()
    # User asks to see copies of a book
    if req.method == "POST" and data.get("request") == "copiesModal":
        book = eval(data['book'])
        app.logger.info(f"Request incoming for copies of book {book} from user {session['user_num']}")
        try:
            copies = bsdb.get_available_copies(book["bookId"], session["user_num"])
            copies_arr = [dict(copy) for copy in copies]
            app.logger.info(f"Copies available: {copies_arr}")
        except Exception:
            app.logger.error(f"Error retrieving copies of {book} for user {session['user_num']}")
            flash("Error retrieving copies of the book.  Maybe try again?", "warning")
            return redirect('/wishlist')
        return {
            "title": copies_arr[0]['title'],
            "copies": copies_arr,
            "count": len(copies_arr),
            "points_available": g.points
        }
    # Page load
    try:
        books = wishlists.get_all_wishlist_books_for_user()
        app.logger.info(f"Made wishlists for user {session['user_num']}")
    except Exception:
        app.logger.error(f"Error making wishlists for user {session['user_num']}")
        flash("We had an error fetching your wishlist", "warning")
        books = []
    return render_template('user/wishlist.html', books=books)
Пример #6
0
 def __init__(self, user_num):
     """
     Class initializer.
     Accepts:
         user_num (int): User id
     Returns:
         None
     """
     self.user_num = user_num
     self.bsdb = get_bsdb()
Пример #7
0
def reject_trade(user_books_id):
    app.logger.info(f"Incoming trade rejection from user {session['user_num']} for book {user_books_id}")
    bsdb = get_bsdb()
    try:
        bsdb.reject_trade(user_books_id)
        app.logger.info(f"Trade successfully rejected.  UserBooks number {user_books_id} is available again.")
        flash("Trade successfully removed", "success")
    except Exception:
        app.logger.error(f"There was an error in rejecting the trade.")
        flash("There was an error in deleting your trade", "warning")
    return redirect(url_for('received_requests'))
Пример #8
0
def accept_trade(user_books_id):
    app.logger.info(f"Incoming trade acceptance from user {session['user_num']} for book {user_books_id}")
    bsdb = get_bsdb()
    try:
        bsdb.accept_trade(user_books_id)
        app.logger.info(f"Trade successfully accepted.")
        flash("Trade successfully accepted", "success")
    except Exception:
        app.logger.info(f"There was an error in accepting the trade.")
        flash("There was an error in accepting your trade", "warning")
    return redirect(url_for('received_requests'))
Пример #9
0
def book_not_received(user_books_id):
    app.logger.info(f"Incoming book NOT received confirmation from {session['user_num']} for book {user_books_id}")
    bsdb = get_bsdb()
    book_not_received = BookReceived(session['user_num'], user_books_id, bsdb)
    try:
        book_not_received.book_not_received()
        app.logger.info(f"Trade failure confirmation from user {session['user_num']} for book {user_books_id}")
        flash("Trade marked as never completed", "success")
    except Exception:
        app.logger.error(
            f"Unsuccessful trade failure confirmation from user {session['user_num']} for book {user_books_id}")
    return redirect(url_for("my_requests"))
Пример #10
0
def browse_books():
    form = BookSearchForm()
    bsdb = get_bsdb()
    recent_books = bsdb.get_recent_additions(8)
    recent_books_arr = [dict(book) for book in recent_books]
    local_results = {}
    external_results = {}
    if req.method == 'POST':
        book_search_query = (form.ISBN.data, form.author.data, form.title.data)
        book_search = BookSearch(book_search_query, bsdb)
        # TODO magic numbers here
        # book_results = book_search.local_book_search(10)
        local_results, external_results = book_search.combined_book_search(10, 10)
        show_recent = False
        show_search = False
        show_results = True
    else:
        book_results = {}
        show_recent = True
        show_search = True
        show_results = False

    # Load current user's points
    if session.get('user_num'):
        try:
            points_available = bsdb.get_current_user_points(session['user_num'])
            app.logger.info(f"User {session['user_num']} has {points_available} points.")
        except Exception:
            app.logger.error(
                f"APP: Browse_books -- Could not determine number of points for user {session['user_num']}.")
            points_available = 0
            flash(
                "We could not load your points, so we assume you have 0 points. Feel free to browse for now, "
                "but we will need to fix this before you can make trade requests.",
                "warning")
    else:
        points_available = 0

    app.logger.info(f"\n\t recent_books: {recent_books_arr}" +
                    f"\t local_results: {local_results}" +
                    f"\t external_results: {external_results}" +
                    f"\t form: {form}" +
                    f"\t Visiting user has {points_available} points available.")
    return render_template('browse-books.html',
                           recent_books=recent_books_arr,
                           local_results=local_results,
                           external_results=external_results,
                           form=form,
                           show_recent=show_recent,
                           show_search=show_search,
                           show_results=show_results,
                           points_available=points_available
                           )
Пример #11
0
def cancel_request(user_books_id):
    app.logger.info(f"Incoming trade request cancellation from {session['user_num']} for book {user_books_id}")
    bsdb = get_bsdb()
    cancel_trade_request = CancelTradeRequest(session['user_num'], user_books_id, bsdb)
    try:
        cancel_trade_request.cancel_request()
        app.logger.info(
            f"Successful trade request cancellation from user {session['user_num']} for book {user_books_id}")
        flash("Trade request canceled", "success")
    except Exception:
        app.logger.error(
            f"Unsuccessful trade request cancellation from user {session['user_num']} for book {user_books_id}")
    return redirect(url_for("my_requests"))
Пример #12
0
def my_books():
    bsdb = get_bsdb()
    # Get the data of books currently listed
    rows = bsdb.get_listed_books(session['user_num'])
    copyqualities = bsdb.get_book_qualities()
    # Build the data to be passed to Jinja
    headers = ["Title", "Author", "Quality", "Points", "ISBN", "ID", "Cover"]
    table_content = [[row[header] for header in headers] for row in rows]
    data = {"headers": headers,
            "rows": table_content,
            "caption": "",
            "copyqualities": copyqualities
            }
    return render_template('user/my-books.html', data=data)
Пример #13
0
def received_requests():
    bsdb = get_bsdb()
    user = session['user_num']
    num_trade_reqs = bsdb.get_num_trade_requests(user)
    num_open_trades = bsdb.get_num_open_trades(user)
    if num_trade_reqs == 0 and num_open_trades == 0:
        return render_template('user/no-trades.html')
    else:
        trade_info = bsdb.get_trade_info(user)
        trade_info_dicts = [dict(row) for row in trade_info]
        return render_template('user/received-requests.html',
                               trade_info=trade_info_dicts,
                               num_open_trades=num_open_trades,
                               num_trade_reqs=num_trade_reqs)
Пример #14
0
def my_requests():
    bsdb = get_bsdb()
    user = session['user_num']
    my_request = MyRequests(user, bsdb)
    try:
        requests = my_request.get_all_open_requests()
        requests_dicts = [dict(row) for row in requests]
        for trade in requests_dicts:
            print(trade['tradeAge'])
    except Exception:
        app.logger.error("Couldn't fill my-requests")
        requests_dicts = []

    if len(requests_dicts) == 0:
        return render_template('user/no-trades.html', no_sent_requests=True)
    else:
        return render_template('user/my-requests.html', requests=requests_dicts)
Пример #15
0
def populate_g():
    bsdb = get_bsdb()
    user_num = session.get("user_num")
    if user_num is not None:
        try:
            user_info = bsdb.get_account_settings(user_num)
            g.username = user_info["username"]
            g.points = user_info["points"]
            g.num_trade_requests = bsdb.get_num_trade_requests(user_num)
            g.num_open_trades = bsdb.get_num_open_trades(user_num)
            app.logger.info(f"Request made.  Current user status:"
                            f"\t g.username: {g.username}" +
                            f"\t g.points: {g.points}"
                            f"\t g.num_trade_requests: {g.num_trade_requests}" +
                            f"\t g.num_open_trades: {g.num_open_trades}")


        except Exception:
            app.logger.error(f"Error setting up g")
            session['user_num'] = None
Пример #16
0
def login():
    form = LoginForm()
    # Checks if input is valid
    if form.validate_on_submit():
        bsdb = get_bsdb()
        username = form.username.data
        password = form.password.data
        error = None
        app.logger.info(f'Login attempt incoming for user {username}')
        id = None
        # Username check
        try:
            id = bsdb.get_username_id(username)
        except Exception:
            app.logger.error(f"Error checking username ( {username} ).")
            error = "We had an error checking your username.  Please try again."

        if id is None:
            app.logger.error(f"Login -- Incorrect username ( {username} ) entered.")
            error = "Incorrect username.  We do not have record of this username."
        # Password check
        else:
            try:
                if password != bsdb.get_password(id):
                    app.logger.warning(f"Incorrect password entered for {username}.")
                    error = "Incorrect password."
            except Exception:
                app.logger.error(f"Error checking password for {username}.")
                error = "We hada n error checking your password.  Please try again."
        # No errors, login proceeds
        if error is None:
            session.clear()
            session['user_num'] = id
            app.logger.info(f"User {username} successfully logged in.")
            return redirect(url_for('home'))
        flash(error, 'warning')
    return render_template('login.html', form=form)
Пример #17
0
def account():
    # Get basic database and forms ready to return
    bsdb = get_bsdb()
    acct = AccountSettings(session['user_num'])
    account_settings_change_form = AccountSettingsChangeForm()
    password_change_form = PasswordChangeForm()
    account_settings = bsdb.get_account_settings(session["user_num"])
    show_account_modal = False
    show_password_modal = False
    # Check against requests to change account settings
    if (req.method == 'POST' and
            account_settings_change_form.submit_account_change.data):
        show_account_modal = True
        app.logger.info(f"request received to change user settings for " +
                        f"user {session['user_num']}")
        # Check to make sure form was valid, return form if it was not
        if not account_settings_change_form.validate_on_submit():
            app.logger.warning(f"Settings change form failed validation")
            flash("Your information wouldn't work.  Try again?", "warning")
            return render_template(
                'user/user-home.html',
                account_settings=account_settings,
                account_settings_change_form=account_settings_change_form,
                password_change_form=password_change_form,
                show_account_modal=show_account_modal,
                show_password_modal=show_password_modal
            )
        # Check that the username isn't changing or is available
        if acct.is_username_valid(session['user_num'],
                                  account_settings_change_form.username.data):
            app.logger.info("username is valid")
            try:
                acct.set_account_information(
                    session['user_num'], account_settings_change_form)
                flash("Account information updated.", "success")
                app.logger.info("returning new account info:")
                account_settings = bsdb.get_account_settings(
                    session["user_num"])
                show_account_modal = False
                account_settings = bsdb.get_account_settings(
                    session["user_num"])
            except Exception:
                flash("Error updating your information.  Try again?",
                      "warning")
        else:
            flash("Username is already taken", "warning")

    # Check against request to change password
    elif req.method == 'POST' and password_change_form.submit.data:
        show_password_modal = True
        app.logger.info(f"request received to change password for " +
                        f"user {session['user_num']}")
        if not password_change_form.validate_on_submit():
            app.logger.warning(f"Password change form failed verification")
            flash("Your infromation wouldn't work.  Try again?", "warning")
            return render_template(
                'user/user-home.html',
                account_settings=account_settings,
                account_settings_change_form=account_settings_change_form,
                password_change_form=password_change_form,
                show_account_modal=show_account_modal,
                show_password_modal=show_password_modal
            )
        try:
            correct_password = acct.is_password_correct(session["user_num"],
                                                        password_change_form)
            if not correct_password:
                flash("Original password was not correct.  Please try again.",
                      "warning")
            else:
                app.logger.info("Original password was entered correctly.")
                try:
                    acct.set_password(session["user_num"],
                                      password_change_form)
                    app.logger.info("New Password set")
                    flash("New Password Sucessfully Set.", "success")
                    show_password_modal = False
                except Exception:
                    app.logger.error("Error setting new password")
                    flash("Error setting new password.  Try again?", "warning")

        except Exception:
            flash("Error determining if the original password is correct.  Try again?", "warning")
            app.logger.error("Error checking original password.")

    # We got here either by being GET or succeeding making changes.
    # Refill account_setting and account_settings_change_form
    account_settings_change_form = acct.fill_account_settings_change_form()
    account_settings = bsdb.get_account_settings(session["user_num"])
    return render_template(
        'user/user-home.html',
        account_settings=account_settings,
        account_settings_change_form=account_settings_change_form,
        password_change_form=password_change_form,
        show_account_modal=show_account_modal,
        show_password_modal=show_password_modal
    )
Пример #18
0
def add_to_wish(bookid=None):
    bsdb = get_bsdb()
    db = get_db()
    db.row_factory = sqlite3.Row

    # Queries used for SELECTing and INSERTing
    get_books_isbn_query = 'SELECT * FROM Books WHERE ISBN = ?'
    get_wishlist_books_query = 'SELECT * FROM WishlistsBooks WHERE wishlistId = ? AND bookId = ?'
    insert_wishlist_query = 'INSERT INTO WishlistsBooks (wishlistId, bookId) VALUES (?, ?)'

    # Special path for browse-books route
    if bookid is not None:
        c = db.cursor()
        c.execute(get_wishlist_books_query,
                  (session['user_num'], bookid))

        # if the book was already in the wishlist, don't add it
        if c.fetchall():
            flash("Book already in your wishlist", "warning")
            app.logger.warning(f"Book {bookid} already in " +
                               f"user {session['user_num']}'s wishlist")
        # otherwise, add book to the wishlist
        else:
            c.execute(insert_wishlist_query,
                      (session['user_num'], bookid))
            flash("Book added to your wishlist", "success")
            app.logger.info(f"Book {id} successfully added to " +
                            f"user {session['user_num']}'s wishlist")
        db.commit()
        db.close()
        return redirect(url_for('browse_books'))
    data = req.args.get("isbn")
    if data == "":
        return redirect('/wishlist')
    c = db.cursor()
    c.execute(get_books_isbn_query, (data,))
    bookId = c.fetchall()[0]['id']
    # need to get Users Wishlist.id number
    c.execute("""
                SELECT
                    id
                FROM 
                    Wishlists
                WHERE
                    Wishlists.userId = ?
                """,
              (session['user_num'],))
    wishlist = c.fetchone()['id']
    c.execute(get_wishlist_books_query,
              (wishlist, bookId))
    if not c.fetchall():
        flash("Book successfully added to your wishlist", "success")
        app.logger.info(f"Book {bookId} added to wishlist {wishlist}")
        c.execute(insert_wishlist_query,
                  (wishlist, bookId))
    else:
        flash("Book already in your wishlist.", "warning")
        app.logger.warning(f"Book {bookId} attempted to add to wishlist {wishlist}, but it was already in that list.")
    db.commit()
    db.close()
    return redirect('/wishlist')