def view_review(id_, title):
    conn, cursor = create_db_conn()
    cursor.execute(
        """
        select r.id as [id], r.title as [title], r.rating as [rating],
        r.review as [review], u.name as [by], u.id as [user_id],
        r.date_created as [date], r.upvotes as [up],
        r.downvotes as [down]
        from reviews as r
        INNER JOIN users as u
          on r.created_by = u.id
        where r.id = ? and title = ?
        """, (id_, title))
    results = cursor_results(cursor)
    if len(results) == 0:
        flash_message('No review found.', 'danger')
        return render_template('view_review.html')
    results = results[0]

    return render_template('view_review.html',
                           title=results['title'],
                           by=results['by'],
                           rating=results['rating'],
                           id=results['id'],
                           user_id=results['user_id'],
                           date=results['date'],
                           up=results['up'],
                           down=results['down'],
                           review=results['review'])
def login():
    """A route for a user to login."""
    if request.method == 'GET':
        make_csrf()
        return render_template('login.html')

    form_email = request.form['email']
    form_password = request.form['password']

    conn, cursor = create_db_conn()
    cursor.execute('select * from users where email = ?', (form_email, ))
    results = cursor_results(cursor)
    conn.close()
    if len(results) == 0:
        flash_message('Incorrect email or password.', 'danger')
        return render_template('login.html')

    if not verify_csrf():
        return render_template('login.html')

    # TODO: add captcha verification

    if check_pw(form_password, results[0]['hash'], results[0]['salt']):
        user = User(results[0]['id'], results[0]['name'], results[0]['email'])
        login_user(user)
        flash_message('You are now logged in.', 'success')
        return redirect(url_for('home'))

    flash_message('Incorrect email or password.', 'danger')
    return render_template('login.html')
def create_review():
    if request.method == 'GET':
        make_csrf()
        return render_template('create_review.html')

    form_title = request.form['title']
    form_rating = request.form['rating']
    form_review = request.form['review']

    if not form_title or not form_rating or not form_review:
        flash_message('Not all information provided.', 'danger')
        return render_template('create_review.html')

    if not verify_csrf():
        return render_template('create_review.html')

    # TODO: add captcha verification

    conn, cursor = create_db_conn()
    cursor.execute(
        'insert into reviews VALUES (?,?,?,?,?,?,?,?)',
        (None, form_title, form_rating, form_review, current_user.id,
         datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'), 0, 0))
    conn.commit()
    cursor.execute('select * from reviews ORDER BY id desc limit 1')
    results = cursor_results(cursor)
    conn.close()

    url = url_for("view_review",
                  id_=results[0]['id'],
                  title=results[0]['title'])

    view_text = ' View it <a href="{}">here</a>.'.format(url)

    flash_message('Your review has been created!' + view_text, 'success')
    return render_template('create_review.html')
def vote():

    review_id = request.args['id']
    up_down = request.args['ud']

    if up_down not in ('0', '1'):
        flash_message('Invalid options.', 'danger')
        return redirect(url_for('home'))

    # TODO: figure out a better way to do this
    # my idea here was to re-route the user to
    # the page they came from
    referrer = request.referrer
    if referrer is None:
        next_url = url_for('home')
    else:
        referrer_parsed = urllib.parse.urlparse(referrer)
        next_url = urllib.parse.urlunparse(
            ('', '', referrer_parsed.path, '', referrer_parsed.query, ''))

    conn, cursor = create_db_conn()
    cursor.execute('select * from votes where review_id = ? and user_id = ?',
                   (review_id, current_user.id))
    results = cursor_results(cursor)
    if len(results) != 0:
        conn.close()
        flash_message("You've already voted on this review.", 'danger')
        return redirect(next_url)

    cursor.execute('insert into votes VALUES (?,?,?,?)',
                   (None, review_id, current_user.id, up_down))
    up_or_down = 'upvotes' if up_down == '1' else 'downvotes'
    cursor.execute(
        """
        update reviews set
        {up_down} = (
            select {up_down} from reviews where id = ?
        ) + 1
        WHERE id = ?
        """.format(up_down=up_or_down), (review_id, review_id))
    conn.commit()
    conn.close()

    flash_message('Your vote has been posted.', 'success')
    return redirect(next_url)
def add_user():
    """A route for creating new users."""
    if request.method == 'GET':
        make_csrf()
        return render_template('add_user.html')
    form_email = request.form['email']
    form_name = request.form['name']
    form_password = request.form['password']

    if not form_email or not form_name or not form_password:
        flash_message('All fields need to be provided.', 'danger')
        return render_template('add_user.html')

    if not verify_csrf():
        return render_template('login.html')

    # TODO: add captcha verification

    # check that the email doesn't already exist
    conn, cursor = create_db_conn()
    cursor.execute('select * from users where email = ?', (form_email, ))
    results = cursor_results(cursor)
    if len(results) != 0:
        conn.close()
        flash_message('Account with that email already exists.', 'danger')
        return render_template('add_user.html')

    # hash the pw
    hashed_pw, salt = create_hash_pw(form_password)

    # add new user to db
    cursor.execute('insert into users VALUES (?,?,?,?,?)',
                   (None, form_name, form_email, hashed_pw, salt))
    conn.commit()
    conn.close()

    flash_message('New account created under {}'.format(form_email), 'success')
    return redirect(url_for('home'))