Site map  

Freedom Internet onderhoud

Een combinatie van een bash script en een C programmaatje om datum en tijd van onderhoud in een bepaalde woonplaats uit de Freedom Internet storings pagina te vissen.
De output heeft het volgende formaat;

2023-10-01	2023-10-02 01:00 - 08:00 Onderhoud internet
2023-10-01	2023-10-02 02:00 - 07:00 Onderhoud internet
2023-10-01	2023-10-02 04:00 - 07:00 Onderhoud internet
2023-10-08	2023-10-09 01:00 - 08:00 Onderhoud internet
2023-10-16	2023-10-17 01:00 - 07:00 Onderhoud internet
2023-10-19	2023-10-20 01:00 - 07:00 Onderhoud internet
2023-11-09	2023-11-10 01:00 - 05:00 Onderhoud internet
2023-11-14	2023-11-15 01:00 - 07:00 Onderhoud internet
2023-11-15	2023-11-16 01:00 - 07:00 Onderhoud internet
2023-11-19	2023-11-20 01:00 - 07:00 Onderhoud internet
2023-11-27	2023-11-28 01:00 - 05:00 Onderhoud internet

De eerste kolom is de datum van één dag voor dat het onderhoud plaats vind. Maar dit kan makkelijk worden aangepast.

Kalender

Ik heb een heel simpele agenda. Het is een tekst file met het volgende formaat;

ISO Datum <Tab> Afspraak <Line Feed>

Voorbeeld:

2012-04-01	11:00 - 12:00 PostNl, Pakket

Het shell script kalender.sh, dat 's ochtends uit cron draait grept deze file en mailt de afspraken van vandaag;

#!/bin/bash

ADDR="Je Email Adres"
FILE="Je Kalender file"

TODAY=$(date +%Y-%m-%d)

if ( grep "^$TODAY" "${FILE}" > /dev/null )
then
	grep "^$TODAY" "${FILE}" | \
	mail -a "From: ${ADDR}" \
	-a "Content-type: text/plain; charset=UTF-8" \
	-s Afspraak "${ADDR}"
fi

De onderhouds lijst

De onderhouds entries worden gegenereerd door het shell script proc-storing.sh. De output cut en paste ik naar mijn agenda.

#!/bin/bash

DIR="/Pad/Naar/files/"
EMAILADR="Je Email adres"
LOCATION="Je Woonplaats"
PROG="/Pad/Naar/proc-storing"
FILE="${LOCATION}.txt"

if [ ! -d "${DIR}" ]
then
	echo "Dir ${DIR} not found"
	exit 1
fi
cd "${DIR}"

rm storingen.txt.bak
mv storingen.txt storingen.txt.bak
lynx -dump -accept_all_cookies -nolist -width=255 https://freedom.nl/storingen > storingen.txt
if [ ! -f storingen.txt ]
then
	echo "File storingen.txt not found"
	mv storingen.txt.bak storingen.txt
	exit 1
fi

if ( diff storingen.txt storingen.txt.bak > /dev/null )
then
	# No change
	exit 0
fi

rm "${FILE}.bak"
mv "${FILE}" "${FILE}.bak"
cat storingen.txt | "${PROG}" "${LOCATION}" > "${FILE}"

if ! ( diff "${FILE}" "${FILE}.bak" > /dev/null )
then
	echo "Nieuwe storingen"
	rm kalender.txt.bak
	mv kalender.txt kalender.txt.bak
	cat "${FILE}" | \
		egrep "	20[0-9][0-9][-]" | \
		awk -F\\\t '{print $2 "\t" $3 " Onderhoud internet"}' | \
		sort > kalender.txt
	( cat "${FILE}" ; echo "" ; cat kalender.txt ; echo "" ) | \
		mail -s "Onderhoud internet" "${EMAILADR}"
fi

Het script;

  1. Download de pagina Storingen en Onderhoud en dumpt deze als tekst file.
  2. Vergelijkt deze met de vorige versie van deze pagina.
    En als de nieuwe versie anders is;
  3. Zoekt naar onderhoud in de woonplaats in kwestie.
  4. Vergelijkt dit onderhoud met vorige versie.
    En als er nieuw onderhoud gevonden word;
  5. Mailt het onderhoud.

Dit script roept voor '3' het C programma proc-storing.c aan;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


/*
*    Find Freedom Internet maintenance date and time on their web page.
*
*    Copyright (c) 2023 R.J. van der Putten, Leiden, Holland, 
*    rob at sput dot nl.
* 
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License version 3 as
*    published by the Free Software Foundation.
* 
*    This program 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.
*/


char *months[12] = { \
	"januari",
	"februari",
	"maart",
	"april",
	"mei",
	"juni",
	"juli",
	"augustus",
	"september",
	"oktober",
	"november",
	"december"
};


/*  Find month  */
int fndmon(char *s)
{
    int i;

    i = 0;
    while (i < 12) {
	if(strcasecmp(s, months[i]) == 0)
	    break;
	i++;
    }

    return(i);
}

/*  Guess year  */
int fndyear(int mon)
{
    int year;
    time_t t;
    struct tm *curr;

    t = 0;
    year = 0;
    curr = NULL;

    t = time(NULL);
    curr = localtime(&t);
    year = curr->tm_year;
    if (mon < 4 && curr->tm_mon > 9) {
	/*  Curr: Oct - Dec and Ann: Jan - Mar; Probably next year  */
	year++;
    } else if (curr->tm_mon < 4 && mon > 9) {
	/*  Curr: Jan - Mar and Ann: Oct - Dec; Probably last year  */
	year--;
    }

    return(year);
}

/*  Process date  */
int procdate(char *s, struct tm *loc)
{
    int mon, year;
    char month[16];

    mon = 0;
    year = 0;
    memset(month, 0, 16);

    /*
    *  Begintijd: Vrijdag 10 november 2023 01.00
    *  Begintijd: Vrijdag 10 november 01.00
    */
    if(strncasecmp(s, "Begintijd: ", 11) != 0)
	return(-1);

    if (sscanf(s, "%*s %*s %d %15s %d %d.%d", \
      &(loc->tm_mday), month, &year, &(loc->tm_hour), &(loc->tm_min)) != 5) {
	/*  Missing year?  */
	if (sscanf(s, "%*s %*s %d %15s %d.%d", \
	  &(loc->tm_mday), month, &(loc->tm_hour), &(loc->tm_min)) != 4) {
	    /*  Garbled date!  */
	    return(-1);
	}
	year = 0;
    }
    mon = fndmon(month);
    if(mon > 11)
	return(-1);
    if (year == 0) {
	/*  No year  */
	year = fndyear(mon);
	loc->tm_year = year;
    } else {
	loc->tm_year = year - 1900;
    }
    loc->tm_mon   = mon;
    loc->tm_isdst = -1;

    return(0);
}


int main(int argc, char **argv)
{
    int i, len, lf, loclen;
    char date[256], line[4096];
    time_t t;
    struct tm loc, *prev;

    if (argc != 2 || argv[1][0] == '-') {
	fprintf(stderr, "Usage: proc-storing Location\n");
	exit(1);
    }

    i = 0;
    len = 0;
    lf = 0;				/*  Location when not zero  */
    loclen = 0;				/*  Length of location  */
    t = 0;				/*  Epoch  */
    prev = NULL;			/*  The previous day  */
    memset(date, 0, 256);		/*  Date  */
    memset(line, 0, 4096);
    memset(&loc, 0, sizeof(loc));	/*  Local time  */

    loclen = strlen(argv[1]);
    if (loclen < 2 || loclen > 255) {
	fprintf(stderr, "Wrong Location length: %d\n", loclen);
	exit(1);
    }

    while (fgets(line, 4096, stdin)) {
	i = 0;
	while (line[i] != 0 && i < 4096) {
	    if (line[i] == 10 || line[i] == 13) {
		line[i] = 0;
		break;
	    }
	    i++;
	}
	len = i + 1;
	if (len > 4088) {
	    fprintf(stderr, "Line too long %d\n", len);
	    exit(1);
	}
	i = 0;
	while (i < len) {
	    if (strncasecmp(line + i, "Begintijd", 9) == 0) {
		strncpy(date, line + i, 255);
		date[255] = 0;
		lf = 0;
		break;
	    } else if (strncasecmp(line + i, "* ", 2) == 0 && \
	      strncasecmp(line + i + 2, argv[1], loclen) == 0) {
		lf = 1;
		printf("%s\n", date);
		break;
	    } else if (lf != 0) {
		if (strncasecmp(line + i, \
		  "Het onderhoud start om", 22) == 0) {
		    printf("\t%s\n", line + i);
		} else if (strncasecmp(line + i, \
		  "De verwachte duur van het onderhoud is", 38) == 0) {
		    /*  All info is available  */
		    if (sscanf(line + i + 39, "%d %*s", &len) == 1 && \
		      procdate(date, &loc) == 0 && \
		      (t = mktime(&loc)) != -1) {
			/*  Date looks OK  */
			t = t - 86400;	/*  Previous day  */
		 	prev = localtime(&t);
		 	printf("\t%04d-%02d-%02d\t", prev->tm_year + 1900, \
			  prev->tm_mon + 1, prev->tm_mday);
			printf("%04d-%02d-%02d %02d:%02d - %02d:%02d\n", \
			  loc.tm_year + 1900, loc.tm_mon + 1, loc.tm_mday, \
			  loc.tm_hour, loc.tm_min, \
			  loc.tm_hour + len, loc.tm_min);
		    }
		    lf = 0;	/*  End of this location  */
		    break;
		}
	    }
	    i++;
	}	/*  End of while i < len  */
    }		/*  End of while fgets line stdin  */

    return(0);
}


Compileer met;

~$ cc -O2 -Wall -o proc-storing proc-storing.c

Houd er rekening mee dat als de lay-out van de pagina wijzigt, het programma niet meer werkt. Zo heb ik op 2023-10-25 het programma dusdanig gewijzigd dat bij ontbrekend jaar, dit geraad word. Ik hoop dat dit werkt.
Noot: Soms word een plaatsnaam op meer dan één manier gespeld.