Compare commits

..

4 Commits

16 changed files with 262 additions and 118 deletions

View File

@ -1,2 +1,5 @@
[extractors]
jinja2 = jinja2.ext:babel_extract
[python: partitioncloud/**.py]
[jinja2: partitioncloud/templates/**.html]

View File

@ -89,7 +89,7 @@ def get_album(uuid):
except LookupError:
return abort(404)
album.users = [User(user_id=i["id"]) for i in album.get_users()]
album.users = [User(user_id=u_id) for u_id in album.get_users()]
user = User(user_id=session.get("user_id"))
partitions = album.get_partitions()
if user.id is None:
@ -204,8 +204,9 @@ def quit_album(uuid):
"""
user = User(user_id=session.get("user_id"))
album = Album(uuid=uuid)
users = album.get_users()
if user.id not in [u["id"] for u in users]:
if user.id not in users:
flash(_("You are not a member of this album"))
return redirect(request.referrer)
@ -234,7 +235,7 @@ def delete_album(uuid):
users = album.get_users()
if len(users) > 1:
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] != user.id:
error = _("You don't own this album.")
if user.access_level == 1:

View File

@ -51,11 +51,11 @@ class Album():
def get_users(self, force_reload=False):
"""
Renvoie les utilisateurs liés à l'album
Renvoie les data["id"] des utilisateurs liés à l'album
"""
if self.users is None or force_reload:
db = get_db()
self.users = db.execute(
data = db.execute(
"""
SELECT * FROM user
JOIN contient_user ON user_id = user.id
@ -64,6 +64,7 @@ class Album():
""",
(self.uuid,)
).fetchall()
self.users = [i["id"] for i in data]
return self.users
def get_partitions(self):

View File

@ -75,21 +75,23 @@ class Groupe():
album.delete(instance_path)
def get_users(self):
def get_users(self, force_reload=False):
"""
Renvoie les data["id"] des utilisateurs liés au groupe
TODO: uniformiser le tout
"""
db = get_db()
return db.execute(
"""
SELECT * FROM user
JOIN groupe_contient_user ON user_id = user.id
JOIN groupe ON groupe.id = groupe_id
WHERE groupe.id = ?
""",
(self.id,)
).fetchall()
if self.users is None or force_reload:
db = get_db()
data = db.execute(
"""
SELECT * FROM user
JOIN groupe_contient_user ON user_id = user.id
JOIN groupe ON groupe.id = groupe_id
WHERE groupe.id = ?
""",
(self.id,)
).fetchall()
self.users = [i["id"] for i in data]
return self.users
def get_albums(self, force_reload=False):
"""
@ -126,6 +128,21 @@ class Groupe():
).fetchall()
return [i["id"] for i in data]
def set_admin(self, user_id, value):
"""
Rend un utilisateur administrateur du groupe
"""
db = get_db()
data = db.execute(
"""
UPDATE groupe_contient_user
SET is_admin=?
WHERE user_id=? AND groupe_id=?
""",
(value, user_id, self.id)
)
db.commit()
def to_zip(self, instance_path):
data = io.BytesIO()
with zipfile.ZipFile(data, mode="w") as z:

View File

@ -75,6 +75,16 @@ class Partition():
)
db.commit()
def update_file(self, file, instance_path):
partition_path = os.path.join(
instance_path,
"partitions",
f"{self.uuid}.pdf"
)
file.save(partition_path)
if os.path.exists(f"{instance_path}/cache/thumbnails/{self.uuid}.jpg"):
os.remove(f"{instance_path}/cache/thumbnails/{self.uuid}.jpg")
def get_user(self):
db = get_db()
user = db.execute(

View File

@ -35,7 +35,7 @@ def get_groupe(uuid):
except LookupError:
return abort(404)
groupe.users = [User(user_id=i["id"]) for i in groupe.get_users()]
groupe.users = [User(user_id=u_id) for u_id in groupe.get_users()]
groupe.get_albums()
user = User(user_id=session.get("user_id"))
@ -131,7 +131,7 @@ def quit_groupe(uuid):
user = User(user_id=session.get("user_id"))
groupe = Groupe(uuid=uuid)
users = groupe.get_users()
if user.id not in [u["id"] for u in users]:
if user.id not in users:
flash(_("You are not a member of this group."))
return redirect(f"/groupe/{uuid}")
@ -140,6 +140,11 @@ def quit_groupe(uuid):
return redirect(f"/groupe/{uuid}#delete")
user.quit_groupe(groupe.uuid)
if len(groupe.get_admins()) == 0: # On s'assure que le groupe contient toujours des administrateurs
for user_id in groupe.get_users(force_reload=True):
groupe.set_admin(user_id, True)
flash(_("Group quitted."))
return redirect("/albums")
@ -151,8 +156,7 @@ def delete_groupe(uuid):
user = User(user_id=session.get("user_id"))
error = None
users = groupe.get_users()
if len(users) > 1:
if len(groupe.get_users()) > 1:
error = _("You are not alone in this group.")
if user.access_level == 1 or user.id not in groupe.get_admins():
@ -185,7 +189,7 @@ def create_album_req(groupe_uuid):
if not name or name.strip() == "":
error = _("Missing name.")
if user.id not in groupe.get_admins():
if user.id not in groupe.get_admins() and user.access_level != 1:
error = _("You are not admin of this group.")
if error is None:
@ -241,7 +245,7 @@ def get_album(groupe_uuid, album_uuid):
user = User(user_id=session.get("user_id"))
# List of users without duplicate
users_id = list({i["id"] for i in album.get_users()+groupe.get_users()})
users_id = list(set(album.get_users()+groupe.get_users()))
album.users = [User(user_id=id) for id in users_id]
partitions = album.get_partitions()

View File

@ -3,6 +3,7 @@
Partition module
"""
import os
import pypdf
from uuid import uuid4
from flask import (Blueprint, abort, send_file, render_template,
request, redirect, flash, session, current_app)
@ -160,6 +161,17 @@ def edit(uuid):
flash(error)
return redirect(f"/partition/{ uuid }/edit")
if request.files.get('file', None):
new_file = request.files["file"]
try:
pypdf.PdfReader(new_file)
new_file.seek(0)
except (pypdf.errors.PdfReadError, pypdf.errors.PdfStreamError):
flash(_("Invalid PDF file"))
return redirect(request.referrer)
partition.update_file(new_file, current_app.instance_path)
partition.update(
name=request.form["name"],
author=request.form["author"],

View File

@ -718,3 +718,56 @@ midi-player {
border-radius: 5px;
background-color: var(--color-crust);
}
/** Input[file] */
.file-area {
position: relative;
}
.file-area input[type=file] {
position: absolute;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
cursor: pointer;
}
.file-area .inner-file-area {
padding: 30px;
background: var(--color-mantle);
border: 2px dashed var(--color-red);
text-align: center;
transition: background 0.3s ease-in-out;
}
.file-area .inner-file-area .success {
display: none;
}
.file-area:hover > .inner-file-area {
background: var(--color-surface0);
}
.file-area input[type=file]:valid + .inner-file-area {
border-color: var(--color-green);
}
.file-area input[type=file]:not(:required) + .inner-file-area {
border-color: var(--color-blue);
}
.file-area input[type=file]:valid + .inner-file-area .success {
display: inline-block;
}
.file-area input[type=file]:valid + .inner-file-area .default {
display: none;
}
.file-area input[type=file]:not(:required) + .inner-file-area .success {
display: none;
}
.file-area input[type=file]:not(:required) + .inner-file-area .default {
display: inline-block;
}

View File

@ -7,7 +7,11 @@
{% if partition_uuid %}
<input name="partition-uuid" value="{{ partition_uuid }}" type="hidden">
{% else %}
<input name="file" type="file" accept=".pdf" required=""><br/>
{% block input_file %}
{% set required=true %}
{% set filetype=".pdf" %}
{% include 'components/input_file.html' %}
{% endblock %}
{% endif %}
<input type="submit" value="{{ _('Add') }}" />
</form>

View File

@ -0,0 +1,7 @@
<div class="file-area">
<input name="file" type="file" accept="{{ filetype }}" {% if required %}required=""{% endif %}>
<div class="inner-file-area">
<div class="success">{{ _("Your file is selected.") }}</div>
<div class="default">{{ _("Select or drag & drop your file") }} ({{ filetype }}).</div>
</div>
</div>

View File

@ -9,7 +9,11 @@
<h2>{{ _("Add an attachment to %(name)s", name=partition.name) }}</h2>
<form action="/partition/{{ partition.uuid }}/add-attachment" method="post" enctype="multipart/form-data">
<input type="text" name="name" id="name" placeholder="{{ _('Name') }}"><br/>
<input name="file" type="file" accept=".mp3,.mid" required=""><br/>
{% block input_file %}
{% set required=true %}
{% set filetype=".mp3,.mid" %}
{% include 'components/input_file.html' %}
{% endblock %}
<input type="submit" value="{{ _('Add') }}">
</form>
<a href="#!" class="close-dialog">Close</a>
@ -55,7 +59,7 @@
{% endif %}
<br/>
{% if user %}
{% if g.user %}
<div class="centered">
<a href="#create-attachment"><button>{{ _("Add an attachment") }}</button></a>
</div>

View File

@ -52,7 +52,13 @@
<td>{{ _("File") }}</td>
<td><a href="/partition/{{ partition.uuid }}">
<img class="partition-thumbnail" src="/thumbnails/{{ partition.uuid }}.jpg" loading="lazy">
</a></td>
</a><br/>
{% block input_file %}
{% set required=false %}
{% set filetype=".pdf" %}
{% include 'components/input_file.html' %}
{% endblock %}
</td>
</tr>
<tr>
<td>{{ _("Title") }}</td>

View File

@ -13,7 +13,13 @@
<td>{{ _("File") }}</td>
<td><a href="/partition/{{ partition.uuid }}">
<img class="partition-thumbnail" src="/thumbnails/{{ partition.uuid }}.jpg" loading="lazy">
</a></td>
</a><br/>
{% block input_file %}
{% set required=false %}
{% set filetype=".pdf" %}
{% include 'components/input_file.html' %}
{% endblock %}
</td>
</tr>
{% if partition.source != "unknown" and partition.source != "upload" %}
<tr>

View File

@ -75,12 +75,12 @@ msgstr "You don't own this album."
msgid "Album deleted."
msgstr "Album deleted."
#: partitioncloud/modules/albums.py:278 partitioncloud/modules/partition.py:153
#: partitioncloud/modules/partition.py:199
#: partitioncloud/modules/albums.py:278 partitioncloud/modules/partition.py:154
#: partitioncloud/modules/partition.py:211
msgid "Missing title"
msgstr "Missing title"
#: partitioncloud/modules/albums.py:280 partitioncloud/modules/partition.py:63
#: partitioncloud/modules/albums.py:280 partitioncloud/modules/partition.py:64
msgid "Missing file"
msgstr "Missing file"
@ -88,7 +88,7 @@ msgstr "Missing file"
msgid "Search results expired"
msgstr "Search results expired"
#: partitioncloud/modules/albums.py:302
#: partitioncloud/modules/albums.py:302 partitioncloud/modules/partition.py:170
msgid "Invalid PDF file"
msgstr ""
@ -183,43 +183,43 @@ msgstr "Group deleted."
msgid "You are not admin of this group."
msgstr "You are not admin of this group."
#: partitioncloud/modules/partition.py:58
#: partitioncloud/modules/partition.py:59
msgid "You don't own this score."
msgstr "You don't own this score."
#: partitioncloud/modules/partition.py:71
#: partitioncloud/modules/partition.py:72
msgid "Missing filename."
msgstr "Missing filename."
#: partitioncloud/modules/partition.py:76
#: partitioncloud/modules/partition.py:77
msgid "Unsupported file type."
msgstr "Unsupported file type."
#: partitioncloud/modules/partition.py:144
#: partitioncloud/modules/partition.py:145
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
#: partitioncloud/modules/partition.py:156
#: partitioncloud/modules/partition.py:213
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
#: partitioncloud/modules/partition.py:158
#: partitioncloud/modules/partition.py:215
msgid "Missing lyrics (can be null)."
msgstr "Missing lyrics (can be null)."
#: partitioncloud/modules/partition.py:169
#: partitioncloud/modules/partition.py:215
#: partitioncloud/modules/partition.py:181
#: partitioncloud/modules/partition.py:227
#, python-format
msgid "Successfully modified %(name)s"
msgstr "Successfully modified %(name)s"
#: partitioncloud/modules/partition.py:230
#: partitioncloud/modules/partition.py:242
msgid "You are not allowed to delete this score."
msgstr "You are not allowed to delete this score."
#: partitioncloud/modules/partition.py:238
#: partitioncloud/modules/partition.py:250
msgid "Score deleted."
msgstr "Score deleted."
@ -411,8 +411,8 @@ msgstr "Do you really want to delete this album?"
#: partitioncloud/templates/groupe/index.html:20
#: partitioncloud/templates/groupe/index.html:57
#: partitioncloud/templates/partition/delete.html:10
#: partitioncloud/templates/partition/details.html:86
#: partitioncloud/templates/partition/edit.html:57
#: partitioncloud/templates/partition/details.html:92
#: partitioncloud/templates/partition/edit.html:63
#: partitioncloud/templates/settings/index.html:19
msgid "Delete"
msgstr "Delete"
@ -526,12 +526,20 @@ msgstr "author"
msgid "lyrics"
msgstr "lyrics"
#: partitioncloud/templates/components/add_partition.html:12
#: partitioncloud/templates/components/add_partition.html:16
#: partitioncloud/templates/groupe/index.html:11
#: partitioncloud/templates/partition/attachments.html:13
#: partitioncloud/templates/partition/attachments.html:17
msgid "Add"
msgstr "Add"
#: partitioncloud/templates/components/input_file.html:4
msgid "Your file is selected."
msgstr "Your file is selected."
#: partitioncloud/templates/components/input_file.html:5
msgid "Select or drag & drop your file"
msgstr "Select or drag & drop your file"
#: partitioncloud/templates/groupe/index.html:8
#, python-format
msgid "Add an album to group %(name)s"
@ -568,7 +576,7 @@ msgstr "Attachments of %(name)s"
msgid "Add an attachment to %(name)s"
msgstr "Add an attachment to %(name)s"
#: partitioncloud/templates/partition/attachments.html:22
#: partitioncloud/templates/partition/attachments.html:26
msgid ""
"No pdf viewer available in this browser.\n"
" You can use Firefox on Android."
@ -576,11 +584,11 @@ msgstr ""
"No pdf viewer available in this browser.\n"
" You can use Firefox on Android."
#: partitioncloud/templates/partition/attachments.html:46
#: partitioncloud/templates/partition/attachments.html:50
msgid "JavaScript is mandatory to read MIDI files"
msgstr "JavaScript is mandatory to read MIDI files"
#: partitioncloud/templates/partition/attachments.html:60
#: partitioncloud/templates/partition/attachments.html:64
msgid "Add an attachment"
msgstr "Add an attachment"
@ -610,45 +618,45 @@ msgstr "Type"
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
#: partitioncloud/templates/partition/details.html:64
#: partitioncloud/templates/partition/details.html:65
#: partitioncloud/templates/partition/edit.html:35
#: partitioncloud/templates/partition/edit.html:36
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
#: partitioncloud/templates/partition/details.html:68
#: partitioncloud/templates/partition/details.html:69
#: partitioncloud/templates/partition/edit.html:39
#: partitioncloud/templates/partition/edit.html:40
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
#: partitioncloud/templates/partition/details.html:72
#: partitioncloud/templates/partition/details.html:73
#: partitioncloud/templates/partition/edit.html:43
#: partitioncloud/templates/partition/edit.html:44
msgid "Lyrics"
msgstr "Lyrics"
#: partitioncloud/templates/partition/details.html:70
#: partitioncloud/templates/partition/edit.html:41
#: partitioncloud/templates/partition/details.html:76
#: partitioncloud/templates/partition/edit.html:47
msgid "Attachments"
msgstr "Attachments"
#: partitioncloud/templates/partition/details.html:75
#: partitioncloud/templates/partition/edit.html:46
#: partitioncloud/templates/partition/details.html:81
#: partitioncloud/templates/partition/edit.html:52
#, python-format
msgid "Yes, %(number)s"
msgstr "Yes, %(number)s"
#: partitioncloud/templates/partition/details.html:77
#: partitioncloud/templates/partition/edit.html:48
#: partitioncloud/templates/partition/details.html:83
#: partitioncloud/templates/partition/edit.html:54
msgid "Add one"
msgstr "Add one"
#: partitioncloud/templates/partition/details.html:83
#: partitioncloud/templates/partition/edit.html:54
#: partitioncloud/templates/partition/details.html:89
#: partitioncloud/templates/partition/edit.html:60
msgid "Update"
msgstr "Update"
@ -657,7 +665,7 @@ msgstr "Update"
msgid "Modify \"%(name)s\""
msgstr "Modify \"%(name)s\""
#: partitioncloud/templates/partition/edit.html:21
#: partitioncloud/templates/partition/edit.html:27
msgid "Source"
msgstr "Source"

View File

@ -75,12 +75,12 @@ msgstr "Vous ne possédez pas cet album."
msgid "Album deleted."
msgstr "Album supprimé."
#: partitioncloud/modules/albums.py:278 partitioncloud/modules/partition.py:153
#: partitioncloud/modules/partition.py:199
#: partitioncloud/modules/albums.py:278 partitioncloud/modules/partition.py:154
#: partitioncloud/modules/partition.py:211
msgid "Missing title"
msgstr "Un titre est requis."
#: partitioncloud/modules/albums.py:280 partitioncloud/modules/partition.py:63
#: partitioncloud/modules/albums.py:280 partitioncloud/modules/partition.py:64
msgid "Missing file"
msgstr "Aucun fichier n'a été fourni."
@ -88,7 +88,7 @@ msgstr "Aucun fichier n'a été fourni."
msgid "Search results expired"
msgstr "Les résultats de la recherche ont expiré."
#: partitioncloud/modules/albums.py:302
#: partitioncloud/modules/albums.py:302 partitioncloud/modules/partition.py:170
msgid "Invalid PDF file"
msgstr "Fichier PDF invalide"
@ -185,43 +185,43 @@ msgstr "Groupe supprimé."
msgid "You are not admin of this group."
msgstr "Vous n'êtes pas administrateur de ce groupe"
#: partitioncloud/modules/partition.py:58
#: partitioncloud/modules/partition.py:59
msgid "You don't own this score."
msgstr "Cette partition ne vous appartient pas"
#: partitioncloud/modules/partition.py:71
#: partitioncloud/modules/partition.py:72
msgid "Missing filename."
msgstr "Pas de nom de fichier"
#: partitioncloud/modules/partition.py:76
#: partitioncloud/modules/partition.py:77
msgid "Unsupported file type."
msgstr "Extension de fichier non supportée"
#: partitioncloud/modules/partition.py:144
#: partitioncloud/modules/partition.py:145
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
#: partitioncloud/modules/partition.py:156
#: partitioncloud/modules/partition.py:213
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
#: partitioncloud/modules/partition.py:158
#: partitioncloud/modules/partition.py:215
msgid "Missing lyrics (can be null)."
msgstr "Des paroles sont requises (à minima nulles)"
#: partitioncloud/modules/partition.py:169
#: partitioncloud/modules/partition.py:215
#: partitioncloud/modules/partition.py:181
#: partitioncloud/modules/partition.py:227
#, python-format
msgid "Successfully modified %(name)s"
msgstr "Partition %(name)s modifiée avec succès."
#: partitioncloud/modules/partition.py:230
#: partitioncloud/modules/partition.py:242
msgid "You are not allowed to delete this score."
msgstr "Vous n'êtes pas autorisé à supprimer cette partition."
#: partitioncloud/modules/partition.py:238
#: partitioncloud/modules/partition.py:250
msgid "Score deleted."
msgstr "Partition supprimée."
@ -417,8 +417,8 @@ msgstr "Êtes vous sûr de vouloir supprimer cet album ?"
#: partitioncloud/templates/groupe/index.html:20
#: partitioncloud/templates/groupe/index.html:57
#: partitioncloud/templates/partition/delete.html:10
#: partitioncloud/templates/partition/details.html:86
#: partitioncloud/templates/partition/edit.html:57
#: partitioncloud/templates/partition/details.html:92
#: partitioncloud/templates/partition/edit.html:63
#: partitioncloud/templates/settings/index.html:19
msgid "Delete"
msgstr "Supprimer"
@ -532,12 +532,20 @@ msgstr "auteur"
msgid "lyrics"
msgstr "paroles"
#: partitioncloud/templates/components/add_partition.html:12
#: partitioncloud/templates/components/add_partition.html:16
#: partitioncloud/templates/groupe/index.html:11
#: partitioncloud/templates/partition/attachments.html:13
#: partitioncloud/templates/partition/attachments.html:17
msgid "Add"
msgstr "Ajouter"
#: partitioncloud/templates/components/input_file.html:4
msgid "Your file is selected."
msgstr "Fichier sélectionné."
#: partitioncloud/templates/components/input_file.html:5
msgid "Select or drag & drop your file"
msgstr "Sélectionner ou déposer un fichier"
#: partitioncloud/templates/groupe/index.html:8
#, python-format
msgid "Add an album to group %(name)s"
@ -577,7 +585,7 @@ msgstr "Attachments de %(name)s"
msgid "Add an attachment to %(name)s"
msgstr "Ajouter un attachment à %(name)s"
#: partitioncloud/templates/partition/attachments.html:22
#: partitioncloud/templates/partition/attachments.html:26
msgid ""
"No pdf viewer available in this browser.\n"
" You can use Firefox on Android."
@ -585,11 +593,11 @@ msgstr ""
"Impossible d'afficher le pdf dans ce navigateur.\n"
" Il est conseillé d'utiliser Firefox sur Android."
#: partitioncloud/templates/partition/attachments.html:46
#: partitioncloud/templates/partition/attachments.html:50
msgid "JavaScript is mandatory to read MIDI files"
msgstr "JavaScript est nécessaire pour lire les fichiers MIDI"
#: partitioncloud/templates/partition/attachments.html:60
#: partitioncloud/templates/partition/attachments.html:64
msgid "Add an attachment"
msgstr "Ajouter un attachment"
@ -619,45 +627,45 @@ msgstr "Type d'ajout"
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
#: partitioncloud/templates/partition/details.html:64
#: partitioncloud/templates/partition/details.html:65
#: partitioncloud/templates/partition/edit.html:35
#: partitioncloud/templates/partition/edit.html:36
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
#: partitioncloud/templates/partition/details.html:68
#: partitioncloud/templates/partition/details.html:69
#: partitioncloud/templates/partition/edit.html:39
#: partitioncloud/templates/partition/edit.html:40
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
#: partitioncloud/templates/partition/details.html:72
#: partitioncloud/templates/partition/details.html:73
#: partitioncloud/templates/partition/edit.html:43
#: partitioncloud/templates/partition/edit.html:44
msgid "Lyrics"
msgstr "Paroles"
#: partitioncloud/templates/partition/details.html:70
#: partitioncloud/templates/partition/edit.html:41
#: partitioncloud/templates/partition/details.html:76
#: partitioncloud/templates/partition/edit.html:47
msgid "Attachments"
msgstr "Pièces jointes"
#: partitioncloud/templates/partition/details.html:75
#: partitioncloud/templates/partition/edit.html:46
#: partitioncloud/templates/partition/details.html:81
#: partitioncloud/templates/partition/edit.html:52
#, python-format
msgid "Yes, %(number)s"
msgstr "Oui, %(number)s"
#: partitioncloud/templates/partition/details.html:77
#: partitioncloud/templates/partition/edit.html:48
#: partitioncloud/templates/partition/details.html:83
#: partitioncloud/templates/partition/edit.html:54
msgid "Add one"
msgstr "En rajouter"
#: partitioncloud/templates/partition/details.html:83
#: partitioncloud/templates/partition/edit.html:54
#: partitioncloud/templates/partition/details.html:89
#: partitioncloud/templates/partition/edit.html:60
msgid "Update"
msgstr "Mettre à jour"
@ -666,7 +674,7 @@ msgstr "Mettre à jour"
msgid "Modify \"%(name)s\""
msgstr "Modifier \"%(name)s\""
#: partitioncloud/templates/partition/edit.html:21
#: partitioncloud/templates/partition/edit.html:27
msgid "Source"
msgstr "Source"

View File

@ -36,8 +36,8 @@ hooks = [
("v1.5.0", [("Move to instance directory", v1_hooks.move_instance)]),
("v1.5.1", [("Move thumbnails", v1_hooks.move_thumbnails)]),
("v1.7.0", [("Install babel", v1_hooks.install_babel)]),
("v1.8.2", [("Install pypdf", v1_hooks.install_pypdf)])
("v1.10.3", [("Install unidecode", v1_hooks.install_unidecode)])
("v1.8.2", [("Install pypdf", v1_hooks.install_pypdf)]),
("v1.10.3", [("Install unidecode", v1_hooks.install_unidecode)]),
]