contrib: some enhancements to the scrotps provided by Edmond Orignac
authorJon Trulson <jon@radscan.com>
Sun, 19 Jun 2016 02:18:52 +0000 (20:18 -0600)
committerJon Trulson <jon@radscan.com>
Sun, 19 Jun 2016 02:18:52 +0000 (20:18 -0600)
cde/contrib/vcal2xapia/README
cde/contrib/vcal2xapia/easter.awk [new file with mode: 0644]
cde/contrib/vcal2xapia/vcal2xapia.awk

index 015b1d3127336bb9c5f7bdc36f392cdc37f9d3ef..638ffba7d088354637f98e85a4ecfd79dc9edcf6 100644 (file)
@@ -33,6 +33,12 @@ Please add in the comments at the top of my AWK program the links to
 his dtksh program and to Adam Stein's Perl programs:
 http://www.csh.rit.edu/~adam/Progs/programs.html
 
+Version 2.2.4:
+
+- improvements to the script to handle repeating appointments.
+
+- easter.awk: script that creates appointments for (Roman Catholic)
+  Easter, Ascencion Day and Whit Sunday.
 
 Best wishes,
 
diff --git a/cde/contrib/vcal2xapia/easter.awk b/cde/contrib/vcal2xapia/easter.awk
new file mode 100644 (file)
index 0000000..5832c26
--- /dev/null
@@ -0,0 +1,154 @@
+
+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 
index b19a1b2116b98114885eed49a01c652a6587f367..1f848dafda03572ab334e48a774be5384c0c16e7 100644 (file)
@@ -1,13 +1,20 @@
+#/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=":"} 
-# My attempt at converting .ics files into XAPIA format for dtcm(1)
 
-/^BEGIN/ {if ($2~"VEVENT") {appnt=1; rxtype=0; nxr=1; mxday=0; mxmonth=0; runtil=0}
+
+/^BEGIN/ {if ($2~"VEVENT") {appnt=1; rxtype=0; nxr=0; mxday=0; mxmonth=0; runtil=0; xinterval=0}
 } 
-/^DTSTART/ {sdate=$2} 
+/^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,8)}
-/^LOCATION/ {summary=summary" in "substr($0,9)} 
+/^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 
@@ -71,11 +78,14 @@ BEGIN {FS=":"}
        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 week interval is really a yearly appointment
-           if ((xinterval==2) && (rxtype=5)) {rxtype=6}
-# Other cases are not good. csa.h indicates that repeats with 
-# an N day/week/month interval are supported by XAPIA
-# but it is not clear whether dtcm supports that  
+# 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};   
@@ -89,16 +99,19 @@ BEGIN {FS=":"}
 # 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. 
+# 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==6) nxr=uyear+1;
-           if ((rxtype==5)||(rxtype==4)) nxr=12*uyear+umonth+1; 
+           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==1) nxr=int(365.25*uyear+30.44*umonth+uday)+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; 
@@ -113,8 +126,9 @@ BEGIN {FS=":"}
 
        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")
+       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);
@@ -135,21 +149,29 @@ BEGIN {FS=":"}
        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"; 
-       print "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Interval//EN:uinteger:0"
+       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)+1;
-       smin=substr(sdate,12,2); 
-       fhour=substr(fdate,10,2)+1;
-       fmin=substr(fdate,12,2); 
-       printf("\tStart: %d%s\n",shour,smin) 
-       printf("\tEnd: %d%s\n",fhour,fmin)
+# 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"}; 
@@ -163,4 +185,4 @@ BEGIN {FS=":"}
        summary="";
     } 
  
-}
\ No newline at end of file
+}