sfeed

Simple RSS and Atom feed parser
git clone https://git.sinitax.com/codemadness/sfeed
Log | Files | Refs | README | LICENSE | Upstream | sfeed.txt

sfeed_frames.c (5250B)


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