Merge pull request #4 from partitioncloud/localization

Add localization
This commit is contained in:
Augustin 2024-01-26 19:32:48 +01:00 committed by GitHub
commit bf48ed29d7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 1522 additions and 206 deletions

4
.gitignore vendored
View File

@ -1,6 +1,10 @@
# cache # cache
**/__pycache__ **/__pycache__
# translations
**.mo
**.pot
# config # config
.vscode/ .vscode/

View File

@ -27,6 +27,7 @@ git clone https://github.com/partitioncloud/partitioncloud-server.git
cd partitioncloud-server cd partitioncloud-server
# Install dependencies # Install dependencies
pip install -r requirements.txt pip install -r requirements.txt
pybabel compile -d partitioncloud/translations
# Create database and folders # Create database and folders
./make.sh init ./make.sh init
``` ```
@ -66,6 +67,30 @@ Modifier le fichier de configuration créé dans `instance/`
![Recherche](https://github.com/partitioncloud/partitioncloud-server/assets/67148092/745bf3e3-37e9-40cd-80d2-14670bce1a45) ![Recherche](https://github.com/partitioncloud/partitioncloud-server/assets/67148092/745bf3e3-37e9-40cd-80d2-14670bce1a45)
## Translations
### Créer une nouvelle traduction
```bash
# Extraire les données
pybabel extract -F babel.cfg -k _l -o partitioncloud/translations/messages.pot .
# Créer un nouveau fichier
pybabel init -i partitioncloud/translations/messages.pot -d partitioncloud/translations/ -l $COUNTRY_CODE
# Modifier translations/$COUNTRY_CODE/LC_MESSAGES/messages.po
# Ajouter $COUNTRY_CODE dans default_config.py: LANGUAGES
# Compiler les nouvelles translations avant de démarrer le serveur
pybabel compile -d partitioncloud/translations/
```
### Mettre à jour une traduction
```bash
# Récupérer les données les plus récentes
pybabel extract -F babel.cfg -k _l -o partitioncloud/translations/messages.pot .
# Les ajouter aux traductions
pybabel update -i partitioncloud/translations/messages.pot -d partitioncloud/translations/
```
## TODO ## TODO
- [ ] Modifier son mot de passe - [ ] Modifier son mot de passe
- [ ] Supprimer un utilisateur - [ ] Supprimer un utilisateur

2
babel.cfg Normal file
View File

@ -0,0 +1,2 @@
[python: partitioncloud/**.py]
[jinja2: partitioncloud/templates/**.html]

View File

@ -26,4 +26,7 @@ MAX_AGE=31
INSTANCE_PATH="instance" INSTANCE_PATH="instance"
# Events to log # Events to log
ENABLED_LOGS=["NEW_GROUPE", "NEW_ALBUM", "NEW_PARTITION", "NEW_USER", "SERVER_RESTART", "FAILED_LOGIN"] ENABLED_LOGS=["NEW_GROUPE", "NEW_ALBUM", "NEW_PARTITION", "NEW_USER", "SERVER_RESTART", "FAILED_LOGIN"]
# Available languages
LANGUAGES=['en', 'fr']

28
make.sh
View File

@ -25,30 +25,50 @@ init () {
echo "Utilisateur root:root ajouté" echo "Utilisateur root:root ajouté"
} }
translations () {
# Rajouter les chaînes non traduites
pybabel extract -F babel.cfg -k _l -o partitioncloud/translations/messages.pot .
pybabel update -i partitioncloud/translations/messages.pot -d partitioncloud/translations/
# Compiler
pybabel compile -d partitioncloud/translations/
}
start () { start () {
pybabel compile -d partitioncloud/translations/
flask run --port=$PORT flask run --port=$PORT
} }
production () { production () {
pybabel compile -d partitioncloud/translations/
FLASK_APP=partitioncloud /usr/bin/gunicorn \ FLASK_APP=partitioncloud /usr/bin/gunicorn \
wsgi:app \ wsgi:app \
--bind 0.0.0.0:$PORT --bind 0.0.0.0:$PORT
} }
load_config () {
# Load variables PORT and INSTANCE_PATH
eval $(cat $1 | grep -E "^PORT=")
eval $(cat $1 | grep -E "^INSTANCE_PATH=")
}
usage () { usage () {
echo "Usage:" echo "Usage:"
echo -e "\t$0 init" echo -e "\t$0 init"
echo -e "\t$0 start" echo -e "\t$0 start"
echo -e "\t$0 production"
echo -e "\t$0 translations"
} }
if [[ $1 && $(type "$1") = *"is a"*"function"* || $(type "$1") == *"est une fonction"* ]]; then
RESULT=$(type "$1")
if [[ $1 && $RESULT = *"is a"*"function"* || $RESULT == *"est une fonction"* ]]; then
# Import config # Import config
source "default_config.py" load_config "default_config.py"
[[ ! -x "$INSTANCE_PATH/config.py" ]] && source "$INSTANCE_PATH/config.py" [[ ! -x "$INSTANCE_PATH/config.py" ]] && load_config "$INSTANCE_PATH/config.py"
$1 ${*:2} # Call the function $1 ${*:2} # Call the function
else else
usage usage
echo $(type "$1") echo $RESULT
exit 1 exit 1
fi fi

View File

@ -10,6 +10,7 @@ import importlib.util
from flask import Flask, g, redirect, render_template, request, send_file, flash, session, abort from flask import Flask, g, redirect, render_template, request, send_file, flash, session, abort
from werkzeug.security import generate_password_hash from werkzeug.security import generate_password_hash
from flask_babel import Babel, _
from .modules.utils import User, Album, get_all_albums from .modules.utils import User, Album, get_all_albums
from .modules import albums, auth, partition, admin, groupe, thumbnails, logging from .modules import albums, auth, partition, admin, groupe, thumbnails, logging
@ -18,6 +19,12 @@ from .modules.db import get_db
app = Flask(__name__) app = Flask(__name__)
def get_locale():
return request.accept_languages.best_match(app.config['LANGUAGES'])
babel = Babel(app, locale_selector=get_locale)
def load_config(): def load_config():
app.config.from_object('default_config') app.config.from_object('default_config')
@ -125,10 +132,10 @@ def add_user():
try: try:
if album_uuid != "": if album_uuid != "":
user.join_album(album_uuid) user.join_album(album_uuid)
flash(f"Utilisateur {username} créé") flash(_("Created user %(username)s", username=username))
return redirect("/albums") return redirect("/albums")
except LookupError: except LookupError:
flash(f"Cet album n'existe pas. L'utilisateur {username} a été créé") flash(_("This album does not exists, but user %(username)s has been created", username=username))
return redirect("/albums") return redirect("/albums")
flash(error) flash(error)

View File

@ -9,6 +9,7 @@ from typing import TypeVar
from flask import (Blueprint, abort, flash, redirect, render_template, from flask import (Blueprint, abort, flash, redirect, render_template,
request, session, current_app) request, session, current_app)
from flask_babel import _
from .auth import login_required from .auth import login_required
from .db import get_db from .db import get_db
@ -37,7 +38,7 @@ def search_page():
Résultats de recherche Résultats de recherche
""" """
if "query" not in request.form or request.form["query"] == "": if "query" not in request.form or request.form["query"] == "":
flash("Aucun terme de recherche spécifié.") flash(_("Missing search query"))
return redirect("/albums") return redirect("/albums")
query = request.form["query"] query = request.form["query"]
@ -119,7 +120,7 @@ def create_album_req():
user = User(user_id=session["user_id"]) user = User(user_id=session["user_id"])
if not name or name.strip() == "": if not name or name.strip() == "":
error = "Un nom est requis. L'album n'a pas été créé" error = _("Missing name.")
if error is None: if error is None:
uuid = utils.create_album(name) uuid = utils.create_album(name)
@ -156,10 +157,10 @@ def join_album(uuid):
try: try:
user.join_album(uuid) user.join_album(uuid)
except LookupError: except LookupError:
flash("Cet album n'existe pas.") flash(_("This album does not exist."))
return redirect(request.referrer) return redirect(request.referrer)
flash("Album ajouté à la collection.") flash(_("Album added to collection."))
return redirect(request.referrer) return redirect(request.referrer)
@ -173,15 +174,15 @@ def quit_album(uuid):
album = Album(uuid=uuid) album = Album(uuid=uuid)
users = album.get_users() users = album.get_users()
if user.id not in [u["id"] for u in users]: if user.id not in [u["id"] for u in users]:
flash("Vous ne faites pas partie de cet album") flash(_("You are not a member of this album"))
return redirect(request.referrer) return redirect(request.referrer)
if len(users) == 1: if len(users) == 1:
flash("Vous êtes seul dans cet album, le quitter entraînera sa suppression.") flash(_("You are alone here, quitting means deleting this album."))
return redirect(f"/albums/{uuid}#delete") return redirect(f"/albums/{uuid}#delete")
user.quit_album(uuid) user.quit_album(uuid)
flash("Album quitté.") flash(_("Album quitted."))
return redirect("/albums") return redirect("/albums")
@ -200,9 +201,9 @@ def delete_album(uuid):
error = None error = None
users = album.get_users() users = album.get_users()
if len(users) > 1: if len(users) > 1:
error = "Vous n'êtes pas seul dans cet album." error = _("You are not alone in this album.")
elif len(users) == 1 and users[0]["id"] != user.id: elif len(users) == 1 and users[0]["id"] != user.id:
error = "Vous ne possédez pas cet album." error = _("You don't own this album.")
if user.access_level == 1: if user.access_level == 1:
error = None error = None
@ -213,7 +214,7 @@ def delete_album(uuid):
album.delete(current_app.instance_path) album.delete(current_app.instance_path)
flash("Album supprimé.") flash(_("Album deleted."))
return redirect("/albums") return redirect("/albums")
@ -236,15 +237,15 @@ def add_partition(album_uuid):
source = "upload" # source type: upload, unknown or url source = "upload" # source type: upload, unknown or url
if (not user.is_participant(album.uuid)) and (user.access_level != 1): if (not user.is_participant(album.uuid)) and (user.access_level != 1):
flash("Vous ne participez pas à cet album.") flash(_("You are not a member of this album"))
return redirect(request.referrer) return redirect(request.referrer)
error = None error = None
if "name" not in request.form: if "name" not in request.form:
error = "Un titre est requis." error = _("Missing title")
elif "file" not in request.files and "partition-uuid" not in request.form: elif "file" not in request.files and "partition-uuid" not in request.form:
error = "Aucun fichier n'a été fourni." error = _("Missing file")
elif "file" not in request.files: elif "file" not in request.files:
partition_type = "uuid" partition_type = "uuid"
search_uuid = request.form["partition-uuid"] search_uuid = request.form["partition-uuid"]
@ -256,7 +257,7 @@ def add_partition(album_uuid):
(search_uuid,) (search_uuid,)
).fetchone() ).fetchone()
if data is None: if data is None:
error = "Les résultats de la recherche ont expiré." error = _("Search results expired")
else: else:
source = data["url"] source = data["url"]
else: else:
@ -322,7 +323,7 @@ def add_partition(album_uuid):
"status": "ok", "status": "ok",
"uuid": partition_uuid "uuid": partition_uuid
} }
flash(f"Partition {request.form['name']} ajoutée") flash(_("Score %(partition_name)s added", partition_name=request.form['name']))
return redirect(f"/albums/{album.uuid}") return redirect(f"/albums/{album.uuid}")
@ -336,13 +337,13 @@ def add_partition_from_search():
error = None error = None
if "album-uuid" not in request.form: if "album-uuid" not in request.form:
error = "Il est nécessaire de sélectionner un album." error = _("Selecting an album is mandatory.")
elif "partition-uuid" not in request.form: elif "partition-uuid" not in request.form:
error = "Il est nécessaire de sélectionner une partition." error = _("Selecting a score is mandatory.")
elif "partition-type" not in request.form: elif "partition-type" not in request.form:
error = "Il est nécessaire de spécifier un type de partition." error = _("Please specify a score type.")
elif (not user.is_participant(request.form["album-uuid"])) and (user.access_level != 1): elif (not user.is_participant(request.form["album-uuid"])) and (user.access_level != 1):
error = "Vous ne participez pas à cet album." error = _("You are not a member of this album")
if error is not None: if error is not None:
flash(error) flash(error)
@ -362,9 +363,9 @@ def add_partition_from_search():
if data is None: if data is None:
album.add_partition(request.form["partition-uuid"]) album.add_partition(request.form["partition-uuid"])
flash("Partition ajoutée.") flash(_("Score added"))
else: else:
flash("Partition déjà dans l'album.") flash(_("Score is already in the album."))
return redirect(f"/albums/{album.uuid}") return redirect(f"/albums/{album.uuid}")
@ -376,5 +377,5 @@ def add_partition_from_search():
user=user user=user
) )
flash("Type de partition inconnu.") flash(_("Unknown score type."))
return redirect("/albums") return redirect("/albums")

View File

@ -7,6 +7,7 @@ from typing import Optional
from flask import (Blueprint, flash, g, redirect, render_template, from flask import (Blueprint, flash, g, redirect, render_template,
request, session, url_for, current_app) request, session, url_for, current_app)
from flask_babel import _
from werkzeug.security import check_password_hash, generate_password_hash from werkzeug.security import check_password_hash, generate_password_hash
@ -23,7 +24,7 @@ def login_required(view):
@functools.wraps(view) @functools.wraps(view)
def wrapped_view(**kwargs): def wrapped_view(**kwargs):
if g.user is None: if g.user is None:
flash("Vous devez être connecté pour accéder à cette page.") flash(_("You need to login to access this resource."))
return redirect(url_for("auth.login")) return redirect(url_for("auth.login"))
return view(**kwargs) return view(**kwargs)
@ -50,12 +51,12 @@ def admin_required(view):
@functools.wraps(view) @functools.wraps(view)
def wrapped_view(**kwargs): def wrapped_view(**kwargs):
if g.user is None: if g.user is None:
flash("Vous devez être connecté pour accéder à cette page.") flash(_("You need to login to access this resource."))
return redirect(url_for("auth.login")) return redirect(url_for("auth.login"))
user = User(user_id=session.get("user_id")) user = User(user_id=session.get("user_id"))
if user.access_level != 1: if user.access_level != 1:
flash("Droits insuffisants.") flash(_("Missing rights."))
return redirect("/albums") return redirect("/albums")
return view(**kwargs) return view(**kwargs)
@ -81,9 +82,9 @@ def create_user(username: str, password: str) -> Optional[str]:
"""Adds a new user to the database""" """Adds a new user to the database"""
error = None error = None
if not username: if not username:
error = "Un nom d'utilisateur est requis." error = _("Missing username.")
elif not password: elif not password:
error = "Un mot de passe est requis." error = _("Missing password.")
try: try:
db = get_db() db = get_db()
@ -96,7 +97,7 @@ def create_user(username: str, password: str) -> Optional[str]:
except db.IntegrityError: except db.IntegrityError:
# The username was already taken, which caused the # The username was already taken, which caused the
# commit to fail. Show a validation error. # commit to fail. Show a validation error.
error = f"Le nom d'utilisateur {username} est déjà pris." error = _("Username %(username)s is not available.", username=username)
return error # may be None return error # may be None
@ -109,7 +110,7 @@ def register():
password for security. password for security.
""" """
if current_app.config["DISABLE_REGISTER"]: if current_app.config["DISABLE_REGISTER"]:
flash("L'enregistrement de nouveaux utilisateurs a été désactivé par l'administrateur.") flash(_("New users registration is disabled by owner."))
return redirect(url_for("auth.login")) return redirect(url_for("auth.login"))
if request.method == "POST": if request.method == "POST":
@ -123,7 +124,7 @@ def register():
else: else:
user = User(name=username) user = User(name=username)
flash("Utilisateur créé avec succès. Vous pouvez vous connecter.") flash(_("Successfully created new user. You can log in."))
logging.log( logging.log(
[user.username, user.id, False], [user.username, user.id, False],
@ -148,7 +149,7 @@ def login():
if (user is None) or not check_password_hash(user["password"], password): if (user is None) or not check_password_hash(user["password"], password):
logging.log([username], logging.LogEntry.FAILED_LOGIN) logging.log([username], logging.LogEntry.FAILED_LOGIN)
error = "Nom d'utilisateur ou mot de passe incorrect." error = _("Incorrect username or password")
if error is None: if error is None:
# store the user id in a new session and return to the index # store the user id in a new session and return to the index

View File

@ -4,6 +4,7 @@ Groupe module
""" """
from flask import (Blueprint, abort, flash, redirect, render_template, from flask import (Blueprint, abort, flash, redirect, render_template,
request, session, current_app) request, session, current_app)
from flask_babel import _
from .auth import login_required from .auth import login_required
from .db import get_db from .db import get_db
@ -67,7 +68,7 @@ def create_groupe():
user = User(user_id=session["user_id"]) user = User(user_id=session["user_id"])
if not name or name.strip() == "": if not name or name.strip() == "":
error = "Un nom est requis. Le groupe n'a pas été créé" error = _("Missing name.")
if error is None: if error is None:
while True: while True:
@ -116,10 +117,10 @@ def join_groupe(uuid):
try: try:
user.join_groupe(uuid) user.join_groupe(uuid)
except LookupError: except LookupError:
flash("Ce groupe n'existe pas.") flash(_("Unknown group."))
return redirect(f"/groupe/{uuid}") return redirect(f"/groupe/{uuid}")
flash("Groupe ajouté à la collection.") flash(_("Group added to collection."))
return redirect(f"/groupe/{uuid}") return redirect(f"/groupe/{uuid}")
@ -130,15 +131,15 @@ def quit_groupe(uuid):
groupe = Groupe(uuid=uuid) groupe = Groupe(uuid=uuid)
users = groupe.get_users() users = groupe.get_users()
if user.id not in [u["id"] for u in users]: if user.id not in [u["id"] for u in users]:
flash("Vous ne faites pas partie de ce groupe") flash(_("You are not a member of this group."))
return redirect(f"/groupe/{uuid}") return redirect(f"/groupe/{uuid}")
if len(users) == 1: if len(users) == 1:
flash("Vous êtes seul dans ce groupe, le quitter entraînera sa suppression.") flash(_("You are alone here, quitting means deleting this group."))
return redirect(f"/groupe/{uuid}#delete") return redirect(f"/groupe/{uuid}#delete")
user.quit_groupe(groupe.uuid) user.quit_groupe(groupe.uuid)
flash("Groupe quitté.") flash(_("Group quitted."))
return redirect("/albums") return redirect("/albums")
@ -151,7 +152,7 @@ def delete_groupe(uuid):
error = None error = None
users = groupe.get_users() users = groupe.get_users()
if len(users) > 1: if len(users) > 1:
error = "Vous n'êtes pas seul dans ce groupe." error = _("You are not alone in this group.")
if user.access_level == 1 or user.id not in groupe.get_admins(): if user.access_level == 1 or user.id not in groupe.get_admins():
error = None error = None
@ -162,7 +163,7 @@ def delete_groupe(uuid):
groupe.delete(current_app.instance_path) groupe.delete(current_app.instance_path)
flash("Groupe supprimé.") flash(_("Group deleted."))
return redirect("/albums") return redirect("/albums")
@ -181,10 +182,10 @@ def create_album_req(groupe_uuid):
error = None error = None
if not name or name.strip() == "": if not name or name.strip() == "":
error = "Un nom est requis. L'album n'a pas été créé" error = _("Missing name.")
if user.id not in groupe.get_admins(): if user.id not in groupe.get_admins():
error ="Vous n'êtes pas administrateur de ce groupe" error = _("You are not admin of this group.")
if error is None: if error is None:
uuid = utils.create_album(name) uuid = utils.create_album(name)

View File

@ -30,7 +30,7 @@ class LogEntry(Enum):
def add_entry(entry: str) -> None: def add_entry(entry: str) -> None:
date = datetime.now().strftime("%y-%b-%Y %H:%M:%S") date = datetime.now().strftime('%y-%b-%Y %H:%M:%S')
with open(log_file, 'a', encoding="utf8") as f: with open(log_file, 'a', encoding="utf8") as f:
f.write(f"[{date}] {entry}\n") f.write(f"[{date}] {entry}\n")

View File

@ -6,6 +6,7 @@ import os
from uuid import uuid4 from uuid import uuid4
from flask import (Blueprint, abort, send_file, render_template, from flask import (Blueprint, abort, send_file, render_template,
request, redirect, flash, session, current_app) request, redirect, flash, session, current_app)
from flask_babel import _
from .db import get_db from .db import get_db
from .auth import login_required, admin_required from .auth import login_required, admin_required
@ -54,12 +55,12 @@ def add_attachment(uuid):
user = User(user_id=session.get("user_id")) user = User(user_id=session.get("user_id"))
if user.id != partition.user_id and user.access_level != 1: if user.id != partition.user_id and user.access_level != 1:
flash("Cette partition ne vous current_appartient pas") flash(_("You don't own this score."))
return redirect(request.referrer) return redirect(request.referrer)
error = None # À mettre au propre error = None # À mettre au propre
if "file" not in request.files: if "file" not in request.files:
error = "Aucun fichier n'a été fourni." error = _("Missing file")
else: else:
if "name" not in request.form or request.form["name"] == "": if "name" not in request.form or request.form["name"] == "":
name = ".".join(request.files["file"].filename.split(".")[:-1]) name = ".".join(request.files["file"].filename.split(".")[:-1])
@ -67,12 +68,12 @@ def add_attachment(uuid):
name = request.form["name"] name = request.form["name"]
if name == "": if name == "":
error = "Pas de nom de fichier" error = _("Missing filename.")
else: else:
filename = request.files["file"].filename filename = request.files["file"].filename
ext = filename.split(".")[-1] ext = filename.split(".")[-1]
if ext not in ["mid", "mp3"]: if ext not in ["mid", "mp3"]:
error = "Extension de fichier non supportée" error = _("Unsupported file type.")
if error is not None: if error is not None:
flash(error) flash(error)
@ -140,7 +141,7 @@ def edit(uuid):
user = User(user_id=session.get("user_id")) user = User(user_id=session.get("user_id"))
if user.access_level != 1 and partition.user_id != user.id: if user.access_level != 1 and partition.user_id != user.id:
flash("Vous n'êtes pas autorisé à modifier cette partition.") flash(_("You are not allowed to edit this file."))
return redirect("/albums") return redirect("/albums")
if request.method == "GET": if request.method == "GET":
@ -149,11 +150,11 @@ def edit(uuid):
error = None error = None
if "name" not in request.form or request.form["name"].strip() == "": if "name" not in request.form or request.form["name"].strip() == "":
error = "Un titre est requis." error = _("Missing title")
elif "author" not in request.form: elif "author" not in request.form:
error = "Un nom d'auteur est requis (à minima nul)" error = _("Missing author in request body (can be null).")
elif "body" not in request.form: elif "body" not in request.form:
error = "Des paroles sont requises (à minima nulles)" error = _("Missing lyrics (can be null).")
if error is not None: if error is not None:
flash(error) flash(error)
@ -165,7 +166,7 @@ def edit(uuid):
body=request.form["body"] body=request.form["body"]
) )
flash(f"Partition {request.form['name']} modifiée avec succès.") flash(_("Successfully modified %(name)s", name=request.form['name']))
return redirect("/albums") return redirect("/albums")
@ -195,11 +196,11 @@ def details(uuid):
error = None error = None
if "name" not in request.form or request.form["name"].strip() == "": if "name" not in request.form or request.form["name"].strip() == "":
error = "Un titre est requis." error = _("Missing title")
elif "author" not in request.form: elif "author" not in request.form:
error = "Un nom d'auteur est requis (à minima nul)" error = _("Missing author in request body (can be null).")
elif "body" not in request.form: elif "body" not in request.form:
error = "Des paroles sont requises (à minima nulles)" error = _("Missing lyrics (can be null).")
if error is not None: if error is not None:
flash(error) flash(error)
@ -211,7 +212,7 @@ def details(uuid):
body=request.form["body"] body=request.form["body"]
) )
flash(f"Partition {request.form['name']} modifiée avec succès.") flash(_("Successfully modified %(name)s", name=request.form['name']))
return redirect("/albums") return redirect("/albums")
@ -226,7 +227,7 @@ def delete(uuid):
user = User(user_id=session.get("user_id")) user = User(user_id=session.get("user_id"))
if user.access_level != 1 and partition.user_id != user.id: if user.access_level != 1 and partition.user_id != user.id:
flash("Vous n'êtes pas autorisé à supprimer cette partition.") flash(_("You are not allowed to delete this score."))
return redirect("/albums") return redirect("/albums")
if request.method == "GET": if request.method == "GET":
@ -234,7 +235,7 @@ def delete(uuid):
partition.delete(current_app.instance_path) partition.delete(current_app.instance_path)
flash("Partition supprimée.") flash(_("Score deleted."))
return redirect("/albums") return redirect("/albums")

View File

@ -2,27 +2,27 @@
{% block content %} {% block content %}
<h2>{% block title %}Panneau d'administration{% endblock %}</h2> <h2>{% block title %}{{ _("Administration Panel") }}{% endblock %}</h2>
<div id="actions-rapides"> <div id="actions-rapides">
<a href="/add-user"> <a href="/add-user">
<div class="button">Nouvel utilisateur</div> <div class="button">{{ _("New user") }}</div>
</a> </a>
<a href="/partition"> <a href="/partition">
<div class="button">Voir les partitions</div> <div class="button">{{ _("See scores") }}</div>
</a> </a>
<a href="/admin/logs"> <a href="/admin/logs">
<div class="button">Voir les logs</div> <div class="button">{{ _("See logs") }}</div>
</a> </a>
</div> </div>
<div class="x-scrollable"> <div class="x-scrollable">
<table> <table>
<thead> <thead>
<tr> <tr>
<th scope="col">Utilisateur</th> <th scope="col">{{ _("User") }}</th>
<th scope="col">Albums</th> <th scope="col">{{ _("Albums") }}</th>
<th scope="col">Partitions</th> <th scope="col">{{ _("Scores") }}</th>
<th scope="col">Privilèges</th> <th scope="col">{{ _("Admin privileges") }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -2,7 +2,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block header %} {% block header %}
<h1>{% block title %}Logs{% endblock %}</h1> <h1>{% block title %}{{ _("Logs") }}{% endblock %}</h1>
{% endblock %} {% endblock %}
{% block content %} {% block content %}

View File

@ -1,7 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block header %} {% block header %}
<h1>{% block title %}Liste des partitions{% endblock %}</h1> <h1>{% block title %}{{ _("Scores list") }}{% endblock %}</h1>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
@ -28,6 +28,6 @@
{% endfor %} {% endfor %}
</div> </div>
{% else %} {% else %}
<div>Aucune partition disponible</div> <div>{{ _("No available scores") }}</div>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -1,15 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}Ajout de partition{% endblock %} {% block title %}{{ _("New score") }}{% endblock %}
{% block content %} {% block content %}
<h2>Ajouter une partition à {{ album.name }}</h2> {% include 'components/add_partition.html' %}
<form action="/albums/{{ album.uuid }}/add-partition" method="post" enctype="multipart/form-data">
<input name="name" type="text" placeholder="titre" required/><br/>
<input name="author" type="text" placeholder="auteur"/><br/>
<textarea id="paroles" name="body" type="text" placeholder="paroles"></textarea><br/>
<input name="partition-uuid" value="{{ partition_uuid }}" type="hidden">
<input type="submit" value="Ajouter" />
</form>
{% endblock %} {% endblock %}

View File

@ -5,22 +5,15 @@
{% block dialogs %} {% block dialogs %}
<dialog id="add-partition"> <dialog id="add-partition">
<h2>Ajouter une partition à {{ album.name }}</h2> {% include 'components/add_partition.html' %}
<form action="/albums/{{ album.uuid }}/add-partition" method="post" enctype="multipart/form-data">
<input name="name" type="text" required="" placeholder="Titre"><br/>
<input name="author" type="text" placeholder="Auteur"><br/>
<textarea id="paroles" name="body" type="text" placeholder="Paroles"></textarea><br/>
<input name="file" type="file" accept=".pdf" required=""><br/>
<input type="submit" value="Ajouter">
</form>
<a href="#!" class="close-dialog">Close</a> <a href="#!" class="close-dialog">Close</a>
</dialog> </dialog>
<dialog id="delete"> <dialog id="delete">
<h2>Supprimer l'album</h2> <h2>{{ _("Delete l'album") }}</h2>
Êtes vous sûr de vouloir supprimer cet album ? {{ _("Do you really want to delete this album?") }}
<br/><br/> <br/><br/>
<form method="post" action="/albums/{{ album.uuid }}/delete"> <form method="post" action="/albums/{{ album.uuid }}/delete">
<input type="submit" style="background-color: var(--color-red);" value="Supprimer"> <input type="submit" style="background-color: var(--color-red);" value="{{ _('Delete') }}">
</form> </form>
<a href="#!" class="close-dialog">Close</a> <a href="#!" class="close-dialog">Close</a>
</dialog> </dialog>
@ -38,7 +31,7 @@
{% block content %} {% block content %}
<header id="album-header"> <header id="album-header">
<h2 id="album-title"> <h2 id="album-title">
{% if groupe %}<a href="/groupe/{{ groupe.uuid }}">{{ groupe.name}}</a> / {% if groupe %}<a href="/groupe/{{ groupe.uuid }}">{{ groupe.name }}</a> /
{% endif %} {% endif %}
{{ album.name }} {{ album.name }}
</h2> </h2>
@ -55,16 +48,16 @@
+ +
<div class="dropdown-content dp1"> <div class="dropdown-content dp1">
{% if g.user %} {% if g.user %}
<a href="#add-partition">Ajouter une partition</a> <a href="#add-partition">{{ _("Add a score") }}</a>
{% endif %} {% endif %}
{% if not_participant %} {% if not_participant %}
<a href="/albums/{{ album.uuid }}/join">Rejoindre</a> <a href="/albums/{{ album.uuid }}/join">{{ _("Join") }}</a>
{% elif album.users | length > 1 %} {% elif album.users | length > 1 %}
<a href="/albums/{{ album.uuid }}/quit">Quitter</a> <a href="/albums/{{ album.uuid }}/quit">{{ _("Quit") }}</a>
{% endif %} {% endif %}
<a href="#share">Partager</a> <a href="#share">{{ _("Share") }}</a>
{% if g.user.access_level == 1 or (not not_participant and album.users | length == 1) %} {% if g.user.access_level == 1 or (not not_participant and album.users | length == 1) %}
<a id="delete-album" href="#delete">Supprimer</a> <a id="delete-album" href="#delete">{{ _("Delete") }}</a>
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -98,6 +91,6 @@
</section> </section>
{% else %} {% else %}
<br/> <br/>
<section id="partitions-grid" style="display: inline;">Aucune partition disponible</section> <section id="partitions-grid" style="display: inline;">{{ _("No available scores") }}</section>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -1,14 +1,14 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}Supprimer {{ album.name }}{% endblock %} {% block title %}{{ _("Delete %(name)s", name=album.name) }}{% endblock %}
{% block content %} {% block content %}
Êtes vous sûr de vouloir supprimer cet album ? {{ _("Do you really want to delete this album?") }}
<form method="post"> <form method="post">
<input type="submit" value="Supprimer"> <input type="submit" value="{{ _('Delete') }}">
</form> </form>
<a class="button-href" href="/albums/{{ album.uuid }}"> <a class="button-href" href="/albums/{{ album.uuid }}">
<button id="cancel-deletion">Annuler</button> <button id="cancel-deletion">{{ _("Cancel") }}</button>
</a> </a>
{% endblock %} {% endblock %}

View File

@ -1,10 +1,13 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}Home{% endblock %} {% block title %}{{ _("Home") }}{% endblock %}
{% block content %} {% block content %}
<div style="text-align: center;"> <div style="text-align: center;">
Bonjour <i><b>{{ user.username }}</b></i> !<br/> {% set user_name %}
Aucun album sélectionné <i><b>{{ user.username }}</b></i>
{% endset %}
{{ _("Hi %(user_name)s !", user_name=user_name) }}<br/>
{{ _("No album selected") }}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -2,9 +2,9 @@
{% block content %} {% block content %}
<h2>{% block title %}Résultats de la recherche "{{ query }}"{% endblock %}</h2> <h2>{% block title %}{{ _('Search results for "%(query)s"', query=query)}}{% endblock %}</h2>
{% if partitions|length != 0 %} {% if partitions|length != 0 %}
<h3>Résultats dans la bibliothèque locale</h3> <h3>{{ _("Results in current database") }}</h3>
<div id="partitions-grid"> <div id="partitions-grid">
{% for partition in partitions %} {% for partition in partitions %}
<div class="partition-container"> <div class="partition-container">
@ -35,14 +35,14 @@
</select> </select>
<input type="hidden" value="{{ partition['uuid'] }}" name="partition-uuid"> <input type="hidden" value="{{ partition['uuid'] }}" name="partition-uuid">
<input type="hidden" value="local_file" name="partition-type"> <input type="hidden" value="local_file" name="partition-type">
<input type="submit" value="Ajouter à l'album" class="add-to-album"> <input type="submit" value="{{ _('Add to album') }}" class="add-to-album">
</form> </form>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
{% endif %} {% endif %}
{% if google_results|length != 0 %} {% if google_results|length != 0 %}
<h3>Résultats de la recherche en ligne</h3> <h3>{{ _("Online search results") }}</h3>
<div id="partitions-grid"> <div id="partitions-grid">
{% for partition in google_results %} {% for partition in google_results %}
<div class="partition-container"> <div class="partition-container">
@ -67,13 +67,13 @@
</select> </select>
<input type="hidden" value="{{ partition['uuid'] }}" name="partition-uuid"> <input type="hidden" value="{{ partition['uuid'] }}" name="partition-uuid">
<input type="hidden" value="online_search" name="partition-type"> <input type="hidden" value="online_search" name="partition-type">
<input type="submit" value="Ajouter à l'album"> <input type="submit" value="{{ _('Add to album') }}">
</form> </form>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
{% endif %} {% endif %}
{% if google_results|length == 0 and partitions|length == 0 %} {% if google_results|length == 0 and partitions|length == 0 %}
Aucun résultat. Essayez d'augmenter le nombre de recherches en ligne ou d'affiner votre recherche. {{ _("No results available. Try to tweak your query or increase the amount of online searches.") }}
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -2,11 +2,11 @@
{% block content %} {% block content %}
<h2>{% block title %}Connexion{% endblock %}</h2> <h2>{% block title %}{{ _("Log in") }}{% endblock %}</h2>
<form method="post"> <form method="post">
<input type="text" name="username" id="username" placeholder="Nom d'utilisateur" required><br/> <input type="text" name="username" id="username" placeholder="{{ _('Username') }}" required><br/>
<input type="password" name="password" id="password" placeholder="Mot de passe" required><br/> <input type="password" name="password" id="password" placeholder="{{ _('Password') }}" required><br/>
<input type="submit" value="Se connecter"> <input type="submit" value="{{ _('Log in') }}">
</form> </form>
{% endblock %} {% endblock %}

View File

@ -2,21 +2,21 @@
{% block content %} {% block content %}
<h2>{% block title %}Créer un compte{% endblock %}</h2> <h2>{% block title %}{{ _("Create account") }}{% endblock %}</h2>
<form method="post" id="add-user-form"> <form method="post" id="add-user-form">
{% if g.user.access_level == 1 %} {% if g.user.access_level == 1 %}
<!-- Uniquement pour /add-user --> <!-- Uniquement pour /add-user -->
<label for="album_uuid">Ajouter à un album: </label><br/> <label for="album_uuid">{{ _("Add to album:") }}</label><br/>
<select name="album_uuid" id="album_uuid" form="add-user-form" style="margin-bottom:15px;"> <select name="album_uuid" id="album_uuid" form="add-user-form" style="margin-bottom:15px;">
<option value="">Aucun</option> <option value="">{{ _("None") }}</option>
{% for album in albums %} {% for album in albums %}
<option value="{{ album['uuid'] }}">{{ album["name"] }}</option> <option value="{{ album['uuid'] }}">{{ album["name"] }}</option>
{% endfor %} {% endfor %}
</select><br/> </select><br/>
{% endif %} {% endif %}
<input type="text" name="username" id="username" placeholder="Nom d'utilisateur" required><br/> <input type="text" name="username" id="username" placeholder="{{ _('Username') }}" required><br/>
<input type="password" name="password" id="password" placeholder="Mot de passe" required><br/> <input type="password" name="password" id="password" placeholder="{{ _('Password') }}" required><br/>
<input type="submit" value="Créer un compte"> <input type="submit" value="{{ _('Create account') }}">
</form> </form>
{% endblock %} {% endblock %}

View File

@ -20,21 +20,21 @@
{% block dialogs %}{% endblock %} {% block dialogs %}{% endblock %}
{% if g.user %} {% if g.user %}
<dialog id="create-album"> <dialog id="create-album">
<h2>Créer un nouvel album</h2> <h2>{{ _("New Album") }}</h2>
<form action="/albums/create-album" method="post"> <form action="/albums/create-album" method="post">
<input type="text" name="name" id="name" placeholder="Nom" required><br/> <input type="text" name="name" id="name" placeholder="{{ _('Name') }}" required><br/>
<input type="submit" value="Créer"> <input type="submit" value="{{ _('Create') }}">
</form> </form>
<br/> <br/>
<br/> <br/>
Je souhaite créer plusieurs albums et pouvoir tous les partager avec un seul lien. <a href="#create-groupe">Créer un groupe</a>. {{ _("I want to create a collection of albums.") }} <a href="#create-groupe">{{ _("Create group") }}</a>.
<a href="#!" class="close-dialog">Close</a> <a href="#!" class="close-dialog">Close</a>
</dialog> </dialog>
<dialog id="create-groupe"> <dialog id="create-groupe">
<h2>Créer un nouveau groupe</h2> <h2>{{ _("Create new group") }}</h2>
<form action="/groupe/create-groupe" method="post"> <form action="/groupe/create-groupe" method="post">
<input type="text" name="name" id="name" placeholder="Nom" required><br/> <input type="text" name="name" id="name" placeholder="{{ _('Name') }}" required><br/>
<input type="submit" value="Créer"> <input type="submit" value="{{ _('Create') }}">
</form> </form>
<a href="#!" class="close-dialog">Close</a> <a href="#!" class="close-dialog">Close</a>
</dialog> </dialog>
@ -58,9 +58,9 @@
<div id="sidebar"> <div id="sidebar">
{% if g.user %} {% if g.user %}
<form id="search-form" action="/albums/search" method="post"> <form id="search-form" action="/albums/search" method="post">
<input type="search" id="search-bar" required="" placeholder="Rechercher" name="query"> <input type="search" id="search-bar" required="" placeholder="{{ _('Search') }}" name="query">
<br> <br>
<select id="nb-queries" name="nb-queries" title="Nombre de recherches en ligne"> <select id="nb-queries" name="nb-queries" title="{{ _('Number of online searches') }}">
{% for i in range(0, user.max_queries+1) %} {% for i in range(0, user.max_queries+1) %}
<option value="{{ i }}">{{ i }}</option> <option value="{{ i }}">{{ i }}</option>
{% endfor %} {% endfor %}
@ -68,11 +68,11 @@
<input id="search-submit" type="submit" value="Go"> <input id="search-submit" type="submit" value="Go">
</form> </form>
{% endif %} {% endif %}
<h2>Albums</h2> <h2>{{ _("Albums") }}</h2>
{% if g.user %} {% if g.user %}
<a href="#create-album"> <a href="#create-album">
<div class="create-button"> <div class="create-button">
Créer un album {{ _("New album") }}
</div> </div>
</a> </a>
{% endif %} {% endif %}
@ -89,7 +89,7 @@
</summary> </summary>
<div class="groupe-albums-cover"> <div class="groupe-albums-cover">
{% if groupe.get_albums() | length == 0 %} {% if groupe.get_albums() | length == 0 %}
Aucun album {{ _("No albums") }}
{% else %} {% else %}
{% for album in groupe.get_albums() %} {% for album in groupe.get_albums() %}
<a href="/groupe/{{ groupe.uuid }}/{{ album['uuid'] }}"> <a href="/groupe/{{ groupe.uuid }}/{{ album['uuid'] }}">
@ -108,7 +108,7 @@
<section id="albums"> <section id="albums">
{% if user.get_albums() | length == 0 %} {% if user.get_albums() | length == 0 %}
<div style="text-align: center;"><i>Aucun album disponible</i></div> <div style="text-align: center;"><i>{{ _("No album available") }}</i></div>
{% else %} {% else %}
{% for album in user.albums %} {% for album in user.albums %}
<a href="/albums/{{ album['uuid'] }}"> <a href="/albums/{{ album['uuid'] }}">
@ -122,7 +122,7 @@
</section> </section>
{% else %} {% else %}
<section id="sidebar-navigation"> <section id="sidebar-navigation">
<div style="text-align: center;"><i>Connectez vous pour avoir accès à vos albums</i></div> <div style="text-align: center;"><i>{{ _("Log in to see your albums") }}</i></div>
</section> </section>
{% endif %} {% endif %}
@ -136,7 +136,7 @@
<path d="M9 12h12l-3 -3"></path> <path d="M9 12h12l-3 -3"></path>
<path d="M18 15l3 -3"></path> <path d="M18 15l3 -3"></path>
</svg> </svg>
Déconnexion {{ _("Log out") }}
</button> </button>
</a><br/> </a><br/>
{% if g.user.access_level == 1 %} {% if g.user.access_level == 1 %}
@ -151,7 +151,7 @@
<path d="M17.27 20l-1.3 .75"></path> <path d="M17.27 20l-1.3 .75"></path>
<path d="M15.97 17.25l1.3 .75"></path> <path d="M15.97 17.25l1.3 .75"></path>
<path d="M20.733 20l1.3 .75"></path> <path d="M20.733 20l1.3 .75"></path>
</svg>Panneau admin </svg>{{ _("Admin Panel") }}
</button></a><br/> </button></a><br/>
{% endif %} {% endif %}
<div class="user"> <div class="user">
@ -163,9 +163,9 @@
</div> </div>
{% else %} {% else %}
{% if not config.DISABLE_REGISTER %} {% if not config.DISABLE_REGISTER %}
<a href="{{ url_for('auth.register') }}"><button>Créer un compte</button></a> <a href="{{ url_for('auth.register') }}"><button>{{ _("Create account") }}</button></a>
{% endif %} {% endif %}
<a href="{{ url_for('auth.login') }}"><button>Se connecter</button></a> <a href="{{ url_for('auth.login') }}"><button>{{ _("Log in") }}</button></a>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -0,0 +1,13 @@
<h2>{{ _("Add a score to %(name)s", name=album.name) }}</h2>
<form action="/albums/{{ album.uuid }}/add-partition" method="post" enctype="multipart/form-data">
<input name="name" type="text" placeholder="{{ _('title') }}" required/><br/>
<input name="author" type="text" placeholder="{{ _('author') }}"/><br/>
<textarea id="lyrics" name="body" type="text" placeholder="{{ _('lyrics') }}"></textarea><br/>
{% if partition_uuid %}
<input name="partition-uuid" value="{{ partition_uuid }}" type="hidden">
{% else %}
<input name="file" type="file" accept=".pdf" required=""><br/>
{% endif %}
<input type="submit" value="{{ _('Add') }}" />
</form>

View File

@ -5,20 +5,19 @@
{% block dialogs %} {% block dialogs %}
<dialog id="create-groupe-album"> <dialog id="create-groupe-album">
<h2>Créer un nouvel album dans le groupe {{ groupe.name }}</h2> <h2>{{ _("Add an album to group %(name)s", name=groupe.name) }}</h2>
<form action="/groupe/{{ groupe.uuid }}/create-album" method="post"> <form action="/groupe/{{ groupe.uuid }}/create-album" method="post">
<input type="text" name="name" id="name" placeholder="Nom" required><br/> <input type="text" name="name" id="name" placeholder="{{ _('Name') }}" required><br/>
<input type="submit" value="Ajouter"> <input type="submit" value="{{ _('Add') }}">
</form> </form>
<a href="#!" class="close-dialog">Close</a> <a href="#!" class="close-dialog">Close</a>
</dialog> </dialog>
<dialog id="delete"> <dialog id="delete">
<h2>Supprimer le groupe</h2> <h2>{{ _("Delete group") }}</h2>
Êtes vous sûr de vouloir supprimer ce groupe ? Cela supprimera les albums {{ _("Do you really want to delete this group and the albums it contains?") }}
sous-jacents et leurs partitions si personne ne les a rejoints (indépendamment du groupe).
<br/><br/> <br/><br/>
<form method="post" action="/groupe/{{ groupe.uuid }}/delete"> <form method="post" action="/groupe/{{ groupe.uuid }}/delete">
<input type="submit" style="background-color: var(--color-red);" value="Supprimer"> <input type="submit" style="background-color: var(--color-red);" value="{{ _('Delete') }}">
</form> </form>
<a href="#!" class="close-dialog">Close</a> <a href="#!" class="close-dialog">Close</a>
</dialog> </dialog>
@ -44,14 +43,14 @@
+ +
<div class="dropdown-content dp1"> <div class="dropdown-content dp1">
{% if not_participant %} {% if not_participant %}
<a href="/groupe/{{ groupe.uuid }}/join">Rejoindre</a> <a href="/groupe/{{ groupe.uuid }}/join">{{ _("Join") }}</a>
{% elif groupe.users | length > 1 %} {% elif groupe.users | length > 1 %}
<a href="/groupe/{{ groupe.uuid }}/quit">Quitter</a> <a href="/groupe/{{ groupe.uuid }}/quit">{{ _("Quit") }}</a>
{% endif %} {% endif %}
<a href="#share">Partager</a> <a href="#share">{{ _("Share") }}</a>
{% if g.user.access_level == 1 or user.id in groupe.get_admins() %} {% if g.user.access_level == 1 or user.id in groupe.get_admins() %}
<a href="#create-groupe-album">Ajouter un album</a> <a href="#create-groupe-album">{{ _("Add an album") }}</a>
<a id="delete-album" href="#delete">Supprimer</a> <a id="delete-album" href="#delete">{{ _("Delete") }}</a>
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -71,6 +70,11 @@
</section> </section>
{% else %} {% else %}
<br/> <br/>
<div id="albums-grid" style="display: inline;">Aucun album disponible. <a href="#create-groupe-album">En créer un</a></div> {% set create %}
<a href="#create-groupe-album">{{ _("Create one") }}</a>
{% endset %}
<div id="albums-grid" style="display: inline;">
{{ _("No available album. %(create)s", create=create) }}
</div>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -2,15 +2,15 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %}Attachments de {{ partition.name }}{% endblock %} {% block title %}{{ _("Attachments of %(name)s", name=partition.name) }}{% endblock %}
{% block dialogs %} {% block dialogs %}
<dialog id="create-attachment"> <dialog id="create-attachment">
<h2>Ajouter un attachment à {{ partition.name }}</h2> <h2>{{ _("Add an attachment to %(name)s", name=partition.name) }}</h2>
<form action="/partition/{{ partition.uuid }}/add-attachment" method="post" enctype="multipart/form-data"> <form action="/partition/{{ partition.uuid }}/add-attachment" method="post" enctype="multipart/form-data">
<input type="text" name="name" id="name" placeholder="Nom"><br/> <input type="text" name="name" id="name" placeholder="{{ _('Name') }}"><br/>
<input name="file" type="file" accept=".mp3,.mid" required=""><br/> <input name="file" type="file" accept=".mp3,.mid" required=""><br/>
<input type="submit" value="Ajouter"> <input type="submit" value="{{ _('Add') }}">
</form> </form>
<a href="#!" class="close-dialog">Close</a> <a href="#!" class="close-dialog">Close</a>
</dialog> </dialog>
@ -19,8 +19,8 @@
{% block content %} {% block content %}
<object id="pdf-embed" width="400" height="500" type="application/pdf" data="/partition/{{ partition.uuid }}"> <object id="pdf-embed" width="400" height="500" type="application/pdf" data="/partition/{{ partition.uuid }}">
<p> <p>
Impossible d'afficher le pdf dans ce navigateur. {{ _("No pdf viewer available in this browser.
Il est conseillé d'utiliser Firefox sur Android. You can use Firefox on Android.") }}
</p> </p>
</object> </object>
@ -43,7 +43,7 @@
src="/partition/attachment/{{ attachment.uuid }}.mid" src="/partition/attachment/{{ attachment.uuid }}.mid"
sound-font visualizer="#midi-visualizer" data-js-focus-visible> sound-font visualizer="#midi-visualizer" data-js-focus-visible>
</midi-player> </midi-player>
<noscript>MIDI support needs JavaScript</noscript> <noscript>{{ _("JavaScript is mandatory to read MIDI files") }}</noscript>
</td> </td>
<td>🎵 {{ attachment.name }}</td> <td>🎵 {{ attachment.name }}</td>
{% endif %} {% endif %}
@ -57,7 +57,7 @@
<br/> <br/>
{% if user %} {% if user %}
<div class="centered"> <div class="centered">
<a href="#create-attachment"><button>Ajouter un attachment</button></a> <a href="#create-attachment"><button>{{ _("Add an attachment") }}</button></a>
</div> </div>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -1,16 +1,16 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block header %} {% block header %}
<h1>{% block title %}Supprimer {{ partition.name }}{% endblock %}</h1> <h1>{% block title %}{{ _("Delete %(name)s", name=partition.name) }}{% endblock %}</h1>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
Êtes vous sûr de vouloir supprimer cette partition ? {{ _("Do you really want to delete this score?") }}
<form method="post"> <form method="post">
<input type="submit" id="delete-partition" value="Supprimer"> <input type="submit" id="delete-partition" value="{{ _('Delete') }}">
</form> </form>
<a class="button-href" href="/partition/{{ partition.uuid }}/edit"> <a class="button-href" href="/partition/{{ partition.uuid }}/edit">
<button id="cancel-deletion">Annuler</button> <button id="cancel-deletion">{{ _("Cancel") }}</button>
</a> </a>
{% endblock %} {% endblock %}

View File

@ -1,15 +1,15 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
<h2>{% block title %}Détails "{{ partition.name }}"{% endblock %}</h2> <h2>{% block title %}{{ _('Details of "%(name)s"', name=partition.name)}}{% endblock %}</h2>
<br /> <br/>
<form action="/partition/{{ partition.uuid }}/edit" method="post" enctype="multipart/form-data"> <form action="/partition/{{ partition.uuid }}/edit" method="post" enctype="multipart/form-data">
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td> <td>
Responsable de l'ajout {{ _("Added by") }}
</td> </td>
<td> <td>
{% if user is not none %} {% if user is not none %}
@ -20,13 +20,13 @@
</div> </div>
</div> </div>
{% else %} {% else %}
inconnu {{ _("Unknown") }}
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
Type d'ajout {{ _("Type") }}
</td> </td>
<td> <td>
{% if partition.source == "unknown" or partition.source == "upload" %} {% if partition.source == "unknown" or partition.source == "upload" %}
@ -38,7 +38,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
Albums {{ _("Albums") }}
</td> </td>
<td class="liste"> <td class="liste">
<ul> <ul>
@ -49,40 +49,41 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Fichier</td> <td>{{ _("File") }}</td>
<td><a href="/partition/{{ partition.uuid }}"> <td><a href="/partition/{{ partition.uuid }}">
<img class="partition-thumbnail" src="/thumbnails/{{ partition.uuid }}.jpg" loading="lazy"> <img class="partition-thumbnail" src="/thumbnails/{{ partition.uuid }}.jpg" loading="lazy">
</a></td> </a></td>
</tr> </tr>
<tr> <tr>
<td>Titre</td> <td>{{ _("Title") }}</td>
<td><input name="name" type="text" value="{{ partition.name }}" placeholder="Titre" required /><br/></td> <td><input name="name" type="text" value="{{ partition.name }}" placeholder="{{ _('Title') }}" required /><br/></td>
</tr> </tr>
<tr> <tr>
<td>Auteur</td> <td>{{ _("Author") }}</td>
<td><input name="author" type="text" value="{{ partition.author }}" placeholder="Auteur" /><br/></td> <td><input name="author" type="text" value="{{ partition.author }}" placeholder="{{ _('Author') }}" /><br/></td>
</tr> </tr>
<tr> <tr>
<td>Paroles</td> <td>{{ _("Lyrics") }}</td>
<td><textarea id="paroles" name="body" type="text" placeholder="Paroles">{{ partition.body }}</textarea><br/></td> <td><textarea id="lyrics" name="body" type="text" placeholder="{{ _('Lyrics') }}">{{ partition.body }}</textarea><br/></td>
</tr> </tr>
<tr> <tr>
<td>Pièces jointes</td> <td>{{ _("Attachments") }}</td>
{% set _ = partition.load_attachments() %} {{ partition.load_attachments() }}
<td><a href="/partition/{{ partition.uuid }}/attachments"> <td><a href="/partition/{{ partition.uuid }}/attachments">
{% if partition.attachments %} {% if partition.attachments %}
Oui, {{ partition.attachments | length }} {% set number=partition.attachments | length %}
{{ _("Yes, %(number)s", number=number) }}
{% else %} {% else %}
En rajouter {{ _("Add one") }}
{% endif %} {% endif %}
</a></td> </a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<input type="submit" value="Mettre à jour" /> <input type="submit" value="{{ _('Update') }}" />
</form> </form>
<a href="/partition/{{ partition.uuid }}/delete"> <a href="/partition/{{ partition.uuid }}/delete">
<button id="delete-partition">Supprimer</button> <button id="delete-partition">{{ _("Delete") }}</button>
</a> </a>
{% endblock %} {% endblock %}

View File

@ -3,14 +3,14 @@
{% block content %} {% block content %}
<h2>{% block title %}Modifier "{{ partition.name }}"{% endblock %}</h2> <h2>{% block title %}{{ _("Modify \"%(name)s\"", name=partition.name) }}{% endblock %}</h2>
<br/> <br/>
<form action="/partition/{{ partition.uuid }}/edit" method="post" enctype="multipart/form-data"> <form action="/partition/{{ partition.uuid }}/edit" method="post" enctype="multipart/form-data">
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td>Fichier</td> <td>{{ _("File") }}</td>
<td><a href="/partition/{{ partition.uuid }}"> <td><a href="/partition/{{ partition.uuid }}">
<img class="partition-thumbnail" src="/thumbnails/{{ partition.uuid }}.jpg" loading="lazy"> <img class="partition-thumbnail" src="/thumbnails/{{ partition.uuid }}.jpg" loading="lazy">
</a></td> </a></td>
@ -18,7 +18,7 @@
{% if partition.source != "unknown" and partition.source != "upload" %} {% if partition.source != "unknown" and partition.source != "upload" %}
<tr> <tr>
<td> <td>
Source {{ _("Source") }}
</td> </td>
<td class="partition-source"> <td class="partition-source">
<a href="{{ partition.source }}">{{ partition.source.split("/")[2] }}</a> <a href="{{ partition.source }}">{{ partition.source.split("/")[2] }}</a>
@ -26,34 +26,35 @@
</tr> </tr>
{% endif %} {% endif %}
<tr> <tr>
<td>Titre</td> <td>{{ _("Title") }}</td>
<td><input name="name" type="text" value="{{ partition.name }}" placeholder="Titre" required /><br/></td> <td><input name="name" type="text" value="{{ partition.name }}" placeholder="{{ _('Title') }}" required /><br/></td>
</tr> </tr>
<tr> <tr>
<td>Auteur</td> <td>{{ _("Author") }}</td>
<td><input name="author" type="text" value="{{ partition.author }}" placeholder="Auteur" /><br/></td> <td><input name="author" type="text" value="{{ partition.author }}" placeholder="{{ _('Author') }}" /><br/></td>
</tr> </tr>
<tr> <tr>
<td>Paroles</td> <td>{{ _("Lyrics") }}</td>
<td><textarea id="paroles" name="body" type="text" placeholder="Paroles">{{ partition.body }}</textarea><br/></td> <td><textarea id="lyrics" name="body" type="text" placeholder="{{ _('Lyrics') }}">{{ partition.body }}</textarea><br/></td>
</tr> </tr>
<tr> <tr>
<td>Pièces jointes</td> <td>{{ _("Attachments") }}</td>
{% set _ = partition.load_attachments() %} {{ partition.load_attachments() }}
<td><a href="/partition/{{ partition.uuid }}/attachments"> <td><a href="/partition/{{ partition.uuid }}/attachments">
{% if partition.attachments %} {% if partition.attachments %}
Oui, {{ partition.attachments | length }} {% set number=partition.attachments | length %}
{{ _("Yes, %(number)s", number=number) }}
{% else %} {% else %}
En rajouter {{ _("Add one") }}
{% endif %} {% endif %}
</a></td> </a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<input type="submit" value="Mettre à jour" /> <input type="submit" value="{{ _('Update') }}" />
</form> </form>
<a href="/partition/{{ partition.uuid }}/delete"> <a href="/partition/{{ partition.uuid }}/delete">
<button id="delete-partition">Supprimer</button> <button id="delete-partition">{{ _("Delete") }}</button>
</a> </a>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,599 @@
# English translations for PROJECT.
# Copyright (C) 2024 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2024.
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-01-25 16:19+0100\n"
"PO-Revision-Date: 2024-01-22 15:38+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.14.0\n"
#: partitioncloud/__init__.py:135
#, python-format
msgid "Created user %(username)s"
msgstr "Created user %(username)s"
#: partitioncloud/__init__.py:138
#, python-format
msgid "This album does not exists, but user %(username)s has been created"
msgstr "This album does not exists, but user %(username)s has been created"
#: partitioncloud/modules/albums.py:41
msgid "Missing search query"
msgstr "Missing search query"
#: partitioncloud/modules/albums.py:123 partitioncloud/modules/groupe.py:71
#: partitioncloud/modules/groupe.py:185
msgid "Missing name."
msgstr "Missing name."
#: partitioncloud/modules/albums.py:160
msgid "This album does not exist."
msgstr "This album does not exist."
#: partitioncloud/modules/albums.py:163
msgid "Album added to collection."
msgstr "Album added to collection."
#: partitioncloud/modules/albums.py:177 partitioncloud/modules/albums.py:240
#: partitioncloud/modules/albums.py:346
msgid "You are not a member of this album"
msgstr "You are not a member of this album"
#: partitioncloud/modules/albums.py:181
msgid "You are alone here, quitting means deleting this album."
msgstr "You are alone here, quitting means deleting this album."
#: partitioncloud/modules/albums.py:185
msgid "Album quitted."
msgstr "Album quitted."
#: partitioncloud/modules/albums.py:204
msgid "You are not alone in this album."
msgstr "You are not alone in this album."
#: partitioncloud/modules/albums.py:206
msgid "You don't own this album."
msgstr "You don't own this album."
#: partitioncloud/modules/albums.py:217
msgid "Album deleted."
msgstr "Album deleted."
#: partitioncloud/modules/albums.py:246 partitioncloud/modules/partition.py:153
#: partitioncloud/modules/partition.py:199
msgid "Missing title"
msgstr "Missing title"
#: partitioncloud/modules/albums.py:248 partitioncloud/modules/partition.py:63
msgid "Missing file"
msgstr "Missing file"
#: partitioncloud/modules/albums.py:260
msgid "Search results expired"
msgstr "Search results expired"
#: partitioncloud/modules/albums.py:326
#, python-format
msgid "Score %(partition_name)s added"
msgstr "Score %(partition_name)s added"
#: partitioncloud/modules/albums.py:340
msgid "Selecting an album is mandatory."
msgstr "Selecting an album is mandatory."
#: partitioncloud/modules/albums.py:342
msgid "Selecting a score is mandatory."
msgstr "Selecting a score is mandatory."
#: partitioncloud/modules/albums.py:344
msgid "Please specify a score type."
msgstr "Please specify a score type."
#: partitioncloud/modules/albums.py:366
msgid "Score added"
msgstr "Score added"
#: partitioncloud/modules/albums.py:368
msgid "Score is already in the album."
msgstr "Score is already in the album."
#: partitioncloud/modules/albums.py:380
msgid "Unknown score type."
msgstr "Unknown score type."
#: partitioncloud/modules/auth.py:27 partitioncloud/modules/auth.py:54
msgid "You need to login to access this resource."
msgstr "You need to login to access this resource."
#: partitioncloud/modules/auth.py:59
msgid "Missing rights."
msgstr "Missing rights."
#: partitioncloud/modules/auth.py:85
msgid "Missing username."
msgstr "Missing username."
#: partitioncloud/modules/auth.py:87
msgid "Missing password."
msgstr "Missing password."
#: partitioncloud/modules/auth.py:100
#, python-format
msgid "Username %(username)s is not available."
msgstr "Username %(username)s is not available."
#: partitioncloud/modules/auth.py:113
msgid "New users registration is disabled by owner."
msgstr "New users registration is disabled by owner."
#: partitioncloud/modules/auth.py:127
msgid "Successfully created new user. You can log in."
msgstr "Successfully created new user. You can log in."
#: partitioncloud/modules/auth.py:152
msgid "Incorrect username or password"
msgstr "Incorrect username or password"
#: partitioncloud/modules/groupe.py:120
msgid "Unknown group."
msgstr "Unknown group."
#: partitioncloud/modules/groupe.py:123
msgid "Group added to collection."
msgstr "Group added to collection."
#: partitioncloud/modules/groupe.py:134
msgid "You are not a member of this group."
msgstr "You are not a member of this group."
#: partitioncloud/modules/groupe.py:138
msgid "You are alone here, quitting means deleting this group."
msgstr "You are alone here, quitting means deleting this group."
#: partitioncloud/modules/groupe.py:142
msgid "Group quitted."
msgstr "Group quitted."
#: partitioncloud/modules/groupe.py:155
msgid "You are not alone in this group."
msgstr "You are not alone in this group."
#: partitioncloud/modules/groupe.py:166
msgid "Group deleted."
msgstr "Group deleted."
#: partitioncloud/modules/groupe.py:188
msgid "You are not admin of this group."
msgstr "You are not admin of this group."
#: partitioncloud/modules/partition.py:58
msgid "You don't own this score."
msgstr "You don't own this score."
#: partitioncloud/modules/partition.py:71
msgid "Missing filename."
msgstr "Missing filename."
#: partitioncloud/modules/partition.py:76
msgid "Unsupported file type."
msgstr "Unsupported file type."
#: partitioncloud/modules/partition.py:144
msgid "You are not allowed to edit this file."
msgstr "You are not allowed to edit this file."
#: partitioncloud/modules/partition.py:155
#: partitioncloud/modules/partition.py:201
msgid "Missing author in request body (can be null)."
msgstr "Missing author in request body (can be null)."
#: partitioncloud/modules/partition.py:157
#: partitioncloud/modules/partition.py:203
msgid "Missing lyrics (can be null)."
msgstr "Missing lyrics (can be null)."
#: partitioncloud/modules/partition.py:169
#: partitioncloud/modules/partition.py:215
#, python-format
msgid "Successfully modified %(name)s"
msgstr "Successfully modified %(name)s"
#: partitioncloud/modules/partition.py:230
msgid "You are not allowed to delete this score."
msgstr "You are not allowed to delete this score."
#: partitioncloud/modules/partition.py:238
msgid "Score deleted."
msgstr "Score deleted."
#: partitioncloud/templates/base.html:23
msgid "New Album"
msgstr "New Album"
#: partitioncloud/templates/base.html:25 partitioncloud/templates/base.html:36
#: partitioncloud/templates/groupe/index.html:10
#: partitioncloud/templates/partition/attachments.html:11
msgid "Name"
msgstr "Name"
#: partitioncloud/templates/base.html:26 partitioncloud/templates/base.html:37
msgid "Create"
msgstr "Create"
#: partitioncloud/templates/base.html:30
msgid "I want to create a collection of albums."
msgstr "I want to create a collection of albums."
#: partitioncloud/templates/base.html:30
msgid "Create group"
msgstr "Create group"
#: partitioncloud/templates/base.html:34
msgid "Create new group"
msgstr "Create new group"
#: partitioncloud/templates/base.html:61
msgid "Search"
msgstr "Search"
#: partitioncloud/templates/base.html:63
msgid "Number of online searches"
msgstr "Number of online searches"
#: partitioncloud/templates/admin/index.html:23
#: partitioncloud/templates/base.html:71
#: partitioncloud/templates/partition/details.html:41
msgid "Albums"
msgstr "Albums"
#: partitioncloud/templates/base.html:75
msgid "New album"
msgstr "New album"
#: partitioncloud/templates/base.html:92
msgid "No albums"
msgstr "No albums"
#: partitioncloud/templates/base.html:111
msgid "No album available"
msgstr "No album available"
#: partitioncloud/templates/base.html:125
msgid "Log in to see your albums"
msgstr "Log in to see your albums"
#: partitioncloud/templates/base.html:139
msgid "Log out"
msgstr "Log out"
#: partitioncloud/templates/base.html:154
msgid "Admin Panel"
msgstr "Admin Panel"
#: partitioncloud/templates/auth/register.html:5
#: partitioncloud/templates/auth/register.html:20
#: partitioncloud/templates/base.html:166
msgid "Create account"
msgstr "Create account"
#: partitioncloud/templates/auth/login.html:5
#: partitioncloud/templates/auth/login.html:10
#: partitioncloud/templates/base.html:168
msgid "Log in"
msgstr "Log in"
#: partitioncloud/templates/admin/index.html:5
msgid "Administration Panel"
msgstr "Administration Panel"
#: partitioncloud/templates/admin/index.html:9
msgid "New user"
msgstr "New user"
#: partitioncloud/templates/admin/index.html:12
msgid "See scores"
msgstr "See scores"
#: partitioncloud/templates/admin/index.html:15
msgid "See logs"
msgstr "See logs"
#: partitioncloud/templates/admin/index.html:22
msgid "User"
msgstr "User"
#: partitioncloud/templates/admin/index.html:24
msgid "Scores"
msgstr "Scores"
#: partitioncloud/templates/admin/index.html:25
msgid "Admin privileges"
msgstr "Admin privileges"
#: partitioncloud/templates/admin/logs.html:5
msgid "Logs"
msgstr "Logs"
#: partitioncloud/templates/admin/partitions.html:4
msgid "Scores list"
msgstr "Scores list"
#: partitioncloud/templates/admin/partitions.html:31
#: partitioncloud/templates/albums/album.html:94
msgid "No available scores"
msgstr "No available scores"
#: partitioncloud/templates/albums/add-partition.html:3
msgid "New score"
msgstr "New score"
#: partitioncloud/templates/albums/album.html:12
msgid "Delete l'album"
msgstr "Delete album"
#: partitioncloud/templates/albums/album.html:13
#: partitioncloud/templates/albums/delete-album.html:6
msgid "Do you really want to delete this album?"
msgstr "Do you really want to delete this album?"
#: partitioncloud/templates/albums/album.html:16
#: partitioncloud/templates/albums/album.html:60
#: partitioncloud/templates/albums/delete-album.html:8
#: partitioncloud/templates/groupe/index.html:20
#: partitioncloud/templates/groupe/index.html:53
#: partitioncloud/templates/partition/delete.html:10
#: partitioncloud/templates/partition/details.html:86
#: partitioncloud/templates/partition/edit.html:57
msgid "Delete"
msgstr "Delete"
#: partitioncloud/templates/albums/album.html:51
msgid "Add a score"
msgstr "Add a score"
#: partitioncloud/templates/albums/album.html:54
#: partitioncloud/templates/groupe/index.html:46
msgid "Join"
msgstr "Join"
#: partitioncloud/templates/albums/album.html:56
#: partitioncloud/templates/groupe/index.html:48
msgid "Quit"
msgstr "Quit"
#: partitioncloud/templates/albums/album.html:58
#: partitioncloud/templates/groupe/index.html:50
msgid "Share"
msgstr "Share"
#: partitioncloud/templates/albums/delete-album.html:3
#: partitioncloud/templates/partition/delete.html:4
#, python-format
msgid "Delete %(name)s"
msgstr "Delete %(name)s"
#: partitioncloud/templates/albums/delete-album.html:11
#: partitioncloud/templates/partition/delete.html:13
msgid "Cancel"
msgstr "Cancel"
#: partitioncloud/templates/albums/index.html:3
msgid "Home"
msgstr "Home"
#: partitioncloud/templates/albums/index.html:10
#, python-format
msgid "Hi %(user_name)s !"
msgstr "Hi %(user_name)s !"
#: partitioncloud/templates/albums/index.html:11
msgid "No album selected"
msgstr "No album selected"
#: partitioncloud/templates/albums/search.html:5
#, python-format
msgid "Search results for \"%(query)s\""
msgstr "Search results for \"%(query)s\""
#: partitioncloud/templates/albums/search.html:7
msgid "Results in current database"
msgstr "Results in current database"
#: partitioncloud/templates/albums/search.html:38
#: partitioncloud/templates/albums/search.html:70
msgid "Add to album"
msgstr "Add to album"
#: partitioncloud/templates/albums/search.html:45
msgid "Online search results"
msgstr ""
#: partitioncloud/templates/albums/search.html:77
msgid ""
"No results available. Try to tweak your query or increase the amount of "
"online searches."
msgstr ""
"No results available. Try to tweak your query or increase the amount of "
"online searches."
#: partitioncloud/templates/auth/login.html:8
#: partitioncloud/templates/auth/register.html:18
msgid "Username"
msgstr "Username"
#: partitioncloud/templates/auth/login.html:9
#: partitioncloud/templates/auth/register.html:19
msgid "Password"
msgstr "Password"
#: partitioncloud/templates/auth/register.html:10
msgid "Add to album:"
msgstr "Add to album:"
#: partitioncloud/templates/auth/register.html:12
msgid "None"
msgstr "None"
#: partitioncloud/templates/components/add_partition.html:1
#, python-format
msgid "Add a score to %(name)s"
msgstr "Add a score to %(name)s"
#: partitioncloud/templates/components/add_partition.html:4
msgid "title"
msgstr "title"
#: partitioncloud/templates/components/add_partition.html:5
msgid "author"
msgstr "author"
#: partitioncloud/templates/components/add_partition.html:6
msgid "lyrics"
msgstr "lyrics"
#: partitioncloud/templates/components/add_partition.html:10
#: partitioncloud/templates/groupe/index.html:11
#: partitioncloud/templates/partition/attachments.html:13
msgid "Add"
msgstr "Add"
#: partitioncloud/templates/groupe/index.html:8
#, python-format
msgid "Add an album to group %(name)s"
msgstr "Add an album to group %(name)s"
#: partitioncloud/templates/groupe/index.html:16
msgid "Delete group"
msgstr "Delete group"
#: partitioncloud/templates/groupe/index.html:17
msgid "Do you really want to delete this group and the albums it contains?"
msgstr "Do you really want to delete this group and the albums it contains?"
#: partitioncloud/templates/groupe/index.html:52
msgid "Add an album"
msgstr "Add an album"
#: partitioncloud/templates/groupe/index.html:74
msgid "Create one"
msgstr "Create one"
#: partitioncloud/templates/groupe/index.html:77
#, python-format
msgid "No available album. %(create)s"
msgstr "No available album. %(create)s"
#: partitioncloud/templates/partition/attachments.html:5
#, python-format
msgid "Attachments of %(name)s"
msgstr "Attachments of %(name)s"
#: partitioncloud/templates/partition/attachments.html:9
#, python-format
msgid "Add an attachment to %(name)s"
msgstr "Add an attachment to %(name)s"
#: partitioncloud/templates/partition/attachments.html:22
msgid ""
"No pdf viewer available in this browser.\n"
" You can use Firefox on Android."
msgstr ""
"No pdf viewer available in this browser.\n"
" You can use Firefox on Android."
#: partitioncloud/templates/partition/attachments.html:46
msgid "JavaScript is mandatory to read MIDI files"
msgstr "JavaScript is mandatory to read MIDI files"
#: partitioncloud/templates/partition/attachments.html:60
msgid "Add an attachment"
msgstr "Add an attachment"
#: partitioncloud/templates/partition/delete.html:8
msgid "Do you really want to delete this score?"
msgstr "Do you really want to delete this score?"
#: partitioncloud/templates/partition/details.html:4
#, python-format
msgid "Details of \"%(name)s\""
msgstr "Details of \"%(name)s\""
#: partitioncloud/templates/partition/details.html:12
msgid "Added by"
msgstr "Added by"
#: partitioncloud/templates/partition/details.html:23
msgid "Unknown"
msgstr "Unknown"
#: partitioncloud/templates/partition/details.html:29
msgid "Type"
msgstr "Type"
#: partitioncloud/templates/partition/details.html:52
#: partitioncloud/templates/partition/edit.html:13
msgid "File"
msgstr "File"
#: partitioncloud/templates/partition/details.html:58
#: partitioncloud/templates/partition/details.html:59
#: partitioncloud/templates/partition/edit.html:29
#: partitioncloud/templates/partition/edit.html:30
msgid "Title"
msgstr "Title"
#: partitioncloud/templates/partition/details.html:62
#: partitioncloud/templates/partition/details.html:63
#: partitioncloud/templates/partition/edit.html:33
#: partitioncloud/templates/partition/edit.html:34
msgid "Author"
msgstr "Author"
#: partitioncloud/templates/partition/details.html:66
#: partitioncloud/templates/partition/details.html:67
#: partitioncloud/templates/partition/edit.html:37
#: partitioncloud/templates/partition/edit.html:38
msgid "Lyrics"
msgstr "Lyrics"
#: partitioncloud/templates/partition/details.html:70
#: partitioncloud/templates/partition/edit.html:41
msgid "Attachments"
msgstr "Attachments"
#: partitioncloud/templates/partition/details.html:75
#: partitioncloud/templates/partition/edit.html:46
#, python-format
msgid "Yes, %(number)s"
msgstr "Yes, %(number)s"
#: partitioncloud/templates/partition/details.html:77
#: partitioncloud/templates/partition/edit.html:48
msgid "Add one"
msgstr "Add one"
#: partitioncloud/templates/partition/details.html:83
#: partitioncloud/templates/partition/edit.html:54
msgid "Update"
msgstr "Update"
#: partitioncloud/templates/partition/edit.html:6
#, python-format
msgid "Modify \"%(name)s\""
msgstr "Modify \"%(name)s\""
#: partitioncloud/templates/partition/edit.html:21
msgid "Source"
msgstr "Source"

View File

@ -0,0 +1,606 @@
# French translations for PROJECT.
# Copyright (C) 2024 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2024.
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-01-25 16:19+0100\n"
"PO-Revision-Date: 2024-01-22 15:24+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: fr\n"
"Language-Team: fr <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.14.0\n"
#: partitioncloud/__init__.py:135
#, python-format
msgid "Created user %(username)s"
msgstr "Utilisateur %(username)s créé"
#: partitioncloud/__init__.py:138
#, python-format
msgid "This album does not exists, but user %(username)s has been created"
msgstr "Cet album n'existe pas. L'utilisateur %(username)s a été créé"
#: partitioncloud/modules/albums.py:41
msgid "Missing search query"
msgstr "Aucun terme de recherche spécifié."
#: partitioncloud/modules/albums.py:123 partitioncloud/modules/groupe.py:71
#: partitioncloud/modules/groupe.py:185
msgid "Missing name."
msgstr "Un nom est requis."
#: partitioncloud/modules/albums.py:160
msgid "This album does not exist."
msgstr "Cet album n'existe pas."
#: partitioncloud/modules/albums.py:163
msgid "Album added to collection."
msgstr "Album ajouté à la collection."
#: partitioncloud/modules/albums.py:177 partitioncloud/modules/albums.py:240
#: partitioncloud/modules/albums.py:346
msgid "You are not a member of this album"
msgstr "Vous ne faites pas partie de cet album"
#: partitioncloud/modules/albums.py:181
msgid "You are alone here, quitting means deleting this album."
msgstr "Vous êtes seul dans cet album, le quitter entraînera sa suppression."
#: partitioncloud/modules/albums.py:185
msgid "Album quitted."
msgstr "Album quitté."
#: partitioncloud/modules/albums.py:204
msgid "You are not alone in this album."
msgstr "Vous n'êtes pas seul dans cet album."
#: partitioncloud/modules/albums.py:206
msgid "You don't own this album."
msgstr "Vous ne possédez pas cet album."
#: partitioncloud/modules/albums.py:217
msgid "Album deleted."
msgstr "Album supprimé."
#: partitioncloud/modules/albums.py:246 partitioncloud/modules/partition.py:153
#: partitioncloud/modules/partition.py:199
msgid "Missing title"
msgstr "Un titre est requis."
#: partitioncloud/modules/albums.py:248 partitioncloud/modules/partition.py:63
msgid "Missing file"
msgstr "Aucun fichier n'a été fourni."
#: partitioncloud/modules/albums.py:260
msgid "Search results expired"
msgstr "Les résultats de la recherche ont expiré."
#: partitioncloud/modules/albums.py:326
#, python-format
msgid "Score %(partition_name)s added"
msgstr "Partition %(partition_name)s ajoutée"
#: partitioncloud/modules/albums.py:340
msgid "Selecting an album is mandatory."
msgstr "Il est nécessaire de sélectionner un album."
#: partitioncloud/modules/albums.py:342
msgid "Selecting a score is mandatory."
msgstr "Il est nécessaire de sélectionner une partition."
#: partitioncloud/modules/albums.py:344
msgid "Please specify a score type."
msgstr "Il est nécessaire de spécifier un type de partition."
#: partitioncloud/modules/albums.py:366
msgid "Score added"
msgstr "Partition ajoutée."
#: partitioncloud/modules/albums.py:368
msgid "Score is already in the album."
msgstr "Partition déjà dans l'album."
#: partitioncloud/modules/albums.py:380
msgid "Unknown score type."
msgstr "Type de partition inconnu."
#: partitioncloud/modules/auth.py:27 partitioncloud/modules/auth.py:54
msgid "You need to login to access this resource."
msgstr "Vous devez être connecté pour accéder à cette page."
#: partitioncloud/modules/auth.py:59
msgid "Missing rights."
msgstr "Droits insuffisants."
#: partitioncloud/modules/auth.py:85
msgid "Missing username."
msgstr "Un nom d'utilisateur est requis."
#: partitioncloud/modules/auth.py:87
msgid "Missing password."
msgstr "Un mot de passe est requis."
#: partitioncloud/modules/auth.py:100
#, python-format
msgid "Username %(username)s is not available."
msgstr "Le nom d'utilisateur %(username)s est déjà pris."
#: partitioncloud/modules/auth.py:113
msgid "New users registration is disabled by owner."
msgstr ""
"L'enregistrement de nouveaux utilisateurs a été désactivé par "
"l'administrateur."
#: partitioncloud/modules/auth.py:127
msgid "Successfully created new user. You can log in."
msgstr "Utilisateur créé avec succès. Vous pouvez vous connecter."
#: partitioncloud/modules/auth.py:152
msgid "Incorrect username or password"
msgstr "Nom d'utilisateur ou mot de passe incorrect."
#: partitioncloud/modules/groupe.py:120
msgid "Unknown group."
msgstr "Ce groupe n'existe pas."
#: partitioncloud/modules/groupe.py:123
msgid "Group added to collection."
msgstr "Groupe ajouté à la collection."
#: partitioncloud/modules/groupe.py:134
msgid "You are not a member of this group."
msgstr "Vous ne faites pas partie de ce groupe"
#: partitioncloud/modules/groupe.py:138
msgid "You are alone here, quitting means deleting this group."
msgstr "Vous êtes seul dans ce groupe, le quitter entraînera sa suppression."
#: partitioncloud/modules/groupe.py:142
msgid "Group quitted."
msgstr "Groupe quitté."
#: partitioncloud/modules/groupe.py:155
msgid "You are not alone in this group."
msgstr "Vous n'êtes pas seul dans ce groupe."
#: partitioncloud/modules/groupe.py:166
msgid "Group deleted."
msgstr "Groupe supprimé."
#: partitioncloud/modules/groupe.py:188
msgid "You are not admin of this group."
msgstr "Vous n'êtes pas administrateur de ce groupe"
#: partitioncloud/modules/partition.py:58
msgid "You don't own this score."
msgstr "Cette partition ne vous appartient pas"
#: partitioncloud/modules/partition.py:71
msgid "Missing filename."
msgstr "Pas de nom de fichier"
#: partitioncloud/modules/partition.py:76
msgid "Unsupported file type."
msgstr "Extension de fichier non supportée"
#: partitioncloud/modules/partition.py:144
msgid "You are not allowed to edit this file."
msgstr "Vous n'êtes pas autorisé à modifier cette partition."
#: partitioncloud/modules/partition.py:155
#: partitioncloud/modules/partition.py:201
msgid "Missing author in request body (can be null)."
msgstr "Un nom d'auteur est requis (à minima nul)"
#: partitioncloud/modules/partition.py:157
#: partitioncloud/modules/partition.py:203
msgid "Missing lyrics (can be null)."
msgstr "Des paroles sont requises (à minima nulles)"
#: partitioncloud/modules/partition.py:169
#: partitioncloud/modules/partition.py:215
#, python-format
msgid "Successfully modified %(name)s"
msgstr "Partition %(name)s modifiée avec succès."
#: partitioncloud/modules/partition.py:230
msgid "You are not allowed to delete this score."
msgstr "Vous n'êtes pas autorisé à supprimer cette partition."
#: partitioncloud/modules/partition.py:238
msgid "Score deleted."
msgstr "Partition supprimée."
#: partitioncloud/templates/base.html:23
msgid "New Album"
msgstr "Créer un nouvel album"
#: partitioncloud/templates/base.html:25 partitioncloud/templates/base.html:36
#: partitioncloud/templates/groupe/index.html:10
#: partitioncloud/templates/partition/attachments.html:11
msgid "Name"
msgstr "Nom"
#: partitioncloud/templates/base.html:26 partitioncloud/templates/base.html:37
msgid "Create"
msgstr "Créer"
#: partitioncloud/templates/base.html:30
msgid "I want to create a collection of albums."
msgstr ""
"Je souhaite créer plusieurs albums et pouvoir tous les partager avec un "
"seul lien."
#: partitioncloud/templates/base.html:30
msgid "Create group"
msgstr "Créer un groupe"
#: partitioncloud/templates/base.html:34
msgid "Create new group"
msgstr "Créer un nouveau groupe"
#: partitioncloud/templates/base.html:61
msgid "Search"
msgstr "Rechercher"
#: partitioncloud/templates/base.html:63
msgid "Number of online searches"
msgstr "Nombre de recherches en ligne"
#: partitioncloud/templates/admin/index.html:23
#: partitioncloud/templates/base.html:71
#: partitioncloud/templates/partition/details.html:41
msgid "Albums"
msgstr "Albums"
#: partitioncloud/templates/base.html:75
msgid "New album"
msgstr "Créer un album"
#: partitioncloud/templates/base.html:92
msgid "No albums"
msgstr "Aucun album disponible"
#: partitioncloud/templates/base.html:111
msgid "No album available"
msgstr "Aucun album disponible"
#: partitioncloud/templates/base.html:125
msgid "Log in to see your albums"
msgstr "Connectez vous pour avoir accès à vos albums"
#: partitioncloud/templates/base.html:139
msgid "Log out"
msgstr "Déconnexion"
#: partitioncloud/templates/base.html:154
msgid "Admin Panel"
msgstr "Panneau admin"
#: partitioncloud/templates/auth/register.html:5
#: partitioncloud/templates/auth/register.html:20
#: partitioncloud/templates/base.html:166
msgid "Create account"
msgstr "Créer un compte"
#: partitioncloud/templates/auth/login.html:5
#: partitioncloud/templates/auth/login.html:10
#: partitioncloud/templates/base.html:168
msgid "Log in"
msgstr "Se connecter"
#: partitioncloud/templates/admin/index.html:5
msgid "Administration Panel"
msgstr "Panneau d'administration"
#: partitioncloud/templates/admin/index.html:9
msgid "New user"
msgstr "Nouvel utilisateur"
#: partitioncloud/templates/admin/index.html:12
msgid "See scores"
msgstr "Voir les partitions"
#: partitioncloud/templates/admin/index.html:15
msgid "See logs"
msgstr "Voir les logs"
#: partitioncloud/templates/admin/index.html:22
msgid "User"
msgstr "Utilisateur"
#: partitioncloud/templates/admin/index.html:24
msgid "Scores"
msgstr "Partitions"
#: partitioncloud/templates/admin/index.html:25
msgid "Admin privileges"
msgstr "Privilèges"
#: partitioncloud/templates/admin/logs.html:5
msgid "Logs"
msgstr "Logs"
#: partitioncloud/templates/admin/partitions.html:4
msgid "Scores list"
msgstr "Liste des partitions"
#: partitioncloud/templates/admin/partitions.html:31
#: partitioncloud/templates/albums/album.html:94
msgid "No available scores"
msgstr "Aucune partition disponible"
#: partitioncloud/templates/albums/add-partition.html:3
msgid "New score"
msgstr "Ajout de partition"
#: partitioncloud/templates/albums/album.html:12
msgid "Delete l'album"
msgstr "Supprimer l'album"
#: partitioncloud/templates/albums/album.html:13
#: partitioncloud/templates/albums/delete-album.html:6
msgid "Do you really want to delete this album?"
msgstr "Êtes vous sûr de vouloir supprimer cet album ?"
#: partitioncloud/templates/albums/album.html:16
#: partitioncloud/templates/albums/album.html:60
#: partitioncloud/templates/albums/delete-album.html:8
#: partitioncloud/templates/groupe/index.html:20
#: partitioncloud/templates/groupe/index.html:53
#: partitioncloud/templates/partition/delete.html:10
#: partitioncloud/templates/partition/details.html:86
#: partitioncloud/templates/partition/edit.html:57
msgid "Delete"
msgstr "Supprimer"
#: partitioncloud/templates/albums/album.html:51
msgid "Add a score"
msgstr "Ajouter une partition"
#: partitioncloud/templates/albums/album.html:54
#: partitioncloud/templates/groupe/index.html:46
msgid "Join"
msgstr "Rejoindre"
#: partitioncloud/templates/albums/album.html:56
#: partitioncloud/templates/groupe/index.html:48
msgid "Quit"
msgstr "Quitter"
#: partitioncloud/templates/albums/album.html:58
#: partitioncloud/templates/groupe/index.html:50
msgid "Share"
msgstr "Partager"
#: partitioncloud/templates/albums/delete-album.html:3
#: partitioncloud/templates/partition/delete.html:4
#, python-format
msgid "Delete %(name)s"
msgstr "Supprimer %(name)s"
#: partitioncloud/templates/albums/delete-album.html:11
#: partitioncloud/templates/partition/delete.html:13
msgid "Cancel"
msgstr "Annuler"
#: partitioncloud/templates/albums/index.html:3
msgid "Home"
msgstr "Accueil"
#: partitioncloud/templates/albums/index.html:10
#, python-format
msgid "Hi %(user_name)s !"
msgstr "Bonjour %(user_name)s !"
#: partitioncloud/templates/albums/index.html:11
msgid "No album selected"
msgstr "Aucun album sélectionné"
#: partitioncloud/templates/albums/search.html:5
#, python-format
msgid "Search results for \"%(query)s\""
msgstr "Résultats de la recherche pour \"%(query)s\""
#: partitioncloud/templates/albums/search.html:7
msgid "Results in current database"
msgstr "Résultats dans la recherche locale"
#: partitioncloud/templates/albums/search.html:38
#: partitioncloud/templates/albums/search.html:70
msgid "Add to album"
msgstr "Ajouter à un album"
#: partitioncloud/templates/albums/search.html:45
msgid "Online search results"
msgstr "Résultats de la recherche en ligne"
#: partitioncloud/templates/albums/search.html:77
msgid ""
"No results available. Try to tweak your query or increase the amount of "
"online searches."
msgstr ""
"Aucun résultat disponible. Essayez d'affiner votre recherche ou "
"d'augmenter le nombre de résultats en ligne"
#: partitioncloud/templates/auth/login.html:8
#: partitioncloud/templates/auth/register.html:18
msgid "Username"
msgstr "Nom d'utilisateur"
#: partitioncloud/templates/auth/login.html:9
#: partitioncloud/templates/auth/register.html:19
msgid "Password"
msgstr "Mot de passe"
#: partitioncloud/templates/auth/register.html:10
msgid "Add to album:"
msgstr "Ajouter à un album:"
#: partitioncloud/templates/auth/register.html:12
msgid "None"
msgstr "Aucun"
#: partitioncloud/templates/components/add_partition.html:1
#, python-format
msgid "Add a score to %(name)s"
msgstr "Ajouter une partition à %(name)s"
#: partitioncloud/templates/components/add_partition.html:4
msgid "title"
msgstr "titre"
#: partitioncloud/templates/components/add_partition.html:5
msgid "author"
msgstr "auteur"
#: partitioncloud/templates/components/add_partition.html:6
msgid "lyrics"
msgstr "paroles"
#: partitioncloud/templates/components/add_partition.html:10
#: partitioncloud/templates/groupe/index.html:11
#: partitioncloud/templates/partition/attachments.html:13
msgid "Add"
msgstr "Ajouter"
#: partitioncloud/templates/groupe/index.html:8
#, python-format
msgid "Add an album to group %(name)s"
msgstr "Ajouter un album au groupe %(name)s"
#: partitioncloud/templates/groupe/index.html:16
msgid "Delete group"
msgstr "Supprimer le groupe"
#: partitioncloud/templates/groupe/index.html:17
msgid "Do you really want to delete this group and the albums it contains?"
msgstr ""
"Êtes vous sûr de vouloir supprimer ce groupe ? Cela supprimera les albums"
" sous-jacents et leurs partitions si personne ne les a rejoints "
"(indépendamment du groupe)."
#: partitioncloud/templates/groupe/index.html:52
msgid "Add an album"
msgstr "Ajouter un album"
#: partitioncloud/templates/groupe/index.html:74
msgid "Create one"
msgstr "En créer un"
#: partitioncloud/templates/groupe/index.html:77
#, python-format
msgid "No available album. %(create)s"
msgstr "Aucun album disponible. %(create)s"
#: partitioncloud/templates/partition/attachments.html:5
#, python-format
msgid "Attachments of %(name)s"
msgstr "Attachments de %(name)s"
#: partitioncloud/templates/partition/attachments.html:9
#, python-format
msgid "Add an attachment to %(name)s"
msgstr "Ajouter un attachment à %(name)s"
#: partitioncloud/templates/partition/attachments.html:22
msgid ""
"No pdf viewer available in this browser.\n"
" You can use Firefox on Android."
msgstr ""
"Impossible d'afficher le pdf dans ce navigateur.\n"
" Il est conseillé d'utiliser Firefox sur Android."
#: partitioncloud/templates/partition/attachments.html:46
msgid "JavaScript is mandatory to read MIDI files"
msgstr "JavaScript est nécessaire pour lire les fichiers MIDI"
#: partitioncloud/templates/partition/attachments.html:60
msgid "Add an attachment"
msgstr "Ajouter un attachment"
#: partitioncloud/templates/partition/delete.html:8
msgid "Do you really want to delete this score?"
msgstr "Êtes vous sûr de vouloir supprimer cette partition ?"
#: partitioncloud/templates/partition/details.html:4
#, python-format
msgid "Details of \"%(name)s\""
msgstr "Détails de \"%(name)s\""
#: partitioncloud/templates/partition/details.html:12
msgid "Added by"
msgstr "Responsable de l'ajout"
#: partitioncloud/templates/partition/details.html:23
msgid "Unknown"
msgstr "Inconnu"
#: partitioncloud/templates/partition/details.html:29
msgid "Type"
msgstr "Type d'ajout"
#: partitioncloud/templates/partition/details.html:52
#: partitioncloud/templates/partition/edit.html:13
msgid "File"
msgstr "Fichier"
#: partitioncloud/templates/partition/details.html:58
#: partitioncloud/templates/partition/details.html:59
#: partitioncloud/templates/partition/edit.html:29
#: partitioncloud/templates/partition/edit.html:30
msgid "Title"
msgstr "Titre"
#: partitioncloud/templates/partition/details.html:62
#: partitioncloud/templates/partition/details.html:63
#: partitioncloud/templates/partition/edit.html:33
#: partitioncloud/templates/partition/edit.html:34
msgid "Author"
msgstr "Auteur"
#: partitioncloud/templates/partition/details.html:66
#: partitioncloud/templates/partition/details.html:67
#: partitioncloud/templates/partition/edit.html:37
#: partitioncloud/templates/partition/edit.html:38
msgid "Lyrics"
msgstr "Paroles"
#: partitioncloud/templates/partition/details.html:70
#: partitioncloud/templates/partition/edit.html:41
msgid "Attachments"
msgstr "Pièces jointes"
#: partitioncloud/templates/partition/details.html:75
#: partitioncloud/templates/partition/edit.html:46
#, python-format
msgid "Yes, %(number)s"
msgstr "Oui, %(number)s"
#: partitioncloud/templates/partition/details.html:77
#: partitioncloud/templates/partition/edit.html:48
msgid "Add one"
msgstr "En rajouter"
#: partitioncloud/templates/partition/details.html:83
#: partitioncloud/templates/partition/edit.html:54
msgid "Update"
msgstr "Mettre à jour"
#: partitioncloud/templates/partition/edit.html:6
#, python-format
msgid "Modify \"%(name)s\""
msgstr "Modifier \"%(name)s\""
#: partitioncloud/templates/partition/edit.html:21
msgid "Source"
msgstr "Source"

View File

@ -1,4 +1,5 @@
flask flask
flask-babel
google google
colorama colorama
qrcode qrcode

View File

@ -1,7 +1,9 @@
import os import os
import sys
import random import random
import string import string
import sqlite3 import sqlite3
from colorama import Fore, Style
from . import config from . import config
@ -40,3 +42,29 @@ def new_uuid():
def format_uuid(uuid): def format_uuid(uuid):
"""Format old uuid4 format""" """Format old uuid4 format"""
return uuid.upper()[:6] return uuid.upper()[:6]
def install_package(package):
print(f"\nThe following python package needs to be installed: {Style.BRIGHT}{Fore.YELLOW}{package}{Style.RESET_ALL}")
print(f"1. Install with {Style.BRIGHT}pip{Style.RESET_ALL} (automatic)")
print(f"2. Install manually (other package manager)")
option = input("Select an option: ")
try:
choice = int(option)
if choice == 1:
return_value = os.system(f"pip install {package} -qq")
if return_value == 0:
return
print(f"{Fore.RED}Installation with pip failed{Style.RESET_ALL}")
sys.exit(return_value)
elif choice == 2:
input("Install via you preferred option, and hit [Enter] when done")
return
except ValueError:
pass
print(f"{Fore.RED}Please enter a valid option{Style.RESET_ALL}")
return install_package(package)

View File

@ -54,7 +54,7 @@ def add_attachments():
def install_colorama(): def install_colorama():
os.system("pip install colorama -qq") utils.install_package("colorama")
""" """
@ -144,7 +144,7 @@ def base_url_parameter_added():
def install_qrcode(): def install_qrcode():
os.system("pip install qrcode -qq") utils.install_package("qrcode")
""" """
@ -171,3 +171,12 @@ def move_thumbnails():
os.makedirs(os.path.join(config.instance, "cache", "thumbnails"), exist_ok=True) os.makedirs(os.path.join(config.instance, "cache", "thumbnails"), exist_ok=True)
os.makedirs(os.path.join(config.instance, "cache", "search-thumbnails"), exist_ok=True) os.makedirs(os.path.join(config.instance, "cache", "search-thumbnails"), exist_ok=True)
"""
v1.7.*
"""
def install_babel():
utils.install_package("flask-babel")

View File

@ -34,7 +34,8 @@ hooks = [
), ),
("v1.4.1", [("Install qrcode", v1_hooks.install_qrcode)]), ("v1.4.1", [("Install qrcode", v1_hooks.install_qrcode)]),
("v1.5.0", [("Move to instance directory", v1_hooks.move_instance)]), ("v1.5.0", [("Move to instance directory", v1_hooks.move_instance)]),
("v1.5.1", [("Move thumbnails", v1_hooks.move_thumbnails)]) ("v1.5.1", [("Move thumbnails", v1_hooks.move_thumbnails)]),
("v1.7.0", [("Install babel", v1_hooks.install_babel)])
] ]