Archiv der Kategorie: Moodle

WebUntis Scraper

Der Stundeplanrechner wirft die WebUntis HTML Dateien in ein WebDAVs Share. Dieses ist auf dem Moodle Server per Symlink in das Arbeitsverzeichnis des folgenden untisparser Skriptes eingebunden. Von dort wird das Ergebnis in ein File Repository des Lehrermoodles geschrieben und aus dem Kursraum „Schwarzes Brett“ (die Kommunikationsplattform der Schule) verlinkt. Das stellt sicher, dass nur Menschen, die a) am Moodle angemeldet und b) Mitglied des entsprechenden Kursraumes sind den Inhalt (hier: Vertretungsplan) einsehen können.

Mit geschlossenem Accordion

Accordion offen

Das muss leider so umständlich sein, weil ich keinen Weg gefunden habe, den WebDavs Ordner als solchen navigierbar im Kursraum so einzubinden, dass man diesen nicht auch von außerhalb des Moodles aufrufen könnte. Mir bleibt (sofern ich richtig liege) nix anderes über, als aus den X html Dateien, die WebUntis mir hinwirft, eine einzige zu bauen, die ich klar benamen und dann „verlinken“ kann. Dazu muss ich die vielen WebUntis HTML Dateien in ihre Bestandteile zerlegen. Ich brauche: Die Tabellen und die Zeitangaben.

Im Prinzip geht das mit beautifulsoup und Python. Meine Python-Kenntnisse sind jedoch leider noch rudimentärer als meine Bash-Kenntnisse … also muss  ein bash Skript her. Und HTML mit Bash nativ parsen  – nun: ich weiß, dass das Probleme macht. Das will man nicht.

Die Lösung ist pup, das ich in ein Bash-Skript einbinde.

Zur Information die Struktur der WebUntis Dateien in ihren Ordnern / Unterordnern:

Die zu erzeugende Output-Datei soll HTML sein und braucht dazu einen Kopf:

<html>
<head>
<title>Vertretungsplan</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0">
<meta http-equiv="pragma" content="no-cache" />

<meta http-equiv="refresh" content="120" />
<style type="text/css">
body { margin-top: 20px; margin-left: 20px; margin-right: 20px;
background: #fff; color: #272727; font: 80% Arial, Helvetica, sans-serif; }
h1 { color: #ee7f00; font-size: 200%; font-weight: bold;}
h2 { color: #ee7f00; font-size: 175%;}
h1, h2 { margin: 0; padding: 25px 0px 5px 0px;}

 /* put your css here or copy from untishtml */
 
 /* Style the buttons that are used to open and close the accordion panel */
.accordion {
    background-color: #eee;
    color: #444;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    text-align: left;
    border: none;
    outline: none;
    transition: 0.4s;
}

/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
.active, .accordion:hover {
    background-color: #ccc;
}

/* Style the accordion panel. Note: hidden by default */
.panel {
    padding: 0 18px;
    background-color: white;
    display: none;
    overflow: hidden;
} 


</style>
</head>
<body>

<script>
  window.onload=function(){
    var acc = document.getElementsByClassName("accordion");
    for (var i = 0; i < acc.length; i++) {
      acc[i].addEventListener("click", function() {
          this.classList.toggle("active");
          var panel = this.nextElementSibling;
          if (panel.style.display === "block") {
              panel.style.display = "none";
          } else {
              panel.style.display = "block";
          }
      });
    }
  };
</script>

<h1>KvFG Vertretungsplan nach Datum und Anzeigetafel</h1>
<p><strong>Es gilt der Plan auf den Anzeigetafeln im Haus bzw. auf den Aush&auml;ngen. Diese Datei ist immer nur Beta!</strong></p>

Siehe zum Code für das Accordion im Kopf und im „Kleister“: https://www.w3schools.com/howto/howto_js_accordion.asp  Leider hat das aber nicht gereicht. Zuerst muss gewartet werden, bis die gesamte Seite geladen ist, dann erst darf die for-Schleife beginnen. Also wird das Skript in den Footer gelegt oder gekapselt in:

window.onload=function(){
... }
/* thanx Janis for debugging */

Was einen Kopf hat, braucht auch einen Fuß:

<p></p>
<p>----</p>
<p>(C) dowel 2018 | UntisParser Version 0.1</p>
<p>Fehler sind immer m&oumlglich und sollten <a href="https://yourschoolsbugtracker.tld" target="_blank">im Bugtracker gemeldet werden</a>, damit diese behoben werden k&ouml;nnen. Wer keinen Bugreport (= Bericht) formulieren kann, muss schweigen.</p>
</body>
</html>

Und dann braucht es den „Kleister“, der die Arbeit macht und alles zusammenpackt. Nennen wir es untisparser.sh und legen es in das passende Verzeichnis auf dem Server:

#!/bin/bash
# UntisParser
# 
# Parse HTML Export Files created by WebUntis
# do "e pluribus unum" with a Bash script
# throw the output into a Moodle file repository
# and link the output from inside a Moodle Courseroom
# 
# You need the pup executable from https://github.com/ericchiang/pup
# 
# (C) dowel
# License: CC BY SA https://creativecommons.org/licenses/by-sa/4.0/deed.de
# Date: 2018-08-23
# Version 0.2
# ####

# def of some base vars
RUNT=$(date '+%Y-%m-%d %H:%M:%S')
RUNF="20 Minuten" # set this in cronjob
RELOAD="120 Sekunden" # see head_filename
WORKDIR="/path/untisparser"
PUPPATH="/path/bin"
HEAD_FILENAME="kopf.html" # asumed to be in workdir
FOOT_FILENAME="fuss.html" # asumed to be in workdir
OUTPUT_PATH="/path/moodledata/repository/anzeigebretter" # set this to your Moodle file repository
OUTPUT_FILENAME="output.html"

# headline def
LUL1H="Anzeige Lehrer/innen Teil 1 Linke Seite (Heute?)"
LUL2H="Anzeige Lehrer/innen Teil 2 Rechte Seite (Morgen?)"
SUS1H="Anzeige Sch&uuml;ler/innen Teil 1 Linke Seite (Heute?)"
SUS2H="Anzeige Sch&uuml;ler/innen Teil 2 Rechte Seite (Morgen?)"


# path stuff
# Where are the Untis files in the workdir?
L_SUBDIR="$WORKDIR/Lehrerbrett"
S_SUBDIR="$WORKDIR/Schuelerbrett"

# How many of the suckers are there?
COUNT_LF1=$(/usr/bin/find $L_SUBDIR/f1 -maxdepth 1 -name '*.htm' | /usr/bin/wc -l)
COUNT_LF2=$(/usr/bin/find $L_SUBDIR/f2 -maxdepth 1 -name '*.htm' | /usr/bin/wc -l)
COUNT_SF1=$(/usr/bin/find $S_SUBDIR/f1 -maxdepth 1 -name '*.htm' | /usr/bin/wc -l)
COUNT_SF2=$(/usr/bin/find $S_SUBDIR/f2 -maxdepth 1 -name '*.htm' | /usr/bin/wc -l)

# Warning jabber because we do not know how many old files there are
# and if cleaner.script has worked the way it should have
# we asume that it failed
WARNMESS="<p>
    --------------------------------------------------------------------------------------<br>
    Stand: $RUNT | Beachte: Das Skript l&auml;uft nur alle $RUNF und die Seite wird nach $RELOAD neu geladen!<br>
    Achte auf das Datum. Es kann sein, dass ab hier alte Dateien ausgelesen werden. Wenn das so ist, dann den Rest ignorieren.</br>
    <a href=\"#top\">Ganz nach oben</a> || LuL: <a href=\"#lul1\">Links</a> | <a href=\"#lul2\">Rechts</a> || SuS <a href=\"#sus1\">Links</a> | <a href=\"#sus2\">Rechts</a>
    </p>"

# create empty output file and fill it with html head and some simple navigation stuff
/bin/cat $WORKDIR/$HEAD_FILENAME > $OUTPUT_PATH/$OUTPUT_FILENAME
/bin/echo "<id=\"top\">" >> $OUTPUT_PATH/$OUTPUT_FILENAME
/bin/echo "<p><em>Links</em> ist meist <em>Heute</em> und <em>Rechts</em> ist meist <em>Morgen</em> - aber nicht immer.</p>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
/bin/echo "<p>Anzeige Lehrer/innen: <a href=\"#lul1\">Links</a> | <a href=\"#lul2\">Rechts</a></p>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
/bin/echo "<p>Anzeige Sch&uuml;ler/innen: <a href=\"#sus1\">Links</a> | <a href=\"#sus2\">Rechts</a></p>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
/bin/echo "<p>Stand: $RUNT | Beachte: Das Skript l&auml;uft nur alle $RUNF!</p>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
/bin/echo "<p></p>">> $OUTPUT_PATH/$OUTPUT_FILENAME

# ticker export
if [ -f $L_SUBDIR/ticker.htm ]
then
    /bin/echo "<h4>L Ticker</h4>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    $PUPPATH/pup --charset iso-8859-1 -f $L_SUBDIR/ticker.htm 'marquee text{}' >> $OUTPUT_PATH/$OUTPUT_FILENAME
fi

if [ -f $S_SUBDIR/ticker.htm ]
then
    /bin/echo "<h4>S Ticker</h4>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    $PUPPATH/pup --charset iso-8859-1 -f $S_SUBDIR/ticker.htm 'marquee text{}' >> $OUTPUT_PATH/$OUTPUT_FILENAME
fi

# Create teacher part of output file

/bin/echo "<h2 id=\"lul1\">$LUL1H</h2>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
COUNT=1
MAXCOUNT=1
let MAXCOUNT=COUNT_LF1+1

# teacher links
while [ $COUNT -lt $MAXCOUNT ] ; do
    # padding
    NUM=$(printf %03d $COUNT)
    # Date extract to button
    /bin/echo "<button class=\"accordion\">" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    $PUPPATH/pup --charset iso-8859-1 -f $L_SUBDIR/f1/subst_$NUM.htm 'div.mon_title' >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "</button>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "<div class=\"panel\">" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Headline is set to H4
    /bin/echo "<h4>Lehrer/innen</h4>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "<p></p>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Table extraction
    $PUPPATH/pup --charset iso-8859-1 -f $L_SUBDIR/f1/subst_$NUM.htm 'table' >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "</div>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Warning 
    /bin/echo $WARNMESS >> $OUTPUT_PATH/$OUTPUT_FILENAME
    let COUNT=COUNT+1
done

# Reset for second part of LuL 

/bin/echo "<h2 id=\"lul2\">$LUL2H</h2>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
COUNT=1
MAXCOUNT=1
let MAXCOUNT=COUNT_LF2+1

# teacher rechts
while [ $COUNT -lt $MAXCOUNT ] ; do
    # padding
    NUM=$(printf %03d $COUNT)
    # Date extract to button
    /bin/echo "<button class=\"accordion\">" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    $PUPPATH/pup --charset iso-8859-1 -f $L_SUBDIR/f2/subst_$NUM.htm 'div.mon_title' >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "</button>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "<div class=\"panel\">" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Headline is set to H4
    /bin/echo "<h4>Lehrer/innen</h4>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "<p></p>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Table extraction
    $PUPPATH/pup --charset iso-8859-1 -f $L_SUBDIR/f2/subst_$NUM.htm 'table' >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "</div>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Warning
    /bin/echo $WARNMESS >> $OUTPUT_PATH/$OUTPUT_FILENAME
    let COUNT=COUNT+1
done

# Create pupil part of output file
/bin/echo "<h2 id=\"sus1\">$SUS1H</H2>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
COUNT=1
MAXCOUNT=1
let MAXCOUNT=COUNT_SF1+1


# pupil links
while [ $COUNT -lt $MAXCOUNT ] ; do
    # padding
    NUM=$(printf %03d $COUNT)
    # Date extract to button
    /bin/echo "<button class=\"accordion\">" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    $PUPPATH/pup --charset iso-8859-1 -f $S_SUBDIR/f1/subst_$NUM.htm 'div.mon_title' >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "</button>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "<div class=\"panel\">" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Headline is set to H4
    /bin/echo "<h4>Sch&uuml;ler/innen</h4>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "<p></p>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Table extraction
    $PUPPATH/pup --charset iso-8859-1 -f $S_SUBDIR/f1/subst_$NUM.htm 'table' >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "</div>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Warning
    /bin/echo $WARNMESS >> $OUTPUT_PATH/$OUTPUT_FILENAME
    let COUNT=COUNT+1
done

# Reset for second part of SuS 

/bin/echo "<h2 id=\"sus2\">$SUS2H</h2>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
COUNT=1
MAXCOUNT=1
let MAXCOUNT=COUNT_SF2+1

# pupil rechts
while [ $COUNT -lt $MAXCOUNT ] ; do
    # padding
    NUM=$(printf %03d $COUNT)
    # Date extract to button
    /bin/echo "<button class=\"accordion\">" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    $PUPPATH/pup --charset iso-8859-1 -f $S_SUBDIR/f2/subst_$NUM.htm 'div.mon_title' >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "</button>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "<div class=\"panel\">" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Headline is set to H3
    /bin/echo "<h4>Sch&uuml;ler/innen</h4>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "<p></p>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Table extraction
    $PUPPATH/pup --charset iso-8859-1 -f $S_SUBDIR/f2/subst_$NUM.htm 'table' >> $OUTPUT_PATH/$OUTPUT_FILENAME
    /bin/echo "</div>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
    # Warning
    /bin/echo $WARNMESS >> $OUTPUT_PATH/$OUTPUT_FILENAME
    let COUNT=COUNT+1
done

# create footer
/bin/echo "<p></p>" >> $OUTPUT_PATH/$OUTPUT_FILENAME
/bin/cat $WORKDIR/$FOOT_FILENAME >> $OUTPUT_PATH/$OUTPUT_FILENAME

# cleanup
/bin/chown www-data.www-data $OUTPUT_PATH/$OUTPUT_FILENAME
/bin/chmod 2750 $OUTPUT_PATH/$OUTPUT_FILENAME
# and we are done
exit 0

Cron ruft das Skript alle 20 Minuten auf. Schöner wäre natürlich, wenn das Skript nur liefe, wenn sich was ändert im WebDavs Share. Aber inotify und Freunde sind auch nicht ohne. So ist es simpel und scheint zu funktionieren, ohne viel Ressourcen zu fressen.

Update 23.08

Einige Fehler im Skript (meist die vergessenenen \ vor den „) behoben und mit Hilfe von JavaScript mehr Übersichtlichkeit im Output erzeugt.

Moodle 2.9.x Teil I

Moodle 2.9.x braucht als DB-Engine zwingend InnoDB und läuft nicht mehr mit MyISAM. Im Verlauf des Updates meldet sich deswegen Moodle mit der Meldung

unsupported_db_storage_engine

Erster Schritt ist die Kontrolle, ob die eigene mySQL DB InnoDB überhaupt unterstützt. Hierzu z.B. in phpmyadmin anmelden und dort auf dem Reiter SQL

SHOW ENGINES

absetzen [1]. Meist zeigt die Ausgabe das hier:

showengines

und alles ist gut. Wenn nicht, dann hat man richtig Arbeit an der Backe und muss zuerst die MySQL Installation auf Vordermann bringen.

Dann im Backend von Moodle (als Administrator) die URL wie folgt anpassen:

https://www.meinmoodle.tld/admin/tool/innodb/index.php

und der Migrationsprozess rattert los. Das kann dauern. Lange.

Moodle schimpft dann evtl. über Tabellen im Antelope Format, statt des gewünschten Barracuda:

unsupported_db_table_row_format

Hier ist man nun auf die Shell gezwungen, wenn ich das richtig sehe. DB-Experten mögen mich korrigieren.

Erst einmal nachschauen, welche Tabellen überhaupt bearbeitet werden müssen. Das geht mit einem Script, das Moodle mitbringt und das über dem Moodle-Stammverzeichnis ausgeführt werden muss:

sudo -u www-data /usr/bin/php moodle/admin/cli/mysql_compressed_rows.php --list

Bei mir ergab das

mdl_data                        Compact     (needs fixing)
mdl_data_fields                 Compact     (needs fixing)
mdl_enrol_paypal                Compact     (needs fixing)
mdl_lti                         Compact     (needs fixing)
mdl_user                        Compact     (needs fixing)
mdl_user_info_field             Compact     (needs fixing)

was sich mit Hilfe des oben genannten Scripts durch den Schalter –fix jedoch nicht reparieren lässt, weil man hierzu mehr Rechte innerhalb der MySQL-DB benötigt, als bei mir hier der Apache hat.

Moodle selbst läuft auch unter Version 2.9.x noch mit Antelope – das Upgrade kann also stattfinden. Da ich die Nebenwirkungen von Barracuda schlecht abschätzen kann, wenn ich mit der DB-Kompression spiele (da hängen auch noch WordPresse und Typos mit dran), bespreche ich mich mal lieber zuerst mit Frank. Mal sehen, was der meint – und dann geht es weiter.

 

 

Atto, TinyMCE und Moodle 2.7.x

Mit der Schule bin ich gestern erst auf die Moodle 2.7.2er Reihe von 2.6.5 aus umgestiegen. Da etwas länger zu warten bringt am Ende weniger Bugs und Ärger. Abgesehen von einer Anpassung der Aufgabenformate ist mir aufgefallen, dass nun Atto als Default-Editor keinen Schalter für Emoticons mehr zeigte. Dieser lässt sich aber nachrüsten:

atto1

Unter /Plugins /Texteditoren /Texteditor Atto /Einstellungen findet man eine Liste der Editorenfunktionen und darunter ein Feld, in das man seine Ergänzungen eintragen kann oder über das man die Reihenfolge der Knöpfe verändert.

atto2

Ein emoticon = emoticon fügt Atto den wichtigsten Knopf im System wieder hinzu.

editoreninmoodle

Will man lieber gleich zum mächtigeren TinyMCE wechseln, dann schiebt man diesen unter /Texteditoren /Übersicht über Atto.

tinymce

Da ist dann der Emoticon-Schalter gleich wieder mit dabei.

Nebenwirkungen

TinyMCE verwendet DragMath als Formeleditor. Das bedeutet Java Plugins müssen im Browser aktiviert werden können (IcedTea). Atto nutzt hierfür MathJAX. Das klappt zwar ohne Java – dafür lädt sich dieser Formeleditor Code aus den USA nach und was dabei in die andere Richtung über den Atlantik geht, weiß wieder keiner.

Man hat demnach die Wahl zwischen Java und NSA. Super.

Moodle Glossary Export

Schüler können aus dem Moodle Glossary in den Grundeinstellungen keine XML Dateien exportieren und das bedeutet, dass sie sich nicht das komplette Glossary besorgen können – nur immer einzelne Einträge. In den Rechteeinstellungen der Aktivität lässt sich dies durch setzen eines Häkchens für die Rolle „Teilnehmer/in“ jedoch erlauben (siehe Bild oben).

In der Seitenleiste „Einstellungen“ finden diese sodann einen Schalter „Exportieren der Einträge“ vor, der dann einem Download-Dialog „Exportiere in Datei“ enthält.

Wie dann mit der XML Datei weiter verfahren wird, mit der die meisten Schüler/innen ja ebenfalls überfordert sind, führe ich noch aus. Ein Konvertierungsscript nach HTML hat ein Schüler von mir schon geschrieben – nur ist dies noch nicht ausführlich getestet und noch nicht von ihm unter CC oder GPL gestellt worden.

Hoffnungsschimmer

Es besteht wieder Hoffnung: Der neueste Moodle 2 Build erstellt doch tatsächlich auch Backups. Daran war auf Grund meiner bisherigen Erfahrungen [1, 2] zu zweifeln gewesen. Noch werde ich meinen Bugreport nicht auf gelöst setzen – erst in ein paar Tagen.

Moodle Backupproblem ungelöst

Da verwurstet moodle.org seine Zeit damit, für mobile Endgeräte eine automatische Erkennung zu basteln, damit diesen gesonderte Themes angeboten werden können, aber das wirklich kritische Problem, dass Moodle einem jede Nacht mitteilt, das Backup sei ohne Fehler durchgelaufen während nichts (im Sinne von gar nichts) gesichert wurde … darum kümmern sie sich nicht. Moodle kotzt mich gerade an.

Sachlicher ausgedrückt: Meine Backupprobleme bleiben auch bei Moodle 2.1 bestehen. Das ist ein Blocker! Wer kann, sollte bei Moodle 1.9.x bleiben.

Moodle 2 Backup kaputt

Jeden Tag schickt mir mein Moodle brav eine Mail, in der steht, dass alle Kurse erfolgreich gesichert worden seien:

Beschreibung
==================================================
Kurse: 178
OK: 178
Übersprungen: 0
Fehler: 0
Noch nicht abgeschlossen: 0

Sicherung erfolgreich abgeschlossen

Leider eine glatte Lüge. Das dumme Ding sichert überhaupt nicht, sondern wirft nur mit Fehlermeldungen um sich, die es dann aber nicht verschickt, sondern nach

/moodledata/temp/backup

wirft, damit auch ja niemand drauf kommt, dass überhaupt was schief geht.

In diesem Verzeichnis finden sich nun aberhunderte von Logs mit dem schlichten Inhalt

[warn] backup_auto_failed_on_course coursename

und das für jeden Kursraum. Ergo: Mal wieder einen Bugreport losgetreten.

Moodle 2 Backupeinstellungen

Die Grundeinstellungen von Moodle2 erlauben es einem Trainer (editingteacher) nicht, dass dieser Nutzerdaten sichert, was dazu führt, dass in den exportierten Kursräumen immer nur Teile des Raumes enthalten sind … was dann wiederum dazu führt, dass der Administrator der Moodle2-Installation das leidige Backupgeschäft nicht an die Trainer in den Kursräumen delegieren kann.

Es reicht leider nicht, als Administrator die Backupeinstellungen vernünftig zu wählen – z.B. wie im Bild oben – so dass diese dem Datenschutz ja durchaus gerecht werden, weil ein Export von Nutzerdaten nur anonymisiert möglich ist und der Export von Logdaten überhaupt nicht. Die Trainerrolle selbst muss angepasst werden.

Dazu als Administrator an der Moodle2-Installation anmelden und im Bereich /Website-Administration /Nutzer/innen /Rechte /Rollen verwalten auf den Eintrag für die Trainer klicken.

Im Bereich „Kurs“ sind auf dieser Einstellungsseite zwei Checkboxen auf „Erlauben“ zu setzen – was in Kombination mit den globalen Einstellungen für die Kursraumsicherung dazu führt, dass nun der komplette Kursraum vom Trainer gesichert werden kann, ohne dass der Datenschutz über die Wupper geht.

Die Nutzerdateien können nun Teil des Kursraumexportes sein und dieser ist damit so umfänglich sicherbar, dass eine Delegation des Backupgeschäftes und vor allem der Backupverantwortung an Trainer OK erscheint.

Meinen Bug-report hab ich einstampfen dürfen.

Dumbobackup

Da meine Moodle 2 Installationen im Moment noch nicht vollständig in backup2l integriert werden können, darf ich die Kursräume händisch sichern. Das nervt, wenn man das nicht automatisieren kann.

Auf dem Server schreibt das in Moodle 2 integrierte Backup die Kursräume jede Nacht in das Verzeichnis

/server/dir/mdlbckp/

Aus diesem Verzeichnis sollen dann die Kursraumbackups (im Moodle 2 üblichen mbz Format) auf die lokale Platte in das Verzeichnis

/localpath/bckp_tagmonatjahr/dir1

wandern, wobei dieses Verzeichnis einen „Datumsstempel“ im Pfadnamen tragen soll.

Ich hab das mal so gelöst:

#!/bin/bash
# Datum in Variable schreiben
d=$(date +%d%m%Y)
# Lokales Verzeichnis mit Zeitstempel anlegen
mkdir -p /localpath/bckp_$d/dir1
# Moodle Kursraumbackups vom Server holen
scp -r user@server.de:/server/dir/mdlbckp/* /localpath/bckp_$d/dir1

Für jedes zu sichernde Moodle 2 auf dem Server wird das Skript dann um einen mkdir -p Aufruf und den entsprechenden scp -r Befehl ergänzt.

Wenn scp Dank public key Verfahren auf den Server zugreifen darf, dann ist das Skriptchen – über einen cronjob aufgerufen – nun wenigstens ein workaround.