Skip to content
Permalink
main
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
from main import app
from flask import Flask, session, g, redirect, url_for, render_template, abort, flash, make_response, request
import os
import sqlite3
from functools import wraps
# more extension types can be added to the array
EXTENSIONS = ['jpg', 'png']
BOOK_COVERS = '/home/codio/workspace/main/static/book_covers'
app.config['BOOK_COVERS'] = BOOK_COVERS
# ALWAYS check user session
@app.before_request
def user_logged_in():
user_id = session.get('access_mode')
if user_id is None:
# Session not found
g.user = None
else:
g.user= user_id
# Wrappers allow additional functionality
# Code inspired by https://flask.palletsprojects.com/en/2.0.x/patterns/viewdecorators/
def login_req(view):
@wraps(view)
def wrapped_view(**kwargs):
# if no login
# massive help from https://www.programcreek.com/python/example/100778/flask.g.user
if g.user is None:
# login again
return redirect(url_for('login'))
return view(**kwargs)
# decorated func
return wrapped_view
# Wrapper
# Code inspired by https://flask.palletsprojects.com/en/2.0.x/patterns/viewdecorators/
def admin_req(view):
@wraps(view)
def wrapped_view(**kwargs):
# check if user is admin
if g.user == 'admin':
# display view
return view(**kwargs)
if g.user is None:
return redirect(url_for('login')) # login again
# already logged in?
return redirect(url_for('homepage'))
return wrapped_view
@app.route('/homepage', methods=['GET','POST'])
@login_req
def homepage():
if request.method == 'POST':
# doesnt show stock list unless session user is admin
if request.form['Submit'] == 'STOCK LEVELS':
return redirect(url_for('stock_levels'))
elif request.form['Submit'] == 'LOGOUT':
# Logout therefore remove everything from session
session.clear()
return redirect(url_for('login'))
elif request.form['Submit'] == 'CART':
# View shopping cart function
return redirect(url_for('shopping_cart')) #this function is located in checkout.py file
else:
# Connect to database and get ALL book data for ALL books
con = sqlite3.connect('bookshop_database.db')
cur = con.cursor()
cur.execute("SELECT * FROM books")
# Put into variable
rows = cur.fetchall()
# Render the homepage
return render_template('homepage.html',page=url_for('homepage'),books=rows)
# Add books to stock
@app.route('/homepage/add_book',methods = ['POST'])
def add_book():
_isbn = request.form['isbn']
con = sqlite3.connect('bookshop_database.db')
cur = con.cursor()
# Check if any existing row that has the same primary key (isbn13)
cur.execute("SELECT * FROM books WHERE isbn13=?;", [_isbn])
row = cur.fetchone()
# session['book'] is nested dictionary
book_dict = {row[3]:{'title':row[0],'cover':row[5],'isbn':row[3],'price':row[7],'quantity':1,'total_individual_price' : row[7],'qty_left' : row[8],}}
if 'book' in session:
# If book isbn has already been added to the cart:
if row[3] in session['book']: # (row[3] is isbn number (PRIMARY KEY))
# Quantity of same book + 1
session['book'][row[3]]['quantity'] += 1
# Add retail price to the existing total for that book
session['book'][row[3]]['total_individual_price'] += row[7]
# Update total cost of cart
session['total_price'] += row[7]
# Quantity + 1
session['total_quantity'] += 1
# Book with diff isbn13 number added to cart:
else:
# Add book to session dict
session['book'] = dict(list(session['book'].items())+list(book_dict.items()))
# Price of book added to order
session['total_price'] += row[7]
# Quantity + 1
session['total_quantity'] += 1
else:
# If no book has been added yet (notice quantity is set to 1)
session['book'] = book_dict
session['total_price'] = row[7]
session['total_quantity'] = 1
return redirect(url_for('homepage'))
# Page for viewing stock (admin required)
# Template checks session for admin priviledges before this is run
@app.route('/homepage/stocklist', methods=['GET','POST'])
@admin_req
def stock_levels():
if request.method == 'POST':
# 2 buttons (POST)
if request.form['Submit'] == 'ADD STOCK':
return redirect(url_for('add_stock'))
elif request.form['Submit'] == 'GO BACK':
return redirect(url_for('homepage'))
else:
# list all books from db if method not post (default)
con = sqlite3.connect('bookshop_database.db')
cur = con.cursor()
cur.execute("SELECT * FROM books")
rows = cur.fetchall()
con.close()
return render_template('stock_checker.html', page = url_for('stock_levels'), books = rows)
# Add new books or update if isbn (PK) is the same as existing
@app.route('/homepage/stocklist/add_stock', methods=['GET','POST'])
@admin_req
def add_stock():
if request.method == 'POST':
if request.form['Submit'] == 'SUBMIT':
file = request.files["inpt_file"]
# When file uploaded is true
if file: # if the user had given us a file
# basic function to check if filetype is valid:
if allowed_file(file.filename):
filename = file.filename
# Save img file to book covers folder
file.save(os.path.join(app.config['BOOK_COVERS'],filename))
con = sqlite3.connect('bookshop_database.db')
con.row_factory = lambda cursor, row: row[0]
cur = con.cursor()
# Check if book with same primary key exists
cur.execute("SELECT isbn13 FROM books WHERE isbn13=?",(request.form['isbn'],))
row = cur.fetchall()
# If it does, before we insert we must delete the current row
if len(row) != 0:
cur.execute("DELETE FROM books WHERE isbn13=?",(request.form['isbn'],))
# we add values that we provided in a form into our database
cur.execute("INSERT INTO books VALUES(?,?,?,?,?,?,?,?,?)",(request.form['book_title'],request.form['author'],request.form['pub_date'],request.form['isbn'],request.form['desc'],filename,request.form['trade_price'],request.form['retail_price'],request.form['qnty']))
con.commit()
con.close()
# return to stock page with new stock details added
return redirect(url_for('stock_levels'))
flash('Bad file extension.')
# essentially try again
return redirect(url_for('add_stock'))
# essentially try again
flash('No image uploaded.')
return redirect(url_for('add_stock'))
else:
return render_template('add_edit_stock.html',page=url_for('add_stock'))
# use of rsplit taken from https://flask.palletsprojects.com/en/2.0.x/patterns/fileuploads/
def allowed_file(filename):
# a '.' is required in order for it to be a valid filename
if '.' not in filename:
return False
# if there is a '.' then ANY of the allowed extensions
if filename.rsplit('.', 1)[1].lower() in EXTENSIONS:
return True
return False