shithub: rssfill

Download patch

ref: 12526901e2bd1b7eb76d029a3f7ef8878de16f4d
parent: 8fdbac99c8c167acc77ca43661a50e9360c905f8
author: sirjofri <sirjofri@sirjofri.de>
date: Tue Jun 9 05:55:13 EDT 2020

adds atom support (including date)

--- /dev/null
+++ b/date.c
@@ -1,0 +1,201 @@
+#include <u.h>
+#include <libc.h>
+#include "date.h"
+
+int
+str2mon(char *s)
+{
+	if(!strcmp(s, "Jan")) return 0;
+	if(!strcmp(s, "Feb")) return 1;
+	if(!strcmp(s, "Mar")) return 2;
+	if(!strcmp(s, "Apr")) return 3;
+	if(!strcmp(s, "May")) return 4;
+	if(!strcmp(s, "Jun")) return 5;
+	if(!strcmp(s, "Jul")) return 6;
+	if(!strcmp(s, "Aug")) return 7;
+	if(!strcmp(s, "Sep")) return 8;
+	if(!strcmp(s, "Oct")) return 9;
+	if(!strcmp(s, "Nov")) return 10;
+	if(!strcmp(s, "Dec")) return 11;
+	return 0;
+}
+
+int
+str2wday(char *s)
+{
+	if(!strcmp(s, "Sun")) return 0;
+	if(!strcmp(s, "Mon")) return 1;
+	if(!strcmp(s, "Tue")) return 2;
+	if(!strcmp(s, "Wed")) return 3;
+	if(!strcmp(s, "Thu")) return 4;
+	if(!strcmp(s, "Fri")) return 5;
+	if(!strcmp(s, "Sat")) return 6;
+	return 0;
+}
+
+int
+doty(int day, int month, int year)
+{
+	int n, i;
+	
+	n = 0;
+	for(i = 0; i < month; i++){
+		if(i == 0) n += 31;
+		if(i == 1){
+			if(year%4 == 0 && year%100 == 0 && year%400 != 0)
+				n += 29;
+			else
+				n += 28;
+		}
+		if(i == 2) n += 31;
+		if(i == 3) n += 30;
+		if(i == 4) n += 31;
+		if(i == 5) n += 30;
+		if(i == 6) n += 31;
+		if(i == 7) n += 31;
+		if(i == 8) n += 30;
+		if(i == 9) n += 31;
+		if(i == 10) n += 30;
+		if(i == 11) n += 31;
+	}
+	
+	n += day;
+	
+	return n;
+}
+
+long
+parseatomdate(char *input)
+{
+	/* YYYY-MM-DDTHH:MM:SSZ */
+	/* YYYY                          year                    */
+	/*      MM                       month                   */
+	/*         DD                    day of month            */
+	/*           T                   or space                */
+	/*            HH                 hour                    */
+	/*               MM              minute                  */
+	/*                  SS           seconds                 */
+	/*                    .SS        seconds (sub, optional) */
+	/*                       Z       zulu (UTC+0)            */
+	/*                       +HH:MM  tz offset               */
+	
+	/* examples:                           length */
+	/*   2020-06-05( |T)13:20:35.44+04:00      28 */
+	/*   2020-06-05( |T)13:20:35+04:00         25 */
+	/*   2020-06-05( |T)13:20:35.44Z           23 */
+	/*   2020-06-05( |T)13:20:35Z              20 */
+	
+	Tm ret;
+	char *args[9];
+	char s[32];
+	int n;
+	
+	strcpy(s, input);
+	
+	switch(strlen(s)){
+	case 28:
+		n = getfields(s, args, 9, 1, "- T:.+Z");
+		if(n != 9)
+			sysfatal("error parsing atom date: %d", n);
+		ret.year = atoi(args[0]) - 1900;
+		ret.mon = atoi(args[1]) - 1;
+		ret.mday = atoi(args[2]);
+		ret.tzoff = atoi(args[7]);
+		ret.hour = atoi(args[3]);
+		ret.min = atoi(args[4]);
+		ret.sec = atoi(args[5]);
+		break;
+	case 25:
+		n = getfields(s, args, 8, 1, "- T:.+Z");
+		if(n != 8)
+			sysfatal("error parsing atom date: %d", n);
+		ret.year = atoi(args[0]) - 1900;
+		ret.mon = atoi(args[1]) - 1;
+		ret.mday = atoi(args[2]);
+		ret.tzoff = atoi(args[6]);
+		ret.hour = atoi(args[3]);
+		ret.min = atoi(args[4]);
+		ret.sec = atoi(args[5]);
+		break;
+	case 23:
+		n = getfields(s, args, 7, 1, "- T:.+Z");
+		if(n != 7)
+			sysfatal("error parsing atom date: %d", n);
+		ret.year = atoi(args[0]) - 1900;
+		ret.mon = atoi(args[1]);
+		ret.mday = atoi(args[2]);
+		ret.tzoff = 0;
+		ret.hour = atoi(args[3]);
+		ret.min = atoi(args[4]);
+		ret.sec = atoi(args[5]);
+		break;
+	case 20:
+		n = getfields(s, args, 6, 1, "- T:.+Z");
+		if(n != 6)
+			sysfatal("error parsing atom date: %d", n);
+		ret.year = atoi(args[0]) - 1900;
+		ret.mon = atoi(args[1]) - 1;
+		ret.mday = atoi(args[2]);
+		ret.tzoff = 0;
+		ret.hour = atoi(args[3]);
+		ret.min = atoi(args[4]);
+		ret.sec = atoi(args[5]);
+		break;
+	default:
+		sysfatal("error parsing atom date format: %s", s);
+	}
+	ret.yday = doty(ret.mday, ret.mon, ret.year);
+	
+	return tm2sec(&ret) - ret.tzoff*60*60;
+}
+
+long
+parsedate(char *s)
+{
+	Tm ret;
+	char input[64];
+	char *args[8];
+	int n, i;
+	
+	strcpy(input, s);
+	n = getfields(input, args, 8, 1, ", :");
+	
+	if(n < 8){
+		/* try parsing atom date */
+		return parseatomdate(s);
+	}
+	
+	for(i = 0; i < n; i++){
+		if(!args[i])
+			sysfatal("error parsing pubDate: %s", s);
+		switch(i){
+		case 0: /* day of the week */
+			ret.wday = str2wday(args[i]);
+			break;
+		case 1: /* day of the month */
+			ret.mday = atoi(args[i]);
+			break;
+		case 2: /* month of the year */
+			ret.mon = str2mon(args[i]);
+			break;
+		case 3: /* year */
+			ret.year = atoi(args[i]) - 1900;
+			break;
+		case 4: /* hour */
+			ret.hour = atoi(args[i]);
+			break;
+		case 5: /* minute */
+			ret.min = atoi(args[i]);
+			break;
+		case 6: /* second */
+			ret.sec = atoi(args[i]);
+			break;
+		case 7: /* timezone offset */
+			ret.tzoff = atoi(args[i])/100;
+			break;
+		}
+	}
+	ret.yday = doty(ret.mday, ret.mon, ret.year);
+	
+	return tm2sec(&ret) - ret.tzoff*60*60;
+}
\ No newline at end of file
--- a/date.h
+++ b/date.h
@@ -1,116 +1,5 @@
-int
-str2mon(char *s)
-{
-	if(!strcmp(s, "Jan")) return 0;
-	if(!strcmp(s, "Feb")) return 1;
-	if(!strcmp(s, "Mar")) return 2;
-	if(!strcmp(s, "Apr")) return 3;
-	if(!strcmp(s, "May")) return 4;
-	if(!strcmp(s, "Jun")) return 5;
-	if(!strcmp(s, "Jul")) return 6;
-	if(!strcmp(s, "Aug")) return 7;
-	if(!strcmp(s, "Sep")) return 8;
-	if(!strcmp(s, "Oct")) return 9;
-	if(!strcmp(s, "Nov")) return 10;
-	if(!strcmp(s, "Dec")) return 11;
-	return 0;
-}
-
-int
-str2wday(char *s)
-{
-	if(!strcmp(s, "Sun")) return 0;
-	if(!strcmp(s, "Mon")) return 1;
-	if(!strcmp(s, "Tue")) return 2;
-	if(!strcmp(s, "Wed")) return 3;
-	if(!strcmp(s, "Thu")) return 4;
-	if(!strcmp(s, "Fri")) return 5;
-	if(!strcmp(s, "Sat")) return 6;
-	return 0;
-}
-
-int
-doty(int day, int month, int year)
-{
-	int n, i;
-	
-	n = 0;
-	for(i = 0; i < month; i++){
-		if(i == 0) n += 31;
-		if(i == 1){
-			if(year%4 == 0 && year%100 == 0 && year%400 != 0)
-				n += 29;
-			else
-				n += 28;
-		}
-		if(i == 2) n += 31;
-		if(i == 3) n += 30;
-		if(i == 4) n += 31;
-		if(i == 5) n += 30;
-		if(i == 6) n += 31;
-		if(i == 7) n += 31;
-		if(i == 8) n += 30;
-		if(i == 9) n += 31;
-		if(i == 10) n += 30;
-		if(i == 11) n += 31;
-	}
-	
-	n += day;
-	
-	return n;
-}
-
-long
-parsedate(char *s)
-{
-	Tm ret;
-	char input[64];
-	char *args[8];
-	int n, i;
-	
-	strcpy(input, s);
-	n = getfields(input, args, 8, 1, ", :");
-	
-	if(n < 8)
-		sysfatal("error parsing pubDate: %s", s);
-	
-	for(i = 0; i < n; i++){
-		if(!args[i])
-			sysfatal("error parsing pubDate: %s", s);
-		switch(i){
-		case 0: /* day of the week */
-			ret.wday = str2wday(args[i]);
-			break;
-		case 1: /* day of the month */
-			ret.mday = atoi(args[i]);
-			break;
-		case 2: /* month of the year */
-			ret.mon = str2mon(args[i]);
-			break;
-		case 3: /* year */
-			ret.year = atoi(args[i]) - 1900;
-			break;
-		case 4: /* hour */
-			ret.hour = atoi(args[i]);
-			break;
-		case 5: /* minute */
-			ret.min = atoi(args[i]);
-			break;
-		case 6: /* second */
-			ret.sec = atoi(args[i]);
-			break;
-		case 7: /* timezone offset */
-			ret.tzoff = atoi(args[i])/100;
-			break;
-		}
-	}
-	/*
-	ret.zone[0] = 'C';
-	ret.zone[1] = 'E';
-	ret.zone[2] = 'S';
-	ret.zone[3] = 'T';
-	*/
-	ret.yday = doty(ret.mday, ret.mon, ret.year);
-	
-	return tm2sec(&ret) - ret.tzoff*60*60;
-}
\ No newline at end of file
+int str2mon(char *s);
+int str2wday(char *s);
+int doty(int day, int month, int year);
+long parseatomdate(char *s);
+long parsedate(char *s);
--- a/fetchnews.rc
+++ b/fetchnews.rc
@@ -2,8 +2,8 @@
 
 O=6
 
-urls=( https://www.tagesschau.de/xml/rss2 https://lukesmith.xyz/rss.xml )
-prefixes=( tschau lukesmith )
+urls=( https://www.tagesschau.de/xml/rss2 https://lukesmith.xyz/rss.xml https://www.heise.de/security/rss/news-atom.xml )
+prefixes=( tschau lukesmith heisesec )
 
 ramfs -m /lib/news
 
--- a/mkfile
+++ b/mkfile
@@ -1,7 +1,7 @@
 </$objtype/mkfile
 
 TARG=rssfill
-OFILES=rssfill.$O
+OFILES=rssfill.$O date.$O
 HFILES=rssfill.h xmlpull.h date.h
 
 </sys/src/cmd/mkone
--- a/rssfill.c
+++ b/rssfill.c
@@ -246,6 +246,10 @@
 				st = DATE;
 				break;
 			}
+			if(!strcmp(x->na, "updated") && st == ITEM){
+				st = DATE;
+				break;
+			}
 			break;
 		case START_END_TAG:
 			break;
@@ -297,6 +301,10 @@
 				break;
 			}
 			if(!strcmp(x->na, "pubDate") && st == DATE){
+				st = ITEM;
+				break;
+			}
+			if(!strcmp(x->na, "updated") && st == DATE){
 				st = ITEM;
 				break;
 			}