mirror of
https://github.com/Derpy-Leggies/OnlyLegs.git
synced 2024-12-29 10:56:10 +00:00
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
This commit is contained in:
parent
9a21064dd5
commit
d36699bd1f
|
@ -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():
|
||||
|
|
|
@ -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():
|
||||
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"])
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -2,77 +2,67 @@
|
|||
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
|
||||
class GroupJunction(db.Model): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
User table
|
||||
Joins with post, groups, session and log
|
||||
Junction table for posts and groups
|
||||
Joins with posts and groups
|
||||
"""
|
||||
__tablename__ = "group_junction"
|
||||
|
||||
__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(
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
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
|
||||
class Post(db.Model): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
Post table
|
||||
Joins with group_junction
|
||||
"""
|
||||
|
||||
__tablename__ = "posts"
|
||||
__tablename__ = "post"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
author_id = db.Column(db.Integer, db.ForeignKey("users.id"))
|
||||
|
||||
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
|
||||
)
|
||||
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
|
||||
class Group(db.Model): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
Group table
|
||||
Joins with group_junction
|
||||
"""
|
||||
|
||||
__tablename__ = "groups"
|
||||
__tablename__ = "group"
|
||||
|
||||
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"))
|
||||
|
||||
author_id = db.Column(db.Integer, db.ForeignKey("user.id"))
|
||||
created_at = db.Column(
|
||||
db.DateTime,
|
||||
nullable=False,
|
||||
|
@ -82,57 +72,29 @@ class Groups(db.Model): # pylint: disable=too-few-public-methods, C0103
|
|||
junction = db.relationship("GroupJunction", backref="groups")
|
||||
|
||||
|
||||
class GroupJunction(db.Model): # pylint: disable=too-few-public-methods, C0103
|
||||
class User(db.Model, UserMixin): # pylint: disable=too-few-public-methods, C0103
|
||||
"""
|
||||
Junction table for posts and groups
|
||||
Joins with posts and groups
|
||||
User table
|
||||
"""
|
||||
__tablename__ = "user"
|
||||
|
||||
__tablename__ = "group_junction"
|
||||
|
||||
# Gallery used information
|
||||
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"))
|
||||
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)
|
||||
|
||||
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(
|
||||
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')
|
||||
|
||||
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
|
||||
)
|
||||
def get_id(self):
|
||||
return str(self.alt_id)
|
||||
|
|
|
@ -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 @@
|
|||
<img src="{{ url_for('api.file', file_name=images.0.filename ) }}?r=prev" onload="imgFade(this)" style="opacity:0;" alt="{% if images.0.alt %}{{ images.0.alt }}{% else %}Group Banner{% endif %}"/>
|
||||
<span class="banner-filter"></span>
|
||||
<div class="banner-content">
|
||||
<p class="banner-info"><a href="{{ url_for('profile.profile', id=group.author_id) }}" class="link">By {{ group.author_username }}</a></p>
|
||||
<p class="banner-info"><a href="{{ url_for('profile.profile', id=group.author.id) }}" class="link">By {{ group.author.username }}</a></p>
|
||||
<h1 class="banner-header">{{ group.name }}</h1>
|
||||
<p class="banner-subtitle">{{ images|length }} Images · {{ group.description }}</p>
|
||||
<div class="pill-row">
|
||||
|
@ -232,7 +232,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,112v96a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V112A16,16,0,0,1,56,96H80a8,8,0,0,1,0,16H56v96H200V112H176a8,8,0,0,1,0-16h24A16,16,0,0,1,216,112ZM93.66,69.66,120,43.31V136a8,8,0,0,0,16,0V43.31l26.34,26.35a8,8,0,0,0,11.32-11.32l-40-40a8,8,0,0,0-11.32,0l-40,40A8,8,0,0,0,93.66,69.66Z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
{% if current_user.id == group.author_id %}
|
||||
{% if current_user.id == group.author.id %}
|
||||
<div>
|
||||
<button class="pill-item pill__critical" onclick="groupDelete()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z"></path></svg>
|
||||
|
@ -249,14 +249,14 @@
|
|||
<div class="banner-small">
|
||||
<div class="banner-content">
|
||||
<h1 class="banner-header">{{ group.name }}</h1>
|
||||
<p class="banner-info">By {{ group.author_username }}</p>
|
||||
<p class="banner-info">By {{ group.author.username }}</p>
|
||||
<div class="pill-row">
|
||||
<div>
|
||||
<button class="pill-item" onclick="groupShare()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,112v96a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V112A16,16,0,0,1,56,96H80a8,8,0,0,1,0,16H56v96H200V112H176a8,8,0,0,1,0-16h24A16,16,0,0,1,216,112ZM93.66,69.66,120,43.31V136a8,8,0,0,0,16,0V43.31l26.34,26.35a8,8,0,0,0,11.32-11.32l-40-40a8,8,0,0,0-11.32,0l-40,40A8,8,0,0,0,93.66,69.66Z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
{% if current_user.id == group.author_id %}
|
||||
{% if current_user.id == group.author.id %}
|
||||
<div>
|
||||
<button class="pill-item pill__critical" onclick="groupDelete()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z"></path></svg>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
{% if current_user.id == image.author_id %}
|
||||
{% if current_user.id == image.author.id %}
|
||||
function imageDelete() {
|
||||
cancelBtn = document.createElement('button');
|
||||
cancelBtn.classList.add('btn-block');
|
||||
|
@ -120,7 +120,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40V216a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160ZM200,216H56V40h88V88a8,8,0,0,0,8,8h48V216Zm-42.34-61.66a8,8,0,0,1,0,11.32l-24,24a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L120,164.69V120a8,8,0,0,1,16,0v44.69l10.34-10.35A8,8,0,0,1,157.66,154.34Z"></path></svg>
|
||||
</a>
|
||||
</div>
|
||||
{% if current_user.id == image.author_id %}
|
||||
{% if current_user.id == image.author.id %}
|
||||
<div>
|
||||
<button class="pill-item pill__critical" onclick="imageDelete()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM96,40a8,8,0,0,1,8-8h48a8,8,0,0,1,8,8v8H96Zm96,168H64V64H192ZM112,104v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Zm48,0v64a8,8,0,0,1-16,0V104a8,8,0,0,1,16,0Z"></path></svg>
|
||||
|
@ -155,7 +155,7 @@
|
|||
<table>
|
||||
<tr>
|
||||
<td>Author</td>
|
||||
<td><a href="{{ url_for('profile.profile', id=image.author_id) }}" class="link">{{ image.author_username }}</a></td>
|
||||
<td><a href="{{ url_for('profile.profile', id=image.author.id) }}" class="link">{{ image.author.username }}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Upload date</td>
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
<div class="navigation">
|
||||
<!--<img src="{{url_for('static', filename='icon.png')}}" alt="Logo" class="logo" onload="this.style.opacity=1;" style="opacity:0">-->
|
||||
|
||||
<a href="{{url_for('gallery.index')}}{% block page_index %}{% endblock %}" class="navigation-item {% block nav_home %}{% endblock %}">
|
||||
<a href="{{ url_for('gallery.index') }}{% block page_index %}{% endblock %}" class="navigation-item {% block nav_home %}{% endblock %}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M208,32H80A16,16,0,0,0,64,48V64H48A16,16,0,0,0,32,80V208a16,16,0,0,0,16,16H176a16,16,0,0,0,16-16V192h16a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM80,48H208v69.38l-16.7-16.7a16,16,0,0,0-22.62,0L93.37,176H80Zm96,160H48V80H64v96a16,16,0,0,0,16,16h96ZM104,88a16,16,0,1,1,16,16A16,16,0,0,1,104,88Z"></path></svg>
|
||||
<span class="tool-tip">
|
||||
Home
|
||||
|
@ -78,7 +78,7 @@
|
|||
</span>
|
||||
</a>
|
||||
|
||||
<a href="{{url_for('group.groups')}}" class="navigation-item {% block nav_groups %}{% endblock %}">
|
||||
<a href="{{ url_for('group.groups') }}" class="navigation-item {% block nav_groups %}{% endblock %}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M245,110.64A16,16,0,0,0,232,104H216V88a16,16,0,0,0-16-16H130.67L102.94,51.2a16.14,16.14,0,0,0-9.6-3.2H40A16,16,0,0,0,24,64V208h0a8,8,0,0,0,8,8H211.1a8,8,0,0,0,7.59-5.47l28.49-85.47A16.05,16.05,0,0,0,245,110.64ZM93.34,64l27.73,20.8a16.12,16.12,0,0,0,9.6,3.2H200v16H146.43a16,16,0,0,0-8.88,2.69l-20,13.31H69.42a15.94,15.94,0,0,0-14.86,10.06L40,166.46V64Z"></path></svg>
|
||||
<span class="tool-tip">
|
||||
Groups
|
||||
|
@ -99,7 +99,7 @@
|
|||
<span class="navigation-spacer"></span>
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<a href="{{url_for('profile.profile')}}" class="navigation-item {% block nav_profile %}{% endblock %}">
|
||||
<a href="{{ url_for('profile.profile') }}" class="navigation-item {% block nav_profile %}{% endblock %}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M231.73,221.94A8,8,0,0,1,224,232H160A8,8,0,0,1,152.27,222a40,40,0,0,1,17.11-23.33,32,32,0,1,1,45.24,0A40,40,0,0,1,231.73,221.94ZM216,72H130.67L102.93,51.2a16.12,16.12,0,0,0-9.6-3.2H40A16,16,0,0,0,24,64V200a16,16,0,0,0,16,16h80a8,8,0,0,0,0-16H40V64H93.33l27.74,20.8a16.12,16.12,0,0,0,9.6,3.2H216v32a8,8,0,0,0,16,0V88A16,16,0,0,0,216,72Z"></path></svg>
|
||||
<span class="tool-tip">
|
||||
Profile
|
||||
|
@ -107,7 +107,7 @@
|
|||
</span>
|
||||
</a>
|
||||
|
||||
<a href="{{url_for('settings.general')}}" class="navigation-item {% block nav_settings %}{% endblock %}">
|
||||
<a href="{{ url_for('settings.general') }}" class="navigation-item {% block nav_settings %}{% endblock %}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M216,130.16q.06-2.16,0-4.32l14.92-18.64a8,8,0,0,0,1.48-7.06,107.6,107.6,0,0,0-10.88-26.25,8,8,0,0,0-6-3.93l-23.72-2.64q-1.48-1.56-3-3L186,40.54a8,8,0,0,0-3.94-6,107.29,107.29,0,0,0-26.25-10.86,8,8,0,0,0-7.06,1.48L130.16,40Q128,40,125.84,40L107.2,25.11a8,8,0,0,0-7.06-1.48A107.6,107.6,0,0,0,73.89,34.51a8,8,0,0,0-3.93,6L67.32,64.27q-1.56,1.49-3,3L40.54,70a8,8,0,0,0-6,3.94,107.71,107.71,0,0,0-10.87,26.25,8,8,0,0,0,1.49,7.06L40,125.84Q40,128,40,130.16L25.11,148.8a8,8,0,0,0-1.48,7.06,107.6,107.6,0,0,0,10.88,26.25,8,8,0,0,0,6,3.93l23.72,2.64q1.49,1.56,3,3L70,215.46a8,8,0,0,0,3.94,6,107.71,107.71,0,0,0,26.25,10.87,8,8,0,0,0,7.06-1.49L125.84,216q2.16.06,4.32,0l18.64,14.92a8,8,0,0,0,7.06,1.48,107.21,107.21,0,0,0,26.25-10.88,8,8,0,0,0,3.93-6l2.64-23.72q1.56-1.48,3-3L215.46,186a8,8,0,0,0,6-3.94,107.71,107.71,0,0,0,10.87-26.25,8,8,0,0,0-1.49-7.06ZM128,168a40,40,0,1,1,40-40A40,40,0,0,1,128,168Z"></path></svg>
|
||||
<span class="tool-tip">
|
||||
Settings
|
||||
|
@ -142,7 +142,7 @@
|
|||
<input class="input-block" type="text" placeholder="alt" id="alt"/>
|
||||
<input class="input-block" type="text" placeholder="description" id="description"/>
|
||||
<input class="input-block" type="text" placeholder="tags" id="tags"/>
|
||||
<button class="btn-block" type="submit">Upload</button>
|
||||
<button class="btn-block primary" type="submit">Upload</button>
|
||||
</form>
|
||||
<div class="upload-jobs"></div>
|
||||
</div>
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
{% for group in groups %}
|
||||
<a id="group-{{ group.id }}" class="group-item" href="{{ url_for('group.group', group_id=group.id) }}" {% if group.images|length > 0 %} style="background-color: rgba({{ group.images.0.colours.0.0 }}, {{ group.images.0.colours.0.1 }}, {{ group.images.0.colours.0.2 }}, 0.4);" {% endif %}>
|
||||
<div class="image-filter">
|
||||
<p class="image-subtitle">By {{ group.author_username }}</p>
|
||||
<p class="image-subtitle">By {{ group.author.username }}</p>
|
||||
<p class="image-title">{{ group.name }}</p>
|
||||
</div>
|
||||
<div class="images size-{{ group.images|length }}">
|
||||
|
|
|
@ -5,7 +5,8 @@ sounds more limiting that it actually is in this gallery
|
|||
"""
|
||||
from flask import Blueprint, abort, render_template, url_for
|
||||
|
||||
from gallery.models import Posts, Users, GroupJunction, Groups
|
||||
from gallery.models import Post, User, GroupJunction, Group
|
||||
from gallery.extensions import db
|
||||
from gallery.utils import contrast
|
||||
|
||||
|
||||
|
@ -17,19 +18,20 @@ def groups():
|
|||
"""
|
||||
Group overview, shows all image groups
|
||||
"""
|
||||
groups = Groups.query.all()
|
||||
groups = Group.query.all()
|
||||
|
||||
# For each group, get the 3 most recent images
|
||||
for group in groups:
|
||||
group.author_username = (
|
||||
Users.query.with_entities(Users.username)
|
||||
.filter(Users.id == group.author_id)
|
||||
User.query.with_entities(User.username)
|
||||
.filter(User.id == group.author_id)
|
||||
.first()[0]
|
||||
)
|
||||
|
||||
# Get the 3 most recent images
|
||||
images = (
|
||||
GroupJunction.query.with_entities(GroupJunction.post_id)
|
||||
GroupJunction.query
|
||||
.with_entities(GroupJunction.post_id)
|
||||
.filter(GroupJunction.group_id == group.id)
|
||||
.order_by(GroupJunction.date_added.desc())
|
||||
.limit(3)
|
||||
|
@ -39,10 +41,9 @@ def groups():
|
|||
group.images = []
|
||||
for image in images:
|
||||
group.images.append(
|
||||
Posts.query.with_entities(
|
||||
Posts.filename, Posts.alt, Posts.colours, Posts.id
|
||||
)
|
||||
.filter(Posts.id == image[0])
|
||||
Post.query
|
||||
.with_entities(Post.filename, Post.alt, Post.colours, Post.id)
|
||||
.filter(Post.id == image[0])
|
||||
.first()
|
||||
)
|
||||
|
||||
|
@ -55,21 +56,12 @@ def group(group_id):
|
|||
Group view, shows all images in a group
|
||||
"""
|
||||
# Get the group, if it doesn't exist, 404
|
||||
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 = (
|
||||
Users.query.with_entities(Users.username)
|
||||
.filter(Users.id == group.author_id)
|
||||
.first()[0]
|
||||
)
|
||||
group = db.get_or_404(Group, group_id, description="Group not found! D:")
|
||||
|
||||
# Get all images in the group from the junction table
|
||||
junction = (
|
||||
GroupJunction.query.with_entities(GroupJunction.post_id)
|
||||
GroupJunction.query
|
||||
.with_entities(GroupJunction.post_id)
|
||||
.filter(GroupJunction.group_id == group_id)
|
||||
.order_by(GroupJunction.date_added.desc())
|
||||
.all()
|
||||
|
@ -78,7 +70,7 @@ def group(group_id):
|
|||
# Get the image data for each image in the group
|
||||
images = []
|
||||
for image in junction:
|
||||
images.append(Posts.query.filter(Posts.id == image[0]).first())
|
||||
images.append(Post.query.filter(Post.id == image[0]).first())
|
||||
|
||||
# Check contrast for the first image in the group for the banner
|
||||
text_colour = "rgb(var(--fg-black))"
|
||||
|
@ -98,16 +90,7 @@ 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 = 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 = (
|
||||
Users.query.with_entities(Users.username)
|
||||
.filter(Users.id == image.author_id)
|
||||
.first()[0]
|
||||
)
|
||||
image = db.get_or_404(Post, image_id, description="Image not found :<")
|
||||
|
||||
# Get all groups the image is in
|
||||
groups = (
|
||||
|
@ -120,8 +103,8 @@ def group_post(group_id, image_id):
|
|||
image.groups = []
|
||||
for group in groups:
|
||||
image.groups.append(
|
||||
Groups.query.with_entities(Groups.id, Groups.name)
|
||||
.filter(Groups.id == group[0])
|
||||
Group.query.with_entities(Group.id, Group.name)
|
||||
.filter(Group.id == group[0])
|
||||
.first()
|
||||
)
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
Onlylegs - Image View
|
||||
"""
|
||||
from math import ceil
|
||||
|
||||
from flask import Blueprint, abort, render_template, url_for, current_app
|
||||
|
||||
from gallery.models import Posts, Users, GroupJunction, Groups
|
||||
from flask import Blueprint, render_template, url_for, current_app
|
||||
from gallery.models import Post, GroupJunction, Group
|
||||
from gallery.extensions import db
|
||||
|
||||
|
||||
blueprint = Blueprint("image", __name__, url_prefix="/image")
|
||||
|
@ -17,45 +16,36 @@ def image(image_id):
|
|||
Image view, shows the image and its metadata
|
||||
"""
|
||||
# Get the image, if it doesn't exist, 404
|
||||
image = Posts.query.filter(Posts.id == image_id).first()
|
||||
if not image:
|
||||
abort(404, "Image not found :<")
|
||||
image = db.get_or_404(Post, image_id, description="Image not found :<")
|
||||
|
||||
# Get the image's author username
|
||||
image.author_username = (
|
||||
Users.query.with_entities(Users.username)
|
||||
.filter(Users.id == image.author_id)
|
||||
.first()[0]
|
||||
)
|
||||
|
||||
# Get the image's groups
|
||||
# Get all groups the image is in
|
||||
groups = (
|
||||
GroupJunction.query.with_entities(GroupJunction.group_id)
|
||||
.filter(GroupJunction.post_id == image_id)
|
||||
.all()
|
||||
)
|
||||
|
||||
# For each group, get the group data and add it to the image item
|
||||
# Get the group data for each group the image is in
|
||||
image.groups = []
|
||||
for group in groups:
|
||||
image.groups.append(
|
||||
Groups.query.with_entities(Groups.name, Groups.id)
|
||||
.filter(Groups.id == group[0])
|
||||
Group.query.with_entities(Group.id, Group.name)
|
||||
.filter(Group.id == group[0])
|
||||
.first()
|
||||
)
|
||||
|
||||
# Get the next and previous images
|
||||
# Check if there is a group ID set
|
||||
next_url = (
|
||||
Posts.query.with_entities(Posts.id)
|
||||
.filter(Posts.id > image_id)
|
||||
.order_by(Posts.id.asc())
|
||||
Post.query.with_entities(Post.id)
|
||||
.filter(Post.id > image_id)
|
||||
.order_by(Post.id.asc())
|
||||
.first()
|
||||
)
|
||||
prev_url = (
|
||||
Posts.query.with_entities(Posts.id)
|
||||
.filter(Posts.id < image_id)
|
||||
.order_by(Posts.id.desc())
|
||||
Post.query.with_entities(Post.id)
|
||||
.filter(Post.id < image_id)
|
||||
.order_by(Post.id.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
|
@ -66,7 +56,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 = Posts.query.with_entities(Posts.id).order_by(Posts.id.desc()).all()
|
||||
total_images = Post.query.with_entities(Post.id).order_by(Post.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,7 +6,7 @@ from math import ceil
|
|||
from flask import Blueprint, render_template, request, current_app
|
||||
from werkzeug.exceptions import abort
|
||||
|
||||
from gallery.models import Posts
|
||||
from gallery.models import Post
|
||||
|
||||
|
||||
blueprint = Blueprint("gallery", __name__)
|
||||
|
@ -27,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 = Posts.query.with_entities(Posts.id).count()
|
||||
total_images = Post.query.with_entities(Post.id).count()
|
||||
pages = ceil(max(total_images, limit) / limit)
|
||||
if page > pages:
|
||||
abort(
|
||||
|
@ -38,10 +38,9 @@ def index():
|
|||
|
||||
# get the images for the current page
|
||||
images = (
|
||||
Posts.query.with_entities(
|
||||
Posts.filename, Posts.alt, Posts.colours, Posts.created_at, Posts.id
|
||||
)
|
||||
.order_by(Posts.id.desc())
|
||||
Post.query
|
||||
.with_entities( Post.filename, Post.alt, Post.colours, Post.created_at, Post.id)
|
||||
.order_by(Post.id.desc())
|
||||
.offset((page - 1) * limit)
|
||||
.limit(limit)
|
||||
.all()
|
||||
|
|
|
@ -5,7 +5,7 @@ from flask import Blueprint, render_template, request
|
|||
from werkzeug.exceptions import abort
|
||||
from flask_login import current_user
|
||||
|
||||
from gallery.models import Posts, Users
|
||||
from gallery.models import Post, User
|
||||
|
||||
|
||||
blueprint = Blueprint("profile", __name__, url_prefix="/profile")
|
||||
|
@ -26,11 +26,11 @@ def profile():
|
|||
abort(404, "You must be logged in to view your own profile!")
|
||||
|
||||
# Get the user's data
|
||||
user = Users.query.filter(Users.id == user_id).first()
|
||||
user = User.query.filter(User.id == user_id).first()
|
||||
|
||||
if not user:
|
||||
abort(404, "User not found :c")
|
||||
|
||||
images = Posts.query.filter(Posts.author_id == user_id).all()
|
||||
images = Post.query.filter(Post.author_id == user_id).all()
|
||||
|
||||
return render_template("profile.html", user=user, images=images)
|
||||
|
|
Loading…
Reference in a new issue