{"id":5195,"date":"2018-08-22T19:31:23","date_gmt":"2018-08-22T17:31:23","guid":{"rendered":"https:\/\/www.bdjl.de\/localhost\/?p=5195"},"modified":"2018-08-23T15:05:09","modified_gmt":"2018-08-23T13:05:09","slug":"webuntis-scraper","status":"publish","type":"post","link":"https:\/\/www.bdjl.de\/localhost\/?p=5195","title":{"rendered":"WebUntis Scraper"},"content":{"rendered":"<p>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 <a href=\"https:\/\/docs.moodle.org\/35\/en\/File_system_repository\" target=\"_blank\" rel=\"noopener\">File Repository<\/a> des Lehrermoodles geschrieben und aus dem Kursraum &#8222;Schwarzes Brett&#8220; (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\u00f6nnen.<\/p>\n<div id=\"attachment_5207\" style=\"width: 650px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-5207\" class=\"wp-image-5207 size-medium\" src=\"https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-640x546.png\" alt=\"\" width=\"640\" height=\"546\" srcset=\"https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-640x546.png 640w, https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-768x655.png 768w, https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-624x532.png 624w, https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan.png 808w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><p id=\"caption-attachment-5207\" class=\"wp-caption-text\">Mit geschlossenem Accordion<\/p><\/div>\n<div id=\"attachment_5216\" style=\"width: 650px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-accordionopen.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-5216\" class=\"size-medium wp-image-5216\" src=\"https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-accordionopen-640x531.png\" alt=\"\" width=\"640\" height=\"531\" srcset=\"https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-accordionopen-640x531.png 640w, https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-accordionopen-768x637.png 768w, https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-accordionopen-624x517.png 624w, https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/vplan-accordionopen.png 808w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><p id=\"caption-attachment-5216\" class=\"wp-caption-text\">Accordion offen<\/p><\/div>\n<p>Das muss leider so umst\u00e4ndlich sein, weil ich keinen Weg gefunden habe, den WebDavs Ordner als solchen navigierbar im Kursraum so einzubinden, dass man diesen nicht auch von au\u00dferhalb des Moodles aufrufen k\u00f6nnte. Mir bleibt (sofern ich richtig liege) nix anderes \u00fcber, als aus den X html Dateien, die WebUntis mir hinwirft, eine einzige zu bauen, die ich klar benamen und dann &#8222;verlinken&#8220; kann. Dazu muss ich die vielen WebUntis HTML Dateien in ihre Bestandteile zerlegen. Ich brauche: Die Tabellen und die Zeitangaben.<\/p>\n<p>Im Prinzip geht das mit beautifulsoup und Python. Meine Python-Kenntnisse sind jedoch leider noch rudiment\u00e4rer als meine Bash-Kenntnisse &#8230; also muss\u00a0 ein bash Skript her. Und HTML mit Bash nativ parsen\u00a0 &#8211; nun: ich wei\u00df, dass das Probleme macht. Das will man nicht.<\/p>\n<p>Die L\u00f6sung ist <a href=\"https:\/\/github.com\/ericchiang\/pup\" target=\"_blank\" rel=\"noopener\">pup<\/a>, das ich in ein Bash-Skript einbinde.<\/p>\n<p>Zur Information die Struktur der WebUntis Dateien in ihren Ordnern \/ Unterordnern:<\/p>\n<p><a href=\"https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/webuntisdirstruct.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5196\" src=\"https:\/\/www.bdjl.de\/localhost\/wp-content\/uploads\/2018\/08\/webuntisdirstruct.png\" alt=\"\" width=\"223\" height=\"641\" \/><\/a><\/p>\n<p>Die zu erzeugende Output-Datei soll HTML sein und braucht dazu einen Kopf:<\/p>\n<pre class=\"lang:default decode:true\">&lt;html&gt;\r\n&lt;head&gt;\r\n&lt;title&gt;Vertretungsplan&lt;\/title&gt;\r\n&lt;meta http-equiv=\"Content-Type\" content=\"text\/html; charset=iso-8859-1\"&gt;\r\n&lt;meta http-equiv=\"cache-control\" content=\"max-age=0\" \/&gt;\r\n&lt;meta http-equiv=\"cache-control\" content=\"no-cache\" \/&gt;\r\n&lt;meta http-equiv=\"expires\" content=\"0\"&gt;\r\n&lt;meta http-equiv=\"pragma\" content=\"no-cache\" \/&gt;\r\n\r\n&lt;meta http-equiv=\"refresh\" content=\"120\" \/&gt;\r\n&lt;style type=\"text\/css\"&gt;\r\nbody { margin-top: 20px; margin-left: 20px; margin-right: 20px;\r\nbackground: #fff; color: #272727; font: 80% Arial, Helvetica, sans-serif; }\r\nh1 { color: #ee7f00; font-size: 200%; font-weight: bold;}\r\nh2 { color: #ee7f00; font-size: 175%;}\r\nh1, h2 { margin: 0; padding: 25px 0px 5px 0px;}\r\n\r\n \/* put your css here or copy from untishtml *\/\r\n \r\n \/* Style the buttons that are used to open and close the accordion panel *\/\r\n.accordion {\r\n    background-color: #eee;\r\n    color: #444;\r\n    cursor: pointer;\r\n    padding: 18px;\r\n    width: 100%;\r\n    text-align: left;\r\n    border: none;\r\n    outline: none;\r\n    transition: 0.4s;\r\n}\r\n\r\n\/* 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) *\/\r\n.active, .accordion:hover {\r\n    background-color: #ccc;\r\n}\r\n\r\n\/* Style the accordion panel. Note: hidden by default *\/\r\n.panel {\r\n    padding: 0 18px;\r\n    background-color: white;\r\n    display: none;\r\n    overflow: hidden;\r\n} \r\n\r\n\r\n&lt;\/style&gt;\r\n&lt;\/head&gt;\r\n&lt;body&gt;\r\n\r\n&lt;script&gt;\r\n  window.onload=function(){\r\n    var acc = document.getElementsByClassName(\"accordion\");\r\n    for (var i = 0; i &lt; acc.length; i++) {\r\n      acc[i].addEventListener(\"click\", function() {\r\n          this.classList.toggle(\"active\");\r\n          var panel = this.nextElementSibling;\r\n          if (panel.style.display === \"block\") {\r\n              panel.style.display = \"none\";\r\n          } else {\r\n              panel.style.display = \"block\";\r\n          }\r\n      });\r\n    }\r\n  };\r\n&lt;\/script&gt;\r\n\r\n&lt;h1&gt;KvFG Vertretungsplan nach Datum und Anzeigetafel&lt;\/h1&gt;\r\n&lt;p&gt;&lt;strong&gt;Es gilt der Plan auf den Anzeigetafeln im Haus bzw. auf den Aush&amp;auml;ngen. Diese Datei ist immer nur Beta!&lt;\/strong&gt;&lt;\/p&gt;\r\n<\/pre>\n<p>Siehe zum Code f\u00fcr das Accordion im Kopf und im &#8222;Kleister&#8220;: <a href=\"https:\/\/www.w3schools.com\/howto\/howto_js_accordion.asp\" target=\"_blank\" rel=\"noopener\">https:\/\/www.w3schools.com\/howto\/howto_js_accordion.asp <\/a>\u00a0Leider 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:<\/p>\n<pre class=\"lang:default decode:true \">window.onload=function(){\r\n... }\r\n\/* thanx Janis for debugging *\/<\/pre>\n<p>Was einen Kopf hat, braucht auch einen Fu\u00df:<\/p>\n<pre class=\"lang:default decode:true \">&lt;p&gt;&lt;\/p&gt;\r\n&lt;p&gt;----&lt;\/p&gt;\r\n&lt;p&gt;(C) dowel 2018 | UntisParser Version 0.1&lt;\/p&gt;\r\n&lt;p&gt;Fehler sind immer m&amp;oumlglich und sollten &lt;a href=\"https:\/\/yourschoolsbugtracker.tld\" target=\"_blank\"&gt;im Bugtracker gemeldet werden&lt;\/a&gt;, damit diese behoben werden k&amp;ouml;nnen. Wer keinen Bugreport (= Bericht) formulieren kann, muss schweigen.&lt;\/p&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>Und dann braucht es den &#8222;Kleister&#8220;, der die Arbeit macht und alles zusammenpackt. Nennen wir es <em>untisparser.sh<\/em> und legen es in das passende Verzeichnis auf dem Server:<\/p>\n<pre class=\"lang:default decode:true \">#!\/bin\/bash\r\n# UntisParser\r\n# \r\n# Parse HTML Export Files created by WebUntis\r\n# do \"e pluribus unum\" with a Bash script\r\n# throw the output into a Moodle file repository\r\n# and link the output from inside a Moodle Courseroom\r\n# \r\n# You need the pup executable from https:\/\/github.com\/ericchiang\/pup\r\n# \r\n# (C) dowel\r\n# License: CC BY SA https:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/deed.de\r\n# Date: 2018-08-23\r\n# Version 0.2\r\n# ####\r\n\r\n# def of some base vars\r\nRUNT=$(date '+%Y-%m-%d %H:%M:%S')\r\nRUNF=\"20 Minuten\" # set this in cronjob\r\nRELOAD=\"120 Sekunden\" # see head_filename\r\nWORKDIR=\"\/path\/untisparser\"\r\nPUPPATH=\"\/path\/bin\"\r\nHEAD_FILENAME=\"kopf.html\" # asumed to be in workdir\r\nFOOT_FILENAME=\"fuss.html\" # asumed to be in workdir\r\nOUTPUT_PATH=\"\/path\/moodledata\/repository\/anzeigebretter\" # set this to your Moodle file repository\r\nOUTPUT_FILENAME=\"output.html\"\r\n\r\n# headline def\r\nLUL1H=\"Anzeige Lehrer\/innen Teil 1 Linke Seite (Heute?)\"\r\nLUL2H=\"Anzeige Lehrer\/innen Teil 2 Rechte Seite (Morgen?)\"\r\nSUS1H=\"Anzeige Sch&amp;uuml;ler\/innen Teil 1 Linke Seite (Heute?)\"\r\nSUS2H=\"Anzeige Sch&amp;uuml;ler\/innen Teil 2 Rechte Seite (Morgen?)\"\r\n\r\n\r\n# path stuff\r\n# Where are the Untis files in the workdir?\r\nL_SUBDIR=\"$WORKDIR\/Lehrerbrett\"\r\nS_SUBDIR=\"$WORKDIR\/Schuelerbrett\"\r\n\r\n# How many of the suckers are there?\r\nCOUNT_LF1=$(\/usr\/bin\/find $L_SUBDIR\/f1 -maxdepth 1 -name '*.htm' | \/usr\/bin\/wc -l)\r\nCOUNT_LF2=$(\/usr\/bin\/find $L_SUBDIR\/f2 -maxdepth 1 -name '*.htm' | \/usr\/bin\/wc -l)\r\nCOUNT_SF1=$(\/usr\/bin\/find $S_SUBDIR\/f1 -maxdepth 1 -name '*.htm' | \/usr\/bin\/wc -l)\r\nCOUNT_SF2=$(\/usr\/bin\/find $S_SUBDIR\/f2 -maxdepth 1 -name '*.htm' | \/usr\/bin\/wc -l)\r\n\r\n# Warning jabber because we do not know how many old files there are\r\n# and if cleaner.script has worked the way it should have\r\n# we asume that it failed\r\nWARNMESS=\"&lt;p&gt;\r\n    --------------------------------------------------------------------------------------&lt;br&gt;\r\n    Stand: $RUNT | Beachte: Das Skript l&amp;auml;uft nur alle $RUNF und die Seite wird nach $RELOAD neu geladen!&lt;br&gt;\r\n    Achte auf das Datum. Es kann sein, dass ab hier alte Dateien ausgelesen werden. Wenn das so ist, dann den Rest ignorieren.&lt;\/br&gt;\r\n    &lt;a href=\\\"#top\\\"&gt;Ganz nach oben&lt;\/a&gt; || LuL: &lt;a href=\\\"#lul1\\\"&gt;Links&lt;\/a&gt; | &lt;a href=\\\"#lul2\\\"&gt;Rechts&lt;\/a&gt; || SuS &lt;a href=\\\"#sus1\\\"&gt;Links&lt;\/a&gt; | &lt;a href=\\\"#sus2\\\"&gt;Rechts&lt;\/a&gt;\r\n    &lt;\/p&gt;\"\r\n\r\n# create empty output file and fill it with html head and some simple navigation stuff\r\n\/bin\/cat $WORKDIR\/$HEAD_FILENAME &gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\/bin\/echo \"&lt;id=\\\"top\\\"&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\/bin\/echo \"&lt;p&gt;&lt;em&gt;Links&lt;\/em&gt; ist meist &lt;em&gt;Heute&lt;\/em&gt; und &lt;em&gt;Rechts&lt;\/em&gt; ist meist &lt;em&gt;Morgen&lt;\/em&gt; - aber nicht immer.&lt;\/p&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\/bin\/echo \"&lt;p&gt;Anzeige Lehrer\/innen: &lt;a href=\\\"#lul1\\\"&gt;Links&lt;\/a&gt; | &lt;a href=\\\"#lul2\\\"&gt;Rechts&lt;\/a&gt;&lt;\/p&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\/bin\/echo \"&lt;p&gt;Anzeige Sch&amp;uuml;ler\/innen: &lt;a href=\\\"#sus1\\\"&gt;Links&lt;\/a&gt; | &lt;a href=\\\"#sus2\\\"&gt;Rechts&lt;\/a&gt;&lt;\/p&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\/bin\/echo \"&lt;p&gt;Stand: $RUNT | Beachte: Das Skript l&amp;auml;uft nur alle $RUNF!&lt;\/p&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\/bin\/echo \"&lt;p&gt;&lt;\/p&gt;\"&gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\r\n# ticker export\r\nif [ -f $L_SUBDIR\/ticker.htm ]\r\nthen\r\n    \/bin\/echo \"&lt;h4&gt;L Ticker&lt;\/h4&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $L_SUBDIR\/ticker.htm 'marquee text{}' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\nfi\r\n\r\nif [ -f $S_SUBDIR\/ticker.htm ]\r\nthen\r\n    \/bin\/echo \"&lt;h4&gt;S Ticker&lt;\/h4&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $S_SUBDIR\/ticker.htm 'marquee text{}' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\nfi\r\n\r\n# Create teacher part of output file\r\n\r\n\/bin\/echo \"&lt;h2 id=\\\"lul1\\\"&gt;$LUL1H&lt;\/h2&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\nCOUNT=1\r\nMAXCOUNT=1\r\nlet MAXCOUNT=COUNT_LF1+1\r\n\r\n# teacher links\r\nwhile [ $COUNT -lt $MAXCOUNT ] ; do\r\n    # padding\r\n    NUM=$(printf %03d $COUNT)\r\n    # Date extract to button\r\n    \/bin\/echo \"&lt;button class=\\\"accordion\\\"&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $L_SUBDIR\/f1\/subst_$NUM.htm 'div.mon_title' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;\/button&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;div class=\\\"panel\\\"&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Headline is set to H4\r\n    \/bin\/echo \"&lt;h4&gt;Lehrer\/innen&lt;\/h4&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;p&gt;&lt;\/p&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Table extraction\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $L_SUBDIR\/f1\/subst_$NUM.htm 'table' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;\/div&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Warning \r\n    \/bin\/echo $WARNMESS &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    let COUNT=COUNT+1\r\ndone\r\n\r\n# Reset for second part of LuL \r\n\r\n\/bin\/echo \"&lt;h2 id=\\\"lul2\\\"&gt;$LUL2H&lt;\/h2&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\nCOUNT=1\r\nMAXCOUNT=1\r\nlet MAXCOUNT=COUNT_LF2+1\r\n\r\n# teacher rechts\r\nwhile [ $COUNT -lt $MAXCOUNT ] ; do\r\n    # padding\r\n    NUM=$(printf %03d $COUNT)\r\n    # Date extract to button\r\n    \/bin\/echo \"&lt;button class=\\\"accordion\\\"&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $L_SUBDIR\/f2\/subst_$NUM.htm 'div.mon_title' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;\/button&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;div class=\\\"panel\\\"&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Headline is set to H4\r\n    \/bin\/echo \"&lt;h4&gt;Lehrer\/innen&lt;\/h4&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;p&gt;&lt;\/p&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Table extraction\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $L_SUBDIR\/f2\/subst_$NUM.htm 'table' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;\/div&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Warning\r\n    \/bin\/echo $WARNMESS &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    let COUNT=COUNT+1\r\ndone\r\n\r\n# Create pupil part of output file\r\n\/bin\/echo \"&lt;h2 id=\\\"sus1\\\"&gt;$SUS1H&lt;\/H2&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\nCOUNT=1\r\nMAXCOUNT=1\r\nlet MAXCOUNT=COUNT_SF1+1\r\n\r\n\r\n# pupil links\r\nwhile [ $COUNT -lt $MAXCOUNT ] ; do\r\n    # padding\r\n    NUM=$(printf %03d $COUNT)\r\n    # Date extract to button\r\n    \/bin\/echo \"&lt;button class=\\\"accordion\\\"&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $S_SUBDIR\/f1\/subst_$NUM.htm 'div.mon_title' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;\/button&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;div class=\\\"panel\\\"&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Headline is set to H4\r\n    \/bin\/echo \"&lt;h4&gt;Sch&amp;uuml;ler\/innen&lt;\/h4&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;p&gt;&lt;\/p&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Table extraction\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $S_SUBDIR\/f1\/subst_$NUM.htm 'table' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;\/div&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Warning\r\n    \/bin\/echo $WARNMESS &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    let COUNT=COUNT+1\r\ndone\r\n\r\n# Reset for second part of SuS \r\n\r\n\/bin\/echo \"&lt;h2 id=\\\"sus2\\\"&gt;$SUS2H&lt;\/h2&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\nCOUNT=1\r\nMAXCOUNT=1\r\nlet MAXCOUNT=COUNT_SF2+1\r\n\r\n# pupil rechts\r\nwhile [ $COUNT -lt $MAXCOUNT ] ; do\r\n    # padding\r\n    NUM=$(printf %03d $COUNT)\r\n    # Date extract to button\r\n    \/bin\/echo \"&lt;button class=\\\"accordion\\\"&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $S_SUBDIR\/f2\/subst_$NUM.htm 'div.mon_title' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;\/button&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;div class=\\\"panel\\\"&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Headline is set to H3\r\n    \/bin\/echo \"&lt;h4&gt;Sch&amp;uuml;ler\/innen&lt;\/h4&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;p&gt;&lt;\/p&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Table extraction\r\n    $PUPPATH\/pup --charset iso-8859-1 -f $S_SUBDIR\/f2\/subst_$NUM.htm 'table' &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    \/bin\/echo \"&lt;\/div&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    # Warning\r\n    \/bin\/echo $WARNMESS &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n    let COUNT=COUNT+1\r\ndone\r\n\r\n# create footer\r\n\/bin\/echo \"&lt;p&gt;&lt;\/p&gt;\" &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\/bin\/cat $WORKDIR\/$FOOT_FILENAME &gt;&gt; $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\r\n# cleanup\r\n\/bin\/chown www-data.www-data $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n\/bin\/chmod 2750 $OUTPUT_PATH\/$OUTPUT_FILENAME\r\n# and we are done\r\nexit 0\r\n\r\n<\/pre>\n<p>Cron ruft das Skript alle 20 Minuten auf. Sch\u00f6ner w\u00e4re nat\u00fcrlich, wenn das Skript nur liefe, wenn sich was \u00e4ndert im WebDavs Share. Aber <em>inotify<\/em> und Freunde sind auch nicht ohne. So ist es simpel und scheint zu funktionieren, ohne viel Ressourcen zu fressen.<\/p>\n<h2>Update 23.08<\/h2>\n<p>Einige Fehler im Skript (meist die vergessenenen \\ vor den &#8222;) behoben und mit Hilfe von JavaScript mehr \u00dcbersichtlichkeit im Output erzeugt.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &#8222;Schwarzes Brett&#8220; (die Kommunikationsplattform der Schule) verlinkt. Das stellt sicher, dass nur [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,13,10],"tags":[21,590,591,85,589],"class_list":["post-5195","post","type-post","status-publish","format-standard","hentry","category-linux","category-moodle","category-schule","tag-bash","tag-html","tag-javascript","tag-moodle-2","tag-pup"],"_links":{"self":[{"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=\/wp\/v2\/posts\/5195","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5195"}],"version-history":[{"count":20,"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=\/wp\/v2\/posts\/5195\/revisions"}],"predecessor-version":[{"id":5220,"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=\/wp\/v2\/posts\/5195\/revisions\/5220"}],"wp:attachment":[{"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5195"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5195"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bdjl.de\/localhost\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5195"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}