From d36699bd1f55079b66731d01f28de2510f8d0ce5 Mon Sep 17 00:00:00 2001 From: Fluffy-Bean Date: Wed, 12 Apr 2023 15:16:43 +0000 Subject: [PATCH] Update database Correctly link user to their posts and groups Change the table names to Group, Post and User Remove unused Bans and Logs table, possibly will return later --- gallery/__init__.py | 6 +- gallery/api.py | 59 +++++-------- gallery/auth.py | 8 +- gallery/models.py | 156 +++++++++++++--------------------- gallery/templates/group.html | 10 +-- gallery/templates/image.html | 6 +- gallery/templates/layout.html | 100 +++++++++++----------- gallery/templates/list.html | 2 +- gallery/views/group.py | 51 ++++------- gallery/views/image.py | 40 ++++----- gallery/views/index.py | 11 ++- gallery/views/profile.py | 6 +- 12 files changed, 185 insertions(+), 270 deletions(-) diff --git a/gallery/__init__.py b/gallery/__init__.py index 32d8b6b..1ecd6d0 100644 --- a/gallery/__init__.py +++ b/gallery/__init__.py @@ -17,8 +17,8 @@ from werkzeug.exceptions import HTTPException from werkzeug.security import generate_password_hash from gallery.extensions import db, migrate, login_manager, assets, compress, cache -from gallery.models import Users from gallery.views import index, image, group, settings, profile +from gallery.models import User from gallery import api from gallery import auth @@ -44,7 +44,7 @@ def create_app(): # pylint: disable=R0914 with app.app_context(): db.create_all() - register_user = Users( + register_user = User( username=app.config["ADMIN_CONF"]["username"], email=app.config["ADMIN_CONF"]["email"], password=generate_password_hash('changeme!', method="sha256"), @@ -81,7 +81,7 @@ def create_app(): # pylint: disable=R0914 @login_manager.user_loader def load_user(user_id): - return Users.query.filter_by(alt_id=user_id).first() + return User.query.filter_by(alt_id=user_id).first() @login_manager.unauthorized_handler def unauthorized(): diff --git a/gallery/api.py b/gallery/api.py index 0c97e39..a21d026 100644 --- a/gallery/api.py +++ b/gallery/api.py @@ -14,7 +14,7 @@ from flask_login import login_required, current_user from colorthief import ColorThief from gallery.extensions import db -from gallery.models import Posts, Groups, GroupJunction +from gallery.models import Post, Group, GroupJunction from gallery.utils import metadata as mt from gallery.utils.generate_image import generate_thumbnail @@ -83,7 +83,7 @@ def upload(): img_colors = ColorThief(img_path).get_palette(color_count=3) # Get color palette # Save to database - query = Posts( + query = Post( author_id=current_user.id, filename=img_name + "." + img_ext, mimetype=img_ext, @@ -105,39 +105,33 @@ def delete_image(image_id): """ Deletes an image from the server and database """ - img = Posts.query.filter_by(id=image_id).first() + post = Post.query.filter_by(id=image_id).first() # Check if image exists and if user is allowed to delete it (author) - if img is None: + if post is None: abort(404) - if img.author_id != current_user.id: + if post.author_id != current_user.id: abort(403) # Delete file try: - os.remove(os.path.join(current_app.config["UPLOAD_FOLDER"], img.filename)) + os.remove(os.path.join(current_app.config["UPLOAD_FOLDER"], post.filename)) except FileNotFoundError: logging.warning( - "File not found: %s, already deleted or never existed", img.filename + "File not found: %s, already deleted or never existed", post.filename ) # Delete cached files cache_path = os.path.join(platformdirs.user_config_dir("onlylegs"), "cache") - cache_name = img.filename.rsplit(".")[0] + cache_name = post.filename.rsplit(".")[0] for cache_file in pathlib.Path(cache_path).glob(cache_name + "*"): os.remove(cache_file) - post = Posts.query.filter_by(id=image_id).first() + GroupJunction.query.filter_by(post_id=image_id).delete() db.session.delete(post) - - groups = GroupJunction.query.filter_by(post_id=image_id).all() - for group in groups: - db.session.delete(group) - - # Commit all changes db.session.commit() - logging.info("Removed image (%s) %s", image_id, img.filename) + logging.info("Removed image (%s) %s", image_id, post.filename) flash(["Image was all in Le Head!", "1"]) return "Gwa Gwa" @@ -148,7 +142,7 @@ def create_group(): """ Creates a group """ - new_group = Groups( + new_group = Group( name=request.form["name"], description=request.form["description"], author_id=current_user.id, @@ -170,25 +164,18 @@ def modify_group(): image_id = request.form["image"] action = request.form["action"] - group = Groups.query.filter_by(id=group_id).first() + group = db.get_or_404(Group, group_id) + image = db.get_or_404(Post, image_id) - if group is None: - abort(404) - elif group.author_id != current_user.id: + if group.author_id != current_user.id: abort(403) - if action == "add": - if not GroupJunction.query.filter_by( - group_id=group_id, post_id=image_id - ).first(): - db.session.add(GroupJunction(group_id=group_id, post_id=image_id)) + if action == "add" and not GroupJunction.query.filter_by(group_id=group_id, post_id=image_id).first(): + db.session.add(GroupJunction(group_id=group_id, post_id=image_id)) elif request.form["action"] == "remove": - db.session.delete( - GroupJunction.query.filter_by(group_id=group_id, post_id=image_id).first() - ) + GroupJunction.query.filter_by(group_id=group_id, post_id=image_id).delete() db.session.commit() - return ":3" @@ -198,21 +185,15 @@ def delete_group(): Deletes a group """ group_id = request.form["group"] - - group = Groups.query.filter_by(id=group_id).first() + group = Group.query.filter_by(id=group_id).first() if group is None: abort(404) elif group.author_id != current_user.id: abort(403) - group_del = Groups.query.filter_by(id=group_id).first() - db.session.delete(group_del) - - junction_del = GroupJunction.query.filter_by(group_id=group_id).all() - for junction in junction_del: - db.session.delete(junction) - + GroupJunction.query.filter_by(group_id=group_id).delete() + db.session.delete(group) db.session.commit() flash(["Group yeeted!", "1"]) diff --git a/gallery/auth.py b/gallery/auth.py index 19b2ca1..0973384 100644 --- a/gallery/auth.py +++ b/gallery/auth.py @@ -11,7 +11,7 @@ from werkzeug.security import check_password_hash, generate_password_hash from flask_login import login_user, logout_user, login_required from gallery.extensions import db -from gallery.models import Users +from gallery.models import User blueprint = Blueprint("auth", __name__, url_prefix="/auth") @@ -28,7 +28,7 @@ def login(): password = request.form["password"].strip() remember = bool(request.form["remember-me"]) - user = Users.query.filter_by(username=username).first() + user = User.query.filter_by(username=username).first() if not user or not check_password_hash(user.password, password): logging.error("Login attempt from %s", request.remote_addr) @@ -77,7 +77,7 @@ def register(): elif password_repeat != password: error.append("Passwords do not match!") - user_exists = Users.query.filter_by(username=username).first() + user_exists = User.query.filter_by(username=username).first() if user_exists: error.append("User already exists!") @@ -86,7 +86,7 @@ def register(): print(error) return jsonify(error), 400 - register_user = Users( + register_user = User( username=username, email=email, password=generate_password_hash(password, method="sha256"), diff --git a/gallery/models.py b/gallery/models.py index 0988cb1..7cf628f 100644 --- a/gallery/models.py +++ b/gallery/models.py @@ -2,137 +2,99 @@ OnlyLegs - Database models and ions for SQLAlchemy """ from uuid import uuid4 - from flask_login import UserMixin from .extensions import db -class Users(db.Model, UserMixin): # pylint: disable=too-few-public-methods, C0103 - """ - User table - Joins with post, groups, session and log - """ - - __tablename__ = "users" - - # Gallery used information - id = db.Column(db.Integer, primary_key=True) - alt_id = db.Column(db.String, unique=True, nullable=False, default=str(uuid4())) - profile_picture = db.Column(db.String, nullable=True, default=None) - username = db.Column(db.String, unique=True, nullable=False) - email = db.Column(db.String, unique=True, nullable=False) - password = db.Column(db.String, nullable=False) - joined_at = db.Column( - db.DateTime, - nullable=False, - server_default=db.func.now(), # pylint: disable=E1102 - ) - - posts = db.relationship("Posts", backref="users") - groups = db.relationship("Groups", backref="users") - log = db.relationship("Logs", backref="users") - - def get_id(self): - return str(self.alt_id) - - -class Posts(db.Model): # pylint: disable=too-few-public-methods, C0103 - """ - Post table - Joins with group_junction - """ - - __tablename__ = "posts" - - id = db.Column(db.Integer, primary_key=True) - author_id = db.Column(db.Integer, db.ForeignKey("users.id")) - created_at = db.Column( - db.DateTime, - nullable=False, - server_default=db.func.now(), # pylint: disable=E1102 - ) - filename = db.Column(db.String, unique=True, nullable=False) - mimetype = db.Column(db.String, nullable=False) - exif = db.Column(db.PickleType, nullable=False) - colours = db.Column(db.PickleType, nullable=False) - description = db.Column(db.String, nullable=False) - alt = db.Column(db.String, nullable=False) - - junction = db.relationship("GroupJunction", backref="posts") - - -class Groups(db.Model): # pylint: disable=too-few-public-methods, C0103 - """ - Group table - Joins with group_junction - """ - - __tablename__ = "groups" - - id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String, nullable=False) - description = db.Column(db.String, nullable=False) - author_id = db.Column(db.Integer, db.ForeignKey("users.id")) - created_at = db.Column( - db.DateTime, - nullable=False, - server_default=db.func.now(), # pylint: disable=E1102 - ) - - junction = db.relationship("GroupJunction", backref="groups") - - class GroupJunction(db.Model): # pylint: disable=too-few-public-methods, C0103 """ Junction table for posts and groups Joins with posts and groups """ - __tablename__ = "group_junction" id = db.Column(db.Integer, primary_key=True) + + group_id = db.Column(db.Integer, db.ForeignKey("group.id")) + post_id = db.Column(db.Integer, db.ForeignKey("post.id")) + date_added = db.Column( db.DateTime, nullable=False, server_default=db.func.now(), # pylint: disable=E1102 ) - group_id = db.Column(db.Integer, db.ForeignKey("groups.id")) - post_id = db.Column(db.Integer, db.ForeignKey("posts.id")) -class Logs(db.Model): # pylint: disable=too-few-public-methods, C0103 +class Post(db.Model): # pylint: disable=too-few-public-methods, C0103 """ - Log table - Joins with user + Post table """ - - __tablename__ = "logs" + __tablename__ = "post" id = db.Column(db.Integer, primary_key=True) - user_id = db.Column(db.Integer, db.ForeignKey("users.id")) - ip_address = db.Column(db.String, nullable=False) - code = db.Column(db.Integer, nullable=False) - note = db.Column(db.String, nullable=False) + + author_id = db.Column(db.Integer, db.ForeignKey("user.id")) + + filename = db.Column(db.String, unique=True, nullable=False) + mimetype = db.Column(db.String, nullable=False) + exif = db.Column(db.PickleType, nullable=False) + colours = db.Column(db.PickleType, nullable=False) + + description = db.Column(db.String, nullable=False) + alt = db.Column(db.String, nullable=False) + created_at = db.Column( db.DateTime, nullable=False, server_default=db.func.now(), # pylint: disable=E1102 ) + + junction = db.relationship("GroupJunction", backref="posts") - -class Bans(db.Model): # pylint: disable=too-few-public-methods, C0103 +class Group(db.Model): # pylint: disable=too-few-public-methods, C0103 """ - Bans table + Group table """ - - __tablename__ = "bans" + __tablename__ = "group" id = db.Column(db.Integer, primary_key=True) - ip_address = db.Column(db.String, nullable=False) - code = db.Column(db.Integer, nullable=False) - note = db.Column(db.String, nullable=False) - banned_at = db.Column( + + name = db.Column(db.String, nullable=False) + description = db.Column(db.String, nullable=False) + + author_id = db.Column(db.Integer, db.ForeignKey("user.id")) + created_at = db.Column( db.DateTime, nullable=False, server_default=db.func.now(), # pylint: disable=E1102 ) + + junction = db.relationship("GroupJunction", backref="groups") + + +class User(db.Model, UserMixin): # pylint: disable=too-few-public-methods, C0103 + """ + User table + """ + __tablename__ = "user" + + # Gallery used information + id = db.Column(db.Integer, primary_key=True) + alt_id = db.Column(db.String, unique=True, nullable=False, default=str(uuid4())) + + profile_picture = db.Column(db.String, nullable=True, default=None) + username = db.Column(db.String, unique=True, nullable=False) + + email = db.Column(db.String, unique=True, nullable=False) + password = db.Column(db.String, nullable=False) + joined_at = db.Column( + db.DateTime, + nullable=False, + server_default=db.func.now(), # pylint: disable=E1102 + ) + + posts = db.relationship('Post', backref='author') + groups = db.relationship('Group', backref='author') + + def get_id(self): + return str(self.alt_id) diff --git a/gallery/templates/group.html b/gallery/templates/group.html index caa5313..a05a4b8 100644 --- a/gallery/templates/group.html +++ b/gallery/templates/group.html @@ -15,7 +15,7 @@ } } - {% if current_user.id == group.author_id %} + {% if current_user.id == group.author.id %} function groupDelete() { cancelBtn = document.createElement('button'); cancelBtn.classList.add('btn-block'); @@ -223,7 +223,7 @@ {% if images.0.alt %}{{ images.0.alt }}{% else %}Group Banner{% endif %}