Update admin panel

This commit is contained in:
augustin64 2022-12-19 15:19:58 +01:00
parent f226a80046
commit 7841612299
13 changed files with 260 additions and 39 deletions

View File

@ -7,6 +7,7 @@ import os
from flask import Flask, g, redirect, render_template, request, send_file, flash
from werkzeug.security import generate_password_hash
from .modules.utils import User, Album, get_all_albums
from .modules import albums, auth, partition, admin
from .modules.auth import admin_required
from .modules.db import get_db
@ -43,6 +44,7 @@ def add_user():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
album_uuid = request.form["album_uuid"]
db = get_db()
error = None
@ -64,11 +66,17 @@ def add_user():
error = f"Le nom d'utilisateur {username} est déjà pris."
else:
# Success, go to the login page.
flash(f"Utilisateur {username} crée")
return redirect("/albums")
user = User(name=username)
try:
user.join_album(album_uuid)
flash(f"Utilisateur {username} créé")
return redirect("/albums")
except LookupError:
flash(f"Cet album n'existe pas. L'utilisateur {username} a été créé")
return redirect("/albums")
flash(error)
return render_template("auth/register.html")
return render_template("auth/register.html", albums=get_all_albums())
if __name__ == "__main__":

View File

@ -21,10 +21,12 @@ def index():
SELECT id FROM user
"""
)
users = [User(u["id"]) for u in users_id]
users = [User(user_id=u["id"]) for u in users_id]
for u in users:
u.albums = u.get_albums()
u.partitions = u.get_partitions()
db.close()
return render_template(
"admin/index.html",
users=users

View File

@ -20,7 +20,7 @@ bp = Blueprint("albums", __name__, url_prefix="/albums")
@bp.route("/")
@login_required
def index():
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
albums = user.get_albums()
if user.access_level == 1:
@ -43,7 +43,7 @@ def search_page():
search.flush_cache()
partitions_local = search.local_search(query, get_all_partitions())
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
if nb_queries > 0:
if user.access_level != 1:
@ -69,8 +69,8 @@ def album(uuid):
"""
try:
album = Album(uuid=uuid)
album.users = [User(i["id"]) for i in album.get_users()]
user = User(session.get("user_id"))
album.users = [User(user_id=i["id"]) for i in album.get_users()]
user = User(user_id=session.get("user_id"))
partitions = album.get_partitions()
if user.id is None:
# On ne propose pas aux gens non connectés de rejoindre l'album
@ -164,7 +164,7 @@ def create_album():
@bp.route("/<uuid>/join")
@login_required
def join_album(uuid):
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
try:
user.join_album(uuid)
except LookupError:
@ -178,7 +178,7 @@ def join_album(uuid):
@bp.route("/<uuid>/quit")
@login_required
def quit_album(uuid):
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
album = Album(uuid=uuid)
users = album.get_users()
if user.id not in [u["id"] for u in users]:
@ -205,7 +205,7 @@ def delete_album(uuid):
error = None
users = album.get_users()
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
if len(users) > 1:
error = "Vous n'êtes pas seul dans cet album."
elif len(users) == 1 and users[0]["id"] != user.id:
@ -228,7 +228,7 @@ def delete_album(uuid):
@login_required
def add_partition(album_uuid):
db = get_db()
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
album = Album(uuid=album_uuid)
if (not user.is_participant(album.uuid)) and (user.access_level != 1):
@ -322,9 +322,8 @@ def add_partition(album_uuid):
@bp.route("/add-partition", methods=["POST"])
@login_required
def add_partition_from_search():
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
error = None
db = get_db()
if "album-uuid" not in request.form:
error = "Il est nécessaire de sélectionner un album."
@ -341,6 +340,7 @@ def add_partition_from_search():
album = Album(request.form["album-uuid"])
if request.form["partition-type"] == "local_file":
db = get_db()
data = db.execute(
"""
SELECT * FROM contient_partition

View File

@ -46,7 +46,7 @@ def admin_required(view):
flash("Vous devez être connecté pour accéder à cette page.")
return redirect(url_for("auth.login"))
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
if user.access_level != 1:
flash("Droits insuffisants.")
return redirect("/albums")

View File

@ -40,7 +40,7 @@ def edit(uuid):
except LookupError:
abort(404)
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
if user.access_level != 1 and partition.user_id != user.id:
flash("Vous n'êtes pas autorisé à modifier cette partition.")
return redirect("/albums")
@ -71,6 +71,52 @@ def edit(uuid):
return redirect("/albums")
@bp.route("/<uuid>/details", methods=["GET", "POST"])
@admin_required
def details(uuid):
db = get_db()
try:
partition = Partition(uuid=uuid)
except LookupError:
abort(404)
user = User(user_id=session.get("user_id"))
try:
partition_user = partition.get_user()
except LookupError:
partition_user = None
if request.method == "GET":
return render_template(
"partition/details.html",
partition=partition,
user=partition_user,
albums=partition.get_albums()
)
error = None
if "name" not in request.form or request.form["name"].strip() == "":
error = "Un titre est requis."
elif "author" not in request.form:
error = "Un nom d'auteur est requis (à minima nul)"
elif "body" not in request.form:
error = "Des paroles sont requises (à minima nulles)"
if error is not None:
flash(error)
return redirect(f"/partition/{ uuid }/details")
partition.update(
name=request.form["name"],
author=request.form["author"],
body=request.form["body"]
)
flash(f"Partition {request.form['name']} modifiée avec succès.")
return redirect("/albums")
@bp.route("/<uuid>/delete", methods=["GET", "POST"])
@login_required
def delete(uuid):
@ -79,7 +125,7 @@ def delete(uuid):
except LookupError:
abort(404)
user = User(session.get("user_id"))
user = User(user_id=session.get("user_id"))
if user.access_level != 1 and partition.user_id != user.id:
flash("Vous n'êtes pas autorisé à supprimer cette partition.")
@ -116,5 +162,5 @@ def partition_search(uuid):
@bp.route("/")
@admin_required
def index():
partitions = get_all_partitions().fetchall()
partitions = get_all_partitions()
return render_template("admin/partitions.html", partitions=partitions)

View File

@ -124,4 +124,5 @@ def flush_cache():
DELETE FROM search_results
WHERE creation_time <= datetime('now', '-15 minutes', 'localtime')
"""
)
)
db.commit()

View File

@ -3,23 +3,36 @@ import os
from .db import get_db
class User():
def __init__(self, user_id):
def __init__(self, user_id=None, name=None):
self.id = user_id
self.username = name
self.albums = None
self.partitions = None
db = get_db()
if self.id is None:
if self.id is None and self.username is None:
self.username = ""
self.access_level = -1
else:
data = db.execute(
"""
SELECT username, access_level FROM user
WHERE id = ?
""",
(self.id,)
).fetchone()
if self.id is not None:
data = db.execute(
"""
SELECT * FROM user
WHERE id = ?
""",
(self.id,)
).fetchone()
elif self.username is not None:
data = db.execute(
"""
SELECT * FROM user
WHERE username = ?
""",
(self.username,)
).fetchone()
self.id = data["id"]
self.username = data["username"]
self.access_level = data["access_level"]
self.color = self.get_color()
@ -57,6 +70,24 @@ class User():
(self.id,),
).fetchall()
def get_partitions(self):
db = get_db()
if self.access_level == 1:
return db.execute(
"""
SELECT * FROM partition
"""
).fetchall()
return db.execute(
"""
SELECT * FROM partition
JOIN user ON user_id = user.id
WHERE user.id = ?
""",
(self.id,),
).fetchall()
def join_album(self, album_uuid):
db = get_db()
@ -294,6 +325,34 @@ class Partition():
)
db.commit()
def get_user(self):
db = get_db()
user = db.execute(
"""
SELECT * FROM user
JOIN partition ON user_id = user.id
WHERE partition.uuid = ?
""",
(self.uuid,),
).fetchone()
if user is None:
raise LookupError
return User(user_id=user["id"])
def get_albums(self):
db = get_db()
return db.execute(
"""
SELECT * FROM album
JOIN contient_partition ON album.id = album_id
WHERE partition_uuid = ?
""",
(self.uuid,),
).fetchall()
def get_all_partitions():
db = get_db()
@ -302,4 +361,29 @@ def get_all_partitions():
SELECT * FROM partition
"""
)
return partitions
# Transform sql object to dictionary usable in any thread
return [
{
"uuid": p["uuid"],
"name": p["name"],
"author": p["author"],
"body": p["body"],
"user_id": p["user_id"]
} for p in partitions
]
def get_all_albums():
db = get_db()
albums = db.execute(
"""
SELECT * FROM album
"""
)
# Transform sql object to dictionary usable in any thread
return [
{
"id": a["id"],
"name": a["name"],
"uuid": a["uuid"]
} for a in albums
]

View File

@ -336,4 +336,25 @@ td {
#paroles {
font-family: inherit;
font-size: 0.8rem;
}
.button:hover {
background-color: #ddd;
}
.button {
display: inline;
background-color: lightgray;
padding: 2px;
margin: 2px;
border-radius: 2px;
font-size: 0.9rem;
}
#actions-rapides {
text-align: center;
}
#actions-rapides a {
text-decoration: none;
}

View File

@ -8,11 +8,16 @@
{% endblock %}
{% block content %}
<div id="actions-rapides">
<a href="/add-user"><div class="button">Ajouter un utilisateur</div></a>
<a href="/partition"><div class="button">Voir toutes les partitions</div></a>
</div>
<table>
<thead>
<tr>
<th scope="col">Utilisateur</th>
<th scope="col">Albums</th>
<th scope="col">Partitions</th>
<th scope="col">Privilèges</th>
</tr>
</thead>
@ -28,6 +33,7 @@
</div>
</td>
<td>{{ user.albums | length }}</td>
<td>{{ user.partitions | length }}</td>
<td>{% if user.access_level != 1 %}❌{% else %}✅{% endif %}</td>
</tr>
{% endfor %}

View File

@ -8,15 +8,18 @@
{% if partitions|length != 0 %}
<div id="partitions-grid">
{% for partition in partitions %}
<a href="/partition/{{ partition['uuid'] }}">
<div class="partition" id="partition-{{ partition['uuid'] }}">
<img class="partition-thumbnail" src="/static/thumbnails/{{ partition['uuid'] }}.jpg">
<div class="partition-description">
<div class="partition-name">{{ partition["name"] }}</div>
<div class="partition-author">{{ partition["author"] }}</div>
<div>
<a href="/partition/{{ partition['uuid'] }}">
<div class="partition" id="partition-{{ partition['uuid'] }}">
<img class="partition-thumbnail" src="/static/thumbnails/{{ partition['uuid'] }}.jpg">
<div class="partition-description">
<div class="partition-name">{{ partition["name"] }}</div>
<div class="partition-author">{{ partition["author"] }}</div>
</div>
</div>
</div>
</a>
</a>
<a href="/partition/{{ partition['uuid'] }}/details"><div class="edit-button">🔍</div></a>
</div>
{% endfor %}
</div>
{% else %}

View File

@ -53,6 +53,7 @@
{% endfor %}
</div>
{% else %}
<div id="partitions-grid">Aucune partition disponible</div>
<br/>
<div id="partitions-grid" style="display: inline;">Aucune partition disponible</div>
{% endif %}
{% endblock %}

View File

@ -5,11 +5,18 @@
{% endblock %}
{% block content %}
<form method="post">
<form method="post" id="add-user-form">
<label for="username">Nom d'utilisateur</label>
<input name="username" id="username" required>
<label for="password">Mot de passe</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="Créer un compte">
</form>
<label for="album_uuid">Ajouter à un album: </label>
<select name="album_uuid" id="album_uuid" form="add-user-form">
<option value="">Aucun</option>
{% for album in albums %}
<option value="{{ album['uuid'] }}">{{ album["name"] }}</option>
{% endfor %}
</select>
{% endblock %}

View File

@ -0,0 +1,42 @@
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Détails - {{ partition.name }}{% endblock %}</h1>
{% endblock %}
{% block content %}
<br />
{% if user is not none %}
Auteur: <div class="user-profile">
<div class="username" style="margin-top: 6px;">{{ user.username }}</div>
<div class="user-profile-picture" style="background-color:{{ user.color }};" title="{{ user.username }}">
{{ user.username[0] | upper }}
</div>
</div>
{% else %}
Auteur: inconnu
{% endif %}
<div id="albums-list">
Albums:
<ul>
{% for album in albums %}
<li><a href="/albums/{{ album.uuid }}">{{ album.name }}</a></li>
{% endfor %}
</ul>
</div>
Fichier: <a href="/partition/{{ partition.uuid }}">voir le fichier ↗</a>
<form action="/partition/{{ partition.uuid }}/edit" method="post" enctype="multipart/form-data" id="edit-form">
Titre*
<input name="name" type="text" value="{{ partition.name }}" required />
Auteur
<input name="author" type="text" value="{{ partition.author }}" />
Paroles
<textarea id="paroles" name="body" type="text">{{ partition.body }}</textarea>
<input type="submit" value="Mettre à jour" />
</form>
<a href="/partition/{{ partition.uuid }}/delete">
<button id="supprimer-partition" style="width: 132px;">Supprimer</button>
</a>
{% endblock %}