Repository: hamzaavvan/library-management-system Branch: master Commit: e784a1866964 Files: 46 Total size: 61.1 KB Directory structure: gitextract_ihduwk7h/ ├── .gitignore ├── App/ │ ├── Actor.py │ ├── Admin.py │ ├── Books.py │ ├── User.py │ └── __init__.py ├── Controllers/ │ ├── AdminManager.py │ ├── BookManager.py │ ├── UserManager.py │ └── __init__.py ├── Misc/ │ └── functions.py ├── Models/ │ ├── AdminDAO.py │ ├── BookDAO.py │ ├── DAO.py │ ├── DB.py │ ├── DBDAO.py │ ├── UserDAO.py │ └── __init__.py ├── README.md ├── app.py ├── db/ │ └── lms.sql ├── info.md ├── requirements.txt ├── routes/ │ ├── __init__.py │ ├── admin.py │ ├── book.py │ └── user.py ├── run ├── static/ │ ├── home.css │ └── style.css └── templates/ ├── admin/ │ ├── books/ │ │ ├── add.html │ │ ├── book_view.html │ │ ├── edit.html │ │ └── views.html │ ├── home.html │ ├── signin.html │ └── users.html ├── book_view.html ├── books.html ├── home.html ├── profile.html ├── shared/ │ ├── admin_layout.html │ └── layout.html ├── signin.html ├── signup.html └── welcome.html ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .fuse* *.pyc __*__ ================================================ FILE: App/Actor.py ================================================ from functools import wraps from flask import g, request, redirect, session class Actor(): sess_key = "" route_url = "/" def uid(self): if self.isLoggedIn(): return session[self.sess_key] return "err" def set_session(self, session, g): g.user = 0 if self.isLoggedIn(): g.user = session[self.sess_key] def isLoggedIn(self): if self.sess_key in session and session[self.sess_key] and session[self.sess_key]>0: return True return False def login_required(self, f, path="signin"): @wraps(f) def decorated_function(*args, **kwargs): if self.sess_key not in session or session[self.sess_key] is None: print(path) return redirect(self.route_url+path) return f(*args, **kwargs) return decorated_function def redirect_if_login(self, f, path="/"): @wraps(f) def decorated_function(*args, **kwargs): if self.sess_key in session and session[self.sess_key] is not None: return redirect(self.route_url+path) return f(*args, **kwargs) return decorated_function def signout(self): session[self.sess_key] = None def signin(self): pass ================================================ FILE: App/Admin.py ================================================ from App.Actor import Actor class Admin(Actor): admin = {} def __init__(self, AdminDAO): self.sess_key = "admin" self.dao = AdminDAO self.route_url = "/admin/" ================================================ FILE: App/Books.py ================================================ class Books(): id = 0 name = "" edition = "" year = "" count = 0 availability = False course = {} def __init__(self, BookDAO): self.dao = BookDAO ================================================ FILE: App/User.py ================================================ from App.Actor import Actor class User(Actor): id = 0 name = "" lock = False user = {} def __init__(self, UserDAO): self.dao = UserDAO self.sess_key = "user" # session key ================================================ FILE: App/__init__.py ================================================ ================================================ FILE: Controllers/AdminManager.py ================================================ from App.Admin import Admin class AdminManager(): def __init__(self, DAO): self.admin = Admin(DAO.db.admin) self.user = DAO.db.user self.dao = self.admin.dao def signin(self, email, password): admin = self.dao.getByEmail(email) if admin is None: return False admin_pass = admin["password"] # admin pass at if admin_pass != password: return False return admin def get(self, id): admin = self.dao.getById(id) return admin def getUsersList(self): admin = self.user.list() print(admin) return admin def signout(self): self.admin.signout() def user_list(self): return self.user.list() ================================================ FILE: Controllers/BookManager.py ================================================ from App.Books import Books class BookManager(): def __init__(self, DAO): self.misc = Books(DAO.db.book) self.dao = self.misc.dao def list(self, availability=1,user_id=None): if user_id!= None: book_list = self.dao.listByUser(user_id) else: book_list = self.dao.list(availability) return book_list def getReserverdBooksByUser(self, user_id): books = self.dao.getReserverdBooksByUser(user_id) return books def getBook(self, id): books = self.dao.getBook(id) return books def search(self, keyword, availability=1): books = self.dao.search_book(keyword, availability) return books def reserve(self, user_id, book_id): books = self.dao.reserve(user_id, book_id) return books def getUserBooks(self, user_id): books = self.dao.getBooksByUser(user_id) return books def getUserBooksCount(self, user_id): books = self.dao.getBooksCountByUser(user_id) return books def delete(self, id): self.dao.delete(id) ================================================ FILE: Controllers/UserManager.py ================================================ from App.User import User class UserManager(): def __init__(self, DAO): self.user = User(DAO.db.user) self.book = DAO.db.book self.dao = self.user.dao def list(self): user_list = self.dao.list() return user_list def signin(self, email, password): user = self.dao.getByEmail(email) if user is None: return False user_pass = user['password'] # user pass at if user_pass != password: return False return user def signout(self): self.user.signout() def get(self, id): user = self.dao.getById(id) return user def signup(self, name, email, password): user = self.dao.getByEmail(email) if user is not None: return "already_exists" user_info = {"name": name, "email": email, "password": password} new_user = self.dao.add(user_info) return new_user def get(self, id): user = self.dao.getById(id) return user def update(self, name, email, password, bio, id): user_info = {"name": name, "email": email, "password": password, "bio":bio} user = self.dao.update(user_info, id) return user def getBooksList(self, id): return self.book.getBooksByUser(id) def getUsersByBook(self, book_id): return self.dao.getUsersByBook(book_id) ================================================ FILE: Controllers/__init__.py ================================================ ================================================ FILE: Misc/functions.py ================================================ import hashlib, binascii import timeago, datetime salt=b'$#0x--.\'/\\98' def hash(string): dk = hashlib.pbkdf2_hmac('sha256', b'password', salt, 100000) return binascii.hexlify(dk).decode("utf-8") def b_hash(string): dk = hashlib.pbkdf2_hmac('sha256', b'password', salt, 100000) return binascii.hexlify(dk) def ago(date): """ Calculate a '3 hours ago' type string from a python datetime. """ now = datetime.datetime.now() + datetime.timedelta(seconds = 60 * 3.4) return (timeago.format(date, now)) # will print x secs/hours/minutes ago ================================================ FILE: Models/AdminDAO.py ================================================ class AdminDAO(): db = {} def __init__(self, DAO): self.db = DAO self.db.table = "admin" def getById(self, id): q = self.db.query("select * from @table where id='{}'".format(id)) user = q.fetchone() return user def getByEmail(self, email): q = self.db.query("select * from @table where email='{}'".format(email)) user = q.fetchone() return user ================================================ FILE: Models/BookDAO.py ================================================ class BookDAO(): def __init__(self, DAO): self.db = DAO self.db.table = "books" def delete(self, id): q = self.db.query("DELETE FROM @table where id={}".format(id)) self.db.commit() return q def reserve(self, user_id, book_id): if not self.available(book_id): return "err_out" q = self.db.query("INSERT INTO reserve (user_id, book_id) VALUES('{}', '{}');".format(user_id, book_id)) self.db.query("UPDATE @table set count=count-1 where id={};".format(book_id)) self.db.commit() return q def getBooksByUser(self, user_id): q = self.db.query("select * from @table left join reserve on reserve.book_id = @table.id where reserve.user_id={}".format(user_id)) books = q.fetchall() print(books) return books def getBooksCountByUser(self, user_id): q = self.db.query("select count(reserve.book_id) as books_count from @table left join reserve on reserve.book_id = @table.id where reserve.user_id={}".format(user_id)) books = q.fetchall() print(books) return books def getBook(self, id): q = self.db.query("select * from @table where id={}".format(id)) book = q.fetchone() print(book) return book def available(self, id): book = self.getById(id) count = book['count'] if count < 1: return False return True def getById(self, id): q = self.db.query("select * from @table where id='{}'".format(id)) book = q.fetchone() return book def list(self, availability=1): query="select * from @table" # Usually when no-admin user query for book if availability==1: query= query+" WHERE availability={}".format(availability) books = self.db.query(query) books = books.fetchall() return books def getReserverdBooksByUser(self, user_id): query="select concat(book_id,',') as user_books from reserve WHERE user_id={}".format(user_id) books = self.db.query(query) books = books.fetchone() return books def search_book(self, name, availability=1): query="select * from @table where name LIKE '%{}%'".format(name) # Usually when no-admin user query for book if availability==1: query= query+" AND availability={}".format(availability) q = self.db.query(query) books = q.fetchall() return books ================================================ FILE: Models/DAO.py ================================================ from Models.DBDAO import DBDAO class DAO(): def __init__(self, app): self.db = DBDAO(app) ================================================ FILE: Models/DB.py ================================================ from flaskext.mysql import MySQL from pymysql.cursors import DictCursor class DB(object): """Initialize mysql database """ host = "localhost" user = "root" password = "" db = "lms" table = "" def __init__(self, app): app.config["MYSQL_DATABASE_HOST"] = self.host; app.config["MYSQL_DATABASE_USER"] = self.user; app.config["MYSQL_DATABASE_PASSWORD"] = self.password; app.config["MYSQL_DATABASE_DB"] = self.db; self.mysql = MySQL(app, cursorclass=DictCursor) def cur(self): return self.mysql.get_db().cursor() def query(self, q): h = self.cur() if (len(self.table)>0): q = q.replace("@table", self.table) h.execute(q) return h def commit(self): self.query("COMMIT;") ================================================ FILE: Models/DBDAO.py ================================================ from copy import copy from Models.BookDAO import BookDAO from Models.UserDAO import UserDAO from Models.AdminDAO import AdminDAO from Models.DB import DB class DBDAO(DB): def __init__(self, app): super(DBDAO, self).__init__(app) self.book = BookDAO(copy(self)) self.user = UserDAO(copy(self)) self.admin = AdminDAO(copy(self)) ================================================ FILE: Models/UserDAO.py ================================================ class UserDAO(): def __init__(self, DAO): self.db = DAO self.db.table = "users" def list(self): users = self.db.query("select @table.id,@table.name,@table.email,@table.bio,@table.mob,@table.lock,@table.created_at,count(reserve.book_id) as books_owned from @table LEFT JOIN reserve ON reserve.user_id=@table.id GROUP BY reserve.user_id").fetchall() return users def getById(self, id): q = self.db.query("select * from @table where id='{}'".format(id)) user = q.fetchone() return user def getUsersByBook(self, book_id): q = self.db.query("select * from @table LEFT JOIN reserve ON reserve.user_id = @table.id WHERE reserve.book_id={}".format(book_id)) user = q.fetchall() return user def getByEmail(self, email): q = self.db.query("select * from @table where email='{}'".format(email)) user = q.fetchone() return user def add(self, user): name = user['name'] email = user['email'] password = user['password'] q = self.db.query("INSERT INTO @table (name, email, password) VALUES('{}', '{}', '{}');".format(name, email, password)) self.db.commit() return q def update(self, user, _id): name = user['name'] email = user['email'] password = user['password'] bio = user['bio'] q = self.db.query("UPDATE @table SET name = '{}', email='{}', password='{}', bio='{}' WHERE id={}".format(name, email, password, bio, _id)) self.db.commit() return q ================================================ FILE: Models/__init__.py ================================================ ================================================ FILE: README.md ================================================ # Library Management System A simple flask app to manage users along with mysql service ![Libray Management App - Flask](https://github.com/hamzaavvan/library-management-system/blob/master/ss/ss2.JPG?raw=true) ## Installation To run the app flawlessly, satisfy the requirements ```bash $ pip install -r requirements.txt ``` ## Set Environment Variables ```bash $ export FLASK_APP=app.py $ export FLASk_ENV=development ``` ## Start Server ```bash $ flask run ``` Or run this command ```bash $ python -m flask run ``` ================================================ FILE: app.py ================================================ from flask import Flask, g, escape, session, redirect, render_template, request, jsonify, Response from Misc.functions import * app = Flask(__name__) app.secret_key = '#$ab9&^BB00_.' # Setting DAO Class from Models.DAO import DAO DAO = DAO(app) # Registering blueprints from routes.user import user_view from routes.book import book_view from routes.admin import admin_view # Registering custom functions to be used within templates app.jinja_env.globals.update( ago=ago, str=str, ) app.register_blueprint(user_view) app.register_blueprint(book_view) app.register_blueprint(admin_view) ================================================ FILE: db/lms.sql ================================================ -- phpMyAdmin SQL Dump -- version 4.8.5 -- https://www.phpmyadmin.net/ -- -- Host: 127.0.0.1 -- Generation Time: Feb 06, 2022 at 01:24 PM -- Server version: 10.1.38-MariaDB -- PHP Version: 7.3.3 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET AUTOCOMMIT = 0; START TRANSACTION; SET time_zone = "+00:00"; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; -- -- Database: `lms` -- -- -------------------------------------------------------- -- -- Table structure for table `admin` -- CREATE TABLE `admin` ( `id` int(11) NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(1000) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -- Dumping data for table `admin` -- INSERT INTO `admin` (`id`, `email`, `password`) VALUES (1, 'hamza@gmail.com', '025db420560617303c2ba988d050ec62562343bc0fb0358d31d2f0bae8dbede8'); -- -------------------------------------------------------- -- -- Table structure for table `books` -- CREATE TABLE `books` ( `id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `desc` longtext NOT NULL, `author` varchar(255) NOT NULL, `availability` tinyint(1) NOT NULL, `edition` varchar(255) NOT NULL, `count` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -- Dumping data for table `books` -- INSERT INTO `books` (`id`, `name`, `desc`, `author`, `availability`, `edition`, `count`) VALUES (1, '101 Ways To Be A Software Engineer', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut repudiandae assumenda distinctio quas tempore, voluptatibus accusamus dolores temporibus, recusandae eligendi similique. Optio, eius? Sint vel nemo, quisquam architecto fugit odio!', 'Mr. Johnny Test', 1, '1', 3), (2, 'JAVA For Absolute Beginners', 'Step into the basics of java programmming along with globally famed programmer', '', 1, '1', 5); -- -------------------------------------------------------- -- -- Table structure for table `reserve` -- CREATE TABLE `reserve` ( `id` int(11) NOT NULL, `user_id` int(11) NOT NULL, `book_id` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -- Dumping data for table `reserve` -- INSERT INTO `reserve` (`id`, `user_id`, `book_id`) VALUES (1, 1, 1), (2, 6, 1); -- -------------------------------------------------------- -- -- Table structure for table `users` -- CREATE TABLE `users` ( `id` int(11) NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL, `email` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL, `password` varchar(1000) COLLATE utf8mb4_unicode_520_ci NOT NULL, `bio` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, `mob` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL, `lock` tinyint(1) NOT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; -- -- Dumping data for table `users` -- INSERT INTO `users` (`id`, `name`, `email`, `password`, `bio`, `mob`, `lock`, `created_at`) VALUES (1, 'Hamza', 'hamza@gmail.com', '025db420560617303c2ba988d050ec62562343bc0fb0358d31d2f0bae8dbede8', 'They watch you from the shelf while you sleep 👀. Are you dreaming of them, they wonder, in that wistful mood books are prone to at night when they’re bored and there’s nothing else to do but tease the cat.?', '', 0, '2021-11-09 00:00:00'), (6, 'Naveed Ali', 'naveed@gmail.com', '025db420560617303c2ba988d050ec62562343bc0fb0358d31d2f0bae8dbede8', 'Hi :)! Long time no see ❤️', '', 0, '2021-11-18 23:07:53'); -- -- Indexes for dumped tables -- -- -- Indexes for table `admin` -- ALTER TABLE `admin` ADD PRIMARY KEY (`id`); -- -- Indexes for table `books` -- ALTER TABLE `books` ADD PRIMARY KEY (`id`); -- -- Indexes for table `reserve` -- ALTER TABLE `reserve` ADD PRIMARY KEY (`id`); -- -- Indexes for table `users` -- ALTER TABLE `users` ADD PRIMARY KEY (`id`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `admin` -- ALTER TABLE `admin` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2; -- -- AUTO_INCREMENT for table `books` -- ALTER TABLE `books` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; -- -- AUTO_INCREMENT for table `reserve` -- ALTER TABLE `reserve` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; -- -- AUTO_INCREMENT for table `users` -- ALTER TABLE `users` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7; COMMIT; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; ================================================ FILE: info.md ================================================ http://www.utm.mx/~caff/doc/OpenUPWeb/openup/guidances/guidelines/entity_control_boundary_pattern_C4047897.html An example of an entity for a customer service application is a Customer entity that manages all information about a customer. **A design element for this entity would include data about the customer, behavior to manage the data, behavior to validate customer information and to perform other business calculations, such as "Is this customer allowed to purchase product X?"** ================================================ FILE: requirements.txt ================================================ flask==2.3.2 flask-mysql==1.5.2 timeago==1.0.15 ================================================ FILE: routes/__init__.py ================================================ ================================================ FILE: routes/admin.py ================================================ from flask import Blueprint, g, escape, session, redirect, render_template, request, jsonify, Response from app import DAO from Misc.functions import * from Controllers.AdminManager import AdminManager from Controllers.BookManager import BookManager from Controllers.UserManager import UserManager admin_view = Blueprint('admin_routes', __name__, template_folder='../templates/admin/', url_prefix='/admin') book_manager = BookManager(DAO) user_manager = UserManager(DAO) admin_manager = AdminManager(DAO) @admin_view.route('/', methods=['GET']) @admin_manager.admin.login_required def home(): admin_manager.admin.set_session(session, g) return render_template('admin/home.html', g=g) @admin_view.route('/signin/', methods=['GET', 'POST']) @admin_manager.admin.redirect_if_login def signin(): g.bg = 1 if request.method == 'POST': _form = request.form email = str(_form["email"]) password = str(_form["password"]) if len(email)<1 or len(password)<1: return render_template('admin/signin.html', error="Email and password are required") d = admin_manager.signin(email, hash(password)) if d and len(d)>0: session['admin'] = int(d["id"]) return redirect("/admin") return render_template('admin/signin.html', error="Email or password incorrect") return render_template('admin/signin.html') @admin_view.route('/signout/', methods=['GET']) @admin_manager.admin.login_required def signout(): admin_manager.signout() return redirect("/admin/", code=302) @admin_view.route('/users/view/', methods=['GET']) @admin_manager.admin.login_required def users_view(): admin_manager.admin.set_session(session, g) id = int(admin_manager.admin.uid()) admin = admin_manager.get(id) myusers = admin_manager.getUsersList() return render_template('users.html', g=g, admin=admin, users=myusers) @admin_view.route('/books/', methods=['GET']) @admin_manager.admin.login_required def books(): admin_manager.admin.set_session(session, g) id = int(admin_manager.admin.uid()) admin = admin_manager.get(id) mybooks = book_manager.list(availability=0) return render_template('books/views.html', g=g, books=mybooks, admin=admin) @admin_view.route('/books/') @admin_manager.admin.login_required def view_book(id): admin_manager.admin.set_session(session, g) if id != None: b = book_manager.getBook(id) users = user_manager.getUsersByBook(id) print('----------------------------') print(users) if b and len(b) <1: return render_template('books/book_view.html', error="No book found!") return render_template("books/book_view.html", books=b, books_owners=users, g=g) @admin_view.route('/books/add', methods=['GET', 'POST']) @admin_manager.admin.login_required def book_add(): admin_manager.admin.set_session(session, g) return render_template('books/add.html', g=g) @admin_view.route('/books/edit/', methods=['GET', 'POST']) @admin_manager.admin.login_required def book_edit(id): admin_manager.admin.set_session(session, g) if id != None: b = book_manager.getBook(id) if b and len(b) <1: return render_template('edit.html', error="No book found!") return render_template("books/edit.html", book=b, g=g) return redirect('/books') @admin_view.route('/books/delete/', methods=['GET']) @admin_manager.admin.login_required def book_delete(id): id = int(id) if id is not None: book_manager.delete(id) return redirect('/admin/books/') @admin_view.route('/books/search', methods=['GET']) def search(): admin_manager.admin.set_session(session, g) if "keyword" not in request.args: return render_template("books/view.html") keyword = request.args["keyword"] if len(keyword)<1: return redirect('/admin/books') id = int(admin_manager.admin.uid()) admin = admin_manager.get(id) d=book_manager.search(keyword, 0) if len(d) >0: return render_template("books/views.html", search=True, books=d, count=len(d), keyword=escape(keyword), g=g, admin=admin) return render_template('books/views.html', error="No books found!", keyword=escape(keyword)) ================================================ FILE: routes/book.py ================================================ from flask import Blueprint, g, escape, session, redirect, render_template, request, jsonify, Response from app import DAO from Controllers.UserManager import UserManager from Controllers.BookManager import BookManager book_view = Blueprint('book_routes', __name__, template_folder='/templates') book_manager = BookManager(DAO) user_manager = UserManager(DAO) @book_view.route('/books/', defaults={'id': None}) @book_view.route('/books/') def home(id): user_manager.user.set_session(session, g) if id != None: b = book_manager.getBook(id) print('----------------------------') print(b) user_books={} if user_manager.user.isLoggedIn(): user_books = book_manager.getReserverdBooksByUser(user_id=user_manager.user.uid())['user_books'].split(',') if b and len(b) <1: return render_template('book_view.html', error="No book found!") return render_template("book_view.html", books=b, g=g, user_books=user_books) else: b = book_manager.list() user_books=[] if user_manager.user.isLoggedIn(): reserved_books = book_manager.getReserverdBooksByUser(user_id=user_manager.user.uid()) if reserved_books is not None: user_books = reserved_books['user_books'].split(',') print("---------------------------------------") print(user_books) if b and len(b) <1: return render_template('books.html', error="No books found!") return render_template("books.html", books=b, g=g, user_books=user_books) return render_template("books.html", books=b, g=g) @book_view.route('/books/add/', methods=['GET']) @user_manager.user.login_required def add(id): user_id = user_manager.user.uid() book_manager.reserve(user_id, id) b = book_manager.list() user_manager.user.set_session(session, g) return render_template("books.html", msg="Book reserved", books=b, g=g) @book_view.route('/books/search', methods=['GET']) def search(): user_manager.user.set_session(session, g) if "keyword" not in request.args: return render_template("search.html") keyword = request.args["keyword"] if len(keyword)<1: return redirect('/books') d=book_manager.search(keyword) if len(d) >0: return render_template("books.html", search=True, books=d, count=len(d), keyword=escape(keyword), g=g) return render_template('books.html', error="No books found!", keyword=escape(keyword)) ================================================ FILE: routes/user.py ================================================ from flask import Blueprint, g, escape, session, redirect, render_template, request, jsonify, Response, flash from app import DAO from Misc.functions import * from Controllers.UserManager import UserManager user_view = Blueprint('user_routes', __name__, template_folder='/templates') user_manager = UserManager(DAO) @user_view.route('/', methods=['GET']) def home(): g.bg = 1 user_manager.user.set_session(session, g) print(g.user) return render_template('home.html', g=g) @user_view.route('/signin', methods=['GET', 'POST']) @user_manager.user.redirect_if_login def signin(): if request.method == 'POST': _form = request.form email = str(_form["email"]) password = str(_form["password"]) if len(email)<1 or len(password)<1: return render_template('signin.html', error="Email and password are required") d = user_manager.signin(email, hash(password)) if d and len(d)>0: session['user'] = int(d['id']) return redirect("/") return render_template('signin.html', error="Email or password incorrect") return render_template('signin.html') @user_view.route('/signup', methods=['GET', 'POST']) @user_manager.user.redirect_if_login def signup(): if request.method == 'POST': name = request.form.get('name') email = request.form.get('email') password = request.form.get('password') if len(name) < 1 or len(email)<1 or len(password)<1: return render_template('signup.html', error="All fields are required") new_user = user_manager.signup(name, email, hash(password)) if new_user == "already_exists": return render_template('signup.html', error="User already exists with this email") return render_template('signup.html', msg = "You've been registered!") return render_template('signup.html') @user_view.route('/signout/', methods=['GET']) @user_manager.user.login_required def signout(): user_manager.signout() return redirect("/", code=302) @user_view.route('/user/', methods=['GET']) @user_manager.user.login_required def show_user(id=None): user_manager.user.set_session(session, g) if id is None: id = int(user_manager.user.uid()) d = user_manager.get(id) mybooks = user_manager.getBooksList(id) return render_template("profile.html", user=d, books=mybooks, g=g) @user_view.route('/user', methods=['POST']) @user_manager.user.login_required def update(): user_manager.user.set_session(session, g) _form = request.form name = str(_form["name"]) email = str(_form["email"]) password = str(_form["password"]) bio = str(_form["bio"]) user_manager.update(name, email, hash(password), bio, user_manager.user.uid()) flash('Your info has been updated!') return redirect("/user/") ================================================ FILE: run ================================================ #!/bin/bash export FLASK_APP=app.py export FLASK_ENV=development service mysql start flask run ================================================ FILE: static/home.css ================================================ .welcome { margin: 0 auto; } .welcome h1 { font-size: 3.5em; } ================================================ FILE: static/style.css ================================================ @import url('https://fonts.googleapis.com/css2?family=Josefin+Sans:wght@100&family=Montserrat:wght@100;300&display=swap');/*! * Bootstrap v3.3.7 (http://getbootstrap.com) * Copyright 2011-2016 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ html, h1,h2,h3,h3,h5,h6 { font-family: 'Montserrat', sans-serif; font-family: sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } h1, h2, h3, h4 { -webkit-font-smoothing: antialiased; } .home { background-image: url("/static/images/bg.jpg"); background-repeat: no-repeat; background-size: cover; background-position: 0 9.5em; } .book { width: 18rem; display: inline-block; margin-right: 15px; margin-bottom: 25px !important; } .book .card-title { font-family: inherit !important; } #photo { margin: 0 auto; display: block; } .pwrapper { margin-top: 5em; } .pwrapper div { box-shadow: 0px 0px 0px #666; } .mwrapper { padding: 0 !important; } .bwrapper.card { border: 0 !important; } .profile.container { max-width: 1181px !important; } .bookdesc{ -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; } ================================================ FILE: templates/admin/books/add.html ================================================ {%extends "/shared/admin_layout.html" %} {% block title %}Manage Books - Add{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block content %}

Add Book

Members will be able to search using title!
Book will not be shown to members if unchecked!
{% endblock %} ================================================ FILE: templates/admin/books/book_view.html ================================================ {%extends "/shared/admin_layout.html" %} {% block title %}Book - {{books['name']}} {% endblock %} {% block content %}
{% if msg %}
{{msg}}
{% endif %}
{% if books %}
{{books[1]}} Edit Delete

Avaliable On:

{{books['name']}}

{% if books['availability'] < 1 %} Assigned {% endif %}

{{books['desc']}}

Author: {{books['author']}}

{% if books['count'] > 0%} Books Left: {{books['count']}} {% else %} All gone {% endif %}

{% if books_owners %}

Book Owner(s)

{% for user in books_owners %}

{{user['name']}}

{% endfor %}
{% endif %}
{% else %}

No Book Found!

{% endif %}
{% endblock %} ================================================ FILE: templates/admin/books/edit.html ================================================ {%extends "/shared/admin_layout.html" %} {% block title %}Manage Books - Edit {{book['name']}}{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block content %}

Edit

"{{book['name']}}"

Members will be able to search using title!
Book will not be shown to members if unchecked!
{% endblock %} ================================================ FILE: templates/admin/books/views.html ================================================ {%extends "/shared/admin_layout.html" %} {% block title %}Manage Books - View {% endblock %} {% block content %}
{% if msg %}
{{msg}}
{% endif %}

Manage Books

{% if books %} {% for book in books %}
{{book[1]}}
{{book['name']}}
{% if book["availability"] < 1 %} Assigned {% endif %}

{{book["desc"]}}

{% if book["count"] > 0%} Books Left: {{book['count']}} {% else %} All gone {% endif %}

Edit Delete
{% endfor %} {% else %}

No Books In Stash!

{% endif %}
{% endblock %} ================================================ FILE: templates/admin/home.html ================================================ {%extends "/shared/admin_layout.html" %} {% block title %}Admin Home{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block content %}

WELCOME

Available books will be shown to members.
{% endblock %} ================================================ FILE: templates/admin/signin.html ================================================ {%extends "/shared/admin_layout.html" %} {% block title %}Admin Signin{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block content %}

ADMIN SIGNIN

{% if error %}
{{error}}
{% endif %}
We'll never share your email with anyone else.
{% endblock %} ================================================ FILE: templates/admin/users.html ================================================ {%extends "/shared/admin_layout.html" %} {% block title %}Manage Users {% endblock %} {% block content %} {% endblock %} ================================================ FILE: templates/book_view.html ================================================ {%extends "/shared/layout.html" %} {% block title %}Book - {{books['name']}} {% endblock %} {% block content %}
{% if msg %}
{{msg}}
{% endif %}
{% if books %}

{{books['name']}}

{% if books['availability'] < 1 %} Assigned {% endif %}

{{books['desc']}}

Author: {{books['author']}}

{% if books['count'] > 0%} Books Left: {{books['count']}} {% else %} All gone {% endif %}

{% else %}

No Book Found!

{% endif %}
{% endblock %} ================================================ FILE: templates/books.html ================================================ {%extends "/shared/layout.html" %} {% block title %}Books{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block content %}
{% if msg %}
{{msg}}
{% endif %}
{% if books %} {% if search %}

Search Found ({{count}})

{% endif %} {% for book in books %}
{{book[1]}}
{{book['name']}}
{% if book['availability'] < 1 %} Assigned {% endif %}

{{book['desc']}}

{% if book['count'] > 0%} Books Left: {{book['count']}} {% else %} All gone {% endif %}

{% if book['count'] > 0 %} {{ 'Added' if str(book['id']) in user_books else 'Add' }} {% endif %}
{% endfor %} {% else %}

No Books Found!

Please contact the librarian

{% endif %}
{% endblock %} ================================================ FILE: templates/home.html ================================================ {%extends "/shared/layout.html" %} {% block title %}Home{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block content %}

WELCOME

Available books will be shown to members.
{% endblock %} ================================================ FILE: templates/profile.html ================================================ {%extends "/shared/layout.html" %} {% block title %}Profile - {{user['name']}} {% endblock %} {% block content %}
{% with messages = get_flashed_messages() %} {% if messages %}
{% for message in messages %} {{ message }} {% endfor %}
{% endif %} {% endwith %}
{{user['name']}}

{{user['bio']}}


Joined: {{ago(user['created_at'])}}

{% if books %}
{% for book in books %}
{{book[1]}}
{{book['name']}}
{% if book['availability'] < 1 %} Assigned {% endif %}

Author: {{book['author']}}

{% endfor %} {% else %}

Manage Books

No Books You Reserved!

{% endif %}

Manage Account

One Account For Everything

{% endblock %} ================================================ FILE: templates/shared/admin_layout.html ================================================ {%block head %} {% block title %}{% endblock %} {% endblock %}
{%block content %}{% endblock %}
================================================ FILE: templates/shared/layout.html ================================================ {%block head %} {% block title %}{% endblock %} {% endblock %}
{%block content %}{% endblock %}
================================================ FILE: templates/signin.html ================================================ {%extends "/shared/layout.html" %} {% block title %}Signin{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block content %}

SIGNIN

{% if error %}
{{error}}
{% endif %}
We'll never share your email with anyone else.
{% endblock %} ================================================ FILE: templates/signup.html ================================================ {%extends "/shared/layout.html" %} {% block title %}Signup{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block content %}

SIGNUP

{% if msg %}
{{msg}}
{% endif %} {% if error %}
{{error}}
{% endif %}
We'll never share your email with anyone else.
{% endblock %} ================================================ FILE: templates/welcome.html ================================================ welcome.html