Change database structure

Update naming to something more useful
Date filled in automatically
This commit is contained in:
Michał Gdula 2023-04-05 16:35:59 +00:00
parent bf083a85ad
commit 4627498b8d
11 changed files with 83 additions and 89 deletions

View file

@ -54,7 +54,7 @@ def create_app(test_config=None):
# App configuration # App configuration
app.config.from_mapping( app.config.from_mapping(
SECRET_KEY=os.environ.get('FLASK_SECRET'), SECRET_KEY=os.environ.get('FLASK_SECRET'),
DATABASE=os.path.join(app.instance_path, 'gallery.sqlite'), DATABASE=os.path.join(app.instance_path, 'gallery.sqlite3'),
UPLOAD_FOLDER=os.path.join(USER_DIR, 'uploads'), UPLOAD_FOLDER=os.path.join(USER_DIR, 'uploads'),
ALLOWED_EXTENSIONS=conf['upload']['allowed-extensions'], ALLOWED_EXTENSIONS=conf['upload']['allowed-extensions'],
MAX_CONTENT_LENGTH=1024 * 1024 * conf['upload']['max-size'], MAX_CONTENT_LENGTH=1024 * 1024 * conf['upload']['max-size'],

View file

@ -3,9 +3,7 @@ OnlyLegs - Authentication
User registration, login and logout and locking access to pages behind a login User registration, login and logout and locking access to pages behind a login
""" """
import re import re
from uuid import uuid4
import logging import logging
from datetime import datetime as dt
from flask import Blueprint, flash, redirect, request, url_for, abort, jsonify from flask import Blueprint, flash, redirect, request, url_for, abort, jsonify
from werkzeug.security import check_password_hash, generate_password_hash from werkzeug.security import check_password_hash, generate_password_hash
@ -34,7 +32,7 @@ def login():
user = db_session.query(db.Users).filter_by(username=username).first() user = db_session.query(db.Users).filter_by(username=username).first()
if not user and not check_password_hash(user.password, password): if not user or not check_password_hash(user.password, password):
logging.error('Login attempt from %s', request.remote_addr) logging.error('Login attempt from %s', request.remote_addr)
error.append('Username or Password is incorrect!') error.append('Username or Password is incorrect!')
@ -45,7 +43,7 @@ def login():
logging.info('User %s logged in from %s', username, request.remote_addr) logging.info('User %s logged in from %s', username, request.remote_addr)
flash(['Logged in successfully!', '4']) flash(['Logged in successfully!', '4'])
return 'gwa gwa' return 'ok', 200
@blueprint.route('/register', methods=['POST']) @blueprint.route('/register', methods=['POST'])
@ -87,16 +85,16 @@ def register():
# If there are errors, return them # If there are errors, return them
if error: if error:
return jsonify(error) print(error)
return jsonify(error), 400
register_user = db.Users(alt_id=str(uuid4()), username=username, email=email, register_user = db.Users(username=username, email=email,
password=generate_password_hash(password, method='sha256'), password=generate_password_hash(password, method='sha256'))
created_at=dt.utcnow())
db_session.add(register_user) db_session.add(register_user)
db_session.commit() db_session.commit()
logging.info('User %s registered', username) logging.info('User %s registered', username)
return 'gwa gwa' return 'ok', 200
@blueprint.route('/logout') @blueprint.route('/logout')
@ -106,4 +104,5 @@ def logout():
Clear the current session, including the stored user id Clear the current session, including the stored user id
""" """
logout_user() logout_user()
flash(['Goodbye!!!', '4'])
return redirect(url_for('gallery.index')) return redirect(url_for('gallery.index'))

View file

@ -1,8 +1,10 @@
""" """
OnlyLegs - Database models and functions for SQLAlchemy OnlyLegs - Database models and functions for SQLAlchemy
""" """
from uuid import uuid4
import os import os
import platformdirs import platformdirs
from datetime import datetime as dt
from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey, PickleType from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey, PickleType
from sqlalchemy.orm import declarative_base, relationship from sqlalchemy.orm import declarative_base, relationship
@ -11,7 +13,7 @@ from flask_login import UserMixin
USER_DIR = platformdirs.user_config_dir('onlylegs') USER_DIR = platformdirs.user_config_dir('onlylegs')
DB_PATH = os.path.join(USER_DIR, 'gallery.sqlite') DB_PATH = os.path.join(USER_DIR, 'instance', 'gallery.sqlite3')
# In the future, I want to add support for other databases # In the future, I want to add support for other databases
@ -28,11 +30,12 @@ class Users (base, UserMixin): # pylint: disable=too-few-public-methods, C0103
# Gallery used information # Gallery used information
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
alt_id = Column(String, unique=True, nullable=False) 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) username = Column(String, unique=True, nullable=False)
email = Column(String, unique=True, nullable=False) email = Column(String, unique=True, nullable=False)
password = Column(String, nullable=False) password = Column(String, nullable=False)
created_at = Column(DateTime, nullable=False) joined_at = Column(DateTime, nullable=False, default=dt.utcnow())
posts = relationship('Posts', backref='users') posts = relationship('Posts', backref='users')
groups = relationship('Groups', backref='users') groups = relationship('Groups', backref='users')
@ -51,20 +54,16 @@ class Posts (base): # pylint: disable=too-few-public-methods, C0103
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
author_id = Column(Integer, ForeignKey('users.id')) author_id = Column(Integer, ForeignKey('users.id'))
created_at = Column(DateTime, nullable=False) created_at = Column(DateTime, nullable=False, default=dt.utcnow())
filename = Column(String, unique=True, nullable=False)
file_name = Column(String, unique=True, nullable=False) mimetype = Column(String, nullable=False)
file_type = Column(String, nullable=False) exif = Column(PickleType, nullable=False)
colours = Column(PickleType, nullable=False)
image_exif = Column(PickleType, nullable=False) description = Column(String, nullable=False)
image_colours = Column(PickleType, nullable=False) alt = Column(String, nullable=False)
post_description = Column(String, nullable=False)
post_alt = Column(String, nullable=False)
junction = relationship('GroupJunction', backref='posts') junction = relationship('GroupJunction', backref='posts')
class Groups (base): # pylint: disable=too-few-public-methods, C0103 class Groups (base): # pylint: disable=too-few-public-methods, C0103
""" """
Group table Group table
@ -76,7 +75,7 @@ class Groups (base): # pylint: disable=too-few-public-methods, C0103
name = Column(String, nullable=False) name = Column(String, nullable=False)
description = Column(String, nullable=False) description = Column(String, nullable=False)
author_id = Column(Integer, ForeignKey('users.id')) author_id = Column(Integer, ForeignKey('users.id'))
created_at = Column(DateTime, nullable=False) created_at = Column(DateTime, nullable=False, default=dt.utcnow())
junction = relationship('GroupJunction', backref='groups') junction = relationship('GroupJunction', backref='groups')
@ -89,7 +88,7 @@ class GroupJunction (base): # pylint: disable=too-few-public-methods, C0103
__tablename__ = 'group_junction' __tablename__ = 'group_junction'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
date_added = Column(DateTime, nullable=False) date_added = Column(DateTime, nullable=False, default=dt.utcnow())
group_id = Column(Integer, ForeignKey('groups.id')) group_id = Column(Integer, ForeignKey('groups.id'))
post_id = Column(Integer, ForeignKey('posts.id')) post_id = Column(Integer, ForeignKey('posts.id'))
@ -105,8 +104,8 @@ class Logs (base): # pylint: disable=too-few-public-methods, C0103
user_id = Column(Integer, ForeignKey('users.id')) user_id = Column(Integer, ForeignKey('users.id'))
ip_address = Column(String, nullable=False) ip_address = Column(String, nullable=False)
code = Column(Integer, nullable=False) code = Column(Integer, nullable=False)
msg = Column(String, nullable=False) note = Column(String, nullable=False)
created_at = Column(DateTime, nullable=False) created_at = Column(DateTime, nullable=False, default=dt.utcnow())
class Bans (base): # pylint: disable=too-few-public-methods, C0103 class Bans (base): # pylint: disable=too-few-public-methods, C0103
@ -118,8 +117,8 @@ class Bans (base): # pylint: disable=too-few-public-methods, C0103
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
ip_address = Column(String, nullable=False) ip_address = Column(String, nullable=False)
code = Column(Integer, nullable=False) code = Column(Integer, nullable=False)
msg = Column(String, nullable=False) note = Column(String, nullable=False)
created_at = Column(DateTime, nullable=False) banned_at = Column(DateTime, nullable=False, default=dt.utcnow())
# check if database file exists, if not create it # check if database file exists, if not create it

View file

@ -2,7 +2,7 @@
{% block nav_groups %}selected{% endblock %} {% block nav_groups %}selected{% endblock %}
{% block head %} {% block head %}
{% if images %} {% if images %}
<meta name="theme-color" content="rgb({{ images.0.image_colours.0.0 }}{{ images.0.image_colours.0.1 }}{{ images.0.image_colours.0.2 }})"/> <meta name="theme-color" content="rgb({{ images.0.colours.0.0 }}{{ images.0.colours.0.1 }}{{ images.0.colours.0.2 }})"/>
{% endif %} {% endif %}
<script type="text/javascript"> <script type="text/javascript">
@ -175,7 +175,7 @@
<style> <style>
{% if images %} {% if images %}
.banner::after { .banner::after {
box-shadow: 0 calc(var(--rad) * -1) 0 0 rgb({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }}); box-shadow: 0 calc(var(--rad) * -1) 0 0 rgb({{ images.0.colours.0.0 }}, {{ images.0.colours.0.1 }}, {{ images.0.colours.0.2 }});
} }
.banner-content p { .banner-content p {
color: {{ text_colour }} !important; color: {{ text_colour }} !important;
@ -185,16 +185,16 @@
} }
.banner-filter { .banner-filter {
background: linear-gradient(90deg, rgb({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }}), rgba({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }}, 0.3)) !important; background: linear-gradient(90deg, rgb({{ images.0.colours.0.0 }}, {{ images.0.colours.0.1 }}, {{ images.0.colours.0.2 }}), rgba({{ images.0.colours.0.0 }}, {{ images.0.colours.0.1 }}, {{ images.0.colours.0.2 }}, 0.3)) !important;
} }
@media (max-width: 800px) { @media (max-width: 800px) {
.banner-filter { .banner-filter {
background: linear-gradient(180deg, rgba({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }}, 0.8), rgba({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }}, 0.5)) !important; background: linear-gradient(180deg, rgba({{ images.0.colours.0.0 }}, {{ images.0.colours.0.1 }}, {{ images.0.colours.0.2 }}, 0.8), rgba({{ images.0.colours.0.0 }}, {{ images.0.colours.0.1 }}, {{ images.0.colours.0.2 }}, 0.5)) !important;
} }
} }
.navigation { .navigation {
background-color: rgb({{ images.0.image_colours.0.0 }}, {{ images.0.image_colours.0.1 }}, {{ images.0.image_colours.0.2 }}) !important; background-color: rgb({{ images.0.colours.0.0 }}, {{ images.0.colours.0.1 }}, {{ images.0.colours.0.2 }}) !important;
} }
.navigation-item > svg { .navigation-item > svg {
fill: {{ text_colour }} !important; fill: {{ text_colour }} !important;
@ -209,7 +209,7 @@
{% block content %} {% block content %}
{% if images %} {% if images %}
<div class="banner"> <div class="banner">
<img src="{{ url_for('api.file', file_name=images.0.file_name ) }}?r=prev" onload="imgFade(this)" style="opacity:0;"/> <img src="{{ url_for('api.file', file_name=images.0.filename ) }}?r=prev" onload="imgFade(this)" style="opacity:0;"/>
<span class="banner-filter"></span> <span class="banner-filter"></span>
<div class="banner-content"> <div class="banner-content">
<p class="banner-info">By {{ group.author_username }} - {{ images|length }} Images</p> <p class="banner-info">By {{ group.author_username }} - {{ images|length }} Images</p>
@ -266,7 +266,7 @@
<p class="image-subtitle"></p> <p class="image-subtitle"></p>
<p class="image-title"><span class="time">{{ image.created_at }}</span></p> <p class="image-title"><span class="time">{{ image.created_at }}</span></p>
</div> </div>
<img alt="{{ image.post_alt }}" data-src="{{ url_for('api.file', file_name=image.file_name) }}?r=thumb" onload="this.classList.add('loaded');" id="lazy-load"/> <img alt="{{ image.alt }}" data-src="{{ url_for('api.file', file_name=image.filename) }}?r=thumb" onload="this.classList.add('loaded');" id="lazy-load"/>
</a> </a>
{% endfor %} {% endfor %}
</div> </div>

View file

@ -2,7 +2,7 @@
{% block nav_groups %}selected{% endblock %} {% block nav_groups %}selected{% endblock %}
{% block head %} {% block head %}
{% if images %} {% if images %}
<meta name="theme-color" content="rgb({{ images.0.image_colours.0.0 }}{{ images.0.image_colours.0.1 }}{{ images.0.image_colours.0.2 }})"/> <meta name="theme-color" content="rgb({{ images.0.colours.0.0 }}{{ images.0.colours.0.1 }}{{ images.0.colours.0.2 }})"/>
{% endif %} {% endif %}
{% if current_user.is_authenticated %} {% if current_user.is_authenticated %}
@ -127,7 +127,7 @@
<div class="images size-{{ group.images|length }}"> <div class="images size-{{ group.images|length }}">
{% if group.images|length > 0 %} {% if group.images|length > 0 %}
{% for image in group.images %} {% for image in group.images %}
<img data-src="{{ url_for('api.file', file_name=image.file_name) }}?r=thumb" onload="this.classList.add('loaded');" id="lazy-load" class="data-{{ loop.index }}"/> <img data-src="{{ url_for('api.file', file_name=image.filename) }}?r=thumb" onload="this.classList.add('loaded');" id="lazy-load" class="data-{{ loop.index }}"/>
{% endfor %} {% endfor %}
{% else %} {% else %}
<img src="{{ url_for('static', filename='error.png') }}" class="loaded"/> <img src="{{ url_for('static', filename='error.png') }}" class="loaded"/>

View file

@ -1,8 +1,8 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block wrapper_class %}image-wrapper{% endblock %} {% block wrapper_class %}image-wrapper{% endblock %}
{% block head %} {% block head %}
<meta property="og:image" content="{{ url_for('api.file', file_name=image.file_name) }}"/> <meta property="og:image" content="{{ url_for('api.file', file_name=image.filename) }}"/>
<meta name="theme-color" content="rgb({{ image.image_colours.0.0 }}{{ image.image_colours.0.1 }}{{ image.image_colours.0.2 }})"/> <meta name="theme-color" content="rgb({{ image.colours.0.0 }}{{ image.colours.0.1 }}{{ image.colours.0.2 }})"/>
<script type="text/javascript"> <script type="text/javascript">
function imageFullscreenOff() { function imageFullscreenOff() {
@ -18,7 +18,7 @@
function imageFullscreenOn() { function imageFullscreenOn() {
let fullscreen = document.querySelector('.image-fullscreen') let fullscreen = document.querySelector('.image-fullscreen')
fullscreen.querySelector('img').src = '{{ url_for('api.file', file_name=image.file_name) }}'; fullscreen.querySelector('img').src = '{{ url_for('api.file', file_name=image.filename) }}';
document.querySelector("html").style.overflow = "hidden"; document.querySelector("html").style.overflow = "hidden";
fullscreen.style.display = 'flex'; fullscreen.style.display = 'flex';
@ -80,31 +80,31 @@
<style> <style>
.background span { .background span {
background-image: linear-gradient(to top, rgba({{ image.image_colours.0.0 }}, {{ image.image_colours.0.1 }}, {{ image.image_colours.0.2 }}, 1), transparent); background-image: linear-gradient(to top, rgba({{ image.colours.0.0 }}, {{ image.colours.0.1 }}, {{ image.colours.0.2 }}, 1), transparent);
} }
</style> </style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="background"> <div class="background">
<img src="{{ url_for('api.file', file_name=image.file_name) }}?r=prev" alt="{{ image.post_alt }}" onload="imgFade(this)" style="opacity:0;"/> <img src="{{ url_for('api.file', file_name=image.filename) }}?r=prev" alt="{{ image.alt }}" onload="imgFade(this)" style="opacity:0;"/>
<span></span> <span></span>
</div> </div>
<div class="image-fullscreen" onclick="imageFullscreenOff()"> <div class="image-fullscreen" onclick="imageFullscreenOff()">
<img src="" alt="{{ image.post_alt }}"/> <img src="" alt="{{ image.alt }}"/>
</div> </div>
<div class="image-grid"> <div class="image-grid">
<div class="image-container" id="image-container"> <div class="image-container" id="image-container">
<img <img
src="{{ url_for('api.file', file_name=image.file_name) }}?r=prev" src="{{ url_for('api.file', file_name=image.filename) }}?r=prev"
alt="{{ image.post_alt }}" alt="{{ image.alt }}"
onload="imgFade(this)" onload="imgFade(this)"
style="opacity: 0;" style="opacity: 0;"
onerror="this.src='{{ url_for('static', filename='error.png')}}'" onerror="this.src='{{ url_for('static', filename='error.png')}}'"
{% if "File" in image.image_exif %} {% if "File" in image.exif %}
width="{{ image.image_exif.File.Width.raw }}" width="{{ image.exif.File.Width.raw }}"
height="{{ image.image_exif.File.Height.raw }}" height="{{ image.exif.File.Height.raw }}"
{% endif %} {% endif %}
/> />
</div> </div>
@ -136,7 +136,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,48,88H208a8,8,0,0,1,5.66,13.66Z"></path></svg>
</span> </span>
</button> </button>
<a class="pill-item" href="/api/file/{{ image.file_name }}" download onclick="addNotification('Download started!', 4)"> <a class="pill-item" href="/api/file/{{ image.filename }}" download onclick="addNotification('Download started!', 4)">
<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> <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>
<span class="tool-tip"> <span class="tool-tip">
Download Download
@ -210,7 +210,7 @@
</tr> </tr>
</table> </table>
<div class="img-colours"> <div class="img-colours">
{% for col in image.image_colours %} {% for col in image.colours %}
<span style="background-color: rgb({{col.0}}, {{col.1}}, {{col.2}})"></span> <span style="background-color: rgb({{col.0}}, {{col.1}}, {{col.2}})"></span>
{% endfor %} {% endfor %}
</div> </div>
@ -226,7 +226,7 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
{% for tag in image.image_exif %} {% for tag in image.exif %}
<div class="info-tab"> <div class="info-tab">
<div class="info-header"> <div class="info-header">
{% if tag == 'Photographer' %} {% if tag == 'Photographer' %}
@ -251,17 +251,17 @@
</div> </div>
<div class="info-table"> <div class="info-table">
<table> <table>
{% for subtag in image.image_exif[tag] %} {% for subtag in image.exif[tag] %}
<tr> <tr>
<td>{{ subtag }}</td> <td>{{ subtag }}</td>
{% if image.image_exif[tag][subtag]['formatted'] %} {% if image.exif[tag][subtag]['formatted'] %}
{% if image.image_exif[tag][subtag]['type'] == 'date' %} {% if image.exif[tag][subtag]['type'] == 'date' %}
<td><span class="time">{{ image.image_exif[tag][subtag]['formatted'] }}</span></td> <td><span class="time">{{ image.exif[tag][subtag]['formatted'] }}</span></td>
{% else %} {% else %}
<td>{{ image.image_exif[tag][subtag]['formatted'] }}</td> <td>{{ image.exif[tag][subtag]['formatted'] }}</td>
{% endif %} {% endif %}
{% elif image.image_exif[tag][subtag]['raw'] %} {% elif image.exif[tag][subtag]['raw'] %}
<td>{{ image.image_exif[tag][subtag]['raw'] }}</td> <td>{{ image.exif[tag][subtag]['raw'] }}</td>
{% else %} {% else %}
<td class="empty-table">Oops, an error</td> <td class="empty-table">Oops, an error</td>
{% endif %} {% endif %}

View file

@ -16,12 +16,12 @@
{% if images %} {% if images %}
<div class="gallery-grid"> <div class="gallery-grid">
{% for image in images %} {% for image in images %}
<a id="image-{{ image.id }}" class="gallery-item" href="{{ url_for('gallery.image', image_id=image.id) }}" style="background-color: rgb({{ image.image_colours.0.0 }}, {{ image.image_colours.0.1 }}, {{ image.image_colours.0.2 }})"> <a id="image-{{ image.id }}" class="gallery-item" href="{{ url_for('gallery.image', image_id=image.id) }}" style="background-color: rgb({{ image.colours.0.0 }}, {{ image.colours.0.1 }}, {{ image.colours.0.2 }})">
<div class="image-filter"> <div class="image-filter">
<p class="image-subtitle"></p> <p class="image-subtitle"></p>
<p class="image-title"><span class="time">{{ image.created_at }}</span></p> <p class="image-title"><span class="time">{{ image.created_at }}</span></p>
</div> </div>
<img fetchpriority="low" alt="{{ image.post_alt }}" data-src="{{ url_for('api.file', file_name=image.file_name) }}?r=thumb" onload="this.classList.add('loaded');" id="lazy-load"/> <img fetchpriority="low" alt="{{ image.alt }}" data-src="{{ url_for('api.file', file_name=image.filename) }}?r=thumb" onload="this.classList.add('loaded');" id="lazy-load"/>
</a> </a>
{% endfor %} {% endfor %}
</div> </div>

View file

@ -5,18 +5,18 @@
<div class="banner-small"> <div class="banner-small">
<div class="banner-content"> <div class="banner-content">
<h1 class="banner-header">{{ user.username }}</h1> <h1 class="banner-header">{{ user.username }}</h1>
<p class="banner-info">Member since <span class="time">{{ user.created_at }}</span></p> <p class="banner-info">Member since <span class="time">{{ user.joined_at }}</span></p>
</div> </div>
</div> </div>
{% if images %} {% if images %}
<div class="gallery-grid"> <div class="gallery-grid">
{% for image in images %} {% for image in images %}
<a id="image-{{ image.id }}" class="gallery-item" href="{{ url_for('gallery.image', image_id=image.id) }}" style="background-color: rgb({{ image.image_colours.0.0 }}, {{ image.image_colours.0.1 }}, {{ image.image_colours.0.2 }})"> <a id="image-{{ image.id }}" class="gallery-item" href="{{ url_for('gallery.image', image_id=image.id) }}" style="background-color: rgb({{ image.colours.0.0 }}, {{ image.colours.0.1 }}, {{ image.colours.0.2 }})">
<div class="image-filter"> <div class="image-filter">
<p class="image-subtitle"></p> <p class="image-subtitle"></p>
<p class="image-title"><span class="time">{{ image.created_at }}</span></p> <p class="image-title"><span class="time">{{ image.created_at }}</span></p>
</div> </div>
<img fetchpriority="low" alt="{{ image.post_alt }}" data-src="{{ url_for('api.file', file_name=image.file_name) }}?r=thumb" onload="this.classList.add('loaded');" id="lazy-load"/> <img fetchpriority="low" alt="{{ image.alt }}" data-src="{{ url_for('api.file', file_name=image.filename) }}?r=thumb" onload="this.classList.add('loaded');" id="lazy-load"/>
</a> </a>
{% endfor %} {% endfor %}
</div> </div>

View file

@ -5,10 +5,9 @@ from uuid import uuid4
import os import os
import pathlib import pathlib
import logging import logging
from datetime import datetime as dt
import platformdirs import platformdirs
from flask import Blueprint, send_from_directory, abort, flash, jsonify, request, current_app from flask import Blueprint, send_from_directory, abort, flash, request, current_app
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
from flask_login import login_required, current_user from flask_login import login_required, current_user
@ -85,13 +84,12 @@ def upload():
# Save to database # Save to database
query = db.Posts(author_id=current_user.id, query = db.Posts(author_id=current_user.id,
created_at=dt.utcnow(), filename=img_name + '.' + img_ext,
file_name=img_name+'.'+img_ext, mimetype=img_ext,
file_type=img_ext, exif=img_exif,
image_exif=img_exif, colours=img_colors,
image_colours=img_colors, description=form['description'],
post_description=form['description'], alt=form['alt'])
post_alt=form['alt'])
db_session.add(query) db_session.add(query)
db_session.commit() db_session.commit()
@ -115,13 +113,13 @@ def delete_image(image_id):
# Delete file # Delete file
try: try:
os.remove(os.path.join(current_app.config['UPLOAD_FOLDER'], img.file_name)) os.remove(os.path.join(current_app.config['UPLOAD_FOLDER'], img.filename))
except FileNotFoundError: except FileNotFoundError:
logging.warning('File not found: %s, already deleted or never existed', img.file_name) logging.warning('File not found: %s, already deleted or never existed', img.filename)
# Delete cached files # Delete cached files
cache_path = os.path.join(platformdirs.user_config_dir('onlylegs'), 'cache') cache_path = os.path.join(platformdirs.user_config_dir('onlylegs'), 'cache')
cache_name = img.file_name.rsplit('.')[0] cache_name = img.filename.rsplit('.')[0]
for cache_file in pathlib.Path(cache_path).glob(cache_name + '*'): for cache_file in pathlib.Path(cache_path).glob(cache_name + '*'):
os.remove(cache_file) os.remove(cache_file)
@ -136,7 +134,7 @@ def delete_image(image_id):
# Commit all changes # Commit all changes
db_session.commit() db_session.commit()
logging.info('Removed image (%s) %s', image_id, img.file_name) logging.info('Removed image (%s) %s', image_id, img.filename)
flash(['Image was all in Le Head!', '1']) flash(['Image was all in Le Head!', '1'])
return 'Gwa Gwa' return 'Gwa Gwa'
@ -149,8 +147,7 @@ def create_group():
""" """
new_group = db.Groups(name=request.form['name'], new_group = db.Groups(name=request.form['name'],
description=request.form['description'], description=request.form['description'],
author_id=current_user.id, author_id=current_user.id)
created_at=dt.utcnow())
db_session.add(new_group) db_session.add(new_group)
db_session.commit() db_session.commit()
@ -180,8 +177,7 @@ def modify_group():
.filter_by(group_id=group_id, post_id=image_id) .filter_by(group_id=group_id, post_id=image_id)
.first()): .first()):
db_session.add(db.GroupJunction(group_id=group_id, db_session.add(db.GroupJunction(group_id=group_id,
post_id=image_id, post_id=image_id))
date_added=dt.utcnow()))
elif request.form['action'] == 'remove': elif request.form['action'] == 'remove':
(db_session.query(db.GroupJunction) (db_session.query(db.GroupJunction)
.filter_by(group_id=group_id, post_id=image_id) .filter_by(group_id=group_id, post_id=image_id)

View file

@ -37,8 +37,8 @@ def groups():
# For each image, get the image data and add it to the group item # For each image, get the image data and add it to the group item
group.images = [] group.images = []
for image in images: for image in images:
group.images.append(db_session.query(db.Posts.file_name, db.Posts.post_alt, group.images.append(db_session.query(db.Posts.filename, db.Posts.alt,
db.Posts.image_colours, db.Posts.id) db.Posts.colours, db.Posts.id)
.filter(db.Posts.id == image[0]) .filter(db.Posts.id == image[0])
.first()) .first())
@ -79,7 +79,7 @@ def group(group_id):
# Check contrast for the first image in the group for the banner # Check contrast for the first image in the group for the banner
text_colour = 'rgb(var(--fg-black))' text_colour = 'rgb(var(--fg-black))'
if images: if images:
text_colour = contrast.contrast(images[0].image_colours[0], text_colour = contrast.contrast(images[0].colours[0],
'rgb(var(--fg-black))', 'rgb(var(--fg-black))',
'rgb(var(--fg-white))') 'rgb(var(--fg-white))')

View file

@ -19,9 +19,9 @@ def index():
""" """
Home page of the website, shows the feed of the latest images Home page of the website, shows the feed of the latest images
""" """
images = db_session.query(db.Posts.file_name, images = db_session.query(db.Posts.filename,
db.Posts.post_alt, db.Posts.alt,
db.Posts.image_colours, db.Posts.colours,
db.Posts.created_at, db.Posts.created_at,
db.Posts.id).order_by(db.Posts.id.desc()).all() db.Posts.id).order_by(db.Posts.id.desc()).all()