Skip to content
Permalink
36ad927061
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
251 lines (188 sloc) 11.6 KB
from flask import flash, Blueprint, request, render_template, url_for, redirect
from .database_models import User, Item # imports user and item class
#ensures no passwords are stored as plain text
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename # allows me to change the uploaded files name
from . import db
from flask_login import login_user, login_required, logout_user, current_user # login management modules
import os
from datetime import datetime, timedelta
import smtplib
routes = Blueprint("routes", __name__) # blueprint allows splitting up routes over several files
# sets where uploaded images are saved and which image extensions are allowed
UPLOAD_FOLDER = "/home/codio/workspace/auction/static/images"
ALLOWED_EXTENSIONS = set(['jpg'])
@routes.route("/", methods=['GET', 'POST'])
#@login_required # requires the user to be logged in to access
def home_page():
items = Item.query.all() # gets all rows of items
users = User.query.all() # gets all rows of items
dt = datetime.now()
return render_template("home_page.html", items=items, user=current_user, users=users, dt=dt) # sends items to the html and keeps track of login status
@routes.route("/login", methods=['GET', 'POST'])
def login(): # users can login to the website using an existing account
if request.method == 'POST':
email = request.form.get("email") # gets values from form
password = request.form.get("password")
user = User.query.filter_by(email = email).first() # checks all the users with the email entered
if user: # if there is an existing user with the corresponding email
if check_password_hash(user.password, password): # hashes password and checks it against the one in the database
login_user(user, remember=True) # remembers the user is logged while the web server is using
return redirect(url_for('routes.home_page')) # redirects the user to the home page
else:
flash("Password incorrect", category="warning") # shows a warning
else:
flash("Account does not exist", category="warning")
return render_template("login.html", user=current_user)
@routes.route("/register", methods=['GET', 'POST'])
def register(): # users can register for a new account, saves new user to the database
if request.method == 'POST':
email = request.form.get("email") # gets data from the form
phone = request.form.get("phone")
username = request.form.get("username")
password = request.form.get("password")
confirm = request.form.get("confirm")
user = User.query.filter_by(email = email).first() # checks all the users with the email entered
if user: # if user already exists
flash("Email used on another account.", category = "warning")
elif password != confirm:
flash("Both passwords must be the same", category = "warning")
elif len(password) <= 5:
flash("Password must be > 5 characters", category = "warning")
else: #add new user to the database
#creates a new User object, and applies a hashing algorithm to the password
new_user = User(email=email, phone=phone, username=username, password=generate_password_hash(password, method='sha256'))
db.session.add(new_user)
db.session.commit() # commits the new user
login_user(new_user, remember=True) # logs in the new user
flash("Account created.", category="success")
return redirect(url_for('routes.home_page'))
return render_template("register.html", user=current_user)
@routes.route("/logout")
@login_required
def logout(): # allows users to logout
logout_user() # remembers that the user has logged out
flash("You are now logged out.", category="success")
return redirect(url_for("routes.home_page")) # redirects user back to the login page
def allowed_file(filename): # checks the image uploaded is of the write extension
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
@routes.route("/sell", methods=['GET', 'POST'])
@login_required
def sell(): # user can enter information about an item they would like to add to the home page in order to sell
if request.method == 'POST':
item_name = request.form.get("item_name") # forms gather information
item_name = item_name.capitalize() # capitalizes name
description = request.form.get("description")
description = description.capitalize()
price = request.form.get("price")
dt = datetime.now()
td = timedelta(days=3)
auction_end = dt + td # gets the auction end time, set to 3 days in the future
#creates a new Item object
new_item = Item(item_name=item_name, description=description, price=price, auction_end=auction_end, user_id=current_user.id)
db.session.add(new_item)
db.session.commit() # commits the new item to the database
item_id = new_item.item_id # gets the current items id
if request.files: # if a file is sent, saves it to the item_image variable
item_image = request.files["item_image"] # gets the file from the form
if allowed_file(item_image.filename): # only allows the file input, and commits to the database, if the image is .jpg
# saves image to the default directory given in the init file, as item_id.fileextension
filename = secure_filename(str(item_id) + ".jpg") # + '.' + item_image.filename.rsplit('.', 1)[1] for other filetypes
item_image.save(os.path.join(UPLOAD_FOLDER, filename)) # saves the file to the specified upload folder
flash("Item added.", category="success")
return redirect(url_for('routes.home_page')) # once item is created redirects to the home page
else:
flash("Invalid filetype.", category="warning")
# if the file uploaded is not a jpg, remove the item from the database
Item.query.filter_by(item_id=item_id).delete()
db.session.commit()
return render_template("sell.html", user=current_user)
@routes.route("/myitems", methods=['GET', 'POST'])
@login_required
def my_items(): # shows items the user has for put sale
length = len(current_user.items) # how many items the user has for sale
dt = datetime.now() # gets the current date and time
if length > 0:
return render_template("my_items.html", user=current_user, dt=dt) # shows the user their items
else: # if the user has no items for sale
return render_template("no_items.html", user=current_user) # tells the user they have nothing for sale
@routes.route("/item/<int:item_id>", methods=['GET', 'POST'])
@login_required
def item_info(item_id): # route shows users a dedicated page for each item, with all its information
user = current_user
users = User.query.all() # gets all users
item = Item.query.filter_by(item_id=item_id).first() # finds the item the user clicked ons information
dt = datetime.now()
# if statements show different html depending on if the item is marked as sold, expired, or still for sale
if item.sold == True:
return render_template("item_sold.html", user=current_user, users=users, item=item)
elif dt > item.auction_end:
return render_template("item_expired.html", user=current_user, users=users, item=item)
elif item.sold == False:
return render_template("item.html", user=current_user, users=users, item=item)
@routes.route("/delete/<int:item_id>", methods=['GET', 'POST'])
@login_required
def item_delete(item_id): # allows a user to delete their item from the website
user = current_user
item = Item.query.filter_by(item_id=item_id).first() # finds the item they clicked on
# prevents another user deleting items they don't own
if item.user_id == user.id: # if the current user is the items owner
Item.query.filter_by(item_id=item_id).delete() # deletes the item
db.session.commit()
flash("Item deleted", category="success")
return redirect(url_for('routes.my_items'))
else:
flash("Unauthorised user", category="warning") # tells the user if they try to delete someone elses item
return redirect(url_for('routes.home_page')) # redirects to the home page
@routes.route("/sold/<int:item_id>", methods=['GET', 'POST'])
@login_required
def sold(item_id): # allows a user to mark an item as sold
user=current_user
item = Item.query.filter_by(item_id=item_id).first() # finds the item they want to mark
# prevents another user marking items they don't own
if item.user_id == user.id: # if the current user is the items owner
item.sold = False
db.session.commit()
else:
flash("Unauthorised user", category="warning") # tells the user if they try to mark someone elses item
return redirect(url_for('routes.home_page')) # redirects to the home page
winner = User.query.filter_by(id=item.sold_to).first()
if item.sold_to > 0:
notify_winner(winner, item) # sends an email to the winner
return redirect(url_for('routes.my_items')) # redirects to the home page
@routes.route("/bid/<int:item_id>", methods=['GET', 'POST'])
@login_required
def bid(item_id): # allows a user to bid on an item
user = current_user
item = Item.query.filter_by(item_id=item_id).first()
if item.sold_to == 0: # if this is the first bid
new_bid = request.form.get("new_bid") # gets the bid from the form
item.current_bid = new_bid # sets the values in the database = to the new values
item.sold_to = user.id
db.session.commit() # updates the database
else: # if the item has been bid on before
outbid_user = User.query.filter_by(id=item.sold_to).first()
notify_outbid(outbid_user, item) # emails the person being outbid
new_bid = request.form.get("new_bid") # gets the bid from the form
item.current_bid = new_bid # sets the values in the database = to the new values
item.sold_to = user.id
db.session.commit()
return redirect(url_for('routes.item_info', item_id=item.item_id)) # redirects to the home page
def notify_winner(winner, item): # emails a user if they win an auction
subj = "You won an auction!"
body = "Hey {}!".format(winner.username)
body += "\nYou just won the {} auction!".format(item.item_name) # not allowing me to send an email with a link in it, coming in blank
send_email("pythonflaskemail@gmail.com", winner.email, subj, body) # changed reciever to reduce spam when testing
def notify_outbid(user, item): # emails a user if they are outbid
subj = "You were just outbid!"
body = "Hey {}!".format(user.username)
body += "\nYou just got outbid on the {} auction!".format(item.item_name) # wont allow me to put a link in the email
send_email("pythonflaskemail@gmail.com", user.email, subj, body)
def send_email(sender, reciever, subj, message): # sends the email using smtplib module
password = "Python150*"
msg = "From: %s\nTo: %s\nSubject: %s\n\n%s" % ( sender, reciever, subj, message )
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login(sender, password)
server.sendmail(sender, "josephlees79@gmail.com", msg)