forked from ScoDoc/ScoDoc
build logo form (header & footer)
This commit is contained in:
parent
d8091b4efb
commit
483c22678a
@ -160,7 +160,7 @@ class Logo:
|
||||
"Not inited: call the select or create function before access"
|
||||
)
|
||||
self.density = "Not inited: call the select or create function before access"
|
||||
self.cm = "Not inited: call the select or create function before access"
|
||||
self.mm = "Not inited: call the select or create function before access"
|
||||
|
||||
def _set_format(self, fmt):
|
||||
self.suffix = fmt
|
||||
@ -199,21 +199,21 @@ class Logo:
|
||||
unit = 1
|
||||
if self.density is None: # no dpi found try jfif infos
|
||||
self.density = img.info.get("jfif_density", None)
|
||||
unit = img.info.get("jfif_unit", 0) # 0 = no unit ; 1 = inch ; 2 = cm
|
||||
unit = img.info.get("jfif_unit", 0) # 0 = no unit ; 1 = inch ; 2 = mm
|
||||
if self.density is not None:
|
||||
x_density, y_density = self.density
|
||||
if unit != 0:
|
||||
unit2cm = [0, 1 / 2.54, 1][unit]
|
||||
x_cm = round(x_size * unit2cm / x_density, 2)
|
||||
y_cm = round(y_size * unit2cm / y_density, 2)
|
||||
self.cm = (x_cm, y_cm)
|
||||
unit2mm = [0, 1 / 0.254, 0.1][unit]
|
||||
x_mm = round(x_size * unit2mm / x_density, 2)
|
||||
y_mm = round(y_size * unit2mm / y_density, 2)
|
||||
self.mm = (x_mm, y_mm)
|
||||
else:
|
||||
self.cm = None
|
||||
self.mm = None
|
||||
else:
|
||||
self.cm = None
|
||||
self.mm = None
|
||||
|
||||
self.size = (x_size, y_size)
|
||||
self.aspect_ratio = float(x_size) / y_size
|
||||
self.aspect_ratio = round(float(x_size) / y_size, 2)
|
||||
|
||||
def select(self):
|
||||
"""
|
||||
@ -250,6 +250,12 @@ class Logo:
|
||||
global_if_not_found=False,
|
||||
)
|
||||
|
||||
def get_usage(self):
|
||||
if self.mm is None:
|
||||
return f'<logo name="{self.logoname}" width="?? mm" height="?? mm">'
|
||||
else:
|
||||
return f'<logo name="{self.logoname}" width="{self.mm[0]}mm" height="{self.mm[1]}mm">'
|
||||
|
||||
|
||||
def guess_image_type(stream) -> str:
|
||||
"guess image type from header in stream"
|
||||
|
@ -16,38 +16,66 @@
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_logo(logo_form, titre=None) %}
|
||||
{% if titre %}
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<h3>{{ titre }}</h3>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td style="padding-right: 20px">
|
||||
<p class="help">{{ logo_form.form.description }} Image actuelle:</p>
|
||||
<div class="img-container"><img src="{{ logo_form.logo.get_url_small() }}"
|
||||
alt="pas de logo chargé" /></div>
|
||||
</td>
|
||||
<td>
|
||||
Nom: {{ logo_form.form.logo.logoname }}<br/>
|
||||
{{ logo_form.form.description }}<br/>
|
||||
Format: {{ logo_form.logo.suffix }}<br/>
|
||||
Taille en px: {{ logo_form.logo.size }}<br/>
|
||||
{% if logo_form.logo.mm %}
|
||||
Taile en mm: {{ logo_form.logo.mm }}<br/>
|
||||
{% endif %}
|
||||
Aspect ratio: {{ logo_form.logo.aspect_ratio }}<br/>
|
||||
Usage: {{ logo_form.logo.get_usage() }}
|
||||
<span class="wtf-field">{{ logo_form.action()|safe }}</span>
|
||||
<span class="wtf-field">{{ render_field(logo_form.upload) }}</span>
|
||||
{% if logo_form.can_delete %}
|
||||
{{ render_field(logo_form.do_delete) }}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
{% if scodoc_dept %}
|
||||
<h1>Logos du département {{ scodoc_dept }}</h1>
|
||||
{% else %}
|
||||
<h1>Configuration générale {{ scodoc_dept }}</h1>
|
||||
<h1>Configuration générale</h1>
|
||||
{% endif %}
|
||||
|
||||
<form class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
{% if not scodoc_dept %}
|
||||
<div class="sco_help">Les paramètres donnés ici s'appliquent à tout ScoDoc (tous les départements):</div>
|
||||
|
||||
{{ render_field(form.bonus_sport_func_name)}}
|
||||
{{ render_field(form.bonus_sport_func_name)}}
|
||||
<div class="configuration_logo">
|
||||
<table>
|
||||
{{ form.footer.form.breakpoint(form) }}
|
||||
{{ render_logo(form.header, 'Logo en-tête') }}
|
||||
{{ render_logo(form.footer, 'Logo pied de page') }}
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="configuration_logo">
|
||||
<h3>Logo en-tête</h3>
|
||||
<p class="help">image placée en haut de certains documents documents PDF. Image actuelle:</p>
|
||||
<div class="img-container"><img src="{{ url_for('scodoc.get_logo_small', name="header") }}"
|
||||
alt="pas de logo chargé" /></div>
|
||||
{{ render_field(form.logo_header) }}
|
||||
<h3>Logo pied de page</h3>
|
||||
<p class="help">image placée en pied de page de certains documents documents PDF. Image actuelle:</p>
|
||||
<div class="img-container"><img src="{{ url_for('scodoc.get_logo_small', name="footer") }}"
|
||||
alt="pas de logo chargé" /></div>
|
||||
{{ render_field(form.logo_footer) }}
|
||||
</div>
|
||||
<!-- <div class="sco_help">Les paramètres ci-dessous peuvent être changés dans chaque département
|
||||
(paramétrage).<br />On indique ici les valeurs initiales par défaut:
|
||||
</div> -->
|
||||
|
||||
<div class="sco-submit">{{ form.submit() }}</div>
|
||||
</form>
|
||||
{% endblock %}
|
@ -32,6 +32,8 @@ Emmanuel Viennet, 2021
|
||||
"""
|
||||
import io
|
||||
|
||||
import wtforms.validators
|
||||
|
||||
from app.auth.models import User
|
||||
import os
|
||||
|
||||
@ -44,9 +46,9 @@ from flask_login.utils import login_required, current_user
|
||||
from flask_wtf import FlaskForm
|
||||
from flask_wtf.file import FileField, FileAllowed
|
||||
from werkzeug.exceptions import BadRequest, NotFound
|
||||
from wtforms import SelectField, SubmitField
|
||||
from wtforms import SelectField, SubmitField, FormField, validators, Form
|
||||
from wtforms.fields import IntegerField
|
||||
from wtforms.fields.simple import BooleanField, StringField, TextAreaField
|
||||
from wtforms.fields.simple import BooleanField, StringField, TextAreaField, HiddenField
|
||||
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
|
||||
|
||||
import app
|
||||
@ -64,6 +66,7 @@ from app.decorators import (
|
||||
permission_required_compat_scodoc7,
|
||||
)
|
||||
from app.scodoc.sco_exceptions import AccessDenied
|
||||
from app.scodoc.sco_logos import find_logo
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
from app.views import scodoc_bp as bp
|
||||
|
||||
@ -178,6 +181,34 @@ def about(scodoc_dept=None):
|
||||
# ---- CONFIGURATION
|
||||
|
||||
|
||||
class LogoForm(FlaskForm):
|
||||
action = HiddenField("action")
|
||||
upload = FileField(
|
||||
label="Modifier l'image:",
|
||||
validators=[
|
||||
FileAllowed(
|
||||
scu.LOGOS_IMAGES_ALLOWED_TYPES,
|
||||
f"n'accepte que les fichiers image {','.join([e for e in scu.LOGOS_IMAGES_ALLOWED_TYPES])}",
|
||||
)
|
||||
],
|
||||
)
|
||||
do_delete = SubmitField("Supprimer")
|
||||
|
||||
def set_infos(self, logo, description=None, can_delete=None):
|
||||
self.logo = logo
|
||||
self.description = description
|
||||
self.can_delete = can_delete
|
||||
|
||||
def breakpoint(self, form):
|
||||
breakpoint()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LogoForm, self).__init__(*args, **kwargs)
|
||||
self.logo = None
|
||||
self.description = None
|
||||
self.can_delete = None
|
||||
|
||||
|
||||
class ScoDocConfigurationForm(FlaskForm):
|
||||
"Panneau de configuration général"
|
||||
|
||||
@ -188,31 +219,24 @@ class ScoDocConfigurationForm(FlaskForm):
|
||||
for x in ScoDocSiteConfig.get_bonus_sport_func_names()
|
||||
],
|
||||
)
|
||||
|
||||
logo_header = FileField(
|
||||
label="Modifier l'image:",
|
||||
description="logo placé en haut des documents PDF",
|
||||
validators=[
|
||||
FileAllowed(
|
||||
scu.LOGOS_IMAGES_ALLOWED_TYPES,
|
||||
f"n'accepte que les fichiers image <tt>{','.join([e for e in scu.LOGOS_IMAGES_ALLOWED_TYPES])}</tt>",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
logo_footer = FileField(
|
||||
label="Modifier l'image:",
|
||||
description="logo placé en pied des documents PDF",
|
||||
validators=[
|
||||
FileAllowed(
|
||||
scu.LOGOS_IMAGES_ALLOWED_TYPES,
|
||||
f"n'accepte que les fichiers image <tt>{','.join([e for e in scu.LOGOS_IMAGES_ALLOWED_TYPES])}</tt>",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
header = FormField(LogoForm)
|
||||
footer = FormField(LogoForm)
|
||||
submit = SubmitField("Enregistrer")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ScoDocConfigurationForm, self).__init__(*args, **kwargs)
|
||||
breakpoint()
|
||||
self.header.form.set_infos(
|
||||
logo=find_logo("header", dept_id=None).select(),
|
||||
description="image placée en haut de certains documents documents PDF.",
|
||||
can_delete=False,
|
||||
)
|
||||
self.footer.form.set_infos(
|
||||
logo=find_logo("footer", dept_id=None).select(),
|
||||
description="image placée en pied de page de certains documents documents PDF.",
|
||||
can_delete=False,
|
||||
)
|
||||
|
||||
|
||||
# Notes pour variables config: (valeurs par défaut des paramètres de département)
|
||||
# Chaines simples
|
||||
@ -241,10 +265,10 @@ def configuration():
|
||||
)
|
||||
if form.validate_on_submit():
|
||||
ScoDocSiteConfig.set_bonus_sport_func(form.bonus_sport_func_name.data)
|
||||
if form.logo_header.data:
|
||||
sco_logos.write_logo(stream=form.logo_header.data, name="header")
|
||||
if form.logo_footer.data:
|
||||
sco_logos.write_logo(stream=form.logo_footer.data, name="footer")
|
||||
if form.header.data:
|
||||
sco_logos.write_logo(stream=form.header.data, name="header")
|
||||
if form.footer.data:
|
||||
sco_logos.write_logo(stream=form.footer.data, name="footer")
|
||||
app.clear_scodoc_cache()
|
||||
flash(f"Configuration enregistrée")
|
||||
return redirect(url_for("scodoc.index"))
|
||||
@ -313,20 +337,6 @@ def get_logo(name: str, dept_id: int):
|
||||
)
|
||||
|
||||
|
||||
# @bp.route("/ScoDoc/logo_header")
|
||||
# @bp.route("/ScoDoc/<scodoc_dept>/logo_header")
|
||||
# def logo_header(scodoc_dept=""):
|
||||
# "Image logo header"
|
||||
# return _return_logo(name="header", scodoc_dept=scodoc_dept)
|
||||
|
||||
|
||||
# @bp.route("/ScoDoc/logo_footer")
|
||||
# @bp.route("/ScoDoc/<scodoc_dept>/logo_footer")
|
||||
# def logo_footer(scodoc_dept=""):
|
||||
# "Image logo footer"
|
||||
# return _return_logo(name="footer", scodoc_dept=scodoc_dept)
|
||||
|
||||
|
||||
# essais
|
||||
# @bp.route("/testlog")
|
||||
# def testlog():
|
||||
|
@ -39,7 +39,7 @@ from flask import current_app, g, request
|
||||
from flask_login import current_user
|
||||
from flask_wtf import FlaskForm
|
||||
from flask_wtf.file import FileField, FileAllowed
|
||||
from wtforms import SubmitField, FormField
|
||||
from wtforms import SubmitField
|
||||
|
||||
from app.decorators import (
|
||||
scodoc,
|
||||
@ -49,7 +49,6 @@ from app.decorators import (
|
||||
admin_required,
|
||||
login_required,
|
||||
)
|
||||
from app.scodoc.sco_logos import find_logo
|
||||
|
||||
from app.views import scolar_bp as bp
|
||||
|
||||
@ -166,6 +165,66 @@ def doc_preferences():
|
||||
return response
|
||||
|
||||
|
||||
class DeptLogosConfigurationForm(FlaskForm):
|
||||
"Panneau de configuration logos dept"
|
||||
|
||||
logo_header = FileField(
|
||||
label="Modifier l'image:",
|
||||
description="logo placé en haut des documents PDF",
|
||||
validators=[
|
||||
FileAllowed(
|
||||
scu.LOGOS_IMAGES_ALLOWED_TYPES,
|
||||
f"n'accepte que les fichiers image <tt>{','.join([e for e in scu.LOGOS_IMAGES_ALLOWED_TYPES])}</tt>",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
logo_footer = FileField(
|
||||
label="Modifier l'image:",
|
||||
description="logo placé en pied des documents PDF",
|
||||
validators=[
|
||||
FileAllowed(
|
||||
scu.LOGOS_IMAGES_ALLOWED_TYPES,
|
||||
f"n'accepte que les fichiers image <tt>{','.join([e for e in scu.LOGOS_IMAGES_ALLOWED_TYPES])}</tt>",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
submit = SubmitField("Enregistrer")
|
||||
|
||||
|
||||
@bp.route("/config_logos", methods=["GET", "POST"])
|
||||
@permission_required(Permission.ScoChangePreferences)
|
||||
def config_logos(scodoc_dept):
|
||||
"Panneau de configuration général"
|
||||
form = DeptLogosConfigurationForm()
|
||||
if form.validate_on_submit():
|
||||
if form.logo_header.data:
|
||||
sco_logos.store_image(
|
||||
form.logo_header.data,
|
||||
os.path.join(
|
||||
scu.SCODOC_LOGOS_DIR, "logos_" + scodoc_dept, "logo_header"
|
||||
),
|
||||
)
|
||||
if form.logo_footer.data:
|
||||
sco_logos.store_image(
|
||||
form.logo_footer.data,
|
||||
os.path.join(
|
||||
scu.SCODOC_LOGOS_DIR, "logos_" + scodoc_dept, "logo_footer"
|
||||
),
|
||||
)
|
||||
app.clear_scodoc_cache()
|
||||
flash(f"Logos enregistrés")
|
||||
return flask.redirect(url_for("scolar.index_html", scodoc_dept=scodoc_dept))
|
||||
|
||||
return render_template(
|
||||
"configuration.html",
|
||||
title="Configuration Logos du département",
|
||||
form=form,
|
||||
scodoc_dept=scodoc_dept,
|
||||
)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
#
|
||||
# ETUDIANTS
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@ -124,7 +124,7 @@ def test_get_jpg_data(create_dept, create_logos):
|
||||
assert logo.suffix == "jpg"
|
||||
assert logo.filename == "A.jpg"
|
||||
assert logo.size == (1200, 600)
|
||||
assert logo.cm == approx((4.0, 3.0), 0.01)
|
||||
assert logo.mm == approx((40, 30), 0.1)
|
||||
|
||||
|
||||
def test_get_png_without_data(create_dept, create_logos):
|
||||
@ -136,7 +136,7 @@ def test_get_png_without_data(create_dept, create_logos):
|
||||
assert logo.filename == "D.png"
|
||||
assert logo.size == (121, 121)
|
||||
assert logo.density is None
|
||||
assert logo.cm is None
|
||||
assert logo.mm is None
|
||||
|
||||
|
||||
def test_create_globale_jpg_logo(create_dept, create_logos):
|
||||
|
Loading…
Reference in New Issue
Block a user