Compare commits

...

9 Commits

40 changed files with 755 additions and 422 deletions

View File

@ -93,7 +93,7 @@ ADMISSION_MODIFIABLE_FIELDS = (
def sco_import_format(with_codesemestre=True):
"returns tuples (Attribut, Type, Table, AllowNulls, Description)"
r = []
for l in open(SCO_SRCDIR + "/" + FORMAT_FILE):
for l in open(SCO_SRC_DIR + "/" + FORMAT_FILE):
l = l.strip()
if l and l[0] != "#":
fs = l.split(";")

View File

@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
SCOVERSION = "7.19a"
SCOVERSION = "8.00a"
SCONAME = "ScoDoc"

View File

@ -33,6 +33,7 @@
import time, string, glob, re, inspect
import urllib, urllib2, cgi, xml
import datetime
try:
from cStringIO import StringIO
@ -42,13 +43,22 @@ from zipfile import ZipFile
import os.path, glob
import traceback
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email.Header import Header
from email import Encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
from email.mime.base import MIMEBase
from sco_zope import *
from sco_zope import (
ObjectManager,
PropertyManager,
RoleManager,
Item,
Persistent,
Implicit,
ClassSecurityInfo,
DTMLFile,
Globals,
)
#
try:
@ -56,7 +66,21 @@ try:
except:
import ZPsycopgDA.DA as ZopeDA # interp.py
from sco_utils import *
import sco_utils
from sco_utils import (
SCO_DEFAULT_SQL_USERS_CNX,
SCO_ENCODING,
CUSTOM_HTML_HEADER_CNX,
SCO_USERS_LIST,
SCO_WEBSITE,
SCO_EXC_MAIL,
SCO_DEV_MAIL,
scodoc_html2txt,
VERSION,
SCODOC_CFG_DIR,
)
from sco_permissions import ScoView, ScoSuperAdmin
from sco_exceptions import AccessDenied
from notes_log import log
import sco_find_etud
from ZScoUsers import pwdFascistCheck
@ -111,7 +135,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
def _check_users_folder(self, REQUEST=None):
"""Vérifie UserFolder et le crée s'il le faut"""
try:
udb = self.UsersDB
self.UsersDB
return "<!-- uf ok -->"
except:
e = self._check_admin_perm(REQUEST)
@ -164,11 +188,11 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
pass
# add missing getAuthFailedMessage (bug in exUserFolder ?)
try:
x = self.getAuthFailedMessage
self.getAuthFailedMessage
except:
log("adding getAuthFailedMessage to Zope install")
parent = self.aq_parent
from OFS.DTMLMethod import addDTMLMethod
from OFS.DTMLMethod import addDTMLMethod # pylint: disable=import-error
addDTMLMethod(parent, "getAuthFailedMessage", file="Identification")
@ -264,7 +288,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
r = []
for folder in folders:
try:
s = folder.Scolarite
_ = folder.Scolarite
r.append(folder)
except:
pass
@ -646,8 +670,8 @@ Problème de connexion (identifiant, mot de passe): <em>contacter votre responsa
**kv
):
"Recuperation des exceptions Zope"
sco_exc_mail = SCO_EXC_MAIL
sco_dev_mail = SCO_DEV_MAIL
sco_exc_mail = SCO_EXC_MAIL # pylint: disable=unused-variable
sco_dev_mail = SCO_DEV_MAIL # pylint: disable=unused-variable
# neat (or should I say dirty ?) hack to get REQUEST
# in fact, our caller (probably SimpleItem.py) has the REQUEST variable
# that we'd like to use for our logs, but does not pass it as an argument.
@ -714,6 +738,7 @@ Problème de connexion (identifiant, mot de passe): <em>contacter votre responsa
)
# display error traceback (? may open a security risk via xss attack ?)
# log('exc B')
# pylint: disable=unused-variable
txt_html = self._report_request(REQUEST, fmt="html")
H.append(
"""<h4 class="scodoc">Zope Traceback (à envoyer par mail à <a href="mailto:%(sco_dev_mail)s">%(sco_dev_mail)s</a>)</h4><div style="background-color: rgb(153,153,204); border: 1px;">
@ -734,6 +759,7 @@ Problème de connexion (identifiant, mot de passe): <em>contacter votre responsa
pass
# --- Mail:
# pylint: disable=unused-variable
error_traceback_txt = scodoc_html2txt(error_tb)
txt = (
"""
@ -752,6 +778,7 @@ ErrorType: %(error_type)s
def _report_request(self, REQUEST, fmt="txt"):
"""string describing current request for bug reports"""
# pylint: disable=unused-variable
AUTHENTICATED_USER = REQUEST.get("AUTHENTICATED_USER", "")
dt = time.asctime()
URL = REQUEST.get("URL", "")
@ -768,8 +795,7 @@ ErrorType: %(error_type)s
HTTP_USER_AGENT = "na"
form = REQUEST.get("form", "")
HTTP_X_FORWARDED_FOR = REQUEST.get("HTTP_X_FORWARDED_FOR", "")
svn_version = get_svn_version(self.file_path)
SCOVERSION = VERSION.SCOVERSION
SCOVERSION = sco_utils.get_scodoc_version() or VERSION.SCOVERSION
txt = (
"""
@ -783,8 +809,6 @@ REFERER: %(REFERER)s
Form: %(form)s
Origin: %(HTTP_X_FORWARDED_FOR)s
Agent: %(HTTP_USER_AGENT)s
subversion: %(svn_version)s
"""
% vars()
)
@ -887,7 +911,7 @@ subversion: %(svn_version)s
"""Liste de id de departements definis par create_dept.sh
(fichiers depts/*.cfg)
"""
filenames = glob.glob(SCODOC_VAR_DIR + "/config/depts/*.cfg")
filenames = glob.glob(SCODOC_CFG_DIR + "/config/depts/*.cfg")
ids = [os.path.split(os.path.splitext(f)[0])[1] for f in filenames]
return ids

View File

@ -52,7 +52,7 @@ log("restarting...")
log("ZScolar home=%s" % file_path)
import sco_utils
from sco_utils import *
import notesdb
from notesdb import *
@ -405,9 +405,9 @@ UE11 Découverte métiers <span class="ue_code">(code UCOD46, 16 ECTS, Apo <span
H = [
"""<h2>Système de gestion scolarité</h2>
<p>&copy; Emmanuel Viennet 1997-2020</p>
<p>Version %s (subversion %s)</p>
<p>Version %s</p>
"""
% (SCOVERSION, get_svn_version(file_path))
% (sco_utils.get_scodoc_version())
]
H.append(
'<p>Logiciel libre écrit en <a href="http://www.python.org">Python</a>.</p><p>Utilise <a href="http://www.reportlab.org/">ReportLab</a> pour générer les documents PDF, et <a href="http://sourceforge.net/projects/pyexcelerator">pyExcelerator</a> pour le traitement des documents Excel.</p>'

View File

@ -1,4 +1,4 @@
#!/bin/bash
# Version majeure de Debian (..., 9, 10)
debian_version=$(cat /etc/debian_version)
debian_version=${debian_version%%.*}
@ -24,28 +24,28 @@ export POSTGRES_SUPERUSER=postgres
export POSTGRES_USER=www-data
# psql command: if various versions installed, force the one we want:
if [ ${debian_version} = "10" ]
if [ "${debian_version}" = "10" ]
then
PSQL=/usr/lib/postgresql/11/bin/psql
elif [ ${debian_version} = "9" ]
elif [ "${debian_version}" = "9" ]
then
PSQL=/usr/lib/postgresql/9.6/bin/psql
elif [ ${debian_version} = "8" ]
elif [ "${debian_version}" = "8" ]
then
PSQL=/usr/lib/postgresql/9.4/bin/psql
elif [ ${debian_version} = "7" ]
elif [ "${debian_version}" = "7" ]
then
PSQL=/usr/lib/postgresql/9.1/bin/psql
elif [ ${debian_version} = "5" ]
elif [ "${debian_version}" = "5" ]
then
PSQL=/usr/lib/postgresql/8.3/bin/psql
elif [ ${debian_version} = "6" ]
elif [ "${debian_version}" = "6" ]
then
PSQL=/usr/lib/postgresql/8.4/bin/psql
else
PSQL=/usr/lib/postgresql/8.1/bin/psql
fi
export PSQL
# tcp port for SQL server (under Debian 4, 5432 or 5433 for 8.1 if 7.4 also installed !)
# Important note: if changed, you should probably also change it in
@ -53,7 +53,7 @@ fi
export POSTGRES_PORT=5432
# Utilise par le script de reset du mot de passe:
if [ ${debian_version} -ge "7" ]
if [ "${debian_version}" -ge "7" ]
then
export ZOPE_VERSION=2.13
else

View File

@ -5,10 +5,10 @@
source config.sh
source utils.sh
check_uid_root $0
check_uid_root "$0"
echo 'Installation du demarrage automatique de ScoDoc (systemd)'
cp $SCODOC_DIR/config/etc/scodoc.service /etc/systemd/system
cp "$SCODOC_DIR"/config/etc/scodoc.service /etc/systemd/system
systemctl enable scodoc.service
echo "A partir de maintenant, utiliser"

View File

@ -11,6 +11,6 @@ source utils.sh
echo 'Creating postgresql database'
# ---
echo 'Creating postgresql database ' $db_name
createdb -E UTF-8 -p $POSTGRES_PORT -O $POSTGRES_USER $db_name
echo 'Creating postgresql database ' "$db_name"
createdb -E UTF-8 -p "$POSTGRES_PORT" -O "$POSTGRES_USER" "$db_name"

View File

@ -13,11 +13,11 @@
source config.sh
source utils.sh
check_uid_root $0
check_uid_root "$0"
echo -n "Nom du departement (un mot sans ponctuation, exemple \"Info\"): "
read DEPT
read -r DEPT
if [[ ! "$DEPT" =~ ^[A-Za-z0-9]+$ ]]
then
@ -31,9 +31,9 @@ export db_name=SCO$(to_upper "$DEPT")
cfg_pathname="${SCODOC_VAR_DIR}/config/depts/$DEPT".cfg
if [ -e $cfg_pathname ]
if [ -e "$cfg_pathname" ]
then
echo 'Erreur: Il existe deja une configuration pour "'$DEPT'"'
echo 'Erreur: Il existe deja une configuration pour "'"$DEPT"'"'
exit 1
fi
@ -48,11 +48,11 @@ su -c ./create_database.sh $POSTGRES_SUPERUSER
su -c ./initialize_database.sh $POSTGRES_USER
# ----------------------- Enregistre fichier config
echo "dbname="$db_name > $cfg_pathname
echo "dbname=$db_name" > "$cfg_pathname"
# ----------------------- Force mise à jour
echo -n "Voulez vous mettre a jour ScoDoc (tres recommande) ? (y/n) [y] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
(cd "$SCODOC_DIR/config"; ./upgrade.sh)

View File

@ -12,7 +12,7 @@
source config.sh
source utils.sh
check_uid_root $0
check_uid_root "$0"
# --- Ensure postgres user www-data exists
init_postgres_user
@ -21,8 +21,8 @@ db_name=SCOUSERS
echo 'Creating postgresql database ' $db_name
su -c "createdb -E UTF-8 -O $POSTGRES_USER -p $POSTGRES_PORT $db_name" $POSTGRES_SUPERUSER
su -c "createdb -E UTF-8 -O $POSTGRES_USER -p $POSTGRES_PORT $db_name" "$POSTGRES_SUPERUSER"
echo 'Initializing tables in database ' $db_name
echo su -c "$PSQL -U $POSTGRES_USER -p $POSTGRES_PORT $db_name < $SCODOC_DIR/misc/create_user_table.sql" $POSTGRES_USER
su -c "$PSQL -U $POSTGRES_USER -p $POSTGRES_PORT $db_name < $SCODOC_DIR/misc/create_user_table.sql" $POSTGRES_USER
echo 'Initializing tables in database ' "$db_name"
echo su -c "$PSQL -U $POSTGRES_USER -p $POSTGRES_PORT $db_name < $SCODOC_DIR/misc/create_user_table.sql" "$POSTGRES_USER"
su -c "$PSQL -U $POSTGRES_USER -p $POSTGRES_PORT $db_name < $SCODOC_DIR/misc/create_user_table.sql" "$POSTGRES_USER"

View File

@ -17,7 +17,7 @@
source config.sh
source utils.sh
check_uid_root $0
check_uid_root "$0"
echo
echo "Ce script supprime la base de donnees ScoDoc d'un departement"
@ -26,7 +26,7 @@ echo "Attention: le departement doit au prealable avoir ete supprime via l'inter
echo "faites le AVANT d'executer ce script !!!"
echo
echo -n "Nom du departement a supprimer (un mot sans ponctuation, exemple \"Info\"): "
read DEPT
read -r DEPT
if [[ ! "$DEPT" =~ ^[A-Za-z0-9]+$ ]]
then
@ -38,26 +38,26 @@ export DEPT
cfg_pathname="${SCODOC_VAR_DIR}/config/depts/$DEPT".cfg
if [ -e $cfg_pathname ]
if [ -e "$cfg_pathname" ]
then
# arret de ScoDoc
scodocctl stop
# suppression de la base postgres
db_name=$(cat $cfg_pathname | sed '/^dbname=*/!d; s///;q')
db_name=$(sed '/^dbname=*/!d; s///;q' < "$cfg_pathname")
echo "suppression de la base postgres $db_name"
su -c "dropdb $db_name" $POSTGRES_SUPERUSER || terminate "ne peux supprimer base de donnees $db_name"
su -c "dropdb $db_name" "$POSTGRES_SUPERUSER" || terminate "ne peux supprimer base de donnees $db_name"
# suppression du fichier de config
/bin/rm -f $cfg_pathname || terminate "ne peux supprimer $cfg_pathname"
/bin/rm -f "$cfg_pathname" || terminate "ne peux supprimer $cfg_pathname"
# relance ScoDoc
echo -n "Demarrer le serveur ScoDoc ? (y/n) [n]"
read ans
read -r ans
if [ "$(norm_ans "$ans")" = 'Y' ]
then
scodocctl start
fi
exit 0
else
echo 'Erreur: pas de configuration trouvee pour "'$DEPT'"'
echo 'Erreur: pas de configuration trouvee pour "'"$DEPT"'"'
exit 1
fi

View File

@ -6,7 +6,7 @@
# Avec option:
# -a : sauve aussi les bases de données
#
DEST_ADDRESS=emmanuel.viennet@univ-paris13.fr
DEST_ADDRESS=emmanuel.viennet@gmail.com
INSTANCE_DIR=/opt/scodoc
@ -36,7 +36,7 @@ while getopts ":d:aunh" opt; do
SEND_BY_MAIL=0
;;
d)
DEPTS_TO_SAVE=$( join_by ' ' $DEPTS_TO_SAVE $OPTARG )
DEPTS_TO_SAVE=$( join_by ' ' "$DEPTS_TO_SAVE" "$OPTARG" )
;;
h)
echo "Diagnostic installation ScoDoc"
@ -71,7 +71,7 @@ then
apt-get install sharutils
fi
mkdir $TMP
mkdir "$TMP"
# Files to copy:
FILES="/etc/hosts /etc/debian_version /etc/apt /etc/apache2"
@ -91,33 +91,33 @@ echo "left in ${TMP}"
# -------------------------------------
copy_log() {
if [ -e $1 ]
if [ -e "$1" ]
then
cp $1 $TMP/scodoc_logs/
cp "$1" "$TMP"/scodoc_logs/
fi
}
mkdir $TMP/scodoc_logs/
copy_log /opt/scodoc/instance/log/event.log
copy_log /opt/scodoc/instance/log/event.log.1
copy_log /opt/scodoc/instance/log/notes.log
copy_log /opt/scodoc/instance/log/notes.log.1
mkdir "$TMP"/scodoc_logs/
copy_log /opt/scodoc/log/event.log
copy_log /opt/scodoc/log/event.log.1
copy_log /opt/scodoc/log/notes.log
copy_log /opt/scodoc/log/notes.log.1
# -------------------------------------
# Linux System Configuration
# -------------------------------------
iptables -L > $TMP/iptables.out
ip a > $TMP/ifconfig.out
ps auxww > $TMP/ps.out
df -h > $TMP/df.out
dpkg -l > $TMP/dpkg.lst
iptables -L > "$TMP"/iptables.out
ip a > "$TMP"/ifconfig.out
ps auxww > "$TMP"/ps.out
df -h > "$TMP"/df.out
dpkg -l > "$TMP"/dpkg.lst
(cd /opt/scodoc/instance/Products/ScoDoc; svn status > $TMP/svn.status)
(cd /opt/scodoc/instance/Products/ScoDoc; svn diff > $TMP/svn.diff)
(cd /opt/scodoc/Products/ScoDoc; svn status > "$TMP"/svn.status)
(cd /opt/scodoc/Products/ScoDoc; svn diff > "$TMP"/svn.diff)
(cd /opt/scodoc/instance/Products/ScoDoc; svnversion > $TMP/svn.version)
ls -laR /opt/scodoc/instance/Products/ScoDoc > $TMP/ls-laR
(cd /opt/scodoc/Products/ScoDoc; svnversion > "$TMP"/svn.version)
ls -laR /opt/scodoc/Products/ScoDoc > "$TMP"/ls-laR
# -------------------------------------
@ -126,7 +126,7 @@ ls -laR /opt/scodoc/instance/Products/ScoDoc > $TMP/ls-laR
(su postgres -c "psql -l") > "${TMP}/psql-l.out"
for dept in "${INSTANCE_DIR}"/var/scodoc/config/depts/*.cfg
do
cnx=$(cat $dept)
cnx=$(cat "$dept")
(su postgres -c "echo '\dt' | psql -d $cnx") > "${TMP}/psql-$(basename ${dept%%.*}).out"
done
@ -137,14 +137,14 @@ done
# copy files:
for f in $FILES
do
cp -R $f $TMP
cp -R "$f" "$TMP"
done
# -------------------------------------
# Optionally save dept(s) database(s)
# -------------------------------------
DEPTS_TO_SAVE=$(echo ${DEPTS_TO_SAVE} | tr ' ' '\n' | sort | uniq)
DEPTS_TO_SAVE=$(echo "${DEPTS_TO_SAVE}" | tr ' ' '\n' | sort | uniq)
# Dump database of a dept (eg "RT")
function dump_dept_db {
@ -176,10 +176,10 @@ fi
# Archive all stuff to /tmp
# -------------------------------------
tar cfz $TMP.tgz $TMP
tar cfz "$TMP".tgz "$TMP"
echo
echo "Fichier de diagnostic: $TMP.tgz"
echo "Fichier de diagnostic: "$TMP".tgz"
echo
# If no mail, stop here
@ -197,9 +197,9 @@ fi
#requires: basename,date,md5sum,sed,sendmail,uuencode
function fappend {
echo "$2">>$1;
echo "$2">>"$1";
}
YYYYMMDD=`date +%Y%m%d`
YYYYMMDD=$(date +%Y%m%d)
# CHANGE THESE
TOEMAIL=$DEST_ADDRESS
@ -212,45 +212,45 @@ MIMETYPE="application/gnutar" #if not sure, use http://www.webmaster-toolkit.com
# DON'T CHANGE ANYTHING BELOW
TMP="/tmp/tmpfil_123"$RANDOM;
BOUNDARY=`date +%s|md5sum`
BOUNDARY=$(date +%s|md5sum)
BOUNDARY=${BOUNDARY:0:32}
FILENAME=`basename $ATTACHMENT`
FILENAME=$(basename "$ATTACHMENT")
rm -rf $TMP;
cat $ATTACHMENT|uuencode --base64 $FILENAME>$TMP;
sed -i -e '1,1d' -e '$d' $TMP;#removes first & last lines from $TMP
DATA=`cat $TMP`
rm -rf "$TMP"
uuencode --base64 "$FILENAME" < "$ATTACHMENT" >"$TMP"
sed -i -e '1,1d' -e '$d' "$TMP"; #removes first & last lines from "$TMP"
DATA=$(cat "$TMP")
rm -rf $TMP;
fappend $TMP "From: $FREMAIL";
fappend $TMP "To: $TOEMAIL";
fappend $TMP "Reply-To: $FREMAIL";
fappend $TMP "Subject: $SUBJECT";
fappend $TMP "Content-Type: multipart/mixed; boundary=\""$BOUNDARY"\"";
fappend $TMP "";
fappend $TMP "This is a MIME formatted message. If you see this text it means that your";
fappend $TMP "email software does not support MIME formatted messages.";
fappend $TMP "";
fappend $TMP "--$BOUNDARY";
fappend $TMP "Content-Type: text/plain; charset=ISO-8859-1; format=flowed";
fappend $TMP "Content-Transfer-Encoding: 7bit";
fappend $TMP "Content-Disposition: inline";
fappend $TMP "";
fappend $TMP "$MSGBODY";
fappend $TMP "";
fappend $TMP "";
fappend $TMP "--$BOUNDARY";
fappend $TMP "Content-Type: $MIMETYPE; name=\"$FILENAME\"";
fappend $TMP "Content-Transfer-Encoding: base64";
fappend $TMP "Content-Disposition: attachment; filename=\"$FILENAME\";";
fappend $TMP "";
fappend $TMP "$DATA";
fappend $TMP "";
fappend $TMP "";
fappend $TMP "--$BOUNDARY--";
fappend $TMP "";
fappend $TMP "";
#cat $TMP>out.txt
cat $TMP|sendmail -t -f none@example.com;
rm $TMP;
rm -rf "$TMP";
fappend "$TMP" "From: $FREMAIL";
fappend "$TMP" "To: $TOEMAIL";
fappend "$TMP" "Reply-To: $FREMAIL";
fappend "$TMP" "Subject: $SUBJECT";
fappend "$TMP" "Content-Type: multipart/mixed; boundary=\""$BOUNDARY"\"";
fappend "$TMP" "";
fappend "$TMP" "This is a MIME formatted message. If you see this text it means that your";
fappend "$TMP" "email software does not support MIME formatted messages.";
fappend "$TMP" "";
fappend "$TMP" "--$BOUNDARY";
fappend "$TMP" "Content-Type: text/plain; charset=ISO-8859-1; format=flowed";
fappend "$TMP" "Content-Transfer-Encoding: 7bit";
fappend "$TMP" "Content-Disposition: inline";
fappend "$TMP" "";
fappend "$TMP" "$MSGBODY";
fappend "$TMP" "";
fappend "$TMP" "";
fappend "$TMP" "--$BOUNDARY";
fappend "$TMP" "Content-Type: $MIMETYPE; name=\"$FILENAME\"";
fappend "$TMP" "Content-Transfer-Encoding: base64";
fappend "$TMP" "Content-Disposition: attachment; filename=\"$FILENAME\";";
fappend "$TMP" "";
fappend "$TMP" "$DATA";
fappend "$TMP" "";
fappend "$TMP" "";
fappend "$TMP" "--$BOUNDARY--";
fappend "$TMP" "";
fappend "$TMP" "";
#cat "$TMP">out.txt
cat "$TMP"|sendmail -t -f none@example.com;
rm "$TMP";

View File

@ -15,15 +15,15 @@ then
fi
echo "Changing to directory " $SCODOC_DIR/config
cd $SCODOC_DIR/config
echo "Changing to directory " "$SCODOC_DIR"/config
cd "$SCODOC_DIR"/config || { echo "directory does not exist"; exit 1; }
echo "Stopping ScoDoc..."
scodocctl stop
# DROITS
echo -n "Verification des droits: proprietaire www-data ? (y/n) [y] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
echo 'changing owner to www-data'
@ -31,7 +31,7 @@ then
fi
echo -n 'Suppression des backups des sources (*~) ? (y/n) [y] '
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
/bin/rm -f ../*~ ../*/*~
@ -40,7 +40,7 @@ fi
# SVN
echo -n "svn update ? (y/n) [y] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
echo 'Updating from SVN...'
@ -50,7 +50,7 @@ fi
# DEPARTEMENTS (maintenant inutile car dans /var)
echo -n "Supprimer les (anciennes) configs de departements ? (y/n) [y] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
echo "moving " depts/*.cfg "to /tmp"
@ -59,7 +59,7 @@ fi
# .../var/
echo -n "Supprimer et recréer .../var (archives, photos, configs, ...) ? (y/n) [y] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
echo "moving ../../../var/scodoc to /tmp"
@ -73,7 +73,7 @@ fi
# LOGS ZOPE
echo -n "Effacer les logs de Zope et ScoDoc ? (y/n) [y] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
(cd ../../../log/; ./purge)
@ -81,7 +81,7 @@ fi
# IMAGE Data.fs
echo -n "Recopier le Data.fs original ? (y/n) [y] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
echo "moving Data.fs to /tmp"

50
config/get_scodoc_version.sh Executable file
View File

@ -0,0 +1,50 @@
#!/bin/bash
# Get version information
# Use VERSION.py, last commit, diff, and last upstream commit date
source config.sh
source utils.sh
# Source code version:
x=$(grep SCOVERSION ../VERSION.py) || terminate "can't access VERSION.py" 1
x=${x#*\"}
src_version=${x%\"*}
# last commit
git_last_commit_hash=$(git log -1 --format=%h)
git_last_commit_date=$(git log -1 --format=%ci)
git_up_commit_hash=$(git log -1 --format=%h origin/ScoDoc8)
git_up_commit_date=$(git log -1 --format=%ci origin/ScoDoc8)
# Check if git has local changes
nchanges=$(git status --porcelain | grep -c -v '^??')
if [ "$nchanges" -gt 0 ]
then
has_local_changes="yes"
else
has_local_changes="no"
fi
# Synthetic one-line version:
sco_version="$src_version ($git_up_commit_hash) $git_up_commit_date"
if [ "$has_local_changes" = "yes" ]
then
sco_version="$sco_version (modified)"
fi
#
if [ "$1" = "-s" ]
then
echo "$sco_version"
else
echo src_version: "$src_version"
echo git_last_commit_hash: "$git_last_commit_hash"
echo git_last_commit_date: "$git_last_commit_date"
echo git_up_commit_hash: "$git_up_commit_hash"
echo git_up_commit_date: "$git_up_commit_date"
echo has_local_diffs: "$has_local_changes"
echo sco_version: "$sco_version"
fi

View File

@ -8,15 +8,16 @@
source config.sh
source utils.sh
if [ $(id -nu) != $POSTGRES_USER ]
if [ "$(id -nu)" != "$POSTGRES_USER" ]
then
echo "$0: script must be runned as user $POSTGRES_USER"
exit 1
fi
echo 'Initializing tables in database ' $db_name
$PSQL -U $POSTGRES_USER -p $POSTGRES_PORT $db_name -f $SCODOC_DIR/misc/createtables.sql
# shellcheck disable=SC2154
echo 'Initializing tables in database ' "$db_name"
$PSQL -U "$POSTGRES_USER" -p "$POSTGRES_PORT" "$db_name" -f "$SCODOC_DIR"/misc/createtables.sql
# Set DeptName in preferences:
echo "insert into sco_prefs (name, value) values ('DeptName', '"${DEPT}\'\) | $PSQL -U $POSTGRES_USER -p $POSTGRES_PORT $db_name
echo "insert into sco_prefs (name, value) values ('DeptName', '"${DEPT}\'\) | $PSQL -U "$POSTGRES_USER" -p "$POSTGRES_PORT" "$db_name"

View File

@ -2,9 +2,10 @@
#
# ScoDoc: install third-party software necessary for our installation
# starting for a minimal Debian (Stretch, 9.0) install.
# starting for a minimal Debian (Buster, 10.0) install.
#
# E. Viennet, Jun 2008, Apr 2009, Sept 2011, Sept 2013, Nov 2013, Mar 2017, Jul 2017, Jun 2019, Oct 2019
# E. Viennet, Jun 2008, Apr 2009, Sept 2011, Sept 2013, Nov 2013, Mar 2017, Jul 2017,
# Jun 2019, Oct 2019, Dec 2020
#
source config.sh
@ -12,16 +13,14 @@ source utils.sh
check_uid_root $0
PYTHON=/opt/zope213/bin/python
# ------------ Safety checks
if [ ${debian_version} != "10" ]
if [ "${debian_version}" != "10" ]
then
echo "Version du systeme Linux Debian incompatible"
exit 1
fi
if [ $(arch) != "x86_64" ]
if [ "$(arch)" != "x86_64" ]
then
echo "Version du systeme Linux Debian incompatible (pas X86 64 bits)"
exit 1
@ -29,8 +28,8 @@ fi
# ------------ Permissions & directories
# source dir should be writable by scodoc to write bytecode files
chgrp www-data $SCODOC_DIR $SCODOC_DIR/ZopeProducts/*
chmod g+w $SCODOC_DIR $SCODOC_DIR/ZopeProducts/*
chgrp www-data "$SCODOC_DIR" "$SCODOC_DIR"/ZopeProducts/*
chmod g+w "$SCODOC_DIR" "$SCODOC_DIR"/ZopeProducts/*
chgrp -R www-data "${SCODOC_VAR_DIR}"/photos
chmod -R g+w "${SCODOC_VAR_DIR}"/photos
@ -53,8 +52,8 @@ fi
for locname in en_US.UTF-8 en_US.ISO-8859-15 en_US.ISO-8859-1
do
outname=$(echo ${locname//-/} | tr '[A-Z]' '[a-z]')
if [ $(locale -a | egrep -i ^${outname}$ | wc -l) -lt 1 ]
outname=$(echo ${locname//-/} | tr 'A-Z' 'a-z')
if [ "$(locale -a | grep -E -i ^${outname}$ | wc -l)" -lt 1 ]
then
echo adding $locname
echo "$locname ${locname##*.}" >> /etc/locale.gen
@ -86,7 +85,7 @@ apt-get -y install postgresql
apt-get -y install graphviz
# ------------ INSTALL DES EXTENSIONS PYTHON (2.7)
# XXX to fix: pip in our env
apt-get -y install python-docutils
apt-get -y install python-jaxml
apt-get -y install python-psycopg2
@ -96,20 +95,21 @@ apt-get -y install python-cracklib # was python-crack
apt-get -y install python-icalendar
apt-get -y install python-requests
# XXX to fix: mx not needed anymore !
apt-get -y install python-egenix-mxtools python-egenix-mxdatetime
# ------------
SVNVERSION=$(cd ..; svnversion)
SVERSION=$(curl --silent http://scodoc.iutv.univ-paris13.fr/scodoc-installmgr/version?mode=install\&svn=$SVNVERSION)
echo $SVERSION > "${SCODOC_VERSION_DIR}/scodoc.sn"
SVERSION=$(curl --silent http://scodoc.iutv.univ-paris13.fr/scodoc-installmgr/version?mode=install\&svn="$SVNVERSION")
echo "$SVERSION" > "${SCODOC_VERSION_DIR}/scodoc.sn"
# ------------ POSTFIX
echo
echo "ScoDoc a besoin de pouvoir envoyer des messages par mail."
echo -n "Voulez vous configurer la messagerie (tres recommande) ? (y/n) [y] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
apt-get -y install postfix
@ -119,7 +119,7 @@ fi
echo
echo "Le firewall aide a proteger votre serveur d'intrusions indesirables."
echo -n "Voulez vous configurer un firewall minimal (ufw) ? (y/n) [n] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" = 'Y' ]
then
echo 'Installation du firewall IP ufw (voir documentation Debian)'
@ -144,16 +144,16 @@ a2enmod rewrite
echo
echo "La configuration du serveur web va modifier votre installation Apache pour supporter ScoDoc."
echo -n "Voulez vous configurer le serveur web Apache maintenant (tres conseille) ? (y/n) [y] "
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
echo "Configuration d'Apache"
server_name=""
while [ -z $server_name ]
while [ -z "$server_name" ]
do
echo "Le nom de votre serveur doit normalement etre connu dans le DNS."
echo -n "Nom complet de votre serveur (exemple: notes.univ.fr): "
read server_name
read -r server_name
done
# --- CERTIFICATS AUTO-SIGNES
echo
@ -161,7 +161,7 @@ then
echo "auto-signes, qui ne seront pas reconnus comme de confiance"
echo "par les navigateurs, mais offrent une certaine securite."
echo -n 'Voulez vous generer des certificats ssl auto-signes ? (y/n) [y] '
read ans
read -r ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
# attention: utilise dans scodoc-site-ssl.orig
@ -177,7 +177,7 @@ then
fi
# ---
echo 'generation de /etc/apache2/sites-available/scodoc-site-ssl'
cat $SCODOC_DIR/config/etc/scodoc-site-ssl-apache2.4.orig | sed -e "s:YOUR\.FULL\.HOST\.NAME:$server_name:g" > /etc/apache2/sites-available/scodoc-site-ssl.conf
cat "$SCODOC_DIR"/config/etc/scodoc-site-ssl-apache2.4.orig | sed -e "s:YOUR\.FULL\.HOST\.NAME:$server_name:g" > /etc/apache2/sites-available/scodoc-site-ssl.conf
echo 'activation du site...'
a2ensite scodoc-site-ssl
@ -187,7 +187,7 @@ then
then
mv $fn $fn.bak
fi
cp $SCODOC_DIR/config/etc/scodoc-site.orig $fn
cp "$SCODOC_DIR"/config/etc/scodoc-site.orig $fn
if [ -z "$(grep Listen /etc/apache2/ports.conf | grep 443)" ]
then
@ -221,7 +221,7 @@ if [ "$(norm_ans "$ans")" != 'N' ]
then
# ScoDoc 7.19+ uses systemd
echo 'Installation du demarrage automatique de ScoDoc (systemd)'
cp $SCODOC_DIR/config/etc/scodoc.service /etc/systemd/system
cp "$SCODOC_DIR"/config/etc/scodoc.service /etc/systemd/system
systemctl enable scodoc.service
fi
@ -232,8 +232,8 @@ echo -n "Mises a jour hebdomadaires (tres recommande) ? (y/n) [y] "
read ans
if [ "$(norm_ans "$ans")" != 'N' ]
then
cp $SCODOC_DIR/config/etc/scodoc-updater.service /etc/systemd/system
cp $SCODOC_DIR/config/etc/scodoc-updater.timer /etc/systemd/system
cp "$SCODOC_DIR"/config/etc/scodoc-updater.service /etc/systemd/system
cp "$SCODOC_DIR"/config/etc/scodoc-updater.timer /etc/systemd/system
systemctl enable scodoc-updater.timer
systemctl start scodoc-updater.timer
fi

View File

@ -8,7 +8,7 @@ PG_DUMPFILE=$1
# Check locale of installation. If invalid, reinitialize all system
is_latin1=$(psql -l | grep postgres | grep iso88591 | wc -l)
if [ $is_latin1 -gt 1 ]
if [ "$is_latin1" -gt 1 ]
then
echo "Recreating postgres cluster using UTF-8"
@ -20,8 +20,8 @@ fi
# Drop all current ScoDoc databases, if any:
for f in $(psql -l --no-align --field-separator . | grep SCO | cut -f 1 -d.); do
echo dropping $f
dropdb $f
echo dropping "$f"
dropdb "$f"
done
echo "Restoring postgres data..."
psql -f "$PG_DUMPFILE" postgres

View File

@ -15,7 +15,7 @@ SCODOC_DIR="${INSTANCE_DIR}/Products/ScoDoc"
SCODOC_VAR_DIR="${INSTANCE_DIR}/var/scodoc"
source utils.sh
check_uid_root $0
check_uid_root "$0"
# Safety check
echo "Ce script va remplacer les donnees de votre installation ScoDoc par celles"
@ -28,7 +28,7 @@ echo
echo "TOUTES LES BASES POSTGRESQL SERONT EFFACEES !!!"
echo
echo -n "Voulez vous poursuivre cette operation ? (y/n) [n]"
read ans
read -r ans
if [ ! "$(norm_ans "$ans")" = 'Y' ]
then
echo "Annulation"
@ -57,7 +57,7 @@ then
echo "Opening tgz archive..."
tmp=$(mktemp -d)
chmod a+rx "$tmp"
cd "$tmp"
cd "$tmp" || { echo "Fatal error: directory not available"; exit 1; }
tar xfz "$SRC"
SRC=$(ls -1d "$tmp"/*)
IS_TMP=1
@ -132,11 +132,11 @@ chmod -R 775 "$SCODOC_DIR"
# Remove tmp directory
if [ $IS_TMP = "1" ]
then
rm -rf $tmp
rm -rf "$tmp"
fi
# Mise a jour BD ScoDoc
cd $SCODOC_DIR/config
cd "$SCODOC_DIR"/config || { echo "Fatal error: invalid directory"; exit 2; }
./upgrade.sh
#

View File

@ -10,6 +10,8 @@
#
source utils.sh
check_uid_root "$0"
# Destination directory
if [ ! $# -eq 1 ]
then
@ -34,9 +36,6 @@ fi
INSTANCE_DIR=/opt/scodoc
SCODOC_DIR="$INSTANCE_DIR/Products/ScoDoc"
source utils.sh
check_uid_root $0
echo "Stopping ScoDoc..."
scodocctl stop
@ -46,7 +45,7 @@ chown postgres "$DEST"
su -c "pg_dumpall > \"$DEST\"/scodoc.dump.txt" postgres
if [ ! $? -eq 0 ]
then
echo "Error dumping postgresql database\nPlease check that SQL server is running\nAborting."
printf "Error dumping postgresql database\nPlease check that SQL server is running\nAborting.\n"
exit 1
fi
chown root "$DEST"
@ -57,7 +56,7 @@ cp -rp "$INSTANCE_DIR/var" "$DEST"
# Depts db config (now in .../var)
shopt -s nullglob
if [ ! -z "$(echo ${SCODOC_DIR}/config/depts/*.cfg)" ]
if [ -n "$(echo ${SCODOC_DIR}/config/depts/*.cfg)" ]
then
echo "Copying legacy depts configs..."
cp -rp "$SCODOC_DIR/config/depts" "$DEST"

View File

@ -0,0 +1,128 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
#
# Configuration globale de ScoDoc (version juin 2009)
# Ce fichier est copié dans /opt/scodoc/var/scodoc/config
# par les scripts d'installation/mise à jour.
# La plupart des réglages sont stoqués en base de donnée et accessibles via le web
# (pages de paramètres ou préférences).
# Les valeurs indiquées ici sont les valeurs initiales que prendront
# les paramètres lors de la création d'un nouveau département,
# elles ne sont plus utilisées ensuite.
# Nota: il y a aussi des réglages dans sco_utils.py, mais ils nécessitent
# souvent de comprendre le code qui les utilise pour ne pas faire d'erreur: attention.
class CFG:
pass
CONFIG = CFG()
# set to 1 if you want to require INE:
# CONFIG.always_require_ine = 0
# The base URL, use only if you are behind a proxy
# eg "https://scodoc.example.net/ScoDoc"
# CONFIG.ABSOLUTE_URL = ""
# -----------------------------------------------------
# -------------- Documents PDF
# -----------------------------------------------------
# Taille du l'image logo: largeur/hauteur (ne pas oublier le . !!!)
# W/H XXX provisoire: utilisera PIL pour connaitre la taille de l'image
# CONFIG.LOGO_FOOTER_ASPECT = 326 / 96.0
# Taille dans le document en millimetres
# CONFIG.LOGO_FOOTER_HEIGHT = 10
# Proportions logo (donné ici pour IUTV)
# CONFIG.LOGO_HEADER_ASPECT = 549 / 346.0
# Taille verticale dans le document en millimetres
# CONFIG.LOGO_HEADER_HEIGHT = 28
# Pied de page PDF : un format Python, %(xxx)s est remplacé par la variable xxx.
# Les variables définies sont:
# day : Day of the month as a decimal number [01,31]
# month : Month as a decimal number [01,12].
# year : Year without century as a decimal number [00,99].
# Year : Year with century as a decimal number.
# hour : Hour (24-hour clock) as a decimal number [00,23].
# minute: Minute as a decimal number [00,59].
#
# server_url: URL du serveur ScoDoc
# scodoc_name: le nom du logiciel (ScoDoc actuellement, voir VERSION.py)
# CONFIG.DEFAULT_PDF_FOOTER_TEMPLATE = "Edité par %(scodoc_name)s le %(day)s/%(month)s/%(year)s à %(hour)sh%(minute)s sur %(server_url)s"
#
# ------------- Calcul bonus modules optionnels (sport, culture...) -------------
#
# CONFIG.compute_bonus = bonus_sport.bonus_iutv
# Mettre "bonus_demo" pour logguer des informations utiles au developpement...
#
# ------------- Capitalisation des UEs -------------
# Deux écoles:
# - règle "DUT": capitalisation des UE obtenues avec moyenne UE >= 10 ET de toutes les UE
# des semestres validés (ADM, ADC, AJ). (conforme à l'arrêté d'août 2005)
#
# - règle "LMD": capitalisation uniquement des UE avec moy. > 10
# Si vrai, capitalise toutes les UE des semestres validés (règle "DUT").
# CONFIG.CAPITALIZE_ALL_UES = True
#
# -----------------------------------------------------
#
# -------------- Personnalisation des pages
#
# -----------------------------------------------------
# Nom (chemin complet) d'un fichier .html à inclure juste après le <body>
# le <body> des pages ScoDoc
# CONFIG.CUSTOM_HTML_HEADER = ""
# Fichier html a inclure en fin des pages (juste avant le </body>)
# CONFIG.CUSTOM_HTML_FOOTER = ""
# Fichier .html à inclure dans la pages connexion/déconnexion (accueil)
# si on veut que ce soit différent (par défaut la même chose)
# CONFIG.CUSTOM_HTML_HEADER_CNX = CONFIG.CUSTOM_HTML_HEADER
# CONFIG.CUSTOM_HTML_FOOTER_CNX = CONFIG.CUSTOM_HTML_FOOTER
# -----------------------------------------------------
# -------------- Noms de Lycées
# -----------------------------------------------------
# Fichier de correspondance codelycee -> noms
# (chemin relatif au repertoire d'install des sources)
# CONFIG.ETABL_FILENAME = "config/etablissements.csv"
# ----------------------------------------------------
# -------------- Divers:
# ----------------------------------------------------
# True for UCAC (étudiants camerounais sans prénoms)
# CONFIG.ALLOW_NULL_PRENOM = False
# Taille max des fichiers archive etudiants (en octets)
# CONFIG.ETUD_MAX_FILE_SIZE = 10 * 1024 * 1024
# Si pas de photo et portail, publie l'url (était vrai jusqu'en oct 2016)
# CONFIG.PUBLISH_PORTAL_PHOTO_URL = False
# Si > 0: longueur minimale requise des nouveaux mots de passe
# (le test cracklib.FascistCheck s'appliquera dans tous les cas)
# CONFIG.MIN_PASSWORD_LENGTH = 0
# Ce dictionnaire est fusionné à celui de sco_codes_parcours
# pour définir les codes jury et explications associées
# CONFIG.CODES_EXPL = {
# # AJ : 'Ajourné (échec)',
# }

View File

@ -4,7 +4,7 @@
# ScoDoc: reglage du mot de passe admin Zope
# (in Zope terminology, an emergency user)
#
# Doit être lancé par l'utilisateur unix root dans le repertoire .../config
# Doit <EFBFBD>tre lanc<6E> par l'utilisateur unix root dans le repertoire .../config
# ^^^^^^^^^^^^^^^^^^^^^
# E. Viennet, Juin 2008, Jul 2019
#
@ -22,14 +22,14 @@ fi
echo "Creation d'un utilisateur d'urgence pour ScoDoc"
echo "(utile en cas de perte de votre mot de passe admin)"
if [ ${debian_version} != "10" ]
if [ "${debian_version}" != "10" ]
then
mdir=/opt/zope213/lib/python2.7/site-packages/Zope2-2.13.21-py2.7.egg/Zope2/utilities
else
mdir=/opt/zope213/lib/python2.7/site-packages/Zope2/utilities
fi
python $mdir/zpasswd.py $SCODOC_DIR/../../access
python $mdir/zpasswd.py "$SCODOC_DIR"/../../access
echo
echo "redemarrer scodoc pour prendre en compte le mot de passe"

View File

@ -1,20 +1,20 @@
#!/bin/bash
# Upgrade ScoDoc installation using SVN
# SVN must be properly configured and have read access to ScoDoc repository
# Upgrade ScoDoc installation using GIT
# GIT must be properly configured and have read access to ScoDoc repository
# This script STOP and RESTART ScoDoc and should be runned as root
#
# Upgrade also the Linux system using apt.
#
# Script for ScoDoc 7 (Debian 7, 8, 9, 10)
# Script for ScoDoc 8 (10)
#
# E. Viennet, sep 2013, mar 2017, jun 2019, aug 2020
# E. Viennet, sep 2013, mar 2017, jun 2019, aug 2020, dec 2020
cd /opt/scodoc/Products/ScoDoc/config
cd /opt/scodoc/Products/ScoDoc/config || { echo "Invalid directory"; exit 1; }
source config.sh
source utils.sh
check_uid_root $0
check_uid_root "$0"
if [ -z "$SCODOC_UPGRADE_RUNNING" ]
then
@ -31,8 +31,8 @@ fi
scodocctl stop
echo
echo "Using SVN to update $SCODOC_DIR..."
(cd "$SCODOC_DIR"; svn update)
echo "Using git to update $SCODOC_DIR..."
(cd "$SCODOC_DIR"; git checkout ScoDoc8; git pull origin master)
SVNVERSION=$(cd ..; svnversion)
@ -72,13 +72,13 @@ fi
# Check that no Zope "access" file has been forgotten in the way:
if [ -e $SCODOC_DIR/../../access ]
if [ -e "$SCODOC_DIR"/../../access ]
then
mv $SCODOC_DIR/../../access $SCODOC_DIR/../../access.bak
mv "$SCODOC_DIR"/../../access "$SCODOC_DIR"/../../access.bak
fi
# Fix some permissions which may have been altered in the way:
chsh -s /bin/sh $POSTGRES_USER # www-data, nologin in Debian 9
chsh -s /bin/sh "$POSTGRES_USER" # www-data, nologin in Debian 9
chown root.www-data "$SCODOC_DIR" # important to create .pyc
chmod 775 "${SCODOC_DIR}"
chmod a+r "$SCODOC_DIR"/*.py
@ -118,6 +118,19 @@ if [ $? -ne 0 ]
then
/opt/zope213/bin/pip install requests
fi
/opt/zope213/bin/python -c "import attrdict" >& /dev/null
if [ $? -ne 0 ]
then
/opt/zope213/bin/pip install attrdict
fi
# Check that local configuration file is installed
LOCAL_CONFIG_FILENAME="/opt/scodoc/var/scodoc/config/scodoc_local.py"
if [ ! -e "$LOCAL_CONFIG_FILENAME" ]
then
cp "$SCODOC_DIR"/config/scodoc_config_tmpl.py "$LOCAL_CONFIG_FILENAME"
chmod 600 "$LOCAL_CONFIG_FILENAME"
fi
# Ensure www-data can duplicate databases (for dumps)
su -c $'psql -c \'alter role "www-data" with CREATEDB;\'' "$POSTGRES_SUPERUSER"
@ -128,7 +141,7 @@ echo "Executing post-upgrade script..."
"$SCODOC_DIR"/config/postupgrade.py
echo "Executing post-upgrade database script..."
su -c "$SCODOC_DIR/config/postupgrade-db.py" $POSTGRES_USER
su -c "$SCODOC_DIR/config/postupgrade-db.py" "$POSTGRES_USER"
#
echo

View File

@ -1,17 +1,17 @@
#!/bin/bash
# Misc utilities for ScoDoc install shell scripts
to_lower() {
echo $1 | tr "[:upper:]" "[:lower:]"
echo "$1" | tr "[:upper:]" "[:lower:]"
}
to_upper() {
echo $1 | tr "[:lower:]" "[:upper:]"
echo "$1" | tr "[:lower:]" "[:upper:]"
}
norm_ans() {
x=$(to_upper $1 | tr O Y)
echo ${x:0:1}
x=$(to_upper "$1" | tr O Y)
echo "${x:0:1}"
}
check_uid_root() {
@ -23,10 +23,11 @@ check_uid_root() {
}
terminate() {
status=${2:-1} # default: exit 1
echo
echo "Erreur: $1"
echo
exit 1
exit $status
}
# Start/stop scodoc, using sysv or systemd
@ -44,7 +45,7 @@ scodocctl() {
systemctl $1 scodoc
else
echo "(using legacy SystemV)"
/etc/init.d/scodoc $1
/etc/init.d/scodoc "$1"
fi
}
@ -54,7 +55,7 @@ init_postgres_user() { # run as root
then
# add database user
echo "Creating postgresql user $POSTGRES_USER"
su -c "createuser -p $POSTGRES_PORT --no-superuser --no-createdb --no-adduser --no-createrole ${POSTGRES_USER}" $POSTGRES_SUPERUSER
su -c "createuser -p $POSTGRES_PORT --no-superuser --no-createdb --no-adduser --no-createrole ${POSTGRES_USER}" "$POSTGRES_SUPERUSER"
fi
}
@ -69,8 +70,8 @@ gen_passwd() {
password=""
while [ "$n" -le "$PASSWORD_LENGTH" ]
do
password="$password${ALLOWABLE_ASCII:$(($RANDOM%${#ALLOWABLE_ASCII})):1}"
n=$((n+1))
password="$password${ALLOWABLE_ASCII:$((RANDOM%${#ALLOWABLE_ASCII})):1}"
n=$((n+1))
done
echo $password
echo "$password"
}

View File

@ -2,10 +2,11 @@
# -*- coding: utf-8 -*-
import pdb, os, sys, time, re, inspect
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.Header import Header
import traceback
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.header import Header
# Simple & stupid file logguer, used only to debug
# (logging to SQL is done in scolog)
@ -88,7 +89,7 @@ def retreive_dept():
return ""
try:
url = REQUEST.URL
m = re.match("^.*ScoDoc/(\w+).*$", url)
m = re.match(r"^.*ScoDoc/(\w+).*$", url)
return m.group(1)
except:
return ""

View File

@ -50,7 +50,7 @@ DONNEE_MANQUANTE = (
# ----------------------------------------------------------------------------------------
def get_code_latex_from_modele(fichier):
"""Lit le code latex à partir d'un modèle. Renvoie une chaine unicode.
Le fichier doit contenir le chemin relatif
vers le modele : attention pas de vérification du format d'encodage
Le fichier doit donc etre enregistré avec le même codage que ScoDoc (utf-8)
@ -85,7 +85,7 @@ def get_tags_latex(code_latex):
à la lecture d'un modèle d'avis pe).
Ces tags sont répérés par les balises **, débutant et finissant le tag
et sont renvoyés sous la forme d'une liste.
result: liste de chaines unicode
"""
if code_latex:
@ -144,7 +144,7 @@ def comp_latex_parcourstimeline(etudiant, promo, taille=17):
# ----------------------------------------------------------------------------------------
def interprete_tag_latex(tag):
"""Découpe les tags latex de la forme S1:groupe:dut:min et renvoie si possible
"""Découpe les tags latex de la forme S1:groupe:dut:min et renvoie si possible
le résultat sous la forme d'un quadruplet.
"""
infotag = tag.split(":")
@ -164,7 +164,7 @@ def get_code_latex_avis_etudiant(
donnees_etudiant, un_avis_latex, annotationPE, footer_latex, prefs
):
"""
Renvoie le code latex permettant de générer l'avis d'un étudiant en utilisant ses
Renvoie le code latex permettant de générer l'avis d'un étudiant en utilisant ses
donnees_etudiant contenu dans le dictionnaire de synthèse du jury PE et en suivant un
fichier modele donné
@ -228,8 +228,8 @@ def get_code_latex_avis_etudiant(
# ----------------------------------------------------------------------------------------
def get_annotation_PE(context, etudid, tag_annotation_pe):
"""Renvoie l'annotation PE dans la liste de ces annotations ;
Cette annotation est reconnue par la présence d'un tag **PE**
"""Renvoie l'annotation PE dans la liste de ces annotations ;
Cette annotation est reconnue par la présence d'un tag **PE**
(cf. context.get_preferences -> pe_tag_annotation_avis_latex).
Result: chaine unicode
@ -269,8 +269,8 @@ def get_annotation_PE(context, etudid, tag_annotation_pe):
# ----------------------------------------------------------------------------------------
def str_from_syntheseJury(donnees_etudiant, aggregat, groupe, tag_scodoc, champ):
"""Extrait du dictionnaire de synthèse du juryPE pour un étudiant donnée,
une valeur indiquée par un champ ;
"""Extrait du dictionnaire de synthèse du juryPE pour un étudiant donnée,
une valeur indiquée par un champ ;
si champ est une liste, renvoie la liste des valeurs extraites.
Result: chaine unicode ou liste de chaines unicode
@ -322,7 +322,7 @@ def str_from_syntheseJury(donnees_etudiant, aggregat, groupe, tag_scodoc, champ)
# ----------------------------------------------------------------------------------------
def get_bilanParTag(donnees_etudiant, groupe="groupe"):
"""Renvoie le code latex d'un tableau récapitulant, pour tous les tags trouvés dans
"""Renvoie le code latex d'un tableau récapitulant, pour tous les tags trouvés dans
les données étudiants, ses résultats.
result: chaine unicode
"""
@ -460,11 +460,11 @@ def get_templates_from_distrib(template="avis"):
if template in ["avis", "footer"]:
# pas de preference pour le template: utilise fichier du serveur
p = os.path.join(SCO_SRCDIR, pe_local_tmpl)
p = os.path.join(SCO_SRC_DIR, pe_local_tmpl)
if os.path.exists(p):
template_latex = get_code_latex_from_modele(p)
else:
p = os.path.join(SCO_SRCDIR, pe_default_tmpl)
p = os.path.join(SCO_SRC_DIR, pe_default_tmpl)
if os.path.exists(p):
template_latex = get_code_latex_from_modele(p)
else:
@ -474,8 +474,7 @@ def get_templates_from_distrib(template="avis"):
# ----------------------------------------------------------------------------------------
def table_syntheseAnnotationPE(context, syntheseJury, tag_annotation_pe):
"""Génère un fichier excel synthétisant les annotations PE telles qu'inscrites dans les fiches de chaque étudiant
"""
"""Génère un fichier excel synthétisant les annotations PE telles qu'inscrites dans les fiches de chaque étudiant"""
sT = SeqGenTable() # le fichier excel à générer
# Les etudids des étudiants à afficher, triés par ordre alphabétiques de nom+prénom

View File

@ -97,7 +97,7 @@ def print_semestres_description(sems, avec_affichage_debug=False):
# ----------------------------------------------------------------------------------------
def calcul_age(born):
"""Calcule l'age à partir de la date de naissance sous forme d'une chaine de caractère 'jj/mm/aaaa'.
"""Calcule l'age à partir de la date de naissance sous forme d'une chaine de caractère 'jj/mm/aaaa'.
Aucun test de validité sur le format de la date n'est fait.
"""
if not isinstance(born, str) or born == "":
@ -122,8 +122,7 @@ def remove_accents(input_unicode_str):
def escape_for_latex(s):
"""Protège les caractères pour inclusion dans du source LaTeX
"""
"""Protège les caractères pour inclusion dans du source LaTeX"""
if not s:
return ""
conv = {
@ -162,8 +161,7 @@ def list_directory_filenames(path):
def add_local_file_to_zip(zipfile, ziproot, pathname, path_in_zip):
"""Read pathname server file and add content to zip under path_in_zip
"""
"""Read pathname server file and add content to zip under path_in_zip"""
rooted_path_in_zip = os.path.join(ziproot, path_in_zip)
data = open(pathname).read()
zipfile.writestr(rooted_path_in_zip, data)
@ -177,7 +175,7 @@ def add_pe_stuff_to_zip(context, zipfile, ziproot):
Also copy logos
"""
PE_AUX_DIR = os.path.join(SCO_SRCDIR, "config/doc_poursuites_etudes")
PE_AUX_DIR = os.path.join(SCO_SRC_DIR, "config/doc_poursuites_etudes")
distrib_dir = os.path.join(PE_AUX_DIR, "distrib")
distrib_pathnames = list_directory_filenames(
distrib_dir

View File

@ -32,10 +32,9 @@
Il suffit d'appeler abs_notify() après chaque ajout d'absence.
"""
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.Header import Header
from email import Encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
from notesdb import *
from sco_utils import *
@ -47,7 +46,7 @@ import sco_formsemestre
def abs_notify(context, etudid, date):
"""Check if notifications are requested and send them
Considère le nombre d'absence dans le semestre courant
Considère le nombre d'absence dans le semestre courant
(s'il n'y a pas de semestre courant, ne fait rien,
car l'etudiant n'est pas inscrit au moment de l'absence!).
"""
@ -64,8 +63,7 @@ def abs_notify(context, etudid, date):
def do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust):
"""Given new counts of absences, check if notifications are requested and send them.
"""
"""Given new counts of absences, check if notifications are requested and send them."""
# prefs fallback to global pref if sem is None:
if sem:
formsemestre_id = sem["formsemestre_id"]
@ -131,8 +129,7 @@ def abs_notify_send(
def abs_notify_get_destinations(context, sem, prefs, etudid, date, nbabs, nbabsjust):
"""Returns set of destination emails to be notified
"""
"""Returns set of destination emails to be notified"""
formsemestre_id = sem["formsemestre_id"]
destinations = [] # list of email address to notify
@ -176,8 +173,8 @@ def abs_notify_is_above_threshold(context, etudid, nbabs, nbabsjust, formsemestr
nbabs: nombre d'absence (de tous types, unité de compte = demi-journée)
nbabsjust: nombre d'absences justifiées
(nbabs > abs_notify_abs_threshold)
(nbabs > abs_notify_abs_threshold)
(nbabs - nbabs_last_notified) > abs_notify_abs_increment
"""
abs_notify_abs_threshold = context.get_preference(
@ -282,8 +279,7 @@ def retreive_current_formsemestre(context, etudid, cur_date):
def mod_with_evals_at_date(context, date_abs, etudid):
"""Liste des moduleimpls avec des evaluations a la date indiquée
"""
"""Liste des moduleimpls avec des evaluations a la date indiquée"""
req = """SELECT m.* FROM notes_moduleimpl m, notes_evaluation e, notes_moduleimpl_inscription i
WHERE m.moduleimpl_id = e.moduleimpl_id AND e.moduleimpl_id = i.moduleimpl_id
AND i.etudid = %(etudid)s AND e.jour = %(date_abs)s"""

View File

@ -28,11 +28,11 @@
"""Génération des bulletins de notes
"""
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email.Header import Header
from email import Encoders
import email
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.header import Header
import htmlutils, time
from reportlab.lib.colors import Color
@ -331,7 +331,7 @@ def formsemestre_bulletinetud_dict(
context, ue_status["formsemestre_id"]
) # > toutes notes
u["modules_capitalized"], junk = _ue_mod_bulletin(
u["modules_capitalized"], _ = _ue_mod_bulletin(
context,
etudid,
formsemestre_id,
@ -990,7 +990,7 @@ def mail_bulletin(context, formsemestre_id, I, pdfdata, filename, recipient_addr
att = MIMEBase("application", "pdf")
att.add_header("Content-Disposition", "attachment", filename=filename)
att.set_payload(pdfdata)
Encoders.encode_base64(att)
email.encoders.encode_base64(att)
msg.attach(att)
log("mail bulletin a %s" % msg["To"])
context.sendEmail(msg)

View File

@ -116,7 +116,8 @@ CODES_EXPL = {
RAT: "En attente d'un rattrapage",
DEF: "Défaillant",
}
# Nota: ces explications sont personnalisables via le fichier de config scodoc_config.py
# Nota: ces explications sont personnalisables via le fichier
# de config locale /opt/scodoc/var/scodoc/config/scodoc_local.py
# variable: CONFIG.CODES_EXP
CODES_SEM_VALIDES = {ADM: True, ADC: True, ADJ: True} # semestre validé

109
sco_config.py Normal file
View File

@ -0,0 +1,109 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""Configuration de ScoDoc (version 2020)
NE PAS MODIFIER localement ce fichier !
mais éditer /opt/scodoc/var/scodoc/config/scodoc_local.py
"""
from attrdict import AttrDict
import bonus_sport
CONFIG = AttrDict()
# set to 1 if you want to require INE:
CONFIG.always_require_ine = 0
# The base URL, use only if you are behind a proxy
# eg "https://scodoc.example.net/ScoDoc"
CONFIG.ABSOLUTE_URL = ""
# -----------------------------------------------------
# -------------- Documents PDF
# -----------------------------------------------------
# Taille du l'image logo: largeur/hauteur (ne pas oublier le . !!!)
# W/H XXX provisoire: utilisera PIL pour connaitre la taille de l'image
CONFIG.LOGO_FOOTER_ASPECT = 326 / 96.0
# Taille dans le document en millimetres
CONFIG.LOGO_FOOTER_HEIGHT = 10
# Proportions logo (donné ici pour IUTV)
CONFIG.LOGO_HEADER_ASPECT = 549 / 346.0
# Taille verticale dans le document en millimetres
CONFIG.LOGO_HEADER_HEIGHT = 28
# Pied de page PDF : un format Python, %(xxx)s est remplacé par la variable xxx.
# Les variables définies sont:
# day : Day of the month as a decimal number [01,31]
# month : Month as a decimal number [01,12].
# year : Year without century as a decimal number [00,99].
# Year : Year with century as a decimal number.
# hour : Hour (24-hour clock) as a decimal number [00,23].
# minute: Minute as a decimal number [00,59].
#
# server_url: URL du serveur ScoDoc
# scodoc_name: le nom du logiciel (ScoDoc actuellement, voir VERSION.py)
CONFIG.DEFAULT_PDF_FOOTER_TEMPLATE = "Edité par %(scodoc_name)s le %(day)s/%(month)s/%(year)s à %(hour)sh%(minute)s sur %(server_url)s"
#
# ------------- Calcul bonus modules optionnels (sport, culture...) -------------
#
CONFIG.compute_bonus = bonus_sport.bonus_iutv
# Mettre "bonus_demo" pour logguer des informations utiles au developpement...
# ------------- Capitalisation des UEs -------------
# Deux écoles:
# - règle "DUT": capitalisation des UE obtenues avec moyenne UE >= 10 ET de toutes les UE
# des semestres validés (ADM, ADC, AJ). (conforme à l'arrêté d'août 2005)
#
# - règle "LMD": capitalisation uniquement des UE avec moy. > 10
# Si vrai, capitalise toutes les UE des semestres validés (règle "DUT").
# CONFIG.CAPITALIZE_ALL_UES = True
# -----------------------------------------------------
# -------------- Personnalisation des pages
# -----------------------------------------------------
# Nom (chemin complet) d'un fichier .html à inclure juste après le <body>
# le <body> des pages ScoDoc
CONFIG.CUSTOM_HTML_HEADER = ""
# Fichier html a inclure en fin des pages (juste avant le </body>)
CONFIG.CUSTOM_HTML_FOOTER = ""
# Fichier .html à inclure dans la pages connexion/déconnexion (accueil)
# si on veut que ce soit différent (par défaut la même chose)
CONFIG.CUSTOM_HTML_HEADER_CNX = CONFIG.CUSTOM_HTML_HEADER
CONFIG.CUSTOM_HTML_FOOTER_CNX = CONFIG.CUSTOM_HTML_FOOTER
# -----------------------------------------------------
# -------------- Noms de Lycées
# -----------------------------------------------------
# Fichier de correspondance codelycee -> noms
# (chemin relatif au repertoire d'install des sources)
CONFIG.ETABL_FILENAME = "config/etablissements.csv"
# ----------------------------------------------------
# -------------- Divers:
# ----------------------------------------------------
# True for UCAC (étudiants camerounais sans prénoms)
CONFIG.ALLOW_NULL_PRENOM = False
# Taille max des fichiers archive etudiants (en octets)
# CONFIG.ETUD_MAX_FILE_SIZE = 10 * 1024 * 1024
# Si pas de photo et portail, publie l'url (était vrai jusqu'en oct 2016)
CONFIG.PUBLISH_PORTAL_PHOTO_URL = False
# Si > 0: longueur minimale requise des nouveaux mots de passe
# (le test cracklib.FascistCheck s'appliquera dans tous les cas)
CONFIG.MIN_PASSWORD_LENGTH = 0
# Ce dictionnaire est fusionné à celui de sco_codes_parcours
# pour définir les codes jury et explications associées
CONFIG.CODES_EXPL = {
# AJ : 'Ajourné (échec)',
}

44
sco_config_load.py Normal file
View File

@ -0,0 +1,44 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""Chargement de la configuration locale
"""
import os
import sys
import sco_utils
from sco_utils import log, SCODOC_CFG_DIR
import sco_config
# scodoc_local defines a CONFIG object
# here we check if there is a local config file
def load_local_configuration():
"""Load local configuration file (if exists)
and merge it with CONFIG.
"""
# this path should be synced with upgrade.sh
LOCAL_CONFIG_FILENAME = os.path.join(SCODOC_CFG_DIR, "scodoc_local.py")
LOCAL_CONFIG = None
if os.path.exists(LOCAL_CONFIG_FILENAME):
if not SCODOC_CFG_DIR in sys.path:
sys.path.insert(1, SCODOC_CFG_DIR)
try:
from scodoc_local import CONFIG as LOCAL_CONFIG
log("imported %s" % LOCAL_CONFIG_FILENAME)
except ImportError:
log("Error: can't import %s" % LOCAL_CONFIG_FILENAME)
del sys.path[1]
if LOCAL_CONFIG is None:
return
# Now merges local config in our CONFIG
for x in [x for x in dir(LOCAL_CONFIG) if x[0] != "_"]:
v = getattr(LOCAL_CONFIG, x)
if not v in sco_config.CONFIG:
log("Warning: local config setting unused parameter %s (skipped)" % x)
else:
if v != sco_config.CONFIG[x]:
log("Setting parameter %s from %s" % (x, LOCAL_CONFIG_FILENAME))
sco_config.CONFIG[x] = v

View File

@ -50,13 +50,13 @@ pg_dump SCORT | psql ANORT
import fcntl
import subprocess
import requests
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email.Header import Header
from email import Encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.header import Header
from notesdb import *
import sco_utils
from sco_utils import *
from notes_log import log
@ -64,8 +64,7 @@ SCO_DUMP_LOCK = "/tmp/scodump.lock"
def sco_dump_and_send_db(context, REQUEST=None):
"""Dump base de données du département courant et l'envoie anonymisée pour debug
"""
"""Dump base de données du département courant et l'envoie anonymisée pour debug"""
H = [context.sco_header(REQUEST, page_title="Assistance technique")]
# get currect (dept) DB name:
cursor = SimpleQuery(context, "SELECT current_database()", {})
@ -150,9 +149,8 @@ def _duplicate_db(db_name, ano_db_name):
def _anonymize_db(ano_db_name):
"""Anonymize a departement database
"""
cmd = os.path.join(SCO_CONFIG_DIR, "anonymize_db.py")
"""Anonymize a departement database"""
cmd = os.path.join(SCO_TOOLS_DIR, "anonymize_db.py")
log("_anonymize_db: {}".format(cmd))
try:
out = subprocess.check_output([cmd, ano_db_name])
@ -171,8 +169,7 @@ def _get_scodoc_serial(context):
def _send_db(context, REQUEST, ano_db_name):
"""Dump this (anonymized) database and send it to tech support
"""
"""Dump this (anonymized) database and send it to tech support"""
log("dumping anonymized database {}".format(ano_db_name))
try:
data = subprocess.check_output("pg_dump {} | gzip".format(ano_db_name), shell=1)
@ -195,7 +192,7 @@ def _send_db(context, REQUEST, ano_db_name):
"nomcomplet"
],
"sco_version": SCOVERSION,
"sco_subversion": get_svn_version(SCO_CONFIG_DIR),
"sco_fullversion": sco_utils.get_scodoc_version(),
},
)
return r

View File

@ -39,8 +39,7 @@ TITLES = ("user_name", "nom", "prenom", "email", "roles", "dept")
def generate_excel_sample():
"""generates an excel document suitable to import users
"""
"""generates an excel document suitable to import users"""
style = sco_excel.Excel_MakeStyle(bold=True)
titles = TITLES
titlesStyles = [style] * len(titles)
@ -105,7 +104,7 @@ def import_users(U, auth_dept="", context=None):
- créer utilisateur et mettre le mot de passe
- envoyer mot de passe par mail
En cas d'erreur: supprimer tous les utilisateurs que l'on vient de créer.
En cas d'erreur: supprimer tous les utilisateurs que l'on vient de créer.
"""
created = [] # liste de uid créés
try:
@ -164,11 +163,11 @@ def generate_password():
return "".join(RNG.sample(l, PASSLEN))
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email.Header import Header
from email import Encoders
import email
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.header import Header
def mail_password(u, context=None, reset=False):

View File

@ -33,11 +33,9 @@ from cStringIO import StringIO
import datetime, re
import time
from stripogram import html2text, html2safehtml
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.Header import Header
from email import Encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
from notesdb import *
from notes_log import log
@ -252,8 +250,7 @@ def scolar_news_summary_rss(context, title, sco_url, n=5):
def _send_news_by_mail(context, n):
"""Notify by email
"""
"""Notify by email"""
infos = _get_formsemestre_infos_from_news(context, n)
formsemestre_id = infos.get("formsemestre_id", None)
prefs = context.get_preferences(formsemestre_id=formsemestre_id)

View File

@ -53,7 +53,7 @@ from PIL import Image as PILImage
from cStringIO import StringIO
import glob
from sco_utils import CONFIG, SCO_SRCDIR
from sco_utils import CONFIG, SCO_SRC_DIR
from notes_log import log
import scolars
@ -62,7 +62,7 @@ from scolog import logdb
# Full paths on server's filesystem. Something like "/opt/scodoc/var/scodoc/photos"
PHOTO_DIR = os.path.join(os.environ["INSTANCE_HOME"], "var", "scodoc", "photos")
ICONS_DIR = os.path.join(SCO_SRCDIR, "static", "icons")
ICONS_DIR = os.path.join(SCO_SRC_DIR, "static", "icons")
UNKNOWN_IMAGE_PATH = os.path.join(ICONS_DIR, "unknown.jpg")
UNKNOWN_IMAGE_URL = "get_photo_image?etudid=" # with empty etudid => unknown face image
IMAGE_EXT = ".jpg"

View File

@ -37,9 +37,9 @@ import datetime
import sco_utils
from sco_utils import ScoEtudInscrit, log, ScoValueError, DictDefault
from sco_utils import SCO_TMPDIR, SCO_ENCODING
from sco_utils import SCO_TMP_DIR, SCO_ENCODING
SCO_CACHE_ETAPE_FILENAME = os.path.join(SCO_TMPDIR, "last_etapes.xml")
SCO_CACHE_ETAPE_FILENAME = os.path.join(SCO_TMP_DIR, "last_etapes.xml")
def has_portal(context):

View File

@ -49,7 +49,7 @@ Chaque parametre est défini dans la base de données SQL par:
Au niveau du code interface, on défini pour chaque préférence:
- name (clé)
- title : titre en français
- initvalue : valeur initiale, chargée depuis config/scodoc_config.py
- initvalue : valeur initiale
- explanation: explication en français
- size: longueur du chap texte
- input_type: textarea,separator,... type de widget TrivialFormulator a utiliser
@ -90,13 +90,6 @@ sinon, elle ne concerne que le semestre indiqué.
- editer les preferences d'un semestre:
sem_preferences(context,formsemestre_id).edit()
* Valeurs par défaut:
On a deux valeurs par défaut possibles:
- via le fichier scodoc_config.py, qui peut être modifié localement.
- si rien dans scodoc_config.py, la valeur définie par
sco_preferences.py est utilisée (ne pas modifier ce fichier).
* Implémentation: sco_preferences.py
PREF_CATEGORIES : définition des catégories de préférences (pour

View File

@ -29,7 +29,7 @@
""" Verification version logiciel vs version "stable" sur serveur
N'effectue pas la mise à jour automatiquement, mais permet un affichage d'avertissement.
"""
import sco_utils
from sco_utils import *
# Appel renvoyant la subversion "stable"
@ -66,65 +66,66 @@ def is_up_to_date(context):
"""True if up_to_date
Returns status, message
"""
global _LAST_UP_TO_DATE_REQUEST, _UP_TO_DATE, _UP_TO_DATE_MSG
if _LAST_UP_TO_DATE_REQUEST and (
datetime.datetime.now() - _LAST_UP_TO_DATE_REQUEST
) < datetime.timedelta(1):
# requete deja effectuee aujourd'hui:
return _UP_TO_DATE, _UP_TO_DATE_MSG
log("Warning: is_up_to_date not implemented for ScoDoc8")
return True, "unimplemented"
# global _LAST_UP_TO_DATE_REQUEST, _UP_TO_DATE, _UP_TO_DATE_MSG
# if _LAST_UP_TO_DATE_REQUEST and (
# datetime.datetime.now() - _LAST_UP_TO_DATE_REQUEST
# ) < datetime.timedelta(1):
# # requete deja effectuee aujourd'hui:
# return _UP_TO_DATE, _UP_TO_DATE_MSG
last_stable_ver = get_last_stable_version()
cur_ver = get_svn_version(context.file_path) # in sco_utils
cur_ver2 = cur_ver
cur_ver_num = -1
# Convert versions to integers:
try:
# cur_ver can be "1234" or "1234M' or '1234:1245M'...
fs = cur_ver.split(":", 1)
if len(fs) > 1:
cur_ver2 = fs[-1]
m = re.match(r"([0-9]*)", cur_ver2)
if not m:
raise ValueError(
"invalid svn version"
) # should never occur, regexp always (maybe empty) match
cur_ver_num = int(m.group(1))
except:
log('Warning: no numeric subversion ! (cur_ver="%s")' % cur_ver)
return _UP_TO_DATE, _UP_TO_DATE_MSG # silently ignore misconfiguration ?
try:
last_stable_ver_num = int(last_stable_ver)
except:
log("Warning: last_stable_version returned by server is invalid !")
return (
_UP_TO_DATE,
_UP_TO_DATE_MSG,
) # should ignore this error (maybe server is unreachable)
#
if cur_ver_num < last_stable_ver_num:
_UP_TO_DATE = False
_UP_TO_DATE_MSG = "Version %s disponible (version %s installée)" % (
last_stable_ver,
cur_ver_num,
)
log(
"Warning: ScoDoc installation is not up-to-date, should upgrade\n%s"
% _UP_TO_DATE_MSG
)
else:
_UP_TO_DATE = True
_UP_TO_DATE_MSG = ""
log(
"ScoDoc is up-to-date (cur_ver: %s, using %s=%s)"
% (cur_ver, cur_ver2, cur_ver_num)
)
# last_stable_ver = get_last_stable_version()
# cur_ver = sco_utils.get_scodoc_version()
# cur_ver2 = cur_ver
# cur_ver_num = -1
# # Convert versions to integers:
# try:
# # cur_ver can be "1234" or "1234M' or '1234:1245M'...
# fs = cur_ver.split(":", 1)
# if len(fs) > 1:
# cur_ver2 = fs[-1]
# m = re.match(r"([0-9]*)", cur_ver2)
# if not m:
# raise ValueError(
# "invalid svn version"
# ) # should never occur, regexp always (maybe empty) match
# cur_ver_num = int(m.group(1))
# except:
# log('Warning: no numeric subversion ! (cur_ver="%s")' % cur_ver)
# return _UP_TO_DATE, _UP_TO_DATE_MSG # silently ignore misconfiguration ?
# try:
# last_stable_ver_num = int(last_stable_ver)
# except:
# log("Warning: last_stable_version returned by server is invalid !")
# return (
# _UP_TO_DATE,
# _UP_TO_DATE_MSG,
# ) # should ignore this error (maybe server is unreachable)
# #
# if cur_ver_num < last_stable_ver_num:
# _UP_TO_DATE = False
# _UP_TO_DATE_MSG = "Version %s disponible (version %s installée)" % (
# last_stable_ver,
# cur_ver_num,
# )
# log(
# "Warning: ScoDoc installation is not up-to-date, should upgrade\n%s"
# % _UP_TO_DATE_MSG
# )
# else:
# _UP_TO_DATE = True
# _UP_TO_DATE_MSG = ""
# log(
# "ScoDoc is up-to-date (cur_ver: %s, using %s=%s)"
# % (cur_ver, cur_ver2, cur_ver_num)
# )
return _UP_TO_DATE, _UP_TO_DATE_MSG
# return _UP_TO_DATE, _UP_TO_DATE_MSG
def html_up_to_date_box(context):
"""
"""
""""""
status, msg = is_up_to_date(context)
if status:
return ""

View File

@ -186,53 +186,84 @@ def get_mention(moy):
return NOTES_MENTIONS_LABS[bisect.bisect_right(NOTES_MENTIONS_TH, moy)]
class DictDefault(dict): # obsolete, use collections.defaultdict
"""A dictionnary with default value for all keys
Each time a non existent key is requested, it is added to the dict.
(used in python 2.4, can't use new __missing__ method)
"""
defaultvalue = 0
def __init__(self, defaultvalue=0, kv_dict={}):
dict.__init__(self)
self.defaultvalue = defaultvalue
self.update(kv_dict)
def __getitem__(self, k):
if self.has_key(k):
return self.get(k)
value = copy.copy(self.defaultvalue)
self[k] = value
return value
class WrapDict:
"""Wrap a dict so that getitem returns '' when values are None"""
def __init__(self, adict, NoneValue=""):
self.dict = adict
self.NoneValue = NoneValue
def __getitem__(self, key):
value = self.dict[key]
if value is None:
return self.NoneValue
else:
return value
def group_by_key(d, key):
g = DictDefault(defaultvalue=[])
for e in d:
g[e[key]].append(e)
return g
# ----- Global lock for critical sections (except notes_tables caches)
GSL = thread.allocate_lock() # Global ScoDoc Lock
if "INSTANCE_HOME" in os.environ:
# ----- Repertoire "var" (local)
SCODOC_VAR_DIR = os.path.join(os.environ["INSTANCE_HOME"], "var", "scodoc")
# ----- Repertoire "config" modifiable
# /opt/scodoc/var/scodoc/config
SCODOC_CFG_DIR = os.path.join(SCODOC_VAR_DIR, "config")
# ----- Version information
SCODOC_VERSION_DIR = os.path.join(SCODOC_VAR_DIR, "config", "version")
SCODOC_VERSION_DIR = os.path.join(SCODOC_CFG_DIR, "version")
# ----- Repertoire tmp
SCO_TMPDIR = os.path.join(SCODOC_VAR_DIR, "tmp")
if not os.path.exists(SCO_TMPDIR):
os.mkdir(SCO_TMPDIR, 0o755)
SCO_TMP_DIR = os.path.join(SCODOC_VAR_DIR, "tmp")
if not os.path.exists(SCO_TMP_DIR):
os.mkdir(SCO_TMP_DIR, 0o755)
# ----- Les logos: /opt/scodoc/var/scodoc/config/logos
SCODOC_LOGOS_DIR = os.path.join(SCODOC_VAR_DIR, "config", "logos")
SCODOC_LOGOS_DIR = os.path.join(SCODOC_CFG_DIR, "logos")
# ----- Repertoire "config" (devrait s'appeler "tools"...)
SCO_CONFIG_DIR = os.path.join(
os.environ["INSTANCE_HOME"], "Products", "ScoDoc", "config"
)
# Dans les sources:
SCO_SRC_DIR = os.path.join(os.environ["INSTANCE_HOME"], "Products", "ScoDoc")
# - Les outils distribués
SCO_TOOLS_DIR = os.path.join(SCO_SRC_DIR, "config")
# ----- Lecture du fichier de configuration
SCO_SRCDIR = os.path.split(VERSION.__file__)[0]
if SCO_SRCDIR:
SCO_SRCDIR += "/"
else:
SCO_SRCDIR = "/opt/scodoc/Products/ScoDoc/" # debug mode
CONFIG = None
try:
_config_filename = SCO_SRCDIR + "config/scodoc_config.py"
_config_text = open(_config_filename).read()
except:
sys.stderr.write("sco_utils: cannot open configuration file %s" % _config_filename)
raise
try:
exec(_config_text)
except:
sys.stderr.write("sco_utils: error in configuration file %s" % _config_filename)
raise
import sco_config
import sco_config_load
sco_config_load.load_local_configuration()
CONFIG = sco_config.CONFIG
if hasattr(CONFIG, "CODES_EXPL"):
CODES_EXPL.update(
CONFIG.CODES_EXPL
) # permet de customiser les explications de codes
if CONFIG.CUSTOM_HTML_HEADER:
CUSTOM_HTML_HEADER = open(CONFIG.CUSTOM_HTML_HEADER).read()
else:
@ -297,50 +328,6 @@ JSON_MIMETYPE = "application/json"
LOGOS_IMAGES_ALLOWED_TYPES = ("jpg", "png") # remind that PIL does not read pdf
class DictDefault(dict): # obsolete, use collections.defaultdict
"""A dictionnary with default value for all keys
Each time a non existent key is requested, it is added to the dict.
(used in python 2.4, can't use new __missing__ method)
"""
defaultvalue = 0
def __init__(self, defaultvalue=0, kv_dict={}):
dict.__init__(self)
self.defaultvalue = defaultvalue
self.update(kv_dict)
def __getitem__(self, k):
if self.has_key(k):
return self.get(k)
value = copy.copy(self.defaultvalue)
self[k] = value
return value
class WrapDict:
"""Wrap a dict so that getitem returns '' when values are None"""
def __init__(self, adict, NoneValue=""):
self.dict = adict
self.NoneValue = NoneValue
def __getitem__(self, key):
value = self.dict[key]
if value is None:
return self.NoneValue
else:
return value
def group_by_key(d, key):
g = DictDefault(defaultvalue=[])
for e in d:
g[e[key]].append(e)
return g
# Admissions des étudiants
# Différents types de voies d'admission:
# (stocké en texte libre dans la base, mais saisie par menus pour harmoniser)
@ -610,15 +597,9 @@ def sendResult(REQUEST, data, name=None, format=None, force_outer_xml_tag=True):
raise ValueError("invalid format: %s" % format)
# Get SVN version
def get_svn_version(path):
if os.path.exists("/usr/bin/svnversion"):
try:
return os.popen("svnversion " + path).read().strip()
except:
return "non disponible (erreur de lecture)"
else:
return "non disponible"
def get_scodoc_version():
"return a string identifying ScoDoc version"
return os.popen("cd %s; ./get_scodoc_version.sh -s" % SCO_TOOLS_DIR).read().strip()
# Simple string manipulations
@ -791,7 +772,7 @@ def icontag(name, file_format="png", **attrs):
"""
if ("width" not in attrs) or ("height" not in attrs):
if name not in ICONSIZES:
img_file = SCO_SRCDIR + "/static/icons/%s.%s" % (name, file_format)
img_file = SCO_SRC_DIR + "/static/icons/%s.%s" % (name, file_format)
im = PILImage.open(img_file)
width, height = im.size[0], im.size[1]
ICONSIZES[name] = (width, height) # cache

View File

@ -28,6 +28,8 @@
"""Imports et configuration des composants Zope
"""
# Allows code linting on platforms without Zope:
# pylint: disable=import-error
from OFS.SimpleItem import Item # Basic zope object
from OFS.PropertyManager import PropertyManager # provide the 'Properties' tab with the

View File

@ -42,11 +42,10 @@ import locale
locale.setlocale(locale.LC_ALL, ("en_US", SCO_ENCODING))
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email.Header import Header
from email import Encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
from email.mime.base import MIMEBase
abbrvmonthsnames = [
"Jan ",
@ -713,7 +712,7 @@ appreciations_edit = _appreciationsEditor.edit
# -------- Noms des Lycées à partir du code
def read_etablissements():
filename = SCO_SRCDIR + "/" + CONFIG.ETABL_FILENAME
filename = SCO_SRC_DIR + "/" + CONFIG.ETABL_FILENAME
log("reading %s" % filename)
f = open(filename)
L = [x[:-1].split(";") for x in f]