diff --git a/.gitignore b/.gitignore index 6d49cf2c8..deaa1705c 100644 --- a/.gitignore +++ b/.gitignore @@ -169,4 +169,5 @@ Thumbs.db .vscode/ *.code-workspace - +# PyCharm projects +.idea/ diff --git a/README.md b/README.md index 8ae84c1fb..10bf02c11 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ de votre installation ScoDoc 7 pour passer à ScoDoc 8 (*ne pas utiliser en prod ## Création d'un département - sudo su + su scodoc # si besoin cd /opt/scodoc source venv/bin/activate flask sco-create-dept DEPT @@ -177,7 +177,7 @@ où `DEPT` est le nom du département (un acronyme en majuscule, comme "RT", "GE ### Suppression d'un département - sudo su + su scodoc # si besoin cd /opt/scodoc source venv/bin/activate flask sco-delete-dept DEPT diff --git a/app/scodoc/TrivialFormulator.py b/app/scodoc/TrivialFormulator.py index d14d5e6a0..69220cf14 100644 --- a/app/scodoc/TrivialFormulator.py +++ b/app/scodoc/TrivialFormulator.py @@ -757,6 +757,6 @@ def tf_error_message(msg): if isinstance(msg, str): msg = [msg] return ( - '
Pour ajouter une session, aller dans Programmes, +
Pour ajouter une session, aller dans Programmes, choisissez une formation, puis suivez le lien "UE, modules, semestres".
Là, en bas de page, suivez le lien diff --git a/app/scodoc/sco_formations.py b/app/scodoc/sco_formations.py index 62c17505e..23880f68a 100644 --- a/app/scodoc/sco_formations.py +++ b/app/scodoc/sco_formations.py @@ -259,6 +259,7 @@ def formation_list_table(context, formation_id=None, args={}, REQUEST=None): f["parcours_name"] = "" f["_titre_target"] = "ue_list?formation_id=%(formation_id)s" % f f["_titre_link_class"] = "stdlink" + f["_titre_id"] = "titre-%s" % f["acronyme"].lower().replace(" ", "-") # Ajoute les semestres associés à chaque formation: f["sems"] = sco_formsemestre.do_formsemestre_list( context, args={"formation_id": f["formation_id"]} @@ -266,13 +267,14 @@ def formation_list_table(context, formation_id=None, args={}, REQUEST=None): f["sems_list_txt"] = ", ".join([s["session_id"] for s in f["sems"]]) f["_sems_list_txt_html"] = ", ".join( [ - '%(session_id)s' - % s + '%(' + "session_id)s " % s for s in f["sems"] ] + [ - 'ajouter' - % f + 'ajouter ' + % (f["acronyme"].lower().replace(" ", "-"), f["formation_id"]) ] ) if f["sems"]: @@ -288,16 +290,17 @@ def formation_list_table(context, formation_id=None, args={}, REQUEST=None): else: but_locked = '' if editable and not locked: - but_suppr = ( - '%s' - % (f["formation_id"], suppricon) + but_suppr = '%s' % ( + f["formation_id"], + f["acronyme"].lower().replace(" ", "-"), + suppricon, ) else: but_suppr = '' if editable: but_edit = ( - '%s' - % (f["formation_id"], editicon) + '%s' + % (f["formation_id"], f["acronyme"].lower().replace(" ", "-"), editicon) ) else: but_edit = '' @@ -365,4 +368,4 @@ def formation_create_new_version(context, formation_id, redirect=True, REQUEST=N "ue_list?formation_id=" + new_id + "&msg=Nouvelle version !" ) else: - return new_id, modules_old2new, ues_old2new \ No newline at end of file + return new_id, modules_old2new, ues_old2new diff --git a/app/views/notes.py b/app/views/notes.py index d29e9e971..8f42c6ba0 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -391,7 +391,7 @@ def index_html(context, REQUEST=None): if editable: H.append( - """
+ """Une "formation" est un programme pédagogique structuré en UE, matières et modules. Chaque semestre se réfère à une formation. La modification d'une formation affecte tous les semestres qui s'y réfèrent.
""" @@ -1968,7 +1968,7 @@ def formsemestre_validation_etud_manu( def formsemestre_validate_previous_ue( context, formsemestre_id, etudid=None, REQUEST=None ): - "Form. saisie UE validée hors ScoDoc " + "Form. saisie UE validée hors ScoDoc" if not sco_permissions_check.can_validate_sem(formsemestre_id): return scu.confirm_dialog( message="Opération non autorisée pour %s"
diff --git a/scodoc.py b/scodoc.py
index 9f6a61023..6c459ca7e 100755
--- a/scodoc.py
+++ b/scodoc.py
@@ -6,7 +6,6 @@
"""
-
from __future__ import print_function
import os
@@ -19,6 +18,7 @@ from flask.cli import with_appcontext
from app import create_app, cli, db
from app.auth.models import User, Role, UserRole
+from app.scodoc.notesdb import set_sco_dept
from app.views import notes, scolar, absences
import app.utils as utils
@@ -152,10 +152,7 @@ def user_password(username, password=None): # user-password
@click.argument("dept")
def sco_delete_dept(dept): # sco-delete-dept
"Delete existing departement"
- if os.getuid() != 0:
- sys.stderr.write("sco_delete_dept: must be run by root\n")
- return 1
- if os.system('cd tools && ./delete_dept.sh -n "{}"'.format(dept)):
+ if os.system('tools/delete_dept.sh -n "{}"'.format(dept)):
sys.stderr.write("error deleting dept " + dept)
return 1
return 0
@@ -165,10 +162,7 @@ def sco_delete_dept(dept): # sco-delete-dept
@click.argument("dept")
def sco_create_dept(dept): # sco-create-dept
"Create new departement"
- if os.getuid() != 0:
- sys.stderr.write("sco_create_dept: must be run by root\n")
- return 1
- if os.system(f'cd tools && ./create_dept.sh -n "{dept}"'):
+ if os.system(f'tools/create_dept.sh -n "{dept}"'):
sys.stderr.write(f"error creating dept {dept}\n")
return 1
return 0
@@ -216,3 +210,22 @@ def clear_cache(): # clear-cache
r = redis.Redis()
r.flushall()
click.echo("Redis caches flushed.")
+
+
+@app.cli.command()
+@click.argument("xml_file")
+@click.argument("dept")
+def import_xml(xml_file, dept):
+ import flask_login
+ from flask_login import login_user, logout_user, current_user
+ from app.scodoc.notesdb import close_dept_connection, open_dept_connection
+ from app.scodoc.sco_formations import formation_import_xml
+
+ with app.test_request_context():
+ u = User.query.first()
+ flask_login.login_user(u)
+ click.echo("Importing {}".format(xml_file))
+ set_sco_dept(dept)
+ doc = open(xml_file).read()
+ formation_import_xml(None, doc)
+ click.echo("Done")
diff --git a/scotests/test_scenario1_formation.py b/scotests/test_scenario1_formation.py
deleted file mode 100644
index 564b3e1ab..000000000
--- a/scotests/test_scenario1_formation.py
+++ /dev/null
@@ -1,73 +0,0 @@
-import sco_formations
-import random
-
-# La variable context est définie par le script de lancement
-# l'affecte ainsi pour évietr les warnins pylint:
-context = context # pylint: disable=undefined-variable
-REQUEST = REQUEST # pylint: disable=undefined-variable
-import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error
-import sco_moduleimpl
-
-G = sco_fake_gen.ScoFake(context.Notes)
-G.verbose = False
-
-file = open("scotests/export_formation1.xml")
-doc = file.read()
-file.close()
-
-
-# --- Création de la formation
-
-f = sco_formations.formation_import_xml(doc=doc, context=context.Notes)
-
-# --- Création des semestres
-
-sem1 = G.create_formsemestre(
- formation_id=f[0],
- semestre_id=1,
- date_debut="01/09/2020",
- date_fin="01/02/2021",
-)
-
-sem3 = G.create_formsemestre(
- formation_id=f[0],
- semestre_id=3,
- date_debut="01/09/2020",
- date_fin="01/02/2021",
-)
-
-sem2 = G.create_formsemestre(
- formation_id=f[0],
- semestre_id=2,
- date_debut="02/02/2021",
- date_fin="01/06/2021",
-)
-
-sem4 = G.create_formsemestre(
- formation_id=f[0],
- semestre_id=4,
- date_debut="02/02/2021",
- date_fin="01/06/2021",
-)
-
-
-# --- Implémentation des modules
-
-li_module = context.Notes.do_module_list()
-mods_imp = []
-for mod in li_module:
- if mod["semestre_id"] == 1:
- formsemestre_id = sem1["formsemestre_id"]
- elif mod["semestre_id"] == 2:
- formsemestre_id = sem2["formsemestre_id"]
- elif mod["semestre_id"] == 3:
- formsemestre_id = sem3["formsemestre_id"]
- else:
- formsemestre_id = sem4["formsemestre_id"]
-
- mi = G.create_moduleimpl(
- module_id=mod["module_id"],
- formsemestre_id=formsemestre_id,
- responsable_id="bach",
- )
- mods_imp.append(mi)
\ No newline at end of file
diff --git a/tests/conftest.py b/tests/conftest.py
index 3e7888f0e..758250f4d 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -30,11 +30,18 @@ def test_client():
db.create_all()
Role.insert_roles()
u = User(user_name="admin")
- admin_role = Role.query.filter_by(name="SuperAdmin").first()
- u.add_role(admin_role, "TEST00")
+ super_admin_role = Role.query.filter_by(name="SuperAdmin").first()
+ u.add_role(super_admin_role, "TEST00")
# u.set_password("admin")
login_user(u)
- # db.session.add(u)
+ # Vérifie que l'utilisateur bach existe
+ u = User.query.filter_by(user_name="bach").first()
+ if u is None:
+ u = User(user_name="bach")
+ if not "Admin" in {r.name for r in u.roles}:
+ admin_role = Role.query.filter_by(name="Admin").first()
+ u.add_role(admin_role, "TEST00")
+ db.session.add(u)
ndb.set_sco_dept("TEST00") # set db connection
truncate_database() # erase tables
yield client
diff --git a/tests/scenarios/export_formation1.xml b/tests/scenarios/export_formation1.xml
new file mode 100755
index 000000000..8baf7a6b7
--- /dev/null
+++ b/tests/scenarios/export_formation1.xml
@@ -0,0 +1,205 @@
+