I had submitted an awk script to convert .vcs or .ics appointmentsinto dtcm(1) appointments in the XAPIA format. This script is distributed with CDE in the contrib/ directory. I have made some improvements to the script to handle repeating appointments. Since there is a CDE release in preparation, I am sending the new script to the list.
I am also sending a script that creates appointments for (Roman Catholic) Easter, Ascencion Day and Whit Sunday. It might also be
distributed with CDE in contrib/ under the terms of MIT license.
#/usr/bin/awk -f # Edmond Orignac (c) 2016. This awk program # attempts to convert .ics/.vcs files into XAPIA format for dtcm(1) appointment. # It is redistributable under the terms of MIT License. BEGIN {FS=":"} /^BEGIN/ {if ($2~"VEVENT") {appnt=1; rxtype=0; nxr=0; mxday=0; mxmonth=0; runtil=0; xinterval=0} } /^TZ/ {if ($2~"[+-][1-9]*") {timezone=$2} else {timezone=0}} # Knowing the timezone, we can convert local time to UTC time. /^DTSTART/ {sdate=$2} /^DTEND/ {fdate=$2} /^DESCRIPTION/ {summary=summary" "substr($0,13)} /^SUMMARY/ {summary=summary" "substr($0,9)} /^LOCATION/ {summary=summary" in "substr($0,10)} /^RRULE/ {rrule=$2; # The event will repeat forever unless we find a limit nxr=0; rfields=split(rrule,rdata,";"); for (i=1;i<=rfields;i++) { if (rdata[i]~"FREQ") { rtype=substr(rdata[i],5); if (rtype~"DAILY") rxtype=1; if (rtype~"WEEKLY") rxtype=2; # We assume a monthly repeat by date for now if (rtype~"MONTHLY") rxtype=5; if (rtype~"YEARLY") rxtype=6; } if (rdata[i]~"COUNT") {nxr=substr(rdata[i],7)}; if (rdata[i]~"BYDAY") { rdays=substr(rdata[i],7); nrdays=split(rdata[i],ddays,","); # nrdays=1: we have a simple monthly repeat by weekday if ((nrdays==1) && (rxtype==5)) {rxtype=4}; # with nrdays > 1 we have a problem: # XAPIA format only allows limited forms of weekly repeats if ((nrdays>1) && (rxtype=2)) { if (nrdays==2) { tuth=match(ddays[1],"TU")+match(ddays[2],"TH"); if (tuth==2) {rxtype=12}; }; if (nrdays==3) { mowefr=0; for (j=1;j<=nrdays;j++) { mowefr+=match(ddays[j],"MO"); mowefr+=match(ddays[j],"WE"); mowefr+=match(ddays[j],"FR"); }; if (mowefr==3) {rxtype=11}; }; if (nrdays==5) { wweek=0; for (j=1;j<=nrdays;j++) { wweek+=match(ddays[j],"MO"); wweek+=match(ddays[j],"TU"); wweek+=match(ddays[j],"WE"); wweek+=match(ddays[j],"TH"); wweek+=match(ddays[j],"FR"); }; if (wweek==5) {rxtype=10}; }; }; }; # This is bad: if we have not found a repeat by day matching one XAPIA # format, the repetition rule is not fully defined. # Most likely we will have only one of the appointments of the week. if (rdata[i]~"BYMONTHDAY=") {mxday=substr(rdata[i],12)}; if (rdata[i]~"BYMONTH=") {mxmonth=substr(rdata[i],9)}; if (rdata[i]~"INTERVAL=") {xinterval=substr(rdata[i],10) # Weekly appointment with a 2 week interval is definec in XAPIA if ((xinterval==2) && (rxtype==2)) {rxtype=3} # Monthly appointment with a 12 month interval is really a yearly appointment if ((xinterval==12) && (rxtype=5)) {rxtype=6} # Weekly appointment with N>2 interval if ((xinterval>2) && (rxtype==2)) {rxtype=8} # Monthly appointment with N>=2 interval (12 month excluded) if ((xinterval>=2) && (rxtype==5)) {rxtype=9} # Daily appointment with N>=2 interval if ((xinterval>=2) && (rxtype==1)) {rxtype=7} }; # Repetition until a date in the future if (rdata[i]~"UNTIL=") {xuntil=substr(rdata[i],7); runtil=1}; }; }; /^END/ {if ($2~"VEVENT") { # # That one is annoying: we have to calculate the number of repetitions ! # We do that by using an average duration for the year and for the month # but obviously this is imprecise, and the last appointment may not be there. # Also, we must do it here since DTSTART can appear at the very end # of an entry. The arithmetics gets sillier with repeat every n week/day/month... if (runtil==1) { uyear=substr(xuntil,1,4)-substr(sdate,1,4); umonth=substr(xuntil,5,2)-substr(sdate,5,2); uday=substr(xuntil,7,2)-substr(sdate,7,2); if (rxtype==1) nxr=int(365.25*uyear+30.44*umonth+uday)+1; if (rxtype==2) nxr=int((365.25*uyear+30.44*umonth+uday)/7.0)+1; if (rxtype==3) nxr=int((365.25*uyear+30.44*umonth+uday)/14.0)+1; if ((rxtype==4)||(rxtype==5)) nxr=12*uyear+umonth+1; if (rxtype==6) nxr=uyear+1; if (rxtype==7) nxr=int((365.25*uyear+30.44*umonth+uday)/xinterval)+1; if (rxtype==8) nxr=int((365.25*uyear+30.44*umonth+uday)/(7*xinterval))+1; if (rxtype==9) nxr=int((12*uyear+umonth)/xinterval)+1; if (rxtype==10) nxr=int(5.0*(365.25*uyear+30.44*umonth+uday)/7.0)+1; if (rxtype==11) nxr=int(3.0*(365.25*uyear+30.44*umounth+uday)/7.0)+1; if (rxtype==12) nxr=int(3.0*(365.25*uyear+30.44*umounth+uday)/7.0)+1; if (nxr<0) nxr=0; }; # Another important thing is that dtcm does not like events that spread # over more than 24 hours. So we have to find how many days is fdate-sdate # and if that is more than 1 day transform the event into a daily repeat. dyear=substr(fdate,1,4)-substr(sdate,1,4); dmonth=substr(fdate,5,2)-substr(sdate,5,2); dday=int(substr(fdate,7,2)-substr(sdate,7,2)+30.44*dmonth+365.25*dyear); if ((rxtype==0) && (dday>0)) {rxtype=1;nxr=dday+1}; # Start hour and End hour have to be converted to UTC first if timezone is defined. printf("\n\n") print "\t** Calendar Appointment **" print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN:string:begin"; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML Start Date//EN:datetime:%s\n",sdate); print "-//XAPIA/CSA/ENTRYATTR//NONSGML Type//EN:uinteger:0"; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Subtype//EN:string:-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Appointment//EN"; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Classification//EN:uinteger:0"; if (rxtype==0) { printf("-//XAPIA/CSA/ENTRYATTR//NONSGML End Date//EN:datetime:%s\n",fdate); } else { qdate=substr(sdate,1,8) substr(fdate,9); printf("-//XAPIA/CSA/ENTRYATTR//NONSGML End Date//EN:datetime:%s\n",qdate); }; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Show Time//EN:sinteger:1"; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML Summary//EN:string:%s\n",summary); print "-//XAPIA/CSA/ENTRYATTR//NONSGML Status//EN:uinteger:2304"; printf("-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Type//EN:sinteger:%d\n",rxtype); printf("-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Times//EN:uinteger:%d\n",nxr); print "-//XAPIA/CSA/ENTRYATTR//NONSGML Audio Reminder//EN:reminder:300:"; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Popup Reminder//EN:reminder:300:"; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Occurrence Number//EN:sinteger:-1"; printf("-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Interval//EN:uinteger:%d\n",rinterval); print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN:string:end"; printf("\tDate: %s/%s/%s\n",substr(sdate,5,2),substr(sdate,7,2),substr(sdate,1,4)); # The start/end time are in UTC and have to be converted to local time. We assume the local time is UTC+1 shour=substr(sdate,10,2); smin=substr(sdate,12,2); fhour=substr(fdate,10,2); fmin=substr(fdate,12,2); if ((fhour+fmin+shour+smin)==0) {fhour=01;fmin=42;shour=01;smin=41} shour++; fhour++; printf("\tStart: %.2d%.2d\n",shour,smin) printf("\tEnd: %.2d%.2d\n",fhour,fmin) if (rxtype==0) {print "\tRepeat: One Time"}; if (rxtype==1) {print "\tRepeat: Daily"}; if (rxtype==2) {print "\tRepeat: Weekly"}; if (rxtype==3) {print "\tRepeat: Every Two Weeks"}; if (rxtype==4) {print "\tRepeat: Monthly By Weekday"}; if (rxtype==5) {print "\tRepeat: Monthly By Date"}; if (rxtype==6) {print "\tRepeat: Yearly"} if (rxtype==7) {printf("\t Repeat Every %d days\n",xinterval)} if (rxtype==8) {printf("\t Repeat Every %d weeks\n",xinterval)} if (rxtype==9) {printf("\t Repeat Every %d months\n",xinterval)} if (rxtype==10) {print "\tRepeat: Monday thru Friday"}; if (rxtype==11) {print "\tRepeat: Mon, Wed, Fri"}; if (rxtype==12) {print "\tRepeat: Tuesday, Thursday"}; printf("\tFor: %d\n",nxr); printf("\tWhat: %s\n",summary); printf("\t\n"); sdate=""; fdate=""; appnt=0; summary=""; } }
BEGIN { y=2016; # change to the appropriate year ! lang=ENVIRON["LANG"] easter["C"]="Easter" easter["fr_FR.ISO8859-1"]="Pâques" easter["it_IT.ISO8859-1"]="Pasqua" easter["es_ES.ISO8859-1"]="Pascua" easter["de_DE.ISO8859-1"]="Ostersonntag" ascension["C"]="Ascension Day" ascension["fr_FR.ISO8859-1"]="Ascension" ascension["it_IT.ISO8859-1"]="Ascensione" ascension["es_ES.ISO8859-1"]="Ascension" ascension["de_DE.ISO8859-1"]="Christi Himmelfahrt" whit["C"]="Whit Sunday" whit["fr_FR.ISO8859-1"]="Pentecôte" whit["it_IT.ISO8859-1"]="Spirito Sancto" whit["es_ES.ISO8859-1"]="Pentecostés" whit["de_DE.ISO8859-1"]="Pfingstsonntag" # Formula to calculate the date of Easter g=y%19; c=int(y/100); c4=int(c/4); e=int((8*c+13)/25); h=(19*g+c-c4-e+15)%30; k=int(h/28); p=int(29/(h+1)); q=int((21-g)/11); i=(k*p*q-1)*k+h; b=int(y/4)+y; j1=b+i+2+c4-c; j2=j1%7; r=28+i-j2; m=int(r/32)+3; d=r-31*(m-3); # Creating an appointment in XAPIA format for Easter sdate=sprintf("%.4d%.2d%.2dT004100Z",d,m,y); fdate=sprintf("%.4d%.2d%.2dT004200Z",d,m,y); appt="easter_"y; printf("\n\n") >appt print "\t** Calendar Appointment **" >appt print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN:string:begin">appt; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML Start Date//EN:datetime:%s\n",sdate)>appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Type//EN:uinteger:0">appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Subtype//EN:string:-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Appointment//EN">appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Classification//EN:uinteger:0">appt; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML End Date//EN:datetime:%s\n",fdate)>appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Show Time//EN:sinteger:0">appt; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML Summary//EN:string: %s %.4d\n",easter[lang],y)>appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Status//EN:uinteger:2304">appt; printf("-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Type//EN:sinteger:0\n")>appt; printf("-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Times//EN:uinteger:0\n")>appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Audio Reminder//EN:reminder:300:">appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Popup Reminder//EN:reminder:300:">appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Occurrence Number//EN:sinteger:-1">appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Interval//EN:uinteger:0">appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN:string:end">appt; printf("\tDate: %s/%s/%s\n",m,d,y)>appt; printf("\tStart: 0241\n",shour,smin)>appt printf("\tEnd: 0242\n",fhour,fmin)>appt printf("\tRepeat: One Time\n")>appt; printf("\tFor: 0\n")>appt; printf("\tWhat: %s %.4d\n",easter[lang],y)>appt; printf("\t")>appt; # Ascension day is 40 days after easter aday=r+39; # print aday; # for debugging purpose only ! m=3; if (aday>31) {aday-=31;m++ } if (aday>30) {aday-=30;m++ } if (aday>31) {aday-=31;m++} if (aday>30) {aday-=30;m++} sdate=sprintf("%.4d%.2d%.2dT004100Z",aday,m,y); fdate=sprintf("%.4d%.2d%.2dT004200Z",aday,m,y); appt="ascension_"y; printf("\n\n") >appt print "\t** Calendar Appointment **" >appt print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN:string:begin">appt; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML Start Date//EN:datetime:%s\n",sdate)>appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Type//EN:uinteger:0">appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Subtype//EN:string:-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Appointment//EN">appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Classification//EN:uinteger:0">appt; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML End Date//EN:datetime:%s\n",fdate)>appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Show Time//EN:sinteger:0">appt; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML Summary//EN:string: %s %.4d\n",ascension[lang],y)>appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Status//EN:uinteger:2304">appt; printf("-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Type//EN:sinteger:0\n")>appt; printf("-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Times//EN:uinteger:0\n")>appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Audio Reminder//EN:reminder:300:">appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Popup Reminder//EN:reminder:300:">appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Occurrence Number//EN:sinteger:-1">appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Interval//EN:uinteger:0">appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN:string:end">appt; printf("\tDate: %s/%s/%s\n",m,aday,y)>appt; printf("\tStart: 0241\n",shour,smin)>appt printf("\tEnd: 0242\n",fhour,fmin)>appt printf("\tRepeat: One Time\n")>appt; printf("\tFor: 0\n")>appt; printf("\tWhat: %s %.4d\n",ascension[lang],y)>appt; printf("\t")>appt; # Whit Monday is 50 days after easter wday=r+48; m=3; if (wday>31) {wday-=30;m++} if (wday>30) {wday-=30;m++} if (wday>31) {wday-=31;m++} if (wday>30) {wday-=30;m++} sdate=sprintf("%.4d%.2d%.2dT004100Z",wday,m,y); fdate=sprintf("%.4d%.2d%.2dT004200Z",wday,m,y); appt="whit_"y; printf("\n\n") >appt print "\t** Calendar Appointment **" >appt print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN:string:begin">appt; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML Start Date//EN:datetime:%s\n",sdate)>appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Type//EN:uinteger:0">appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Subtype//EN:string:-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Appointment//EN">appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Classification//EN:uinteger:0">appt; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML End Date//EN:datetime:%s\n",fdate)>appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Show Time//EN:sinteger:0">appt; printf("-//XAPIA/CSA/ENTRYATTR//NONSGML Summary//EN:string: %s %.4d\n",whit[lang],y)>appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Status//EN:uinteger:2304">appt; printf("-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Type//EN:sinteger:0\n")>appt; printf("-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Times//EN:uinteger:0\n")>appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Audio Reminder//EN:reminder:300:">appt; print "-//XAPIA/CSA/ENTRYATTR//NONSGML Popup Reminder//EN:reminder:300:">appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Occurrence Number//EN:sinteger:-1">appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Interval//EN:uinteger:0">appt; print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN:string:end">appt; printf("\tDate: %s/%s/%s\n",m,wday,y)>appt; printf("\tStart: 0241\n",shour,smin)>appt printf("\tEnd: 0242\n",fhour,fmin)>appt printf("\tRepeat: One Time\n")>appt; printf("\tFor: 0\n")>appt; printf("\tWhat: %s %.4d\n",whit[lang],y)>appt; printf("\t")>appt; } # We can also calculate the date of Pentecost (Whit Sunday/Monday) = Easter +50 days # and of Ascension Day = Easter + 4O days # To write to files in awk, it is enough to do print(f) something > FILE
------------------------------------------------------------------------------ What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports. http://sdm.link/zohomanageengine
_______________________________________________ cdesktopenv-devel mailing list cdesktopenv-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cdesktopenv-devel