#!/bin/bash # The epsi2ics project produces an ICS file from an EPSI school-year calendar. # Copyright © 2019 Y. Gablin, under the GPL-3.0-or-later license. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing. # # This script only works when executed in the timezone of the calendar, and only if this timezone offset # is low enough to keep all events in the day they belong to in the web calendar (usually −6h ≤ TZ ≤ +8h). # # from EPSI “edtmobilityeng” to ICS, for the current school year # $1: EPSI Login (firstname.lastname) # $2: output file (else standard output) if [ -n "$2" -a -d "$(dirname "$2")" -a -w "$(dirname "$2")" ]; then exec >"$2" fi ( dtstamp=$(date -u +%Y%m%dT%H%M%SZ) currentYear=$(date +%Y) splitDay=$(date +%j -d "${currentYear}-08-01" | sed 's/^0*//') # XXXX-08-01 ∈ [1 … 366] dayOfYear=$(date +%j | sed 's/^0*//') # this day ∈ [1 … 366] if [ $dayOfYear -lt $splitDay ]; then offsetMax=$(( splitDay-dayOfYear )) offset=$(( offsetMax-365 )) else offset=$(( splitDay-dayOfYear )) offsetMax=$(( 365+offset )) fi dayOfWeek=$(date +%u -d "${offset}days") # ∈ [1=monday … 5=friday] cat <<-ENDOFTEXT BEGIN:VCALENDAR VERSION:2.0 PRODID:yalis.fr/epsi2ical v1.1 ENDOFTEXT while [ $offset -lt $offsetMax ]; do mon=$(date +%Y%m%dT%z -d "$(($offset+1-$dayOfWeek))days") tue=$(date +%Y%m%dT%z -d "$(($offset+2-$dayOfWeek))days") wed=$(date +%Y%m%dT%z -d "$(($offset+3-$dayOfWeek))days") thu=$(date +%Y%m%dT%z -d "$(($offset+4-$dayOfWeek))days") fri=$(date +%Y%m%dT%z -d "$(($offset+5-$dayOfWeek))days") for ((i=1; i<5; i=i*2)); do week="$(curl -s "https://edtmobiliteng.wigorservices.net/WebPsDyn.aspx?action=posEDTBEECOME&serverid=C&Tel=${1}&date=$(date +%m/%d/%Y -d "${offset}days")")" \ && { echo "$week"; break; } sleep ${i}s done \ | tr '\r\n' ' ' \ | sed -r 's/[[:blank:]]+/ /g' \ | grep -oE '
]*class="Case" [^>]*style="[^"]*left *:[^"]*"|DIV [^>]*style="[^"]*left *:[^"]*" [^>]*class="Case"|]*class="TC(ase|Prof|hdeb|Salle)"([^<]|<[^/]|' \ | awk -vmon=$mon -vtue=$tue -vwed=$wed -vthu=$thu -vfri=$fri -vid="epsi2ics/${1}@${HOSTNAME}" -vdtstamp=$dtstamp -F$'\t' ' function out() { if (from!="" && to!="" && ase!="") printf( \ "BEGIN:VEVENT\nUID:%s/%s/%s\nDTSTAMP:%s\nDTSTART:%s\nDTEND:%s\nSUMMARY:%s\nLOCATION:%s\nDESCRIPTION:🗣 %s 👥 %s\nEND:VEVENT\n", \ from, id, prof, dtstamp, from, to, ase, where, prof, who) from="" to="" ase="" where="" prof="" who="" day="" zoneH=0 zoneM=0 } function toZtime(localH, localM) { localM-=zoneM if (localM<0) { localM+=60 localH-=1 } else if (localM>59) { localM-=60 localH+=1 } localH-=zoneH return sprintf("%s%02d%02d00Z", day, localH, localM) } /class="Case"/ { out() pc=gensub(".*left *: *([0-9]+)[%.].*", "\\1", 1) if (pc < 115) tmpd=mon else if (pc < 135) tmpd=tue else if (pc < 155) tmpd=wed else if (pc < 175) tmpd=thu else tmpd=fri day=substr(tmpd, 1, 9) zoneH=substr(tmpd, 10, 3)+0 zoneM=(substr(tmpd, 10, 1) substr(tmpd, 13, 2))+0 } /class="TCase"/ { ase=gensub(".*
(.*)(.*)
(.*) *0?([0-9]+):0?([0-9]+) *- *0?([0-9]+):0?([0-9]+) *(Salle:)?(.*)