Localization: add python strings

This commit is contained in:
augustin64 2024-01-22 16:06:03 +01:00
parent 2ff7a515d5
commit 210ab6c0d3
13 changed files with 556 additions and 60 deletions

4
.gitignore vendored
View File

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

View File

@ -27,6 +27,7 @@ git clone https://github.com/partitioncloud/partitioncloud-server.git
cd partitioncloud-server
# Install dependencies
pip install -r requirements.txt
pybabel compile -d partitioncloud/translations
# Create database and folders
./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)
## 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
- [ ] Modifier son mot de passe
- [ ] Supprimer un utilisateur

2
babel.cfg Normal file
View File

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

View File

@ -27,3 +27,6 @@ INSTANCE_PATH="instance"
# Events to log
ENABLED_LOGS=["NEW_GROUPE", "NEW_ALBUM", "NEW_PARTITION", "NEW_USER", "SERVER_RESTART", "FAILED_LOGIN"]
# Available languages
LANGUAGES=['en', 'fr']

View File

@ -10,6 +10,7 @@ import importlib.util
from flask import Flask, g, redirect, render_template, request, send_file, flash, session, abort
from werkzeug.security import generate_password_hash
from flask_babel import Babel, _
from .modules.utils import User, Album, get_all_albums
from .modules import albums, auth, partition, admin, groupe, thumbnails, logging
@ -18,6 +19,12 @@ from .modules.db import get_db
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():
app.config.from_object('default_config')
@ -125,10 +132,10 @@ def add_user():
try:
if album_uuid != "":
user.join_album(album_uuid)
flash(f"Utilisateur {username} créé")
flash(_("Utilisateur %(username)s créé", username=username))
return redirect("/albums")
except LookupError:
flash(f"Cet album n'existe pas. L'utilisateur {username} a été créé")
flash(_("Cet album n'existe pas. L'utilisateur %(username)s a été créé", username=username))
return redirect("/albums")
flash(error)

View File

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

View File

@ -7,6 +7,7 @@ from typing import Optional
from flask import (Blueprint, flash, g, redirect, render_template,
request, session, url_for, current_app)
from flask_babel import _
from werkzeug.security import check_password_hash, generate_password_hash
@ -23,7 +24,7 @@ def login_required(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
if g.user is None:
flash("Vous devez être connecté pour accéder à cette page.")
flash(_("Vous devez être connecté pour accéder à cette page."))
return redirect(url_for("auth.login"))
return view(**kwargs)
@ -50,12 +51,12 @@ def admin_required(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
if g.user is None:
flash("Vous devez être connecté pour accéder à cette page.")
flash(_("Vous devez être connecté pour accéder à cette page."))
return redirect(url_for("auth.login"))
user = User(user_id=session.get("user_id"))
if user.access_level != 1:
flash("Droits insuffisants.")
flash(_("Droits insuffisants."))
return redirect("/albums")
return view(**kwargs)
@ -81,9 +82,9 @@ def create_user(username: str, password: str) -> Optional[str]:
"""Adds a new user to the database"""
error = None
if not username:
error = "Un nom d'utilisateur est requis."
error = _("Un nom d'utilisateur est requis.")
elif not password:
error = "Un mot de passe est requis."
error = _("Un mot de passe est requis.")
try:
db = get_db()
@ -96,7 +97,7 @@ def create_user(username: str, password: str) -> Optional[str]:
except db.IntegrityError:
# The username was already taken, which caused the
# commit to fail. Show a validation error.
error = f"Le nom d'utilisateur {username} est déjà pris."
error = _("Le nom d'utilisateur %(username)s est déjà pris.", username=username)
return error # may be None
@ -109,7 +110,7 @@ def register():
password for security.
"""
if current_app.config["DISABLE_REGISTER"]:
flash("L'enregistrement de nouveaux utilisateurs a été désactivé par l'administrateur.")
flash(_("L'enregistrement de nouveaux utilisateurs a été désactivé par l'administrateur."))
return redirect(url_for("auth.login"))
if request.method == "POST":
@ -123,7 +124,7 @@ def register():
else:
user = User(name=username)
flash("Utilisateur créé avec succès. Vous pouvez vous connecter.")
flash(_("Utilisateur créé avec succès. Vous pouvez vous connecter."))
logging.log(
[user.username, user.id, False],
@ -148,7 +149,7 @@ def login():
if (user is None) or not check_password_hash(user["password"], password):
logging.log([username], logging.LogEntry.FAILED_LOGIN)
error = "Nom d'utilisateur ou mot de passe incorrect."
error = _("Nom d'utilisateur ou mot de passe incorrect.")
if error is None:
# 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,
request, session, current_app)
from flask_babel import _
from .auth import login_required
from .db import get_db
@ -67,7 +68,7 @@ def create_groupe():
user = User(user_id=session["user_id"])
if not name or name.strip() == "":
error = "Un nom est requis. Le groupe n'a pas été créé"
error = _("Un nom est requis. Le groupe n'a pas été créé")
if error is None:
while True:
@ -116,10 +117,10 @@ def join_groupe(uuid):
try:
user.join_groupe(uuid)
except LookupError:
flash("Ce groupe n'existe pas.")
flash(_("Ce groupe n'existe pas."))
return redirect(f"/groupe/{uuid}")
flash("Groupe ajouté à la collection.")
flash(_("Groupe ajouté à la collection."))
return redirect(f"/groupe/{uuid}")
@ -130,15 +131,15 @@ def quit_groupe(uuid):
groupe = Groupe(uuid=uuid)
users = groupe.get_users()
if user.id not in [u["id"] for u in users]:
flash("Vous ne faites pas partie de ce groupe")
flash(_("Vous ne faites pas partie de ce groupe"))
return redirect(f"/groupe/{uuid}")
if len(users) == 1:
flash("Vous êtes seul dans ce groupe, le quitter entraînera sa suppression.")
flash(_("Vous êtes seul dans ce groupe, le quitter entraînera sa suppression."))
return redirect(f"/groupe/{uuid}#delete")
user.quit_groupe(groupe.uuid)
flash("Groupe quitté.")
flash(_("Groupe quitté."))
return redirect("/albums")
@ -151,7 +152,7 @@ def delete_groupe(uuid):
error = None
users = groupe.get_users()
if len(users) > 1:
error = "Vous n'êtes pas seul dans ce groupe."
error = _("Vous n'êtes pas seul dans ce groupe.")
if user.access_level == 1 or user.id not in groupe.get_admins():
error = None
@ -162,7 +163,7 @@ def delete_groupe(uuid):
groupe.delete(current_app.instance_path)
flash("Groupe supprimé.")
flash(_("Groupe supprimé."))
return redirect("/albums")
@ -181,10 +182,10 @@ def create_album_req(groupe_uuid):
error = None
if not name or name.strip() == "":
error = "Un nom est requis. L'album n'a pas été créé"
error = _("Un nom est requis. L'album n'a pas été créé")
if user.id not in groupe.get_admins():
error ="Vous n'êtes pas administrateur de ce groupe"
error = _("Vous n'êtes pas administrateur de ce groupe")
if error is None:
uuid = utils.create_album(name)

View File

@ -30,7 +30,7 @@ class LogEntry(Enum):
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:
f.write(f"[{date}] {entry}\n")

View File

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

View File

@ -0,0 +1,224 @@
# 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-22 16:04+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.12.1\n"
#: partitioncloud/__init__.py:136
#, fuzzy, python-format
msgid "Utilisateur %(username)s créé"
msgstr "Created user %(username)s"
#: partitioncloud/__init__.py:139
#, fuzzy, python-format
msgid "Cet album n'existe pas. L'utilisateur %(username)s a été créé"
msgstr "This album does not exists, but user %(username)s has been created"
#: partitioncloud/modules/albums.py:41
msgid "Aucun terme de recherche spécifié."
msgstr "Missing search query"
#: partitioncloud/modules/albums.py:123 partitioncloud/modules/groupe.py:185
msgid "Un nom est requis. L'album n'a pas été créé"
msgstr "Missing name."
#: partitioncloud/modules/albums.py:160
msgid "Cet album n'existe pas."
msgstr "This album does not exist."
#: partitioncloud/modules/albums.py:163
msgid "Album ajouté à la collection."
msgstr "Album added to collection."
#: partitioncloud/modules/albums.py:177 partitioncloud/modules/albums.py:240
#: partitioncloud/modules/albums.py:346
msgid "Vous ne faites pas partie de cet album"
msgstr "You are not a member of this album"
#: partitioncloud/modules/albums.py:181
msgid "Vous êtes seul dans cet album, le quitter entraînera sa suppression."
msgstr "You are alone here, quitting means deleting this album."
#: partitioncloud/modules/albums.py:185
msgid "Album quitté."
msgstr "Album quitted."
#: partitioncloud/modules/albums.py:204
msgid "Vous n'êtes pas seul dans cet album."
msgstr "You are not alone in this album."
#: partitioncloud/modules/albums.py:206
msgid "Vous ne possédez pas cet album."
msgstr "You don't own this album."
#: partitioncloud/modules/albums.py:217
msgid "Album supprimé."
msgstr "Album deleted."
#: partitioncloud/modules/albums.py:246 partitioncloud/modules/partition.py:153
#: partitioncloud/modules/partition.py:199
msgid "Un titre est requis."
msgstr "Missing title"
#: partitioncloud/modules/albums.py:248 partitioncloud/modules/partition.py:63
msgid "Aucun fichier n'a été fourni."
msgstr "Missing file"
#: partitioncloud/modules/albums.py:260
msgid "Les résultats de la recherche ont expiré."
msgstr "Search results expired"
#: partitioncloud/modules/albums.py:326
#, fuzzy, python-format
msgid "Partition %(partition_name)s ajoutée"
msgstr "Score %(partition_name)s added"
#: partitioncloud/modules/albums.py:340
msgid "Il est nécessaire de sélectionner un album."
msgstr "Selecting an album is mandatory."
#: partitioncloud/modules/albums.py:342
msgid "Il est nécessaire de sélectionner une partition."
msgstr "Selecting a score is mandatory."
#: partitioncloud/modules/albums.py:344
msgid "Il est nécessaire de spécifier un type de partition."
msgstr "Please specify a score type."
#: partitioncloud/modules/albums.py:366
msgid "Partition ajoutée."
msgstr "Score added"
#: partitioncloud/modules/albums.py:368
msgid "Partition déjà dans l'album."
msgstr "Score is already in the album."
#: partitioncloud/modules/albums.py:380
msgid "Type de partition inconnu."
msgstr "Unknown score type."
#: partitioncloud/modules/auth.py:27 partitioncloud/modules/auth.py:54
msgid "Vous devez être connecté pour accéder à cette page."
msgstr "You need to login to access this resource."
#: partitioncloud/modules/auth.py:59
msgid "Droits insuffisants."
msgstr "Missing rights."
#: partitioncloud/modules/auth.py:85
msgid "Un nom d'utilisateur est requis."
msgstr "Missing username."
#: partitioncloud/modules/auth.py:87
msgid "Un mot de passe est requis."
msgstr "Missing password."
#: partitioncloud/modules/auth.py:100
#, python-format
msgid "Le nom d'utilisateur %(username)s est déjà pris."
msgstr "Username %(username)s is not available."
#: partitioncloud/modules/auth.py:113
msgid ""
"L'enregistrement de nouveaux utilisateurs a été désactivé par "
"l'administrateur."
msgstr "New users registration is disabled by owner."
#: partitioncloud/modules/auth.py:127
msgid "Utilisateur créé avec succès. Vous pouvez vous connecter."
msgstr "Successfully created new user. You can log in."
#: partitioncloud/modules/auth.py:152
msgid "Nom d'utilisateur ou mot de passe incorrect."
msgstr "Incorrect username or password"
#: partitioncloud/modules/groupe.py:71
msgid "Un nom est requis. Le groupe n'a pas été créé"
msgstr "Missing name."
#: partitioncloud/modules/groupe.py:120
msgid "Ce groupe n'existe pas."
msgstr "Unknown group."
#: partitioncloud/modules/groupe.py:123
msgid "Groupe ajouté à la collection."
msgstr "Group added to collection."
#: partitioncloud/modules/groupe.py:134
msgid "Vous ne faites pas partie de ce groupe"
msgstr "You are not a member of this group."
#: partitioncloud/modules/groupe.py:138
msgid "Vous êtes seul dans ce groupe, le quitter entraînera sa suppression."
msgstr "You are alone here, quitting means deleting this group."
#: partitioncloud/modules/groupe.py:142
msgid "Groupe quitté."
msgstr "Group quitted."
#: partitioncloud/modules/groupe.py:155
msgid "Vous n'êtes pas seul dans ce groupe."
msgstr "You are not alone in this group."
#: partitioncloud/modules/groupe.py:166
msgid "Groupe supprimé."
msgstr "Group deleted."
#: partitioncloud/modules/groupe.py:188
msgid "Vous n'êtes pas administrateur de ce groupe"
msgstr "You are not admin of this group."
#: partitioncloud/modules/partition.py:58
msgid "Cette partition ne vous appartient pas"
msgstr "You don't own this score."
#: partitioncloud/modules/partition.py:71
msgid "Pas de nom de fichier"
msgstr "Missing filename."
#: partitioncloud/modules/partition.py:76
msgid "Extension de fichier non supportée"
msgstr "Unsupported file type."
#: partitioncloud/modules/partition.py:144
msgid "Vous n'êtes pas autorisé à modifier cette partition."
msgstr "You are not allowed to edit this file."
#: partitioncloud/modules/partition.py:155
#: partitioncloud/modules/partition.py:201
msgid "Un nom d'auteur est requis (à minima nul)"
msgstr "Missing author in request body (can be null)."
#: partitioncloud/modules/partition.py:157
#: partitioncloud/modules/partition.py:203
msgid "Des paroles sont requises (à minima nulles)"
msgstr "Missing lyrics (can be null)."
#: partitioncloud/modules/partition.py:169
#: partitioncloud/modules/partition.py:215
#, python-format
msgid "Partition %(name)s modifiée avec succès."
msgstr "Successfully modified %(name)s"
#: partitioncloud/modules/partition.py:230
msgid "Vous n'êtes pas autorisé à supprimer cette partition."
msgstr "You are not allowed to delete this score."
#: partitioncloud/modules/partition.py:238
msgid "Partition supprimée."
msgstr "Score deleted."

View File

@ -0,0 +1,226 @@
# 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-22 16:04+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.12.1\n"
#: partitioncloud/__init__.py:136
#, fuzzy, python-format
msgid "Utilisateur %(username)s créé"
msgstr "Utilisateur %(username)s créé"
#: partitioncloud/__init__.py:139
#, fuzzy, python-format
msgid "Cet album n'existe pas. L'utilisateur %(username)s a été créé"
msgstr "Cet album n'existe pas. L'utilisateur %(username)s a été créé"
#: partitioncloud/modules/albums.py:41
msgid "Aucun terme de recherche spécifié."
msgstr "Aucun terme de recherche spécifié."
#: partitioncloud/modules/albums.py:123 partitioncloud/modules/groupe.py:185
msgid "Un nom est requis. L'album n'a pas été créé"
msgstr "Un nom est requis. L'album n'a pas été créé"
#: partitioncloud/modules/albums.py:160
msgid "Cet album n'existe pas."
msgstr "Cet album n'existe pas."
#: partitioncloud/modules/albums.py:163
msgid "Album ajouté à la collection."
msgstr "Album ajouté à la collection."
#: partitioncloud/modules/albums.py:177 partitioncloud/modules/albums.py:240
#: partitioncloud/modules/albums.py:346
msgid "Vous ne faites pas partie de cet album"
msgstr "Vous ne faites pas partie de cet album"
#: partitioncloud/modules/albums.py:181
msgid "Vous êtes seul dans cet album, le quitter entraînera sa suppression."
msgstr "Vous êtes seul dans cet album, le quitter entraînera sa suppression."
#: partitioncloud/modules/albums.py:185
msgid "Album quitté."
msgstr "Album quitté."
#: partitioncloud/modules/albums.py:204
msgid "Vous n'êtes pas seul dans cet album."
msgstr "Vous n'êtes pas seul dans cet album."
#: partitioncloud/modules/albums.py:206
msgid "Vous ne possédez pas cet album."
msgstr "Vous ne possédez pas cet album."
#: partitioncloud/modules/albums.py:217
msgid "Album supprimé."
msgstr "Album supprimé."
#: partitioncloud/modules/albums.py:246 partitioncloud/modules/partition.py:153
#: partitioncloud/modules/partition.py:199
msgid "Un titre est requis."
msgstr "Un titre est requis."
#: partitioncloud/modules/albums.py:248 partitioncloud/modules/partition.py:63
msgid "Aucun fichier n'a été fourni."
msgstr "Aucun fichier n'a été fourni."
#: partitioncloud/modules/albums.py:260
msgid "Les résultats de la recherche ont expiré."
msgstr "Les résultats de la recherche ont expiré."
#: partitioncloud/modules/albums.py:326
#, fuzzy, python-format
msgid "Partition %(partition_name)s ajoutée"
msgstr "Partition %(partition_name)s ajoutée"
#: partitioncloud/modules/albums.py:340
msgid "Il est nécessaire de sélectionner un album."
msgstr "Il est nécessaire de sélectionner un album."
#: partitioncloud/modules/albums.py:342
msgid "Il est nécessaire de sélectionner une partition."
msgstr "Il est nécessaire de sélectionner une partition."
#: partitioncloud/modules/albums.py:344
msgid "Il est nécessaire de spécifier un type de partition."
msgstr "Il est nécessaire de spécifier un type de partition."
#: partitioncloud/modules/albums.py:366
msgid "Partition ajoutée."
msgstr "Partition ajoutée."
#: partitioncloud/modules/albums.py:368
msgid "Partition déjà dans l'album."
msgstr "Partition déjà dans l'album."
#: partitioncloud/modules/albums.py:380
msgid "Type de partition inconnu."
msgstr "Type de partition inconnu."
#: partitioncloud/modules/auth.py:27 partitioncloud/modules/auth.py:54
msgid "Vous devez être connecté pour accéder à cette page."
msgstr "Vous devez être connecté pour accéder à cette page."
#: partitioncloud/modules/auth.py:59
msgid "Droits insuffisants."
msgstr "Droits insuffisants."
#: partitioncloud/modules/auth.py:85
msgid "Un nom d'utilisateur est requis."
msgstr "Un nom d'utilisateur est requis."
#: partitioncloud/modules/auth.py:87
msgid "Un mot de passe est requis."
msgstr "Un mot de passe est requis."
#: partitioncloud/modules/auth.py:100
#, fuzzy, python-format
msgid "Le nom d'utilisateur %(username)s est déjà pris."
msgstr "Le nom d'utilisateur %(username)s est déjà pris."
#: partitioncloud/modules/auth.py:113
msgid ""
"L'enregistrement de nouveaux utilisateurs a été désactivé par "
"l'administrateur."
msgstr ""
"L'enregistrement de nouveaux utilisateurs a été désactivé par "
"l'administrateur."
#: partitioncloud/modules/auth.py:127
msgid "Utilisateur créé avec succès. Vous pouvez vous connecter."
msgstr "Utilisateur créé avec succès. Vous pouvez vous connecter."
#: partitioncloud/modules/auth.py:152
msgid "Nom d'utilisateur ou mot de passe incorrect."
msgstr "Nom d'utilisateur ou mot de passe incorrect."
#: partitioncloud/modules/groupe.py:71
msgid "Un nom est requis. Le groupe n'a pas été créé"
msgstr "Un nom est requis. Le groupe n'a pas été créé"
#: partitioncloud/modules/groupe.py:120
msgid "Ce groupe n'existe pas."
msgstr "Ce groupe n'existe pas."
#: partitioncloud/modules/groupe.py:123
msgid "Groupe ajouté à la collection."
msgstr "Groupe ajouté à la collection."
#: partitioncloud/modules/groupe.py:134
msgid "Vous ne faites pas partie de ce groupe"
msgstr "Vous ne faites pas partie de ce groupe"
#: partitioncloud/modules/groupe.py:138
msgid "Vous êtes seul dans ce groupe, le quitter entraînera sa suppression."
msgstr "Vous êtes seul dans ce groupe, le quitter entraînera sa suppression."
#: partitioncloud/modules/groupe.py:142
msgid "Groupe quitté."
msgstr "Groupe quitté."
#: partitioncloud/modules/groupe.py:155
msgid "Vous n'êtes pas seul dans ce groupe."
msgstr "Vous n'êtes pas seul dans ce groupe."
#: partitioncloud/modules/groupe.py:166
msgid "Groupe supprimé."
msgstr "Groupe supprimé."
#: partitioncloud/modules/groupe.py:188
msgid "Vous n'êtes pas administrateur de ce groupe"
msgstr "Vous n'êtes pas administrateur de ce groupe"
#: partitioncloud/modules/partition.py:58
msgid "Cette partition ne vous appartient pas"
msgstr "Cette partition ne vous appartient pas"
#: partitioncloud/modules/partition.py:71
msgid "Pas de nom de fichier"
msgstr "Pas de nom de fichier"
#: partitioncloud/modules/partition.py:76
msgid "Extension de fichier non supportée"
msgstr "Extension de fichier non supportée"
#: partitioncloud/modules/partition.py:144
msgid "Vous n'êtes pas autorisé à modifier cette partition."
msgstr "Vous n'êtes pas autorisé à modifier cette partition."
#: partitioncloud/modules/partition.py:155
#: partitioncloud/modules/partition.py:201
msgid "Un nom d'auteur est requis (à minima nul)"
msgstr "Un nom d'auteur est requis (à minima nul)"
#: partitioncloud/modules/partition.py:157
#: partitioncloud/modules/partition.py:203
msgid "Des paroles sont requises (à minima nulles)"
msgstr "Des paroles sont requises (à minima nulles)"
#: partitioncloud/modules/partition.py:169
#: partitioncloud/modules/partition.py:215
#, fuzzy, python-format
msgid "Partition %(name)s modifiée avec succès."
msgstr "Partition %(name)s modifiée avec succès."
#: partitioncloud/modules/partition.py:230
msgid "Vous n'êtes pas autorisé à supprimer cette partition."
msgstr "Vous n'êtes pas autorisé à supprimer cette partition."
#: partitioncloud/modules/partition.py:238
msgid "Partition supprimée."
msgstr "Partition supprimée."

View File

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