forked from ScoDoc/ScoDoc
temp
This commit is contained in:
parent
f40c0d8a6e
commit
e1f36d9484
143
app/scodoc/sco_config_actions.py
Normal file
143
app/scodoc/sco_config_actions.py
Normal file
|
@ -0,0 +1,143 @@
|
|||
# -*- mode: python -*-
|
||||
# -*- 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
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
Module main: page d'accueil, avec liste des départements
|
||||
|
||||
Emmanuel Viennet, 2021
|
||||
"""
|
||||
from app.models import ScoDocSiteConfig
|
||||
|
||||
|
||||
class Action:
|
||||
"""Base class for all classes describing an action from from config form."""
|
||||
|
||||
def __init__(self, message, parameters):
|
||||
self.message = message
|
||||
self.parameters = parameters
|
||||
|
||||
@staticmethod
|
||||
def get_action(parameters):
|
||||
"""Check (from parameters) if some action has to be done and
|
||||
then return list of action (or else return empty list)."""
|
||||
raise NotImplementedError
|
||||
|
||||
def display(self):
|
||||
"""return a str describing the action to be done"""
|
||||
return self.message.format_map(self.parameters)
|
||||
|
||||
def execute(self):
|
||||
"""Executes the action"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class LogoUpdate(Action):
|
||||
"""Action: change a logo
|
||||
dept_id: dept_id or '_',
|
||||
logo_id: logo_id,
|
||||
upload: image file replacement
|
||||
"""
|
||||
|
||||
def __init__(self, parameters):
|
||||
super().__init__(
|
||||
"Modification du logo {logo_id} pour le département {dept_id} ({upload}).",
|
||||
parameters,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_action(parameters):
|
||||
if parameters["upload"] is not None:
|
||||
return [LogoUpdate(parameters)]
|
||||
return []
|
||||
|
||||
def execute(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class LogoDelete(Action):
|
||||
"""Action: Delete an existing logo
|
||||
dept_id: dept_id or '_',
|
||||
logo_id: logo_id
|
||||
"""
|
||||
|
||||
def __init__(self, parameters):
|
||||
super().__init__(
|
||||
"Suppression du logo {logo_id} pour le département {dept_id}.",
|
||||
parameters,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_action(parameters):
|
||||
if parameters["do_delete"]:
|
||||
return [LogoDelete(parameters)]
|
||||
return []
|
||||
|
||||
def execute(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class LogoInsert(Action):
|
||||
"""Action: add a new logo
|
||||
dept_id: dept_id or '_',
|
||||
logo_id: logo_id,
|
||||
upload: image file replacement
|
||||
"""
|
||||
|
||||
def __init__(self, parameters):
|
||||
super().__init__(
|
||||
"Ajout du logo {name} pour le département {dept_id} ({upload}).",
|
||||
parameters,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_action(parameters):
|
||||
if parameters["upload"] and parameters["name"]:
|
||||
return [LogoInsert(parameters)]
|
||||
return []
|
||||
|
||||
def execute(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class BonusSportUpdate(Action):
|
||||
"""Action: Change bonus_sport_function_name.
|
||||
bonus_sport_function_name: the new value"""
|
||||
|
||||
def __init__(self, parameters):
|
||||
super().__init__(
|
||||
"Changement du calcul de bonus sport ({bonus_sport_func_name}).",
|
||||
parameters,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_action(parameters):
|
||||
if parameters["bonus_sport_func_name"] is not None:
|
||||
return [BonusSportUpdate(parameters)]
|
||||
return []
|
||||
|
||||
def execute(self):
|
||||
ScoDocSiteConfig.set_bonus_sport_func(self.parameters["bonus_sport_func_name"])
|
|
@ -43,13 +43,57 @@ from app.models import Departement
|
|||
from app.models import ScoDocSiteConfig
|
||||
from app.scodoc import sco_logos, html_sco_header
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc.sco_config_actions import (
|
||||
LogoDelete,
|
||||
LogoUpdate,
|
||||
LogoInsert,
|
||||
BonusSportUpdate,
|
||||
)
|
||||
|
||||
JAVASCRIPTS = html_sco_header.BOOTSTRAP_MULTISELECT_JS + []
|
||||
|
||||
CSSSTYLES = html_sco_header.BOOTSTRAP_MULTISELECT_CSS
|
||||
|
||||
|
||||
# ---- CONFIGURATION
|
||||
# class ItemForm(FlaskForm):
|
||||
# """Unused Generic class to document common behavior for classes
|
||||
# * ScoConfigurationForm
|
||||
# * DeptForm
|
||||
# * LogoForm
|
||||
# Some or all of these implements:
|
||||
# * Composite design pattern (ScoConfigurationForm and DeptForm)
|
||||
# - a FieldList(FormField(ItemForm))
|
||||
# - FieldListItem are created by browsing the model
|
||||
# - index dictionnary to provide direct access to a SubItemForm
|
||||
# - the direct access method (get_form)
|
||||
# * have some information added to be displayed
|
||||
# - information are collected from a model object
|
||||
# Common methods:
|
||||
# * build(model) (not for LogoForm who has no child)
|
||||
# for each child:
|
||||
# * create en entry in the FieldList for each subitem found
|
||||
# * update self.index
|
||||
# * fill_in additional information into the form
|
||||
# * recursively calls build for each chid
|
||||
# some spécific information may be added after standard processing
|
||||
# (typically header/footer description)
|
||||
# * preview(data)
|
||||
# check the data from a post and build a list of operations that has to be done.
|
||||
# for a two phase process:
|
||||
# * phase 1 (list all opérations)
|
||||
# * phase 2 (may be confirmation and execure)
|
||||
# - if no op found: return to the form with a message 'Aucune modification trouvée'
|
||||
# - only one operation found: execute and go to main page
|
||||
# - more than 1 operation found. asked form confirmation (and execution if confirmed)
|
||||
#
|
||||
# Someday we'll have time to refactor as abstract classes but Abstract FieldList makes this a bit complicated
|
||||
# """
|
||||
|
||||
# Terminology:
|
||||
# dept_id : identifies a dept in modele (= list_logos()). None designates globals logos
|
||||
# dept_key : identifies a dept in this form only (..index[dept_key], and fields 'dept_key').
|
||||
# 'GLOBAL' designates globals logos (we need a string value to set up HiddenField
|
||||
GLOBAL = "_"
|
||||
|
||||
|
||||
class AddLogoForm(FlaskForm):
|
||||
|
@ -79,38 +123,9 @@ class AddLogoForm(FlaskForm):
|
|||
],
|
||||
)
|
||||
|
||||
|
||||
# class ItemForm(FlaskForm):
|
||||
# """Unused Generic class to document common behavior for classes
|
||||
# * ScoConfigurationForm
|
||||
# * DeptForm
|
||||
# * LogoForm
|
||||
# Some or all of these implements:
|
||||
# * Composite design pattern (ScoConfigurationForm and DeptForm)
|
||||
# - a FieldList(FormField(ItemForm))
|
||||
# - FieldListItem are created by browsing the model
|
||||
# - index dictionnary to provide direct access to a SubItemForm
|
||||
# - the direct access method (get_form)
|
||||
# * have some information added to be displayed
|
||||
# - information are collected from a model object
|
||||
# Common methods:
|
||||
# build(model) (not for LogoForm who has no child)
|
||||
# for each child:
|
||||
# * create en entry in the FieldList for each subitem found
|
||||
# * update self.index
|
||||
# * fill_in additional information into the form
|
||||
# * recursively calls build for each chid
|
||||
# some spécific information may be added after standard processing
|
||||
# (typically header/footer description)
|
||||
#
|
||||
# Someday we'll have time to refactor as abstract classes but Abstract FieldList makes this a bit complicated
|
||||
# """
|
||||
|
||||
# Terminology:
|
||||
# dept_id : identifies a dept in modele (= list_logos()). None designates globals logos
|
||||
# dept_key : identifies a dept in this form only (..index[dept_key], and fields 'dept_key').
|
||||
# 'GLOBAL' designates globals logos (we need a string value to set up HiddenField
|
||||
GLOBAL = "_"
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs["meta"] = {"csrf": False}
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class LogoForm(FlaskForm):
|
||||
|
@ -131,6 +146,7 @@ class LogoForm(FlaskForm):
|
|||
do_delete = BooleanField("Supprimer l'image", default=None)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs["meta"] = {"csrf": False}
|
||||
super().__init__(*args, **kwargs)
|
||||
self.logo = None
|
||||
self.description = None
|
||||
|
@ -140,6 +156,13 @@ class LogoForm(FlaskForm):
|
|||
self.logo = modele
|
||||
self.do_delete.data = False
|
||||
|
||||
@staticmethod
|
||||
def get_actions(logo_data):
|
||||
actions = []
|
||||
actions += LogoDelete.get_action(logo_data)
|
||||
actions += LogoUpdate.get_action(logo_data)
|
||||
return actions
|
||||
|
||||
|
||||
class DeptForm(FlaskForm):
|
||||
dept_key = HiddenField()
|
||||
|
@ -147,6 +170,7 @@ class DeptForm(FlaskForm):
|
|||
logos = FieldList(FormField(LogoForm))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs["meta"] = {"csrf": False}
|
||||
super().__init__(*args, **kwargs)
|
||||
self.index = None
|
||||
self.dept_name = None
|
||||
|
@ -197,6 +221,14 @@ class DeptForm(FlaskForm):
|
|||
self.index[logoname] = entry.form
|
||||
entry.form.build(modele[logoname])
|
||||
|
||||
def get_actions(self, dept_data):
|
||||
actions = []
|
||||
actions += LogoInsert.get_action(dept_data["add_logo"])
|
||||
for logo_data in dept_data["logos"]:
|
||||
logo_form = self.index[logo_data["logo_id"]]
|
||||
actions += logo_form.get_actions(logo_data)
|
||||
return actions
|
||||
|
||||
def get_form(self, logoname=None):
|
||||
"""Retourne le formulaire associé à un logo. None si pas trouvé"""
|
||||
if logoname is None: # recherche de département
|
||||
|
@ -206,7 +238,6 @@ class DeptForm(FlaskForm):
|
|||
|
||||
class ScoDocConfigurationForm(FlaskForm):
|
||||
"Panneau de configuration général"
|
||||
|
||||
bonus_sport_func_name = SelectField(
|
||||
label="Fonction de calcul des bonus sport&culture",
|
||||
choices=[
|
||||
|
@ -253,10 +284,10 @@ class ScoDocConfigurationForm(FlaskForm):
|
|||
|
||||
def _build_dept(self, dept_id, dept_name, modele):
|
||||
dept_key = dept_id or GLOBAL
|
||||
data = {"dept_id": dept_key}
|
||||
data = {"dept_key": dept_key}
|
||||
entry = self.depts.append_entry(data)
|
||||
entry.form.build(dept_name, modele.get(dept_id, {}))
|
||||
self.index[dept_key] = entry.form
|
||||
self.index[str(dept_key)] = entry.form
|
||||
|
||||
def build(self, modele):
|
||||
"Build the Form hierachy (DeptForm, LogoForm) and add extra data (from modele)"
|
||||
|
@ -278,16 +309,27 @@ class ScoDocConfigurationForm(FlaskForm):
|
|||
return None
|
||||
return dept_form.get_form(logoname)
|
||||
|
||||
def get_actions(self, data):
|
||||
actions = []
|
||||
if BonusSportUpdate.get_action(data):
|
||||
actions.append(BonusSportUpdate(data))
|
||||
for dept_data in data["depts"]:
|
||||
dept_form = self.index[str(dept_data["dept_key"])]
|
||||
actions += dept_form.get_actions(dept_data)
|
||||
return actions
|
||||
|
||||
|
||||
def configuration():
|
||||
"Panneau de configuration général"
|
||||
"""Panneau de configuration général"""
|
||||
form = ScoDocConfigurationForm(
|
||||
bonus_sport_func_name=ScoDocSiteConfig.get_bonus_sport_func_name(),
|
||||
)
|
||||
modele = sco_logos.list_logos()
|
||||
form.build(modele)
|
||||
if form.validate_on_submit():
|
||||
ScoDocSiteConfig.set_bonus_sport_func(form.bonus_sport_func_name.data)
|
||||
actions = form.get_actions(form.data)
|
||||
for action in actions:
|
||||
action.execute()
|
||||
# if form.header.data:
|
||||
# sco_logos.write_logo(stream=form.header.data, name="header")
|
||||
# if form.footer.data:
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
{% macro render_add_logo(add_logo_form) %}
|
||||
<div class=""logo-add">
|
||||
<h3>Ajouter un logo</h3>
|
||||
{{ add_logo_form.hidden_tag() }}
|
||||
{{ render_field(add_logo_form.name) }}
|
||||
{{ render_field(add_logo_form.upload) }}
|
||||
<div>
|
||||
|
@ -26,6 +27,7 @@
|
|||
|
||||
{% macro render_logo(logo_form) %}
|
||||
<div class="logo-edit">
|
||||
{{ logo_form.hidden_tag() }}
|
||||
{% if logo_form.titre %}
|
||||
<tr class="logo-edit">
|
||||
<td colspan="2" class=""titre">
|
||||
|
@ -67,6 +69,8 @@
|
|||
<table>
|
||||
{% for logoform in dept_form.index.values() %}
|
||||
{{ render_logo(logoform) }}
|
||||
{% else %}
|
||||
<p class="logo-edit">Aucun logo défini en propre à ce département</p>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endmacro %}
|
||||
|
@ -83,6 +87,7 @@
|
|||
|
||||
<h1>Bibliothèque de logos</h1>
|
||||
{% for dept, dept_form in form.index.items() %}
|
||||
{{ dept_form.hidden_tag() }}
|
||||
{% if dept_form.is_local() %}
|
||||
<div class=""departement">
|
||||
<h2>Logos du département {{ dept_form.dept_name }}</h2>
|
||||
|
@ -103,7 +108,6 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="sco-submit">{{ form.submit() }}</div>
|
||||
</form>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user