Пример #1
0
def reset_password(token):
    if 'user' in session:
        return redirect(url_for('home'))
    try:
        username = jwt.decode(token,
                              app.config['SECRET_KEY'],
                              algorithms=['HS256'])['reset_password']
    except:
        flash(f'Link invalid or expired.', 'danger')
        return redirect(url_for('home'))
    if username:
        user = db.execute(f"SELECT * FROM Users WHERE username=:username", {
            'username': username
        }).fetchone()
        form = UpdateUserForm()
        search = SearchForm()
        if request.method == 'POST' and form.validate():
            hashed_pw = bcrypt.generate_password_hash(
                form.new_password.data).decode('utf-8')
            db.execute(f"UPDATE Users SET password='******'")
            db.commit()
            # log user
            session['user'] = user
            flash(
                f"Welcome back {session['user'][1]}! Your password has been reset and you are now connected!",
                "success")
            return redirect(url_for('user_account', username=user.username))
    return render_template('reset_password.html',
                           title="Reset Password",
                           user=user,
                           form=form,
                           searchform=search)
Пример #2
0
def log_user(login_form):
    # check email exist in database
    registered_user = db.execute("SELECT * FROM Users WHERE email=:email", {
        'email': login_form.email.data
    }).fetchone()
    if registered_user is None:
        flash("User doesn't exist", 'danger')
        return redirect(url_for('login'))
    #check if password match db
    hashed_pw = db.execute("SELECT password FROM Users WHERE email=:email", {
        'email': login_form.email.data
    }).fetchone()
    if hashed_pw is None:
        flash("Invalid password. Please try again", "danger")
        return redirect(url_for('login'))
    pw_checked = bcrypt.check_password_hash(f'{hashed_pw[0]}',
                                            login_form.password.data)
    if pw_checked is False:
        flash("Invalid password. Please try again", "danger")
        return redirect(url_for('login'))
    #Redirect if user already logged in
    if session.get('user'):
        flash("You are already logged in", "danger")
        return redirect(url_for('user_account'))
    #Log user in
    session['user'] = registered_user
    flash(f"Welcome {session['user'][1]}! You are now connected!", "success")
    #return redirect(url_for('home'))
    return session['user']
Пример #3
0
def register_user(register_form):
    # hash password for security
    hashed_pw = bcrypt.generate_password_hash(
        register_form.password.data).decode('utf-8')
    # check if username and email are unique
    usernames = db.execute(
        "SELECT username FROM Users WHERE username=:username", {
            'username': register_form.username.data
        }).fetchone()
    emails = db.execute("SELECT email FROM Users WHERE email=:email", {
        'email': register_form.email.data
    }).fetchone()
    if usernames:
        flash('Username is already taken. Please chose another one', 'danger')
        return redirect(url_for('register'))
    if emails:
        flash('Email address is already taken. Please chose another one',
              'danger')
        return redirect(url_for('register'))
    else:
        # create user and add to database
        user = db.execute(
            "INSERT INTO Users(username, email, password, avatar) VALUES(:username, :email, :hashed_pw, :avatar)",
            {
                "username": register_form.username.data,
                "email": register_form.email.data,
                "hashed_pw": hashed_pw,
                "avatar": 'default.jpg'
            })
        db.commit()
        flash("Your account has been succesfully created. You can now log in!",
              "success")
        return redirect(url_for('login'))
Пример #4
0
def most_reviewed():
    isbns = db.execute("SELECT isbn FROM Books LIMIT 350").fetchall()
    res = review_counts_res(isbns)
    book_counts = res['books']
    book_counts.sort(key=lambda k: k['work_reviews_count'], reverse=True)
    isbn = []  # ----- Create a list of the 6 most reviewed books isbns
    for book in book_counts[0:6]:
        # Check if goodread average is already in db
        avg = db.execute("SELECT average_rating FROM Books WHERE isbn=:isbn", {
            'isbn': book['isbn']
        }).fetchone()
        if avg[0] is None:
            # ---- Update database with goodread average rating
            db.execute(
                "UPDATE Books SET average_rating=:average_rating WHERE isbn=:isbn",
                {
                    'average_rating': book['average_rating'],
                    'isbn': book['isbn']
                })
            db.commit()
        # ---- Add 6 most reviewed isbns to the list
        isbn.append(book['isbn'])
    # ---- Fetch the 6 most goodread reviewed books from our database
    isbn = tuple(isbn)
    most_reviewed = db.execute(
        f"SELECT * FROM Books WHERE isbn IN {isbn}").fetchall()
    return most_reviewed
Пример #5
0
def delete_account():
    if 'user' in session:
        user = session['user']
        # log user out
        session.pop('user', None)
        # delete all datas from db
        db.execute(f"DELETE FROM Users WHERE id='{user.id}'")
        db.commit()
        flash(f"Your account have been deleted", "info")
        return redirect(url_for('register'))
    else:
        abort(404)
Пример #6
0
def same_author(book):
    isbns = db.execute(
        f"SELECT isbn FROM Books WHERE author='{book.author}'").fetchall(
        )  # Fetch isbns from books of the same author
    books = search_results(
        isbns)  # Check for goodread average rating and update if necessary
    results = sorted(
        [result for result in books if result != book], key=lambda x: x[
            2])  #Remove current book from results and reorder by title ASC
    return results
Пример #7
0
def reset_pwd_request(request_form):
    user = db.execute("SELECT * FROM Users WHERE email=:email", {
        'email': request_form.email.data
    }).fetchone()
    if user:
        send_pwd_reset_email(user)
        flash(
            f'An email has been send to you with the instructions to reset your password',
            "info")
        return redirect(url_for('home'))
Пример #8
0
def search():
    searchform = SearchForm()
    if request.method == 'POST':
        try:
            # Search database for results matching the search
            isbns = db.execute(
                f"SELECT isbn FROM Books WHERE title ILIKE '%{searchform.search.data}%' OR author ILIKE '%{searchform.search.data}%' OR isbn LIKE '%{searchform.search.data}%' OR year='{searchform.search.data}' ORDER BY title ASC"
            ).fetchall()
        except:
            if 'user' in session:
                return render_template(
                    'search.html',
                    title="Search",
                    searchform=searchform,
                    message=(f"No results. Please try again"),
                    user=session['user'])
            return render_template('search.html',
                                   title="Search",
                                   searchform=searchform,
                                   message=(f"No results. Please try again"))
        # If no results found return to no result page :
        if (len(isbns) == 0) or (len(isbns) > 350):
            if 'user' in session:
                return render_template(
                    'search.html',
                    title="Search",
                    searchform=searchform,
                    message=(f"No results. Please try again"),
                    user=session['user'])
            return render_template('search.html',
                                   title="Search",
                                   searchform=searchform,
                                   message=(f"No results. Please try again"))
        # If results are found, save in a session for reordering the results by title, author, rate etc..
        session['results'] = search_results(isbns)
        if 'user' in session:
            return render_template('search.html',
                                   title="Search",
                                   user=session['user'],
                                   searchform=searchform,
                                   books=session['results'])
        return render_template('search.html',
                               title="Search",
                               searchform=searchform,
                               books=session['results'])
    if 'user' in session:
        return render_template('search.html',
                               title="Search",
                               searchform=searchform,
                               user=session['user'])
    return render_template('search.html',
                           title="Search",
                           searchform=searchform)
Пример #9
0
def user_reviews(username):
    if 'user' not in session:
        flash("You need to login first", "danger")
        return redirect(url_for('login'))
    search = SearchForm()
    recents = db.execute(
        f"SELECT * FROM Books JOIN Reviews ON Reviews.book_id=books.id WHERE user_id={session['user'][0]}"
    ).fetchall()
    return render_template('reviews.html',
                           title="Your Reviews",
                           user=session['user'],
                           searchform=search,
                           recents=recents)
Пример #10
0
def search_results(results):
    #Check for goodread average rating
    books = review_counts_res(results)
    updated = []  # Create list of updated rating search
    for book in books['books']:
        # Check if average rating in database is same as goodreads
        avg = db.execute(
            f"SELECT average_rating FROM Books WHERE isbn='{book['isbn']}'"
        ).fetchone()
        if avg[0] is None:
            # Update db if rating is none or different
            db.execute(
                "UPDATE Books SET average_rating=:average_rating WHERE isbn=:isbn",
                {
                    'average_rating': book['average_rating'],
                    'isbn': book['isbn']
                })
            db.commit()
        update = db.execute(
            f"SELECT * FROM Books WHERE isbn='{book['isbn']}'").fetchone()
        updated.append(update)
    return updated
Пример #11
0
def book_api(isbn):
    books = db.execute("SELECT * FROM Books WHERE isbn=:isbn", {
        'isbn': isbn
    }).fetchall()
    if len(books) != 1:
        return jsonify({"error": "Invalid book isbn"}), 422
    print(books)
    for book in books:
        return jsonify({
            "isbn": isbn,
            "title": book['title'],
            "author": book['author'],
            "year": book['year'],
            "average_score": book.average_rating,
            "review_count": book.review_count
        })
Пример #12
0
def book(book_title, book_id):
    search = SearchForm()
    review = SubmitReviewForm()
    login = LoginForm()
    requestForm = RequestResetForm()
    book = db.execute("SELECT * FROM Books WHERE id=:id", {
        'id': book_id
    }).fetchone()
    description = book_description(book.title, book.author)
    author = same_author(book)
    recents = db.execute(
        f"SELECT * FROM Users JOIN Reviews ON Reviews.user_id=Users.id WHERE book_id IN (SELECT id FROM Books WHERE id={book_id})"
    ).fetchall()
    recents.sort(reverse=True)
    now = current_time()
    if 'user' in session:
        # Check if user already left a review
        edit = db.execute(
            f"SELECT book_id FROM Reviews WHERE user_id={session['user'].id} AND book_id={book_id}"
        ).fetchall()
        if len(edit) > 0:
            return render_template('book.html',
                                   title=book_title,
                                   searchform=search,
                                   book=book,
                                   author=author,
                                   description=description,
                                   edit=edit,
                                   recents=recents,
                                   user=session['user'])
        if request.method == "POST" and review.validate():
            db.execute(
                "INSERT INTO Reviews (body_text, rating, datetime, book_id, user_id) VALUES (:body_text, :rating, :datetime, :book_id, :user_id)",
                {
                    "body_text": review.review.data,
                    "rating": review.rating.data,
                    "datetime": now,
                    "book_id": book_id,
                    "user_id": session['user'].id
                })
            # Add review count to book database
            db.execute(
                "UPDATE Books SET review_count = review_count + 1 WHERE id=:id",
                {"id": book_id})
            db.commit()
            flash(f'Your review has been post', 'success')
            return redirect(
                url_for('book', book_title=book.title, book_id=book.id))
        return render_template('book.html',
                               title=book_title,
                               searchform=search,
                               book=book,
                               author=author,
                               description=description,
                               review=review,
                               recents=recents,
                               user=session['user'])
    if request.method == "POST" and login.validate():
        log_user(login)
        return redirect(url_for('book', book_title=book.title,
                                book_id=book.id))
    if request.method == "POST" and requestForm.validate():
        return reset_pwd_request(requestForm)
    return render_template('book.html',
                           title=book_title,
                           form=login,
                           searchform=search,
                           book=book,
                           author=author,
                           description=description,
                           recents=recents,
                           requestform=requestForm)
Пример #13
0
def user_update(form, user):
    # Check new username and email address are not already use
    if form.username.data is not user.username and form.email.data is not user.email:
        username = db.execute(
            "SELECT username FROM Users WHERE username=:username", {
                'username': form.username.data
            }).fetchone()
        email = db.execute("SELECT email FROM Users WHERE email=:email", {
            'email': form.email.data
        }).fetchone()
        if username:
            flash('Username is already taken. Please chose another one',
                  'danger')
            return redirect(
                url_for('user_account', username=session['user'][1]))
        if email:
            flash('Email address is already taken. Please chose another one',
                  'danger')
            return redirect(
                url_for('user_account', username=session['user'][1]))
    # ------------ USERNAME -----------
    # Update username in database
    if form.username.data:
        db.execute(
            f"UPDATE Users SET username='******' WHERE username=:username",
            {'username': user.username})
        db.commit()
        flash("Your username has been updated!", "info")
    # ------------ EMAIL -----------
    # Update email in database
    if form.email.data:
        db.execute(
            f"UPDATE Users SET email='{form.email.data}' WHERE email=:email",
            {'email': user.email})
        db.commit()
        flash("Your email address has been updated!", "info")
    # ------------ PASSWORD -----------
    if form.new_password.data:
        #check current password is correct
        hashed_pw = db.execute("SELECT password FROM Users WHERE id=:id", {
            'id': user.id
        }).fetchone()
        pw_checked = bcrypt.check_password_hash(f'{hashed_pw[0]}',
                                                form.current_password.data)
        if pw_checked is False:
            flash("Invalid password. Please try again", "danger")
            return redirect(
                url_for('user_account', username=session['user'][1]))
        #check if new password is new
        if bcrypt.check_password_hash(f'{hashed_pw[0]}',
                                      form.new_password.data):
            flash("You are already using this password", "info")
            return redirect(
                url_for('user_account', username=session['user'][1]))
        # Update password in database
        else:
            # hash password for security
            hashed_pw = bcrypt.generate_password_hash(
                form.new_password.data).decode('utf-8')
            db.execute(
                f"UPDATE Users SET password='******' WHERE password=:password",
                {'password': user.password})
            db.commit()
            flash("Your password has been reset", "info")
    # -------------- PICTURE -----------
    if form.picture.data:
        picture_file = save_picture(form.picture.data)
        db.execute(f"UPDATE Users SET avatar='{picture_file}' WHERE id=:id",
                   {'id': user.id})
        db.commit()
    # Query database for updated user and refresh the session variable
    session['user'] = db.execute(
        f"SELECT * FROM Users WHERE id='{user.id}'").fetchone()
    return redirect(url_for('user_account', username=session['user'][1]))