Autor Thema: mit Perl Vertretungsplan der Schule auslesen  (Gelesen 1358 mal)

Online CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 28059
mit Perl Vertretungsplan der Schule auslesen
« am: 25 Januar 2022, 13:10:04 »
Hallo,

Da ich mich nun schon öfters dabei erwischt habe das ich vergessen habe nach dem Vertretungsplan der Schule meines Sohnes zu schauen habe ich das ganze Automatisiert.
Ich habe ein Perlscript welchen die Internetseite aufruft, die Tabelle extrahiert und schaut ob Eintrage für die Klasse meines Sohnes vorhanden sind.
Ist dies der Fall bekomme ich eine Mail mit angepassten Layout an Infos.
Damit das Skript öfters ausgeführt werden kann, ich aber nicht ständig am selben Tag über einen Eintrag informiert werde wird zusätzlich nach Veränderungen geschaut und nur bei Veränderung eine Mail losgeschickt.

Die Internetseite hat 2 Tabellen. Eine für den aktuellen und eine für den Folgetag. Über beide Tabellen steht das Datum für welchen Tag die jeweilige Tabelle gedacht ist.

Das Layout der Seite in Kurzform
Teil 1 wo Tabelle 1 steht
<div class="articleBody" itemprop="articleBody">
<p><span style="color: #008000;"><strong><span style="font-size: 14pt;"><span style="font-size: 18pt; color: #ff6600;">Vertretungsplan für Dienstag, 21.01.2022</span></span></strong></span></p>
<p><strong><span style="font-size: 14pt;"><span style="font-size: 18pt;"><span style="color: #000000; font-size: 14pt;">Ordnungsklasse/Fundsachen: </span>3c</span><br /></span></strong></p>
<p style="text-align: left;"><span style="font-size: 14pt; color: #ff0000;"><strong>Wir bitten um Verständnis, dass Eltern generell das Schulgebäude und in der Zeit von 7.30 Uhr bis 14.30 Uhr das Schulgelände nicht betreten dürfen. Tragen Sie bitte Ihren <span style="text-decoration: underline;">Mund-Nasen-Schutz</span> auf dem Schulgelände.<br /></strong></span></p>
<p style="text-align: left;"><span style="font-size: 14pt; color: #339966;"><strong><span style="text-decoration: underline;">Projekt</span>:       <br /></strong></span></p>
<table style="height: 240px; border-color: #000000; width: 656px;" border="1">
<tbody>
<tr style="height: 20px;">
<td style="height: 20px; width: 32px;"><span style="font-size: 18pt; color: #ff9900;"><strong>Stunde</strong></span></td>
<td style="height: 20px; width: 106px;"><span style="font-size: 18pt; color: #ff9900;"><strong>Klasse</strong></span></td>
<td style="height: 20px; width: 53.6px;"><span style="font-size: 18pt; color: #ff9900;"><strong>Lehrkraft</strong></span></td>
<td style="height: 20px; width: 250.4px;">
<p><span style="font-size: 18pt; color: #ff9900;"><strong>Bemerkungen</strong></span></p>
</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px; text-align: center;" colspan="4"><span style="font-size: 12pt; color: #ff0000;"><strong>Kontrolle der Selbsttestbescheinigungen!!!</strong> </span></td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">1.</td>
<td style="height: 4px; width: 106px;">2a</td>
<td style="height: 4px; width: 53.6px;">Holl</td>
<td style="height: 4px; width: 250.4px;">Sport</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">1.</td>
<td style="height: 4px; width: 106px;">5b</td>
<td style="height: 4px; width: 53.6px;">MK</td>
<td style="height: 4px; width: 250.4px;">Kunst</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">2.</td>
<td style="height: 4px; width: 106px;">2a</td>
<td style="height: 4px; width: 53.6px;">And</td>
<td style="height: 4px; width: 250.4px;">Deutsch</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">2.</td>
<td style="height: 4px; width: 106px;">2d</td>
<td style="height: 4px; width: 53.6px;">Kr</td>
<td style="height: 4px; width: 250.4px;">Sport</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">2./4.</td>
<td style="height: 4px; width: 106px;">3a</td>
<td style="height: 4px; width: 53.6px;">Schr</td>
<td style="height: 4px; width: 250.4px;">Deutsch, Mathematik</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">2.</td>
<td style="height: 4px; width: 106px;">4a</td>
<td style="height: 4px; width: 53.6px;">MK</td>
<td style="height: 4px; width: 250.4px;">Kunst</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">2.</td>
<td style="height: 4px; width: 106px;">5b</td>
<td style="height: 4px; width: 53.6px;">San</td>
<td style="height: 4px; width: 250.4px;">Englisch</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">2.</td>
<td style="height: 4px; width: 106px;">6b</td>
<td style="height: 4px; width: 53.6px;">He</td>
<td style="height: 4px; width: 250.4px;">Nawi</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">3./4.</td>
<td style="height: 4px; width: 106px;">2a</td>
<td style="height: 4px; width: 53.6px;">San</td>
<td style="height: 4px; width: 250.4px;">Deutsch, Mathematik</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">3.</td>
<td style="height: 4px; width: 106px;">3a</td>
<td style="height: 4px; width: 53.6px;">MK</td>
<td style="height: 4px; width: 250.4px;">Englisch</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">3.</td>
<td style="height: 4px; width: 106px;">3c</td>
<td style="height: 4px; width: 53.6px;">Kr</td>
<td style="height: 4px; width: 250.4px;">Sport</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">3.</td>
<td style="height: 4px; width: 106px;">6b</td>
<td style="height: 4px; width: 53.6px;">Qu</td>
<td style="height: 4px; width: 250.4px;">Nawi</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">4.</td>
<td style="height: 4px; width: 106px;">1c ev. Religion</td>
<td style="height: 4px; width: 53.6px;">Mang</td>
<td style="height: 4px; width: 250.4px;">evangelisch Religion</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">4.</td>
<td style="height: 4px; width: 106px;">1b ev. Religion </td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;">evangel. Religion Ausfall (Kinder gehen in den Hort)</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">4.</td>
<td style="height: 4px; width: 106px;">5c</td>
<td style="height: 4px; width: 53.6px;">MK</td>
<td style="height: 4px; width: 250.4px;">Englisch</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">4./5.</td>
<td style="height: 4px; width: 106px;">6d</td>
<td style="height: 4px; width: 53.6px;">And</td>
<td style="height: 4px; width: 250.4px;">Deutsch, Nawi</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">5.</td>
<td style="height: 4px; width: 106px;">2b ev. Religion</td>
<td style="height: 4px; width: 53.6px;">Mang</td>
<td style="height: 4px; width: 250.4px;">evangelisch Religion</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">5.</td>
<td style="height: 4px; width: 106px;">2a ev. Religion</td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;">evangel. Religion Ausfall (Kinder gehen in den Hort)</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">7.</td>
<td style="height: 4px; width: 106px;">5c  Ausfall</td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;"> </td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;"> </td>
<td style="height: 4px; width: 106px;"> </td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;"> </td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;"> </td>
<td style="height: 4px; width: 106px;"> </td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;"> </td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;"> </td>
<td style="height: 4px; width: 106px;"> </td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;"> </td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;"> </td>
<td style="height: 4px; width: 106px;"> </td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;"> </td>
</tr>
<tr style="height: 6px;">
<td style="height: 6px; width: 32px;"> </td>
<td style="height: 6px; width: 106px;"> </td>
<td style="height: 6px; width: 53.6px;"> </td>
<td style="height: 6px; width: 250.4px;"> </td>
</tr>
<tr style="height: 6px;">
<td style="height: 6px; width: 32px;"> </td>
<td style="height: 6px; width: 106px;"> </td>
<td style="height: 6px; width: 53.6px;"> </td>
<td style="height: 6px; width: 250.4px;"> </td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;">Aufsicht</td>
<td style="height: 4px; width: 106px;">7.30 Uhr</td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;"> </td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;"> </td>
<td style="height: 4px; width: 106px;">9.35 Uhr</td>
<td style="height: 4px; width: 53.6px;">Kri</td>
<td style="height: 4px; width: 250.4px;">Schulhof</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;"> </td>
<td style="height: 4px; width: 106px;">11.35 Uhr</td>
<td style="height: 4px; width: 53.6px;">San</td>
<td style="height: 4px; width: 250.4px;">Mensa</td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;"> </td>
<td style="height: 4px; width: 106px;">11.35 Uhr</td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;"> </td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 32px;"> </td>
<td style="height: 4px; width: 106px;">13.50 Uhr</td>
<td style="height: 4px; width: 53.6px;"> </td>
<td style="height: 4px; width: 250.4px;"> </td>
</tr>
</tbody>
</table>

Teil2 wo Tabelle 2 steht. Es ist eigentlich eine Seite, ich zeige aber nur Teile.
p><span style="color: #008000;"><strong><span style="font-size: 18pt;"><span style="color: #ff6600;">Vertretungsplan für Mittwoch, 26.01.2022     </span></span></strong></span></p>
<p style="text-align: left;"><span style="color: #008000;"><strong><span style="font-size: 18pt;"><span style="color: #ff6600;"><span style="color: #008000;"><span style="font-size: 14pt; color: #000000;">Ordnungsklasse/Fundsachen/Spielekiste:</span> 3c                    </span></span><br /></span></strong></span></p>
<p><span style="color: #ff0000; font-size: 14pt;"><strong>Wir bitten um Verständnis, dass Eltern generell das Schulgebäude und in der Zeit von 7.30-14.30 Uhr das Schulgelände nicht betreten dürfen. Tragen Sie bitte Ihren <span style="text-decoration: underline;">Mund-Nasen-Schutz</span> auf dem Schulgelände.<br /></strong></span></p>
<p><span style="color: #339966; font-size: 14pt;"><strong><span style="text-decoration: underline;">Exkursion</span>:              <span style="text-decoration: underline;">Projekt</span>: <br /></strong></span></p>
<table style="height: 627px; border-color: #000000; width: 657px;" border="1">
<tbody>
<tr style="height: 42px;">
<td style="height: 42px; width: 86px; text-align: center;">
<p><span style="font-size: 18pt; color: #ff9900;"><strong>Stunde</strong></span></p>
</td>
<td style="height: 42px; width: 100px; text-align: center;">
<p><span style="font-size: 18pt; color: #ff9900;"><strong>Klasse</strong></span></p>
</td>
<td style="height: 42px; width: 103.733px; text-align: center;"><span style="font-size: 18pt; color: #ff9900;"><strong>Lehrer</strong></span></td>
<td style="height: 42px; width: 237.267px; text-align: center;">
<p><span style="font-size: 18pt; color: #ff9900;"><strong>Bemerkungen</strong></span></p>
</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 527px; text-align: center;" colspan="4"><span style="font-size: 12pt; color: #ff0000;"><strong>Kontrolle der Selbsttestbescheinigungen!!!</strong> </span></td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">1./3.</td>
<td style="height: 2px; width: 100px;">6a</td>
<td style="height: 2px; width: 103.733px;">Stei</td>
<td style="height: 2px; width: 237.267px;">Deutsch</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">2.</td>
<td style="height: 2px; width: 100px;">1d</td>
<td style="height: 2px; width: 103.733px;">And</td>
<td style="height: 2px; width: 237.267px;">Deutsch</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">2./3./5.</td>
<td style="height: 2px; width: 100px;">2a</td>
<td style="height: 2px; width: 103.733px;">Kö</td>
<td style="height: 2px; width: 237.267px;">Englisch, Deutsch, Kunst</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">2.</td>
<td style="height: 2px; width: 100px;">2b</td>
<td style="height: 2px; width: 103.733px;">Foe</td>
<td style="height: 2px; width: 237.267px;">Kunst</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">2./5.</td>
<td style="height: 2px; width: 100px;">5b</td>
<td style="height: 2px; width: 103.733px;">San</td>
<td style="height: 2px; width: 237.267px;">Englisch</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">2.</td>
<td style="height: 2px; width: 100px;">5d</td>
<td style="height: 2px; width: 103.733px;">MK</td>
<td style="height: 2px; width: 237.267px;">Kunst</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">2.</td>
<td style="height: 2px; width: 100px;">6c</td>
<td style="height: 2px; width: 103.733px;">Kl</td>
<td style="height: 2px; width: 237.267px;">Mathematik</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">3.</td>
<td style="height: 2px; width: 100px;">3a</td>
<td style="height: 2px; width: 103.733px;">Schr</td>
<td style="height: 2px; width: 237.267px;">Deutsch</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">3.</td>
<td style="height: 2px; width: 100px;">5c</td>
<td style="height: 2px; width: 103.733px;">Kr</td>
<td style="height: 2px; width: 237.267px;">Deutsch</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">3.</td>
<td style="height: 2px; width: 100px;">6c</td>
<td style="height: 2px; width: 103.733px;">San</td>
<td style="height: 2px; width: 237.267px;">Nawi</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">4.</td>
<td style="height: 2px; width: 100px;">2a</td>
<td style="height: 2px; width: 103.733px;">Be</td>
<td style="height: 2px; width: 237.267px;">Mathematik</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">4.</td>
<td style="height: 2px; width: 100px;">2d</td>
<td style="height: 2px; width: 103.733px;">Kr</td>
<td style="height: 2px; width: 237.267px;">Sport</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">4.</td>
<td style="height: 2px; width: 100px;">3a</td>
<td style="height: 2px; width: 103.733px;">MK</td>
<td style="height: 2px; width: 237.267px;">Sachunterricht</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">4.</td>
<td style="height: 2px; width: 100px;">5d</td>
<td style="height: 2px; width: 103.733px;">Stei</td>
<td style="height: 2px; width: 237.267px;">Deutsch</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">4./5.</td>
<td style="height: 2px; width: 100px;">6d</td>
<td style="height: 2px; width: 103.733px;">And</td>
<td style="height: 2px; width: 237.267px;">Deutsch</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">5.</td>
<td style="height: 2px; width: 100px;">3a</td>
<td style="height: 2px; width: 103.733px;">Rie</td>
<td style="height: 2px; width: 237.267px;">Deutsch</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">5.</td>
<td style="height: 2px; width: 100px;">5c</td>
<td style="height: 2px; width: 103.733px;">MK</td>
<td style="height: 2px; width: 237.267px;">Englisch</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;">6./7.</td>
<td style="height: 2px; width: 100px;">5c</td>
<td style="height: 2px; width: 103.733px;">San</td>
<td style="height: 2px; width: 237.267px;">Nawi</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;"> </td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;"> </td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;"> </td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;"> </td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;"> </td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;"> </td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;"> </td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"><strong>Aufsicht</strong>:</td>
<td style="height: 2px; width: 100px;">7.30 Uhr</td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 4px;">
<td style="height: 4px; width: 86px;"> </td>
<td style="height: 4px; width: 100px;">9.35 Uhr</td>
<td style="height: 4px; width: 103.733px;"> </td>
<td style="height: 4px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;">9.35 Uhr</td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;">11.35 Uhr</td>
<td style="height: 2px; width: 103.733px;">San</td>
<td style="height: 2px; width: 237.267px;">Spielplatz</td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;">11.35 Uhr</td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;">13.50 Uhr</td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;">14.45 Uhr</td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;"> </td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
<tr style="height: 2px;">
<td style="height: 2px; width: 86px;"> </td>
<td style="height: 2px; width: 100px;"> </td>
<td style="height: 2px; width: 103.733px;"> </td>
<td style="height: 2px; width: 237.267px;"> </td>
</tr>
</tbody>
</table>


Auf Basis dieser Daten arbeitet mein Skript

Das Perlskript
#!/usr/bin/perl -w
###############################################################################
#
# Developed with VSCodium and richterger perl plugin.
#
#  (c) 2022 Copyright: Marko Oldenburg (development@cooltux.net)
#  All rights reserved
#
#
#  This script is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  any later version.
#
#  The GNU General Public License can be found at
#  http://www.gnu.org/copyleft/gpl.html.
#  A copy is found in the textfile GPL.txt and important notices to the license
#  from the author is found in LICENSE.txt distributed with these scripts.
#
#  This script is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#
###############################################################################

use strict;
use warnings;

our $VERSION = '1.00';

use feature qw /say/;
use experimental qw /switch smartmatch/;
use Carp;
use autodie qw /:io/;

use HTTP::Tiny;            # apt install libhttp-tiny-perl
use HTML::TableExtract;    # apt install libhtml-tableextract-perl
use Encode qw /decode encode/;
use MIME::Lite;                   # apt install libmime-lite-perl
use Readonly;                     # apt install libreadonly-perl
use Hash::Diff qw /left_diff/;    # apt install libhash-diff-perl
use Try::Tiny;

### zum testen
# use Data::Dumper;

#
### config
# url
Readonly my $URL => 'http://www.7';

## json File
Readonly my $JSONFILE => './Vertretungsplan.json';  # Path wo das JSON File abgelegt werden soll

## mail
Readonly my $MAILFROM => '<Sender Mail>';  # Sender der Mail
Readonly my $MAILTO   => '<Empfänger Mail>';  # Empfänger der Mail

## zu ermittelne Klasse
Readonly my $KLASSE => '3b';    # Welche Schulkasse soll gesucht werden

## global variables
my @textlines;
my $tableValuesObj = {};

# try to use JSON::MaybeXS wrapper
#   for chance of better performance + open code
eval {
    require JSON::MaybeXS;
    import JSON::MaybeXS qw( decode_json encode_json );
    1;
} or do {

    # try to use JSON wrapper
    #   for chance of better performance
    eval {
        # JSON preference order
        local $ENV{PERL_JSON_BACKEND} =
          'Cpanel::JSON::XS,JSON::XS,JSON::PP,JSON::backportPP'
          unless ( defined( $ENV{PERL_JSON_BACKEND} ) );

        require JSON;
        import JSON qw( decode_json encode_json );
        1;
    } or do {

        # In rare cases, Cpanel::JSON::XS may
        #   be installed but JSON|JSON::MaybeXS not ...
        eval {
            require Cpanel::JSON::XS;
            import Cpanel::JSON::XS qw(decode_json encode_json);
            1;
        } or do {

            # In rare cases, JSON::XS may
            #   be installed but JSON not ...
            eval {
                require JSON::XS;
                import JSON::XS qw(decode_json encode_json);
                1;
            } or do {

                # Fallback to built-in JSON which SHOULD
                #   be available since 5.014 ...
                eval {
                    require JSON::PP;
                    import JSON::PP qw(decode_json encode_json);
                    1;
                } or do {

                    # Fallback to JSON::backportPP in really rare cases
                    require JSON::backportPP;
                    import JSON::backportPP qw(decode_json encode_json);
                    1;
                };
            };
        };
    };
};

### Script

sub sendMail {

    my $msg = MIME::Lite->new(
        From     => $MAILFROM,
        To       => $MAILTO,
        Subject  => 'Wichtige Information vom Vertretungsplan!!!',
        Type     => 'TEXT',
        Encoding => '8bit',
        Data     => decode(
            'UTF-8',
"Es gibt Informationen bezüglich Stundenvertretung für unsere Klasse\n\n\n"
        ),
    );

    $msg->attach( Data => join '', map { "$_\n" } @textlines );

    $msg->send;

    return;
}

sub findCorrectTable {
    my $content = shift;

    my @tables;
    my $match = '>Vertretungsplan\sfür\s';

    ( undef, @tables ) = split /$match/x, $content;

    return \@tables;
}

sub fetchUrl {

    # instantiating the HTTP variable
    my $httpVariable = HTTP::Tiny->new;

    # storing the response using the get
    # method
    my $response = $httpVariable->get($URL);

    # checking if the code returned successful

    $response->{content} = findCorrectTable( $response->{content} );

    return $response;
}

sub jsonFileRead {
    my $fileExists;

    my $json;
    my $jsonObj;

    try {
        open my $fh, q{<}, $JSONFILE;
        $json = do { local $/ = undef; <$fh> };
        close $fh;

        $jsonObj    = decode_json($json);
        $fileExists = 1;
    }
    catch {
        if ( $_->isa('autodie::exception') && $_->matches(':io') ) {
            jsonFileWrite();
        }
        else {
            croak $_;
        }
    };    # Note semicolon.

    return $fileExists, $jsonObj;
}

sub jsonCompare {
    my $jsonObj = shift;

    my $jsonObjDiff = left_diff( $tableValuesObj, $jsonObj );

    return $jsonObjDiff;
}

sub jsonFileWrite {

    try {
        my $json = encode_json($tableValuesObj);

        open my $fh, q{>}, $JSONFILE;
        say $fh $json;
        close $fh;
    }
    catch {
        if ( $_->isa('autodie::exception') && $_->matches(':io') ) {
            say 'Error doing something with ' . $JSONFILE . ': ' . $_;
        }
        else {
            croak $_;
        }
    };    # Note semicolon.

    return;
}

sub currentState {
    my $state = 0;

    my ( $fileExists, $jsonObj ) = jsonFileRead();

    if ($fileExists) {
        if ( keys %{ jsonCompare($jsonObj) } ) {
            $state = 1;
            jsonFileWrite();
        }
    }
    else { $state = 1; }

    return $state;
}

sub createMailMessage {

    my ($state) = currentState();

    if ($state) {
        for ( sort keys %{$tableValuesObj} ) {
            my $tableValues = $tableValuesObj->{$_};
            my $message;

            if ( map { /Ausfall/x } $tableValues->{class} ) {
                $message = decode( 'UTF-8',
                        'Die '
                      . $tableValues->{lesson}
                      . ' Stunde fällt mit der Bemerkung "'
                      . $tableValues->{comment}
                      . '" aus' );
            }
            else {
                $tableValues->{comment} =
                  $tableValues->{comment}
                  ? ' mit der Bemerkung ' . $tableValues->{comment} . '.'
                  : '.';

                $message =
                    'Der Lehrer '
                  . $tableValues->{teacher}
                  . ' vertritt die '
                  . $tableValues->{lesson}
                  . ' Stunde'
                  . $tableValues->{comment};

                # Ausfall
            }

            push @textlines, "\n$tableValues->{date}"
              if !( "\n$tableValues->{date}" ~~ @textlines );

            push @textlines, $message;
        }
    }

    return;
}

sub extractTable {
    my $contents = shift;
    my $count    = 0;

    for my $content ( @{$contents} ) {
        my $te = HTML::TableExtract->new( depth => 0, count => 0 );
        $te->parse( decode( 'UTF-8', $content ) );

        my $date = ( map { m/([A-Za-z]+,\s\d{2}.\d{2}.\d{4})/x } $content )[0];

        for my $ts ( $te->tables ) {
            for my $row ( $ts->rows ) {
                if ( $row->[1] ) {
                    if (   grep { /^\d[a-d]/x } $row->[1]
                        && grep { /$KLASSE/x } $row->[1] )
                    {
                        $tableValuesObj->{$count} = {
                            lesson  => $row->[0],
                            teacher => $row->[2],
                            comment => $row->[3],
                            class   => $row->[1],
                            date    => $date
                        };

                        $count++;
                    }
                }
            }
        }
    }

    return;
}

### Main
my $fetchResponse = fetchUrl();

if ( $fetchResponse->{success} ) {
    extractTable( $fetchResponse->{content} );
    createMailMessage();
}
else {

    # displating the reason for failed
    # request
    # say 'Failed to establish connection: '
    #   . $response->{status}
    #   . $response->{reasons};
}

sendMail()
  if (@textlines);

exit(0)


Damit die Infomail zugestellt werden kann man ein lokaler sendmail oder postfix laufen.

Ich habe das Skipt unter anderem auch für Fingerübungen geschrieben da ich mehr und mehr die "neuen" Möglichkeiten von Perl lernen möchte.



Grüße
Marko
« Letzte Änderung: 25 Januar 2022, 22:28:57 von CoolTux »
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Mein Dokuwiki:
https://www.cooltux.net
Informativ Informativ x 1 Liste anzeigen

Offline Clyde

  • Full Member
  • ***
  • Beiträge: 143
Antw:mit Perl Vertretungsplan der Schule auslesen
« Antwort #1 am: 14 September 2022, 14:46:44 »
Moin!

Ich hol das nochmal vor, da ich die Tage die gleiche Idee hatte.

Leider komme ich nicht ohne Zugangsdaten auf die Seite mit der Tabelle.
Der Schulserver fährt ein IServ-System welches wohl schon recht verbreitet ist.
Zugangsdaten habe ich natürlich, aber ich habe keine Idee wie ich die beim Seitenaufruf übergebe.

Hat da jemand eine Idee?

2x Cubietruck, CUL868, HM-USB-CFG2
FS20, FHT, KS300, HM, MAX, Tradfri

Offline Prof. Dr. Peter Henning

  • Developer
  • Hero Member
  • ****
  • Beiträge: 8585
Antw:mit Perl Vertretungsplan der Schule auslesen
« Antwort #2 am: 02 Oktober 2022, 11:46:21 »
Ist in der Anleitung zu HTTPMOD ausführlich beschrieben.

LG

pah

Offline Clyde

  • Full Member
  • ***
  • Beiträge: 143
Antw:mit Perl Vertretungsplan der Schule auslesen
« Antwort #3 am: 03 Oktober 2022, 11:20:39 »
Damit komme ich nicht weiter, weil sich mir nicht erschließt was ich in den Attributen eintragen soll.
basic auth funktioniert nicht. Es wird auf eine Login Seite (Formular) weitergeleitet.

Allerdings weiß nur die URL die ich aufrufen möchte.
Dazu habe ich Usernamen und Passwort für den Zugang.
Kann man damit weiter kommen?
Für BurpSuite fehlen mir wohl leider die Kenntnisse.
2x Cubietruck, CUL868, HM-USB-CFG2
FS20, FHT, KS300, HM, MAX, Tradfri

Offline Clyde

  • Full Member
  • ***
  • Beiträge: 143
Antw:mit Perl Vertretungsplan der Schule auslesen
« Antwort #4 am: 03 Oktober 2022, 11:27:12 »
https://igs-row.de/iserv/auth/login

Leider ergibt sich für mich nicht, wie ich die Daten übergeben kann.
2x Cubietruck, CUL868, HM-USB-CFG2
FS20, FHT, KS300, HM, MAX, Tradfri