This commit is contained in:
Jean-Marie Place 2021-10-10 08:58:43 +02:00 committed by Jean-Marie Place
parent 2f72401ba1
commit ce4bfd9f21
4 changed files with 290 additions and 145 deletions

View File

@ -0,0 +1,235 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# ScoDoc
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
import imghdr
import os
from pathlib import Path
from flask import flash, redirect, url_for, render_template
from werkzeug.utils import secure_filename
import app.scodoc.sco_utils as scu
import app
from app import Departement
from app.models import ScoDocSiteConfig
from app.scodoc import sco_logos
import flask
from flask import jsonify, url_for, flash, redirect, render_template, make_response
from wtforms import SelectField, FileField, FormField
from flask import current_app, g, request
from flask_login import current_user
from flask_wtf import FlaskForm
from wtforms import SubmitField
from flask_wtf.file import FileField, FileAllowed
import PIL
from PIL import Image as PILImage
# ---- CONFIGURATION
GLOBAL = "_global" # catogry for server level logos
class Logo:
def __init__(self, logoname, scodoc_dept=None):
"""Responsable de toutes les opérations (ajout, remplacement, suppression) et de a récupération des
informations sur un logp"""
self.logoname = logoname
self.scodoc_dept = scodoc_dept
self.width = None
self.height = None
if scodoc_dept is None:
self.filename = secure_filename("logo_" + logoname + ".jpg")
else:
breakpoint()
self.filename = secure_filename("logo_" + scodoc_dept + "_" + logoname + ".jpg")
self.pathname = os.path.join(scu.SCODOC_LOGOS_DIR, self.filename)
self.path = Path(self.filename)
self.format = None
self.get_info()
def get_info(self):
"""Get image infos (type, size, ..)"""
with open(self.pathname, "rb") as f:
header = f.read(512)
f.seek(0)
fmt = imghdr.what(None, header)
if not fmt:
return None
self.format = fmt if fmt != "jpeg" else "jpg"
img = PILImage.open(f)
self.width, self.height = img.size
def get_url(self):
return url_for(self.logoname, self.scodoc_dept)
def get_all_logos():
inventory = {}
depts = [
x.acronym
for x in (
Departement.query.filter_by(visible=True)
.order_by(Departement.acronym)
.all()
)
]
inventory[GLOBAL] = {}
for dept in depts:
inventory[dept] = {}
for path in Path(scu.SCODOC_LOGOS_DIR).iterdir():
if path.suffix == ".jpg" and path.name.startswith("logo_"):
full_name = path.name.replace('.jpg', '').replace('logo_', '') # forme : logo_[dept_]logoname.jpeg
split = full_name.split('_')
if len(split) > 1 and split[0] in depts:
logoname = "_".join(split[1:])
logo = Logo(logoname, split[0])
inventory[dept][logoname] = logo
else:
logoname = full_name
logo = Logo(logoname) # global logo
inventory[GLOBAL][logoname] = logo
return inventory
class LogoForm(FlaskForm):
logo = FileField(
label="Modifier l'image:",
description="logo",
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>",
)
],
)
def __init__(self, formdata=None, data=None, **kwargs):
super().__init__(formdata=formdata, data=data, **kwargs)
# 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")
class ScoDocConfigurationForm(FlaskForm):
"""Panneau de configuration général"""
bonus_sport_func_name = SelectField(
label="Fonction de calcul des bonus sport&culture",
choices=[
(x, x if x else "Aucune")
for x in ScoDocSiteConfig.get_bonus_sport_func_names()
],
)
logo_header = FormField(LogoForm)
# 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")
def __init__(self, formdata, data, bonus_sport_func_name=None):
log_header = Logo("header")
log_footer = Logo("footer")
data = {
"bonus_sport_func_name": bonus_sport_func_name,
}
self.footer = url_for("scodoc.logo_footer")
self.header = url_for("scodoc.logo_header")
super().__init__(formdata=formdata, data=data)
def configuration():
"Panneau de configuration général"
breakpoint()
inventory = get_all_logos()
header = Logo("header")
form = LogoForm()
# form = ScoDocConfigurationForm(
# bonus_sport_func_name=ScoDocSiteConfig.get_bonus_sport_func_name(),
# )
if form.validate_on_submit():
# ScoDocSiteConfig.set_bonus_sport_func(form.bonus_sport_func_name.data)
# if form.logo_header.data:
# sco_logos.store_image(
# form.logo_header.data, os.path.join(scu.SCODOC_LOGOS_DIR, "logo_header")
# )
# if form.logo_footer.data:
# sco_logos.store_image(
# form.logo_footer.data, os.path.join(scu.SCODOC_LOGOS_DIR, "logo_footer")
# )
# app.clear_scodoc_cache()
# flash(f"Configuration enregistrée")
return redirect(url_for("scodoc.index"))
return render_template(
"configuration.html",
title="Configuration ScoDoc",
form=form,
scodoc_dept=None,
)

View File

@ -1,53 +1,53 @@
{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% macro render_field(field) %}
<div>
<span class="wtf-field">{{ field.label }} :</span>
<span class="wtf-field">{{ field()|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</span>
</div>
{% endmacro %}
{% block app_content %}
{% if scodoc_dept %}
<h1>Logos du département {{ scodoc_dept }}</h1>
{% else %}
<h1>Configuration générale {{ scodoc_dept }}</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)}}
{% 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.logo_header', scodoc_dept=scodoc_dept) }}"
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.logo_footer', scodoc_dept=g.scodoc_dept) }}"
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>
{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% macro render_field(field) %}
<div>
<span class="wtf-field">{{ field.label }} :</span>
<span class="wtf-field">{{ field()|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</span>
</div>
{% endmacro %}
{% block app_content %}
{% if scodoc_dept %}
<h1>Logos du département {{ scodoc_dept }}</h1>
{% else %}
<h1>Configuration générale {{ scodoc_dept }}</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)}}
{% 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.logo_header', scodoc_dept=scodoc_dept) }}"#}
{# 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.logo_footer', scodoc_dept=g.scodoc_dept) }}"#}
{# 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 %}

View File

@ -52,7 +52,7 @@ from app.models import Departement, Identite
from app.models import FormSemestre, NotesFormsemestreInscription
from app.models import ScoDocSiteConfig
import sco_version
from app.scodoc import sco_logos
from app.scodoc import sco_logos, sco_configuration_form
from app.scodoc import sco_find_etud
from app.scodoc import sco_utils as scu
from app.decorators import (
@ -62,6 +62,7 @@ from app.decorators import (
permission_required_compat_scodoc7,
)
from app.scodoc.sco_exceptions import AccessDenied
from app.scodoc.sco_configuration_form import configuration
from app.scodoc.sco_permissions import Permission
from app.views import scodoc_bp as bp
@ -173,45 +174,6 @@ def about(scodoc_dept=None):
)
# ---- CONFIGURATION
class ScoDocConfigurationForm(FlaskForm):
"Panneau de configuration général"
bonus_sport_func_name = SelectField(
label="Fonction de calcul des bonus sport&culture",
choices=[
(x, x if x else "Aucune")
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>",
)
],
)
submit = SubmitField("Enregistrer")
# Notes pour variables config: (valeurs par défaut des paramètres de département)
# Chaines simples
# SCOLAR_FONT = "Helvetica"
@ -233,30 +195,7 @@ class ScoDocConfigurationForm(FlaskForm):
@bp.route("/ScoDoc/configuration", methods=["GET", "POST"])
@admin_required
def configuration():
"Panneau de configuration général"
form = ScoDocConfigurationForm(
bonus_sport_func_name=ScoDocSiteConfig.get_bonus_sport_func_name(),
)
if form.validate_on_submit():
ScoDocSiteConfig.set_bonus_sport_func(form.bonus_sport_func_name.data)
if form.logo_header.data:
sco_logos.store_image(
form.logo_header.data, os.path.join(scu.SCODOC_LOGOS_DIR, "logo_header")
)
if form.logo_footer.data:
sco_logos.store_image(
form.logo_footer.data, os.path.join(scu.SCODOC_LOGOS_DIR, "logo_footer")
)
app.clear_scodoc_cache()
flash(f"Configuration enregistrée")
return redirect(url_for("scodoc.index"))
return render_template(
"configuration.html",
title="Configuration ScoDoc",
form=form,
scodoc_dept=None,
)
return sco_configuration_form.configuration()
def _return_logo(logo_type="header", scodoc_dept=""):

View File

@ -38,7 +38,6 @@ from flask import jsonify, url_for, flash, render_template, make_response
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
from app.decorators import (
@ -165,34 +164,6 @@ 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):