mirror of
https://github.com/Derpy-Leggies/OnlyLegs.git
synced 2025-06-29 11:36:16 +00:00
Switch to Flask-SQLAlchemy
Add FLask-Migrate for next step in the Migration 😉
This commit is contained in:
parent
7d0078ea9a
commit
7c553e99b8
12 changed files with 368 additions and 403 deletions
|
@ -2,41 +2,31 @@
|
|||
Onlylegs Gallery
|
||||
This is the main app file, it loads all the other files and sets up the app
|
||||
"""
|
||||
|
||||
# Import system modules
|
||||
import os
|
||||
import logging
|
||||
|
||||
# Flask
|
||||
from flask_compress import Compress
|
||||
from flask_caching import Cache
|
||||
from flask_assets import Environment, Bundle
|
||||
from flask_login import LoginManager
|
||||
from flask_assets import Bundle
|
||||
from flask import Flask, render_template, abort
|
||||
from werkzeug.exceptions import HTTPException
|
||||
|
||||
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 import api
|
||||
from gallery import auth
|
||||
|
||||
# Configuration
|
||||
import platformdirs
|
||||
from dotenv import load_dotenv
|
||||
from yaml import safe_load
|
||||
|
||||
# Import database
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from gallery import db
|
||||
|
||||
|
||||
USER_DIR = platformdirs.user_config_dir("onlylegs")
|
||||
|
||||
|
||||
db_session = sessionmaker(bind=db.engine)
|
||||
db_session = db_session()
|
||||
login_manager = LoginManager()
|
||||
assets = Environment()
|
||||
cache = Cache(config={"CACHE_TYPE": "SimpleCache", "CACHE_DEFAULT_TIMEOUT": 300})
|
||||
compress = Compress()
|
||||
|
||||
|
||||
def create_app(test_config=None): # pylint: disable=R0914
|
||||
def create_app(): # pylint: disable=R0914
|
||||
"""
|
||||
Create and configure the main app
|
||||
"""
|
||||
|
@ -54,7 +44,7 @@ def create_app(test_config=None): # pylint: disable=R0914
|
|||
# App configuration
|
||||
app.config.from_mapping(
|
||||
SECRET_KEY=os.environ.get("FLASK_SECRET"),
|
||||
DATABASE=os.path.join(app.instance_path, "gallery.sqlite3"),
|
||||
SQLALCHEMY_DATABASE_URI=("sqlite:///gallery.sqlite3"),
|
||||
UPLOAD_FOLDER=os.path.join(USER_DIR, "uploads"),
|
||||
ALLOWED_EXTENSIONS=conf["upload"]["allowed-extensions"],
|
||||
MAX_CONTENT_LENGTH=1024 * 1024 * conf["upload"]["max-size"],
|
||||
|
@ -63,10 +53,8 @@ def create_app(test_config=None): # pylint: disable=R0914
|
|||
WEBSITE_CONF=conf["website"],
|
||||
)
|
||||
|
||||
if test_config is None:
|
||||
app.config.from_pyfile("config.py", silent=True)
|
||||
else:
|
||||
app.config.from_mapping(test_config)
|
||||
db.init_app(app)
|
||||
migrate.init_app(app, db)
|
||||
|
||||
login_manager.init_app(app)
|
||||
login_manager.login_view = "gallery.index"
|
||||
|
@ -74,7 +62,7 @@ def create_app(test_config=None): # pylint: disable=R0914
|
|||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return db_session.query(db.Users).filter_by(alt_id=user_id).first()
|
||||
return Users.query.filter_by(alt_id=user_id).first()
|
||||
|
||||
@login_manager.unauthorized_handler
|
||||
def unauthorized():
|
||||
|
@ -82,23 +70,6 @@ def create_app(test_config=None): # pylint: disable=R0914
|
|||
msg = "You are not authorized to view this page!!!!"
|
||||
return render_template("error.html", error=error, msg=msg), error
|
||||
|
||||
scripts = Bundle(
|
||||
"js/*.js",
|
||||
filters="jsmin",
|
||||
output="gen/js.js",
|
||||
depends="js/*.js"
|
||||
)
|
||||
|
||||
styles = Bundle(
|
||||
"sass/*.sass",
|
||||
filters="libsass, cssmin",
|
||||
output="gen/styles.css",
|
||||
depends="sass/**/*.sass",
|
||||
)
|
||||
|
||||
assets.register("scripts", scripts)
|
||||
assets.register("styles", styles)
|
||||
|
||||
# Error handlers, if the error is not a HTTP error, return 500
|
||||
@app.errorhandler(Exception)
|
||||
def error_page(err): # noqa
|
||||
|
@ -109,30 +80,30 @@ def create_app(test_config=None): # pylint: disable=R0914
|
|||
err.code,
|
||||
)
|
||||
|
||||
# Load login, registration and logout manager
|
||||
from gallery import auth
|
||||
scripts = Bundle("js/*.js", filters="jsmin", output="gen/js.js", depends="js/*.js")
|
||||
|
||||
styles = Bundle(
|
||||
"sass/*.sass",
|
||||
filters="libsass, cssmin",
|
||||
output="gen/styles.css",
|
||||
depends="sass/**/*.sass",
|
||||
)
|
||||
|
||||
assets.register("scripts", scripts)
|
||||
assets.register("styles", styles)
|
||||
|
||||
# Load all the blueprints
|
||||
app.register_blueprint(auth.blueprint)
|
||||
|
||||
# Load the API
|
||||
from gallery import api
|
||||
|
||||
app.register_blueprint(api.blueprint)
|
||||
|
||||
# Load the different views
|
||||
from gallery.views import index, image, group, settings, profile
|
||||
|
||||
app.register_blueprint(index.blueprint)
|
||||
app.register_blueprint(image.blueprint)
|
||||
app.register_blueprint(group.blueprint)
|
||||
app.register_blueprint(profile.blueprint)
|
||||
app.register_blueprint(settings.blueprint)
|
||||
|
||||
# Log to file that the app has started
|
||||
logging.info("Gallery started successfully!")
|
||||
|
||||
# Initialize extensions and return app
|
||||
assets.init_app(app)
|
||||
cache.init_app(app)
|
||||
compress.init_app(app)
|
||||
|
||||
logging.info("Gallery started successfully!")
|
||||
return app
|
||||
|
|
|
@ -14,16 +14,14 @@ from flask_login import login_required, current_user
|
|||
|
||||
from colorthief import ColorThief
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from gallery.extensions import db
|
||||
from gallery.models import Posts, Groups, GroupJunction
|
||||
|
||||
from gallery import db
|
||||
from gallery.utils import metadata as mt
|
||||
from gallery.utils.generate_image import generate_thumbnail
|
||||
|
||||
|
||||
blueprint = Blueprint("api", __name__, url_prefix="/api")
|
||||
db_session = sessionmaker(bind=db.engine)
|
||||
db_session = db_session()
|
||||
|
||||
|
||||
@blueprint.route("/file/<file_name>", methods=["GET"])
|
||||
|
@ -87,7 +85,7 @@ def upload():
|
|||
img_colors = ColorThief(img_path).get_palette(color_count=3) # Get color palette
|
||||
|
||||
# Save to database
|
||||
query = db.Posts(
|
||||
query = Posts(
|
||||
author_id=current_user.id,
|
||||
filename=img_name + "." + img_ext,
|
||||
mimetype=img_ext,
|
||||
|
@ -97,8 +95,8 @@ def upload():
|
|||
alt=form["alt"],
|
||||
)
|
||||
|
||||
db_session.add(query)
|
||||
db_session.commit()
|
||||
db.session.add(query)
|
||||
db.session.commit()
|
||||
|
||||
return "Gwa Gwa" # Return something so the browser doesn't show an error
|
||||
|
||||
|
@ -109,7 +107,7 @@ def delete_image(image_id):
|
|||
"""
|
||||
Deletes an image from the server and database
|
||||
"""
|
||||
img = db_session.query(db.Posts).filter_by(id=image_id).first()
|
||||
img = Posts.query.filter_by(id=image_id).first()
|
||||
|
||||
# Check if image exists and if user is allowed to delete it (author)
|
||||
if img is None:
|
||||
|
@ -131,16 +129,15 @@ def delete_image(image_id):
|
|||
for cache_file in pathlib.Path(cache_path).glob(cache_name + "*"):
|
||||
os.remove(cache_file)
|
||||
|
||||
# Delete from database
|
||||
db_session.query(db.Posts).filter_by(id=image_id).delete()
|
||||
|
||||
# Remove all entries in junction table
|
||||
groups = db_session.query(db.GroupJunction).filter_by(post_id=image_id).all()
|
||||
post = Posts.query.filter_by(id=image_id).first()
|
||||
db.session.delete(post)
|
||||
|
||||
groups = GroupJunction.query.filter_by(post_id=image_id).all()
|
||||
for group in groups:
|
||||
db_session.delete(group)
|
||||
db.session.delete(group)
|
||||
|
||||
# Commit all changes
|
||||
db_session.commit()
|
||||
db.session.commit()
|
||||
|
||||
logging.info("Removed image (%s) %s", image_id, img.filename)
|
||||
flash(["Image was all in Le Head!", "1"])
|
||||
|
@ -153,14 +150,14 @@ def create_group():
|
|||
"""
|
||||
Creates a group
|
||||
"""
|
||||
new_group = db.Groups(
|
||||
new_group = Groups(
|
||||
name=request.form["name"],
|
||||
description=request.form["description"],
|
||||
author_id=current_user.id,
|
||||
)
|
||||
|
||||
db_session.add(new_group)
|
||||
db_session.commit()
|
||||
db.session.add(new_group)
|
||||
db.session.commit()
|
||||
|
||||
return ":3"
|
||||
|
||||
|
@ -175,7 +172,7 @@ def modify_group():
|
|||
image_id = request.form["image"]
|
||||
action = request.form["action"]
|
||||
|
||||
group = db_session.query(db.Groups).filter_by(id=group_id).first()
|
||||
group = Groups.query.filter_by(id=group_id).first()
|
||||
|
||||
if group is None:
|
||||
abort(404)
|
||||
|
@ -183,20 +180,12 @@ def modify_group():
|
|||
abort(403)
|
||||
|
||||
if action == "add":
|
||||
if not (
|
||||
db_session.query(db.GroupJunction)
|
||||
.filter_by(group_id=group_id, post_id=image_id)
|
||||
.first()
|
||||
):
|
||||
db_session.add(db.GroupJunction(group_id=group_id, post_id=image_id))
|
||||
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))
|
||||
elif request.form["action"] == "remove":
|
||||
(
|
||||
db_session.query(db.GroupJunction)
|
||||
.filter_by(group_id=group_id, post_id=image_id)
|
||||
.delete()
|
||||
)
|
||||
db.session.delete(GroupJunction.query.filter_by(group_id=group_id, post_id=image_id).first())
|
||||
|
||||
db_session.commit()
|
||||
db.session.commit()
|
||||
|
||||
return ":3"
|
||||
|
||||
|
@ -208,16 +197,21 @@ def delete_group():
|
|||
"""
|
||||
group_id = request.form["group"]
|
||||
|
||||
group = db_session.query(db.Groups).filter_by(id=group_id).first()
|
||||
group = Groups.query.filter_by(id=group_id).first()
|
||||
|
||||
if group is None:
|
||||
abort(404)
|
||||
elif group.author_id != current_user.id:
|
||||
abort(403)
|
||||
|
||||
db_session.query(db.Groups).filter_by(id=group_id).delete()
|
||||
db_session.query(db.GroupJunction).filter_by(group_id=group_id).delete()
|
||||
db_session.commit()
|
||||
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)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
flash(["Group yeeted!", "1"])
|
||||
return ":3"
|
||||
|
|
|
@ -10,13 +10,11 @@ from werkzeug.security import check_password_hash, generate_password_hash
|
|||
|
||||
from flask_login import login_user, logout_user, login_required
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from gallery import db
|
||||
from gallery.extensions import db
|
||||
from gallery.models import Users
|
||||
|
||||
|
||||
blueprint = Blueprint("auth", __name__, url_prefix="/auth")
|
||||
db_session = sessionmaker(bind=db.engine)
|
||||
db_session = db_session()
|
||||
|
||||
|
||||
@blueprint.route("/login", methods=["POST"])
|
||||
|
@ -30,7 +28,7 @@ def login():
|
|||
password = request.form["password"].strip()
|
||||
remember = bool(request.form["remember-me"])
|
||||
|
||||
user = db_session.query(db.Users).filter_by(username=username).first()
|
||||
user = Users.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)
|
||||
|
@ -79,7 +77,7 @@ def register():
|
|||
elif password_repeat != password:
|
||||
error.append("Passwords do not match!")
|
||||
|
||||
user_exists = db_session.query(db.Users).filter_by(username=username).first()
|
||||
user_exists = Users.query.filter_by(username=username).first()
|
||||
if user_exists:
|
||||
error.append("User already exists!")
|
||||
|
||||
|
@ -93,8 +91,8 @@ def register():
|
|||
email=email,
|
||||
password=generate_password_hash(password, method="sha256"),
|
||||
)
|
||||
db_session.add(register_user)
|
||||
db_session.commit()
|
||||
db.session.add(register_user)
|
||||
db.session.commit()
|
||||
|
||||
logging.info("User %s registered", username)
|
||||
return "ok", 200
|
||||
|
|
153
gallery/db.py
153
gallery/db.py
|
@ -1,153 +0,0 @@
|
|||
"""
|
||||
OnlyLegs - Database models and ions for SQLAlchemy
|
||||
"""
|
||||
from uuid import uuid4
|
||||
import os
|
||||
import platformdirs
|
||||
|
||||
from sqlalchemy import (
|
||||
create_engine,
|
||||
Column,
|
||||
Integer,
|
||||
String,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
PickleType,
|
||||
func,
|
||||
)
|
||||
from sqlalchemy.orm import declarative_base, relationship
|
||||
from flask_login import UserMixin
|
||||
|
||||
|
||||
USER_DIR = platformdirs.user_config_dir("onlylegs")
|
||||
DB_PATH = os.path.join(USER_DIR, "instance", "gallery.sqlite3")
|
||||
|
||||
|
||||
# In the future, I want to add support for other databases
|
||||
engine = create_engine(f"sqlite:///{DB_PATH}", echo=False)
|
||||
base = declarative_base()
|
||||
|
||||
|
||||
class Users(base, UserMixin): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
User table
|
||||
Joins with post, groups, session and log
|
||||
"""
|
||||
|
||||
__tablename__ = "users"
|
||||
|
||||
# Gallery used information
|
||||
id = Column(Integer, primary_key=True)
|
||||
alt_id = Column(String, unique=True, nullable=False, default=str(uuid4()))
|
||||
profile_picture = Column(String, nullable=True, default=None)
|
||||
username = Column(String, unique=True, nullable=False)
|
||||
email = Column(String, unique=True, nullable=False)
|
||||
password = Column(String, nullable=False)
|
||||
joined_at = Column(
|
||||
DateTime, nullable=False, server_default=func.now() # pylint: disable=E1102
|
||||
)
|
||||
|
||||
posts = relationship("Posts", backref="users")
|
||||
groups = relationship("Groups", backref="users")
|
||||
log = relationship("Logs", backref="users")
|
||||
|
||||
def get_id(self):
|
||||
return str(self.alt_id)
|
||||
|
||||
|
||||
class Posts(base): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
Post table
|
||||
Joins with group_junction
|
||||
"""
|
||||
|
||||
__tablename__ = "posts"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
author_id = Column(Integer, ForeignKey("users.id"))
|
||||
created_at = Column(
|
||||
DateTime, nullable=False, server_default=func.now() # pylint: disable=E1102
|
||||
)
|
||||
filename = Column(String, unique=True, nullable=False)
|
||||
mimetype = Column(String, nullable=False)
|
||||
exif = Column(PickleType, nullable=False)
|
||||
colours = Column(PickleType, nullable=False)
|
||||
description = Column(String, nullable=False)
|
||||
alt = Column(String, nullable=False)
|
||||
|
||||
junction = relationship("GroupJunction", backref="posts")
|
||||
|
||||
|
||||
class Groups(base): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
Group table
|
||||
Joins with group_junction
|
||||
"""
|
||||
|
||||
__tablename__ = "groups"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
description = Column(String, nullable=False)
|
||||
author_id = Column(Integer, ForeignKey("users.id"))
|
||||
created_at = Column(
|
||||
DateTime, nullable=False, server_default=func.now() # pylint: disable=E1102
|
||||
)
|
||||
|
||||
junction = relationship("GroupJunction", backref="groups")
|
||||
|
||||
|
||||
class GroupJunction(base): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
Junction table for posts and groups
|
||||
Joins with posts and groups
|
||||
"""
|
||||
|
||||
__tablename__ = "group_junction"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
date_added = Column(
|
||||
DateTime, nullable=False, server_default=func.now() # pylint: disable=E1102
|
||||
)
|
||||
group_id = Column(Integer, ForeignKey("groups.id"))
|
||||
post_id = Column(Integer, ForeignKey("posts.id"))
|
||||
|
||||
|
||||
class Logs(base): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
Log table
|
||||
Joins with user
|
||||
"""
|
||||
|
||||
__tablename__ = "logs"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
user_id = Column(Integer, ForeignKey("users.id"))
|
||||
ip_address = Column(String, nullable=False)
|
||||
code = Column(Integer, nullable=False)
|
||||
note = Column(String, nullable=False)
|
||||
created_at = Column(
|
||||
DateTime, nullable=False, server_default=func.now() # pylint: disable=E1102
|
||||
)
|
||||
|
||||
|
||||
class Bans(base): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
Bans table
|
||||
"""
|
||||
|
||||
__tablename__ = "bans"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
ip_address = Column(String, nullable=False)
|
||||
code = Column(Integer, nullable=False)
|
||||
note = Column(String, nullable=False)
|
||||
banned_at = Column(
|
||||
DateTime, nullable=False, server_default=func.now() # pylint: disable=E1102
|
||||
)
|
||||
|
||||
|
||||
# check if database file exists, if not create it
|
||||
if not os.path.isfile(DB_PATH):
|
||||
base.metadata.create_all(engine)
|
||||
print("Database created")
|
13
gallery/extensions.py
Normal file
13
gallery/extensions.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_migrate import Migrate
|
||||
from flask_login import LoginManager
|
||||
from flask_assets import Environment
|
||||
from flask_compress import Compress
|
||||
from flask_caching import Cache
|
||||
|
||||
db = SQLAlchemy()
|
||||
migrate = Migrate()
|
||||
login_manager = LoginManager()
|
||||
assets = Environment()
|
||||
compress = Compress()
|
||||
cache = Cache(config={"CACHE_TYPE": "SimpleCache", "CACHE_DEFAULT_TIMEOUT": 300})
|
138
gallery/models.py
Normal file
138
gallery/models.py
Normal file
|
@ -0,0 +1,138 @@
|
|||
"""
|
||||
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)
|
||||
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
|
||||
"""
|
||||
Log table
|
||||
Joins with user
|
||||
"""
|
||||
|
||||
__tablename__ = "logs"
|
||||
|
||||
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)
|
||||
created_at = db.Column(
|
||||
db.DateTime,
|
||||
nullable=False,
|
||||
server_default=db.func.now(), # pylint: disable=E1102
|
||||
)
|
||||
|
||||
|
||||
class Bans(db.Model): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
Bans table
|
||||
"""
|
||||
|
||||
__tablename__ = "bans"
|
||||
|
||||
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(
|
||||
db.DateTime,
|
||||
nullable=False,
|
||||
server_default=db.func.now(), # pylint: disable=E1102
|
||||
)
|
|
@ -5,14 +5,11 @@ sounds more limiting that it actually is in this gallery
|
|||
"""
|
||||
from flask import Blueprint, abort, render_template, url_for
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from gallery import db
|
||||
from gallery.models import Posts, Users, GroupJunction, Groups
|
||||
from gallery.utils import contrast
|
||||
|
||||
|
||||
blueprint = Blueprint("group", __name__, url_prefix="/group")
|
||||
db_session = sessionmaker(bind=db.engine)
|
||||
db_session = db_session()
|
||||
|
||||
|
||||
@blueprint.route("/", methods=["GET"])
|
||||
|
@ -20,21 +17,21 @@ def groups():
|
|||
"""
|
||||
Group overview, shows all image groups
|
||||
"""
|
||||
groups = db_session.query(db.Groups).all()
|
||||
groups = Groups.query.all()
|
||||
|
||||
# For each group, get the 3 most recent images
|
||||
for group in groups:
|
||||
group.author_username = (
|
||||
db_session.query(db.Users.username)
|
||||
.filter(db.Users.id == group.author_id)
|
||||
Users.query.with_entities(Users.username)
|
||||
.filter(Users.id == group.author_id)
|
||||
.first()[0]
|
||||
)
|
||||
|
||||
# Get the 3 most recent images
|
||||
images = (
|
||||
db_session.query(db.GroupJunction.post_id)
|
||||
.filter(db.GroupJunction.group_id == group.id)
|
||||
.order_by(db.GroupJunction.date_added.desc())
|
||||
GroupJunction.query.with_entities(GroupJunction.post_id)
|
||||
.filter(GroupJunction.group_id == group.id)
|
||||
.order_by(GroupJunction.date_added.desc())
|
||||
.limit(3)
|
||||
)
|
||||
|
||||
|
@ -42,10 +39,10 @@ def groups():
|
|||
group.images = []
|
||||
for image in images:
|
||||
group.images.append(
|
||||
db_session.query(
|
||||
db.Posts.filename, db.Posts.alt, db.Posts.colours, db.Posts.id
|
||||
Posts.query.with_entities(
|
||||
Posts.filename, Posts.alt, Posts.colours, Posts.id
|
||||
)
|
||||
.filter(db.Posts.id == image[0])
|
||||
.filter(Posts.id == image[0])
|
||||
.first()
|
||||
)
|
||||
|
||||
|
@ -58,32 +55,30 @@ def group(group_id):
|
|||
Group view, shows all images in a group
|
||||
"""
|
||||
# Get the group, if it doesn't exist, 404
|
||||
group = db_session.query(db.Groups).filter(db.Groups.id == group_id).first()
|
||||
group = Groups.query.filter(Groups.id == group_id).first()
|
||||
|
||||
if group is None:
|
||||
abort(404, "Group not found! D:")
|
||||
|
||||
# Get the group's author username
|
||||
group.author_username = (
|
||||
db_session.query(db.Users.username)
|
||||
.filter(db.Users.id == group.author_id)
|
||||
Users.query.with_entities(Users.username)
|
||||
.filter(Users.id == group.author_id)
|
||||
.first()[0]
|
||||
)
|
||||
|
||||
# Get all images in the group from the junction table
|
||||
junction = (
|
||||
db_session.query(db.GroupJunction.post_id)
|
||||
.filter(db.GroupJunction.group_id == group_id)
|
||||
.order_by(db.GroupJunction.date_added.desc())
|
||||
GroupJunction.query.with_entities(GroupJunction.post_id)
|
||||
.filter(GroupJunction.group_id == group_id)
|
||||
.order_by(GroupJunction.date_added.desc())
|
||||
.all()
|
||||
)
|
||||
|
||||
# Get the image data for each image in the group
|
||||
images = []
|
||||
for image in junction:
|
||||
images.append(
|
||||
db_session.query(db.Posts).filter(db.Posts.id == image[0]).first()
|
||||
)
|
||||
images.append(Posts.query.filter(Posts.id == image[0]).first())
|
||||
|
||||
# Check contrast for the first image in the group for the banner
|
||||
text_colour = "rgb(var(--fg-black))"
|
||||
|
@ -103,21 +98,21 @@ def group_post(group_id, image_id):
|
|||
Image view, shows the image and its metadata from a specific group
|
||||
"""
|
||||
# Get the image, if it doesn't exist, 404
|
||||
image = db_session.query(db.Posts).filter(db.Posts.id == image_id).first()
|
||||
image = Posts.query.filter(Posts.id == image_id).first()
|
||||
if image is None:
|
||||
abort(404, "Image not found")
|
||||
|
||||
# Get the image's author username
|
||||
image.author_username = (
|
||||
db_session.query(db.Users.username)
|
||||
.filter(db.Users.id == image.author_id)
|
||||
Users.query.with_entities(Users.username)
|
||||
.filter(Users.id == image.author_id)
|
||||
.first()[0]
|
||||
)
|
||||
|
||||
# Get all groups the image is in
|
||||
groups = (
|
||||
db_session.query(db.GroupJunction.group_id)
|
||||
.filter(db.GroupJunction.post_id == image_id)
|
||||
GroupJunction.query.with_entities(GroupJunction.group_id)
|
||||
.filter(GroupJunction.post_id == image_id)
|
||||
.all()
|
||||
)
|
||||
|
||||
|
@ -125,24 +120,24 @@ def group_post(group_id, image_id):
|
|||
image.groups = []
|
||||
for group in groups:
|
||||
image.groups.append(
|
||||
db_session.query(db.Groups.id, db.Groups.name)
|
||||
.filter(db.Groups.id == group[0])
|
||||
Groups.query.with_entities(Groups.id, Groups.name)
|
||||
.filter(Groups.id == group[0])
|
||||
.first()
|
||||
)
|
||||
|
||||
# Get the next and previous images in the group
|
||||
next_url = (
|
||||
db_session.query(db.GroupJunction.post_id)
|
||||
.filter(db.GroupJunction.group_id == group_id)
|
||||
.filter(db.GroupJunction.post_id > image_id)
|
||||
.order_by(db.GroupJunction.date_added.asc())
|
||||
GroupJunction.query.with_entities(GroupJunction.post_id)
|
||||
.filter(GroupJunction.group_id == group_id)
|
||||
.filter(GroupJunction.post_id > image_id)
|
||||
.order_by(GroupJunction.date_added.asc())
|
||||
.first()
|
||||
)
|
||||
prev_url = (
|
||||
db_session.query(db.GroupJunction.post_id)
|
||||
.filter(db.GroupJunction.group_id == group_id)
|
||||
.filter(db.GroupJunction.post_id < image_id)
|
||||
.order_by(db.GroupJunction.date_added.desc())
|
||||
GroupJunction.query.with_entities(GroupJunction.post_id)
|
||||
.filter(GroupJunction.group_id == group_id)
|
||||
.filter(GroupJunction.post_id < image_id)
|
||||
.order_by(GroupJunction.date_added.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
|
|
|
@ -5,13 +5,10 @@ from math import ceil
|
|||
|
||||
from flask import Blueprint, abort, render_template, url_for, current_app
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from gallery import db
|
||||
from gallery.models import Posts, Users, GroupJunction, Groups
|
||||
|
||||
|
||||
blueprint = Blueprint("image", __name__, url_prefix="/image")
|
||||
db_session = sessionmaker(bind=db.engine)
|
||||
db_session = db_session()
|
||||
|
||||
|
||||
@blueprint.route("/<int:image_id>")
|
||||
|
@ -20,21 +17,21 @@ def image(image_id):
|
|||
Image view, shows the image and its metadata
|
||||
"""
|
||||
# Get the image, if it doesn't exist, 404
|
||||
image = db_session.query(db.Posts).filter(db.Posts.id == image_id).first()
|
||||
image = Posts.query.filter(Posts.id == image_id).first()
|
||||
if not image:
|
||||
abort(404, "Image not found :<")
|
||||
|
||||
# Get the image's author username
|
||||
image.author_username = (
|
||||
db_session.query(db.Users.username)
|
||||
.filter(db.Users.id == image.author_id)
|
||||
Users.query.with_entities(Users.username)
|
||||
.filter(Users.id == image.author_id)
|
||||
.first()[0]
|
||||
)
|
||||
|
||||
# Get the image's groups
|
||||
groups = (
|
||||
db_session.query(db.GroupJunction.group_id)
|
||||
.filter(db.GroupJunction.post_id == image_id)
|
||||
GroupJunction.query.with_entities(GroupJunction.group_id)
|
||||
.filter(GroupJunction.post_id == image_id)
|
||||
.all()
|
||||
)
|
||||
|
||||
|
@ -42,23 +39,23 @@ def image(image_id):
|
|||
image.groups = []
|
||||
for group in groups:
|
||||
image.groups.append(
|
||||
db_session.query(db.Groups.id, db.Groups.name)
|
||||
.filter(db.Groups.id == group[0])
|
||||
Groups.query.with_entities(Groups.name, Groups.id)
|
||||
.filter(Groups.id == group[0])
|
||||
.first()
|
||||
)
|
||||
|
||||
# Get the next and previous images
|
||||
# Check if there is a group ID set
|
||||
next_url = (
|
||||
db_session.query(db.Posts.id)
|
||||
.filter(db.Posts.id > image_id)
|
||||
.order_by(db.Posts.id.asc())
|
||||
Posts.query.with_entities(Posts.id)
|
||||
.filter(Posts.id > image_id)
|
||||
.order_by(Posts.id.asc())
|
||||
.first()
|
||||
)
|
||||
prev_url = (
|
||||
db_session.query(db.Posts.id)
|
||||
.filter(db.Posts.id < image_id)
|
||||
.order_by(db.Posts.id.desc())
|
||||
Posts.query.with_entities(Posts.id)
|
||||
.filter(Posts.id < image_id)
|
||||
.order_by(Posts.id.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
|
@ -69,7 +66,7 @@ def image(image_id):
|
|||
prev_url = url_for("image.image", image_id=prev_url[0])
|
||||
|
||||
# Yoink all the images in the database
|
||||
total_images = db_session.query(db.Posts.id).order_by(db.Posts.id.desc()).all()
|
||||
total_images = Posts.query.with_entities(Posts.id).order_by(Posts.id.desc()).all()
|
||||
limit = current_app.config["UPLOAD_CONF"]["max-load"]
|
||||
|
||||
# If the number of items is less than the limit, no point of calculating the page
|
||||
|
|
|
@ -6,13 +6,10 @@ from math import ceil
|
|||
from flask import Blueprint, render_template, request, current_app
|
||||
from werkzeug.exceptions import abort
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from gallery import db
|
||||
from gallery.models import Posts
|
||||
|
||||
|
||||
blueprint = Blueprint("gallery", __name__)
|
||||
db_session = sessionmaker(bind=db.engine)
|
||||
db_session = db_session()
|
||||
|
||||
|
||||
@blueprint.route("/")
|
||||
|
@ -30,7 +27,7 @@ def index():
|
|||
|
||||
# get the total number of images in the database
|
||||
# calculate the total number of pages, and make sure the page number is valid
|
||||
total_images = db_session.query(db.Posts.id).count()
|
||||
total_images = Posts.query.with_entities(Posts.id).count()
|
||||
pages = ceil(max(total_images, limit) / limit)
|
||||
if page > pages:
|
||||
abort(
|
||||
|
@ -41,14 +38,10 @@ def index():
|
|||
|
||||
# get the images for the current page
|
||||
images = (
|
||||
db_session.query(
|
||||
db.Posts.filename,
|
||||
db.Posts.alt,
|
||||
db.Posts.colours,
|
||||
db.Posts.created_at,
|
||||
db.Posts.id,
|
||||
Posts.query.with_entities(
|
||||
Posts.filename, Posts.alt, Posts.colours, Posts.created_at, Posts.id
|
||||
)
|
||||
.order_by(db.Posts.id.desc())
|
||||
.order_by(Posts.id.desc())
|
||||
.offset((page - 1) * limit)
|
||||
.limit(limit)
|
||||
.all()
|
||||
|
|
|
@ -5,13 +5,10 @@ from flask import Blueprint, render_template, request
|
|||
from werkzeug.exceptions import abort
|
||||
from flask_login import current_user
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from gallery import db
|
||||
from gallery.models import Posts, Users
|
||||
|
||||
|
||||
blueprint = Blueprint("profile", __name__, url_prefix="/profile")
|
||||
db_session = sessionmaker(bind=db.engine)
|
||||
db_session = db_session()
|
||||
|
||||
|
||||
@blueprint.route("/profile")
|
||||
|
@ -29,11 +26,11 @@ def profile():
|
|||
abort(404, "You must be logged in to view your own profile!")
|
||||
|
||||
# Get the user's data
|
||||
user = db_session.query(db.Users).filter(db.Users.id == user_id).first()
|
||||
user = Users.query.filter(Users.id == user_id).first()
|
||||
|
||||
if not user:
|
||||
abort(404, "User not found :c")
|
||||
|
||||
images = db_session.query(db.Posts).filter(db.Posts.author_id == user_id).all()
|
||||
images = Posts.query.filter(Posts.author_id == user_id).all()
|
||||
|
||||
return render_template("profile.html", user=user, images=images)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue