sfeed

simple feed reader - forked from git.codemadness.org/sfeed
git clone git://src.gearsix.net/sfeed
Log | Files | Refs | Atom | README | LICENSE

sfeed_html.c (3821B)


      1 #include <sys/types.h>
      2 
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 #include <time.h>
      7 
      8 #include "util.h"
      9 
     10 static struct feed *feeds;
     11 static int showsidebar;
     12 static char *line;
     13 static size_t linesize;
     14 static unsigned long totalnew, total;
     15 static time_t comparetime;
     16 
     17 static void
     18 printfeed(FILE *fp, struct feed *f)
     19 {
     20 	char *fields[FieldLast];
     21 	struct tm rtm, *tm;
     22 	time_t parsedtime;
     23 	unsigned int isnew;
     24 	ssize_t linelen;
     25 
     26 	if (f->name[0]) {
     27 		fputs("<h2 id=\"", stdout);
     28 		xmlencode(f->name, stdout);
     29 		fputs("\"><a href=\"#", stdout);
     30 		xmlencode(f->name, stdout);
     31 		fputs("\">", stdout);
     32 		xmlencode(f->name, stdout);
     33 		fputs("</a></h2>\n", stdout);
     34 	}
     35 	fputs("<pre>\n", stdout);
     36 
     37 	while ((linelen = getline(&line, &linesize, fp)) > 0 &&
     38 	       !ferror(stdout)) {
     39 		if (line[linelen - 1] == '\n')
     40 			line[--linelen] = '\0';
     41 		parseline(line, fields);
     42 
     43 		parsedtime = 0;
     44 		if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) &&
     45 		    (tm = localtime_r(&parsedtime, &rtm))) {
     46 			isnew = (parsedtime >= comparetime) ? 1 : 0;
     47 			totalnew += isnew;
     48 			f->totalnew += isnew;
     49 
     50 			fprintf(stdout, "%04d-%02d-%02d&nbsp;%02d:%02d ",
     51 			        tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
     52 			        tm->tm_hour, tm->tm_min);
     53 		} else {
     54 			isnew = 0;
     55 			fputs("                 ", stdout);
     56 		}
     57 		f->total++;
     58 		total++;
     59 
     60 		if (fields[FieldLink][0]) {
     61 			fputs("<a href=\"", stdout);
     62 			xmlencode(fields[FieldLink], stdout);
     63 			fputs("\">", stdout);
     64 		}
     65 		if (isnew)
     66 			fputs("<b><u>", stdout);
     67 		xmlencode(fields[FieldTitle], stdout);
     68 		if (isnew)
     69 			fputs("</u></b>", stdout);
     70 		if (fields[FieldLink][0])
     71 			fputs("</a>", stdout);
     72 		fputs("\n", stdout);
     73 	}
     74 	fputs("</pre>\n", stdout);
     75 }
     76 
     77 int
     78 main(int argc, char *argv[])
     79 {
     80 	struct feed *f;
     81 	char *name;
     82 	FILE *fp;
     83 	int i;
     84 
     85 	if (pledge(argc == 1 ? "stdio" : "stdio rpath", NULL) == -1)
     86 		err(1, "pledge");
     87 
     88 	if (!(feeds = calloc(argc, sizeof(struct feed))))
     89 		err(1, "calloc");
     90 	if ((comparetime = time(NULL)) == (time_t)-1)
     91 		errx(1, "time");
     92 	/* 1 day is old news */
     93 	comparetime -= 86400;
     94 
     95 	fputs("<!DOCTYPE HTML>\n"
     96 	      "<html>\n"
     97 	      "\t<head>\n"
     98 	      "\t<meta name=\"referrer\" content=\"no-referrer\" />\n"
     99 	      "\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"
    100 	      "\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n"
    101 	      "\t</head>\n"
    102 	      "\t<body class=\"noframe\">\n", stdout);
    103 
    104 	showsidebar = (argc > 1);
    105 	if (showsidebar)
    106 		fputs("\t\t<div id=\"items\">\n", stdout);
    107 	else
    108 		fputs("\t\t<div id=\"items\" class=\"nosidebar\">\n", stdout);
    109 
    110 	if (argc == 1) {
    111 		feeds[0].name = "";
    112 		printfeed(stdin, &feeds[0]);
    113 		checkfileerror(stdin, "<stdin>", 'r');
    114 	} else {
    115 		for (i = 1; i < argc; i++) {
    116 			name = ((name = strrchr(argv[i], '/'))) ? name + 1 : argv[i];
    117 			feeds[i - 1].name = name;
    118 			if (!(fp = fopen(argv[i], "r")))
    119 				err(1, "fopen: %s", argv[i]);
    120 			printfeed(fp, &feeds[i - 1]);
    121 			checkfileerror(fp, argv[i], 'r');
    122 			checkfileerror(stdout, "<stdout>", 'w');
    123 			fclose(fp);
    124 		}
    125 	}
    126 	fputs("</div>\n", stdout); /* div items */
    127 
    128 	if (showsidebar) {
    129 		fputs("\t<div id=\"sidebar\">\n\t\t<ul>\n", stdout);
    130 
    131 		for (i = 1; i < argc; i++) {
    132 			f = &feeds[i - 1];
    133 			if (f->totalnew > 0)
    134 				fputs("<li class=\"n\"><a href=\"#", stdout);
    135 			else
    136 				fputs("<li><a href=\"#", stdout);
    137 			xmlencode(f->name, stdout);
    138 			fputs("\">", stdout);
    139 			if (f->totalnew > 0)
    140 				fputs("<b><u>", stdout);
    141 			xmlencode(f->name, stdout);
    142 			fprintf(stdout, " (%lu)", f->totalnew);
    143 			if (f->totalnew > 0)
    144 				fputs("</u></b>", stdout);
    145 			fputs("</a></li>\n", stdout);
    146 		}
    147 		fputs("\t\t</ul>\n\t</div>\n", stdout);
    148 	}
    149 
    150 	fprintf(stdout, "\t</body>\n\t<title>(%lu/%lu) - Newsfeed</title>\n</html>\n",
    151 	        totalnew, total);
    152 
    153 	checkfileerror(stdout, "<stdout>", 'w');
    154 
    155 	return 0;
    156 }