commit 7e575e13c0cdcc4341fa2f0b6dcb90cb4bd3cd71
parent b2fa0c97f2b5d97631d39fa0cb3f7fe51a10a3c7
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun, 21 Jun 2015 00:24:30 +0200
improvements
Diffstat:
M | sfeed_frames.1 | | | 2 | +- |
M | sfeed_frames.c | | | 221 | +++++++++++++++++++++++++++++++++++++------------------------------------------ |
M | sfeed_html.c | | | 154 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
M | sfeed_plain.1 | | | 22 | ++++++++++++++-------- |
M | sfeed_plain.c | | | 56 | ++++++++++++++++++++++++++++++++++++++++---------------- |
M | sfeed_update.1 | | | 79 | +++++++++++++++++++++++++++---------------------------------------------------- |
M | util.c | | | 14 | +++++++------- |
M | util.h | | | 28 | ++++++++++++++-------------- |
8 files changed, 288 insertions(+), 288 deletions(-)
diff --git a/sfeed_frames.1 b/sfeed_frames.1
@@ -6,7 +6,7 @@
.Nd formats a feeds file to HTML with frames
.Sh SYNOPSIS
.Nm
-.Op Ar directory path
+.Op Ar feed...
.Sh DESCRIPTION
.Nm
formats a feeds file (TSV) from
diff --git a/sfeed_frames.c b/sfeed_frames.c
@@ -12,15 +12,16 @@
#include <unistd.h>
#include <utime.h>
-#include "queue.h"
#include "util.h"
-static int showsidebar = 1; /* show sidebar ? */
-static FILE *fpindex = NULL, *fpitems = NULL, *fpmenu = NULL;
-static FILE *fpcontent = NULL;
static char *line = NULL;
-static SLIST_HEAD(fhead, feed) fhead = SLIST_HEAD_INITIALIZER(fhead);
+size_t linesize = 0;
+
static struct utimbuf contenttime;
+static time_t comparetime;
+static unsigned long totalnew = 0;
+
+static struct feed **feeds = NULL;
/* normalize path names, transform to lower-case and replace non-alpha and
* non-digit with '-' */
@@ -34,7 +35,7 @@ normalizepath(const char *path, char *buf, size_t bufsiz)
buf[i++] = tolower((int)*path);
r = 0;
} else {
- /* don't repeat '-'. */
+ /* don't repeat '-' */
if(!r)
buf[i++] = '-';
r++;
@@ -50,102 +51,53 @@ normalizepath(const char *path, char *buf, size_t bufsiz)
return i;
}
-int
-main(int argc, char *argv[])
+static void
+printfeed(FILE *fpitems, FILE *fpin, struct feed *f)
{
- struct feed *f, *fcur = NULL;
- char *fields[FieldLast];
- char name[256]; /* buffer for feedname */
char dirpath[PATH_MAX], filepath[PATH_MAX];
- char reldirpath[PATH_MAX], relfilepath[PATH_MAX];
- char *feedname = "", *basepath = ".";
- unsigned long totalfeeds = 0, totalnew = 0;
- unsigned int isnew;
- time_t parsedtime, comparetime;
- size_t linesize = 0, namelen, basepathlen;
+ char *fields[FieldLast], *feedname;
+ char name[PATH_MAX];
+ size_t namelen;
struct stat st;
+ FILE *fpcontent = NULL;
+ unsigned int isnew;
+ time_t parsedtime;
int r;
- if(argc > 1 && argv[1][0] != '\0')
- basepath = argv[1];
-
- /* 1 day is old news */
- comparetime = time(NULL) - 86400;
-
- basepathlen = strlen(basepath);
- if(basepathlen > 0) {
- mkdir(basepath, S_IRWXU);
- err(1, "mkdir: %s", basepath);
+ if(f->name[0])
+ feedname = f->name;
+ else
+ feedname = "unnamed";
+
+ /* make directory for feedname */
+ if(!(namelen = normalizepath(feedname, name, sizeof(name))))
+ return;
+
+ if(strlcpy(dirpath, name, sizeof(dirpath)) >= sizeof(dirpath))
+ errx(1, "strlcpy: path truncation");
+ /* directory doesn't exist: try to create it. */
+ if(stat(dirpath, &st) == -1 && mkdir(dirpath, S_IRWXU) == -1)
+ err(1, "mkdir: %s", dirpath);
+
+ /* menu if not unnamed */
+ if(f->name[0]) {
+ fputs("<h2 id=\"", fpitems);
+ printxmlencoded(f->name, fpitems);
+ fputs("\"><a href=\"#", fpitems);
+ printxmlencoded(f->name, fpitems);
+ fputs("\">", fpitems);
+ printxmlencoded(f->name, fpitems);
+ fputs("</a></h2>\n", fpitems);
}
- /* write main index page */
- esnprintf(dirpath, sizeof(dirpath), "%s/index.html", basepath);
- if(!(fpindex = fopen(dirpath, "w+b")))
- err(1, "fopen: %s", dirpath);
- esnprintf(dirpath, sizeof(dirpath), "%s/menu.html", basepath);
- if(!(fpmenu = fopen(dirpath, "w+b")))
- err(1, "fopen: %s", dirpath);
- esnprintf(dirpath, sizeof(dirpath), "%s/items.html", basepath);
- if(!(fpitems = fopen(dirpath, "w+b")))
- err(1, "fopen: %s", dirpath);
- fputs("<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"../style.css\" />"
- "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head>"
- "<body class=\"frame\"><div id=\"items\">", fpitems);
-
- if(!(fcur = calloc(1, sizeof(struct feed))))
- err(1, "calloc");
- SLIST_INSERT_HEAD(&fhead, fcur, entry);
-
- while(parseline(&line, &linesize, fields, FieldLast, '\t', stdin) > 0) {
- feedname = fields[FieldFeedName];
- if(feedname[0] == '\0') {
- feedname = "unknown";
- /* assume single feed (hide sidebar) */
- if(!totalfeeds)
- showsidebar = 0;
- }
- /* first of feed section or new feed section (differ from previous). */
- if(!totalfeeds || strcmp(fcur->name, feedname)) {
- /* make directory for feedname */
- if(!(namelen = normalizepath(feedname, name, sizeof(name))))
- continue;
- esnprintf(dirpath, sizeof(dirpath), "%s/%s", basepath, name);
-
- /* directory doesn't exist: try to create it. */
- if(stat(dirpath, &st) == -1 && mkdir(dirpath, S_IRWXU) == -1)
- err(1, "mkdir: %s", dirpath);
- if(strlcpy(reldirpath, name, sizeof(reldirpath)) >= sizeof(reldirpath))
- errx(1, "strlcpy: truncation");
-
- if(!(f = calloc(1, sizeof(struct feed))))
- err(1, "calloc");
- if(!(f->name = strdup(feedname)))
- err(1, "strdup");
- SLIST_INSERT_AFTER(fcur, f, entry);
- fcur = f;
-
- /* end previous feed section. */
- if(totalfeeds)
- fputs("</table>\n", fpitems);
-
- /* write menu link if new. */
- if(fields[FieldFeedName][0] != '\0') {
- fputs("<h2 id=\"", fpitems);
- printfeednameid(fcur->name, fpitems);
- fputs("\"><a href=\"#", fpitems);
- printfeednameid(fcur->name, fpitems);
- fputs("\">", fpitems);
- fputs(fcur->name, fpitems);
- fputs("</a></h2>\n", fpitems);
- }
- fputs("<table cellpadding=\"0\" cellspacing=\"0\">\n", fpitems);
- totalfeeds++;
- }
+ fputs("<table cellpadding=\"0\" cellspacing=\"0\">\n", fpitems);
+ while(parseline(&line, &linesize, fields, FieldLast, '\t', fpin) > 0) {
/* write content */
if(!(namelen = normalizepath(fields[FieldTitle], name, sizeof(name))))
continue;
- esnprintf(filepath, sizeof(filepath), "%s/%s.html", dirpath, name);
- esnprintf(relfilepath, sizeof(relfilepath), "%s/%s.html", reldirpath, name);
+ r = snprintf(filepath, sizeof(filepath), "%s/%s.html", dirpath, name);
+ if(r == -1 || (size_t)r >= sizeof(filepath))
+ errx(1, "snprintf: path truncation");
/* file doesn't exist yet and has write access */
if(access(filepath, F_OK) != 0) {
@@ -155,22 +107,17 @@ main(int argc, char *argv[])
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head>\n"
"<body class=\"frame\"><div class=\"content\">"
"<h2><a href=\"", fpcontent);
- if(fields[FieldBaseSiteUrl][0] != '\0')
- printlink(fields[FieldLink], fields[FieldBaseSiteUrl], fpcontent);
- else
- printlink(fields[FieldLink], fields[FieldFeedUrl], fpcontent);
+ printxmlencoded(fields[FieldLink], fpcontent);
fputs("\">", fpcontent);
- printhtmlencoded(fields[FieldTitle], fpcontent);
+ printxmlencoded(fields[FieldTitle], fpcontent);
fputs("</a></h2>", fpcontent);
printcontent(fields[FieldContent], fpcontent);
fputs("</div></body></html>", fpcontent);
fclose(fpcontent);
}
- /* write item. */
- r = strtotime(fields[FieldUnixTimestamp], &parsedtime);
-
/* set modified and access time of file to time of item. */
+ r = strtotime(fields[FieldUnixTimestamp], &parsedtime);
if(r != -1) {
contenttime.actime = parsedtime;
contenttime.modtime = parsedtime;
@@ -179,8 +126,8 @@ main(int argc, char *argv[])
isnew = (r != -1 && parsedtime >= comparetime) ? 1 : 0;
totalnew += isnew;
- fcur->totalnew += isnew;
- fcur->total++;
+ f->totalnew += isnew;
+ f->total++;
if(isnew)
fputs("<tr class=\"n\">", fpitems);
else
@@ -191,32 +138,76 @@ main(int argc, char *argv[])
if(isnew)
fputs("<b><u>", fpitems);
fputs("<a href=\"", fpitems);
- fputs(relfilepath, fpitems);
+ fputs(filepath, fpitems);
fputs("\" target=\"content\">", fpitems);
- printhtmlencoded(fields[FieldTitle], fpitems);
+ printxmlencoded(fields[FieldTitle], fpitems);
fputs("</a>", fpitems);
if(isnew)
fputs("</u></b>", fpitems);
fputs("</td></tr>\n", fpitems);
}
- if(totalfeeds) {
- fputs("</table>\n", fpitems);
+ fputs("</table>\n", fpitems);
+}
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fpindex, *fpitems, *fpmenu, *fp;
+ int showsidebar = (argc > 1);
+ int i;
+ struct feed *f;
+
+ if(!(feeds = calloc(argc, sizeof(struct feed *))))
+ err(1, "calloc");
+
+ /* 1 day is old news */
+ comparetime = time(NULL) - 86400;
+
+ /* write main index page */
+ if(!(fpindex = fopen("index.html", "w+b")))
+ err(1, "fopen: index.html");
+ if(!(fpmenu = fopen("menu.html", "w+b")))
+ err(1, "fopen: menu.html");
+ if(!(fpitems = fopen("items.html", "w+b")))
+ err(1, "fopen: items.html");
+ fputs("<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"../style.css\" />"
+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head>"
+ "<body class=\"frame\"><div id=\"items\">", fpitems);
+
+ if(argc == 1) {
+ if(!(feeds[0] = calloc(1, sizeof(struct feed))))
+ err(1, "calloc");
+ feeds[0]->name = "";
+ printfeed(fpitems, stdin, feeds[0]);
+ } else {
+ for(i = 1; i < argc; i++) {
+ if(!(feeds[i - 1] = calloc(1, sizeof(struct feed))))
+ err(1, "calloc");
+ feeds[i - 1]->name = xbasename(argv[i]);
+
+ if(!(fp = fopen(argv[i], "r")))
+ err(1, "fopen: %s", argv[i]);
+ printfeed(fpitems, fp, feeds[i - 1]);
+ if(ferror(fp))
+ err(1, "ferror: %s", argv[i]);
+ fclose(fp);
+ }
}
fputs("\n</div></body>\n</html>", fpitems); /* div items */
+
if(showsidebar) {
fputs("<html><head>"
"<link rel=\"stylesheet\" type=\"text/css\" href=\"../style.css\" />\n"
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"
"</head><body class=\"frame\"><div id=\"sidebar\">", fpmenu);
- SLIST_FOREACH(f, &fhead, entry) {
- if(!f->name || f->name[0] == '\0')
- continue;
+ for(i = 1; i < argc; i++) {
+ f = feeds[i - 1];
if(f->totalnew)
fputs("<a class=\"n\" href=\"items.html#", fpmenu);
else
fputs("<a href=\"items.html#", fpmenu);
- printfeednameid(f->name, fpmenu);
+ printxmlencoded(f->name, fpmenu);
fputs("\" target=\"items\">", fpmenu);
if(f->totalnew > 0)
fputs("<b><u>", fpmenu);
@@ -245,13 +236,9 @@ main(int argc, char *argv[])
"</frameset>\n"
"</html>", fpindex);
- /* cleanup */
- if(fpmenu)
- fclose(fpmenu);
- if(fpitems)
- fclose(fpitems);
- if(fpindex)
- fclose(fpindex);
+ fclose(fpitems);
+ fclose(fpmenu);
+ fclose(fpindex);
return 0;
}
diff --git a/sfeed_html.c b/sfeed_html.c
@@ -5,80 +5,42 @@
#include <string.h>
#include <time.h>
-#include "queue.h"
#include "util.h"
-static int showsidebar = 1; /* show sidebar ? */
-static SLIST_HEAD(feedshead, feed) fhead = SLIST_HEAD_INITIALIZER(fhead);
+static struct feed **feeds = NULL;
+static int showsidebar = 0; /* show sidebar ? */
static char *line = NULL;
+static size_t linesize = 0;
+static unsigned long totalnew = 0;
+static time_t comparetime;
-int
-main(void)
+static void
+printfeed(FILE *fp, struct feed *f)
{
char *fields[FieldLast];
- unsigned long totalfeeds = 0, totalnew = 0;
+ time_t parsedtime;
unsigned int islink, isnew;
- struct feed *f, *fcur = NULL;
- time_t parsedtime, comparetime;
- size_t size = 0;
int r;
- /* 1 day old is old news */
- comparetime = time(NULL) - 86400;
-
- fputs("<!DOCTYPE HTML>\n"
- "<html>\n"
- "\t<head>\n"
- "\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"
- "\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n"
- "\t</head>\n"
- "\t<body class=\"noframe\">\n", stdout);
-
- if(!(fcur = calloc(1, sizeof(struct feed))))
- err(1, "calloc");
- SLIST_INSERT_HEAD(&fhead, fcur, entry);
+ if(f->name[0] != '\0') {
+ fputs("<h2 id=\"", stdout);
+ printxmlencoded(f->name, stdout);
+ fputs("\"><a href=\"#", stdout);
+ printxmlencoded(f->name, stdout);
+ fputs("\">", stdout);
+ printxmlencoded(f->name, stdout);
+ fputs("</a></h2>\n", stdout);
+ }
+ fputs("<table cellpadding=\"0\" cellspacing=\"0\">\n", stdout);
- while(parseline(&line, &size, fields, FieldLast, '\t', stdin) > 0) {
+ while(parseline(&line, &linesize, fields, FieldLast, '\t', fp) > 0) {
r = strtotime(fields[FieldUnixTimestamp], &parsedtime);
isnew = (r != -1 && parsedtime >= comparetime) ? 1 : 0;
islink = (fields[FieldLink][0] != '\0') ? 1 : 0;
- /* first of feed section or new feed section (differs from
- * previous one). */
- if(!totalfeeds || strcmp(fcur->name, fields[FieldFeedName])) {
- if(!(f = calloc(1, sizeof(struct feed))))
- err(1, "calloc");
- if(!(f->name = strdup(fields[FieldFeedName])))
- err(1, "strdup");
-
- SLIST_INSERT_AFTER(fcur, f, entry);
- fcur = f;
-
- if(totalfeeds) { /* end previous one. */
- fputs("</table>\n", stdout);
- } else {
- if(fields[FieldFeedName][0] == '\0' || !showsidebar) {
- /* set nosidebar class on div for styling */
- fputs("\t\t<div id=\"items\" class=\"nosidebar\">\n", stdout);
- showsidebar = 0;
- } else {
- fputs("\t\t<div id=\"items\">\n", stdout);
- }
- }
- if(fields[FieldFeedName][0] != '\0') {
- fputs("<h2 id=\"", stdout);
- printfeednameid(fcur->name, stdout);
- fputs("\"><a href=\"#", stdout);
- printfeednameid(fcur->name, stdout);
- fputs("\">", stdout);
- fputs(fcur->name, stdout);
- fputs("</a></h2>\n", stdout);
- }
- fputs("<table cellpadding=\"0\" cellspacing=\"0\">\n", stdout);
- totalfeeds++;
- }
+
totalnew += isnew;
- fcur->totalnew += isnew;
- fcur->total++;
+ f->totalnew += isnew;
+ f->total++;
if(isnew)
fputs("<tr class=\"n\">", stdout);
@@ -91,34 +53,79 @@ main(void)
fputs("<b><u>", stdout);
if(islink) {
fputs("<a href=\"", stdout);
- if(fields[FieldBaseSiteUrl][0] != '\0')
- printlink(fields[FieldLink],
- fields[FieldBaseSiteUrl], stdout);
- else
- printlink(fields[FieldLink],
- fields[FieldFeedUrl], stdout);
+ printxmlencoded(fields[FieldLink], stdout);
fputs("\">", stdout);
}
- printhtmlencoded(fields[FieldTitle], stdout);
+ printxmlencoded(fields[FieldTitle], stdout);
if(islink)
fputs("</a>", stdout);
if(isnew)
fputs("</u></b>", stdout);
fputs("</td></tr>\n", stdout);
}
- if(totalfeeds)
- fputs("</table>\n\t\t</div>\n", stdout); /* div items */
+ fputs("</table>\n", stdout);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct feed *f;
+ FILE *fp;
+ int i;
+
+ if(!(feeds = calloc(argc, sizeof(struct feed *))))
+ err(1, "calloc");
+
+ /* 1 day old is old news */
+ comparetime = time(NULL) - 86400;
+
+ fputs("<!DOCTYPE HTML>\n"
+ "<html>\n"
+ "\t<head>\n"
+ "\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"
+ "\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n"
+ "\t</head>\n"
+ "\t<body class=\"noframe\">\n", stdout);
+
+ showsidebar = (argc > 1);
+ if(showsidebar)
+ fputs("\t\t<div id=\"items\">\n", stdout);
+ else
+ fputs("\t\t<div id=\"items\" class=\"nosidebar\">\n", stdout);
+
+ if(argc == 1) {
+ if(!(feeds[0] = calloc(1, sizeof(struct feed))))
+ err(1, "calloc");
+ feeds[0]->name = "";
+ printfeed(stdin, feeds[0]);
+ if(ferror(stdin))
+ err(1, "ferror: <stdin>:");
+ } else {
+ for(i = 1; i < argc; i++) {
+ if(!(feeds[i - 1] = calloc(1, sizeof(struct feed))))
+ err(1, "calloc");
+ feeds[i - 1]->name = xbasename(argv[i]);
+
+ if(!(fp = fopen(argv[i], "r")))
+ err(1, "fopen: %s", argv[i]);
+ printfeed(fp, feeds[i - 1]);
+ if(ferror(fp))
+ err(1, "ferror: %s", argv[i]);
+ fclose(fp);
+ }
+ }
+ fputs("</div>\n", stdout); /* div items */
+
if(showsidebar) {
fputs("\t<div id=\"sidebar\">\n\t\t<ul>\n", stdout);
- SLIST_FOREACH(f, &fhead, entry) {
- if(!f->name || f->name[0] == '\0')
- continue;
+ for (i = 1; i < argc; i++) {
+ f = feeds[i - 1];
if(f->totalnew > 0)
fputs("<li class=\"n\"><a href=\"#", stdout);
else
fputs("<li><a href=\"#", stdout);
- printfeednameid(f->name, stdout);
+ printxmlencoded(f->name, stdout);
fputs("\">", stdout);
if(f->totalnew > 0)
fputs("<b><u>", stdout);
@@ -129,6 +136,7 @@ main(void)
}
fputs("\t\t</ul>\n\t</div>\n", stdout);
}
+
fprintf(stdout, "\t</body>\n\t<title>Newsfeed (%lu)</title>\n</html>",
totalnew);
diff --git a/sfeed_plain.1 b/sfeed_plain.1
@@ -3,19 +3,25 @@
.Os
.Sh NAME
.Nm sfeed_plain
-.Nd formats a feeds file to plain text
+.Nd formats a feeds file to a plain-text list
.Sh SYNOPSIS
.Nm
+.Op Ar file...
.Sh DESCRIPTION
.Nm
-formats a feeds file (TSV) from
-.Xr sfeed_update 1
-to plain text. It reads TSV data from stdin and writes formatted plain text to
-stdout. For the exact TSV format see
-.Xr sfeed_update 1 .
+formats one or more
+.Ar files
+to a plain-text list. Each plain-text item will contain the feed name which
+will be the filename. If no argument is given it will read a feed from stdin,
+but there will not be a feed name.
+The data read from
+.Ar files
+or stdin is in a TAB-separated-like format from
+.Xr sfeed 1
+For a more detailed list of this format and its fields see
+.Xr sfeed 1
.Sh SEE ALSO
.Xr sfeed 1 ,
-.Xr sfeed_html 1 ,
-.Xr sfeed_update 1
+.Xr sfeed_html 1
.Sh AUTHORS
.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org
diff --git a/sfeed_plain.c b/sfeed_plain.c
@@ -1,3 +1,4 @@
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -5,31 +6,54 @@
#include "util.h"
-int
-main(void)
+static time_t comparetime;
+static char *line = NULL;
+static size_t size = 0;
+
+static void
+printfeed(FILE *fp, const char *feedname)
{
- char *line = NULL, *fields[FieldLast];
- time_t parsedtime, comparetime;
- size_t size = 0;
+ char *fields[FieldLast];
+ time_t parsedtime;
int r;
- comparetime = time(NULL) - (3600 * 24); /* 1 day is old news */
- while(parseline(&line, &size, fields, FieldLast, '\t', stdin) > 0) {
+ while(parseline(&line, &size, fields, FieldLast, '\t', fp) > 0) {
r = strtotime(fields[FieldUnixTimestamp], &parsedtime);
if(r != -1 && parsedtime >= comparetime)
- fputs(" N ", stdout);
+ fputs(" N ", stdout);
else
- fputs(" ", stdout);
- if(fields[FieldFeedName][0] != '\0')
- printf("%-15.15s ", fields[FieldFeedName]);
- printf("%-30.30s ", fields[FieldTimeFormatted]);
+ fputs(" ", stdout);
+
+ if(feedname[0])
+ printf("%-15.15s ", feedname);
+ printf(" %-30.30s ", fields[FieldTimeFormatted]);
printutf8pad(stdout, fields[FieldTitle], 70, ' ');
fputs(" ", stdout);
- if(fields[FieldBaseSiteUrl][0] != '\0')
- printlink(fields[FieldLink], fields[FieldBaseSiteUrl], stdout);
- else
- printlink(fields[FieldLink], fields[FieldFeedUrl], stdout);
+ fputs(fields[FieldLink], stdout);
putchar('\n');
}
+}
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fp;
+ int i;
+
+ /* 1 day is old news */
+ comparetime = time(NULL) - (3600 * 24);
+
+ if(argc == 1) {
+ printfeed(stdin, "");
+ } else {
+ for(i = 1; i < argc; i++) {
+ if(!(fp = fopen(argv[i], "r")))
+ err(1, "fopen: %s", argv[i]);
+ printfeed(fp, xbasename(argv[i]));
+ if(ferror(fp))
+ err(1, "ferror: %s", argv[i]);
+ fclose(fp);
+ }
+ }
return 0;
}
diff --git a/sfeed_update.1 b/sfeed_update.1
@@ -9,80 +9,55 @@
.Op Ar configfile
.Sh DESCRIPTION
.Nm
-updates feeds and merges the new data with the previous feeds. This is the file
-$HOME/.sfeed/feeds by default.
+updates feeds files and merges the new data with the previous files. These
+are the files in the directory
+.Pa $HOME/.sfeed/feeds
+by default.
.Sh OPTIONS
.Bl -tag -width 17n
.It Ar configfile
-config file, if not specified uses the location $HOME/.sfeed/sfeedrc by default
-see the
+config file, if not specified uses the path
+.Pa $HOME/.sfeed/sfeedrc
+by default. See the
.Sx FILES READ
section for more information.
.El
-.Sh TAB-SEPARATED FORMAT FIELDS
-The items are saved in a TSV-like format except newlines, tabs and
-backslash are escaped with \\ (\\n, \\t and \\\\). Carriage returns (\\r) are
-removed.
-.Pp
-The order and format of the fields are:
-.Bl -tag -width 17n
-.It Ar item timestamp
-string, UNIX timestamp in GMT+0
-.It Ar item timestamp
-string, date and time in the format: YYYY-mm-dd HH:MM:SS tzname[[+-][HHMM]]
-.It Ar item title
-string
-.It Ar item link
-string
-.It Ar item content
-string
-.It Ar item content\-type
-string, "html" or "plain"
-.It Ar item id
-string
-.It Ar item author
-string
-.It Ar feed type
-string, "rss" or "atom"
-.El
-.Sh EXTRA FIELDS
-Extra fields added by sfeed_update:
-.Bl -tag -width 17n
-.It Ar feed name
-string
-.It Ar feed url
-string
-.It Ar item baseurl site
-string
-.El
.Sh FILES READ
.Bl -tag -width 17n
.It Ar sfeedrc
Config file, see the sfeedrc.example file for an example.
-This file is evaluated as a shellscript in sfeed_update.
+This file is evaluated as a shellscript in
+.Nm .
You can for example override the fetchfeed() function to
-use wget, fetch or an other download program or you can
-override the merge() function to change the merge logic.
-The function feeds() is called to fetch the feeds. By
-default the function feed() is executed as a parallel
-job to speedup updating.
+use
+.Xr curl 1 ,
+.Xr wget 1 ,
+or an other network downloader or you can override the merge() function to
+change the merge logic. The function feeds() is called to fetch the feeds. By
+default the function feed() is executed as a parallel job to speedup updating.
.El
.Sh FILES WRITTEN
.Bl -tag -width 17n
-.It Ar feeds
-Tab-separated format containing all feeds.
+.It Ar feedname
+Tab-separated format containing all items per feed.
The sfeed_update script merges new items with this file.
-.It Ar feeds.new
+.It Ar feedname.new
Temporary file used by sfeed_update to merge items.
.El
.Sh EXAMPLES
-To update feeds and format the feeds file:
+To update your feeds and format them in various formats:
.Bd -literal
+# Update
sfeed_update "configfile"
-sfeed_plain < $HOME/.sfeed/feeds > $HOME/.sfeed/feeds.txt
-sfeed_html < $HOME/.sfeed/feeds > $HOME/.sfeed/feeds.html
+# Plain-text list
+sfeed_plain $HOME/.sfeed/feeds/* > $HOME/.sfeed/feeds.txt
+# HTML
+sfeed_html $HOME/.sfeed/feeds/* > $HOME/.sfeed/feeds.html
+# HTML with frames
+mkdir somedir && cd somedir && sfeed_frames $HOME/.sfeed/feeds/*
.Ed
.Sh SEE ALSO
+.Xr sfeed 1 ,
.Xr sfeed_html 1 ,
.Xr sfeed_plain 1 ,
.Xr sh 1
diff --git a/util.c b/util.c
@@ -14,7 +14,7 @@
#include "util.h"
void
-printurlencode(const char *s, size_t len, FILE *fp)
+printurlencoded(const char *s, size_t len, FILE *fp)
{
size_t i;
@@ -43,7 +43,7 @@ printlink(const char *link, const char *baseurl, FILE *fp)
if(isrelative) {
if((ebaseproto = strstr(baseurl, "://"))) {
ebaseproto += strlen("://");
- printurlencode(baseurl, ebaseproto - baseurl, fp);
+ printurlencoded(baseurl, ebaseproto - baseurl, fp);
} else {
ebaseproto = baseurl;
if(*baseurl || (link[0] == '/' && link[1] == '/'))
@@ -54,19 +54,19 @@ printlink(const char *link, const char *baseurl, FILE *fp)
link += 2;
else if((ebasedomain = strchr(ebaseproto, '/')))
/* relative to baseurl and baseurl path. */
- printurlencode(ebaseproto, ebasedomain - ebaseproto, fp);
+ printurlencoded(ebaseproto, ebasedomain - ebaseproto, fp);
else
- printurlencode(ebaseproto, strlen(ebaseproto), fp);
+ printurlencoded(ebaseproto, strlen(ebaseproto), fp);
} else if((ebasedomain = strrchr(ebaseproto, '/'))) {
/* relative to baseurl and baseurl path. */
- printurlencode(ebaseproto, ebasedomain - ebaseproto + 1, fp);
+ printurlencoded(ebaseproto, ebasedomain - ebaseproto + 1, fp);
} else {
- printurlencode(ebaseproto, strlen(ebaseproto), fp);
+ printurlencoded(ebaseproto, strlen(ebaseproto), fp);
if(*baseurl && *link)
fputc('/', fp);
}
}
- printurlencode(link, strlen(link), fp);
+ printurlencoded(link, strlen(link), fp);
}
/* read a field-separated line from 'fp',
diff --git a/util.h b/util.h
@@ -5,8 +5,6 @@
#include "compat.h"
#endif
-#include "queue.h"
-
#define ISUTF8(c) (((c) & 0xc0) != 0x80)
#define LEN(x) (sizeof (x) / sizeof *(x))
@@ -17,20 +15,22 @@ struct feed {
unsigned long total; /* total items */
time_t timenewest;
char timenewestformat[64];
- SLIST_ENTRY(feed) entry;
};
enum { FieldUnixTimestamp = 0, FieldTimeFormatted, FieldTitle, FieldLink,
FieldContent, FieldContentType, FieldId, FieldAuthor, FieldFeedType,
- FieldFeedName, FieldFeedUrl, FieldBaseSiteUrl, FieldLast };
+ FieldLast };
+
+ssize_t chartoxmlentity(int, char *, size_t);
+int parseline(char **, size_t *, char **, unsigned int, int, FILE *);
+void printcontent(const char *, FILE *);
+void printxmlencoded(const char *, FILE *);
+void printlink(const char *, const char *, FILE *);
+void printurlencoded(const char *, size_t, FILE *);
+void printutf8pad(FILE *, const char *, size_t, int);
+int strtotime(const char *, time_t *);
+char *trimstart(const char *);
+char *trimend(const char *);
+char *xbasename(const char *);
+
-int esnprintf(char *, size_t, const char *, ...);
-int parseline(char **, size_t *, char **, unsigned int, int, FILE *);
-void printcontent(const char *, FILE *);
-void printfeednameid(const char *, FILE *);
-void printhtmlencoded(const char *, FILE *);
-void printlink(const char *, const char *, FILE *);
-void printutf8pad(FILE *, const char *, size_t, int);
-int strtotime(const char *, time_t *);
-const char * trimstart(const char *);
-const char * trimend(const char *);