sfeed_jsonfeed: rename to sfeed_json + a few tweaks - randomcrap - random crap programs of varying quality
(HTM) git clone git://git.codemadness.org/randomcrap
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 9cb7a64e11a02f5fc05f1fd439fe5d7f9be99551
(DIR) parent 2c74d5b3ae88411b316b99630f5864c3137ccce9
(HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Mon, 10 Apr 2023 16:26:05 +0200
sfeed_jsonfeed: rename to sfeed_json + a few tweaks
Diffstat:
A sfeed/sfeed_json.1 | 48 +++++++++++++++++++++++++++++++
A sfeed/sfeed_json.c | 171 +++++++++++++++++++++++++++++++
D sfeed/sfeed_jsonfeed.1 | 42 -------------------------------
D sfeed/sfeed_jsonfeed.c | 171 -------------------------------
4 files changed, 219 insertions(+), 213 deletions(-)
---
(DIR) diff --git a/sfeed/sfeed_json.1 b/sfeed/sfeed_json.1
@@ -0,0 +1,48 @@
+.Dd March 8, 2023
+.Dt SFEED_JSON 1
+.Os
+.Sh NAME
+.Nm sfeed_json
+.Nd format feed data to JSON Feed
+.Sh SYNOPSIS
+.Nm
+.Op Ar
+.Sh DESCRIPTION
+.Nm
+formats feed data (TSV) from
+.Xr sfeed 1
+from stdin or for each
+.Ar file
+to stdout as JSON Feed data.
+If one or more
+.Ar file
+arguments are specified then the basename of the
+.Ar file
+is used as the feed name in the output.
+If no
+.Ar file
+arguments are specified and so the data is read from stdin then the feed name
+is empty.
+If
+.Nm
+is reading from one or more
+.Ar file
+arguments it will prefix the entry title with "[feed name] ".
+.Sh EXIT STATUS
+.Ex -std
+.Sh EXAMPLES
+.Bd -literal
+curl -s 'https://codemadness.org/atom.xml' | sfeed | sfeed_json
+.Ed
+.Sh SEE ALSO
+.Xr sfeed 1 ,
+.Xr sfeed_atom 1 ,
+.Xr sfeed 5
+.Sh STANDARDS
+.Rs
+.%T JSON Feed Version 1.1
+.%U https://www.jsonfeed.org/version/1.1/
+.%D Nov, 2022
+.Re
+.Sh AUTHORS
+.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org
(DIR) diff --git a/sfeed/sfeed_json.c b/sfeed/sfeed_json.c
@@ -0,0 +1,171 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "util.h"
+
+static char *line;
+static size_t linesize;
+static int firstitem = 1;
+
+/* Unescape / decode fields printed by string_print_encoded() */
+static void
+printcontent(const char *s)
+{
+ for (; *s; s++) {
+ switch (*s) {
+ case '\\':
+ s++;
+ switch (*s) {
+ case 'n': fputs("\\n", stdout); break;
+ case '\\': fputs("\\\\", stdout); break;
+ case 't': fputs("\\t", stdout); break;
+ }
+ break; /* ignore invalid escape sequence */
+ case '"': fputs("\\\"", stdout); break;
+ default:
+ putchar(*s);
+ break;
+ }
+ }
+}
+
+static void
+printfield(const char *s)
+{
+ for (; *s; s++) {
+ if (*s == '\\')
+ fputs("\\\\", stdout);
+ else if (*s == '"')
+ fputs("\\\"", stdout);
+ else
+ putchar(*s);
+ }
+}
+
+static void
+printfeed(FILE *fp, const char *feedname)
+{
+ char *fields[FieldLast], timebuf[32];
+ struct tm parsedtm, *tm;
+ time_t parsedtime;
+ ssize_t linelen;
+ int ch;
+ char *p, *s;
+
+ while ((linelen = getline(&line, &linesize, fp)) > 0 &&
+ !ferror(stdout)) {
+ if (line[linelen - 1] == '\n')
+ line[--linelen] = '\0';
+ parseline(line, fields);
+
+ if (!firstitem)
+ fputs(",\n", stdout);
+ firstitem = 0;
+
+ fputs("{\n\t\"id\": \"", stdout);
+ printfield(fields[FieldId]);
+ fputs("\"", stdout);
+
+ parsedtime = 0;
+ if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) &&
+ (tm = gmtime_r(&parsedtime, &parsedtm)) &&
+ strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ", tm)) {
+ fputs(",\n\t\"date_published\": \"", stdout);
+ fputs(timebuf, stdout);
+ fputs("\"", stdout);
+ }
+
+ fputs(",\n\t\"title\": \"", stdout);
+ if (feedname[0]) {
+ fputs("[", stdout);
+ printfield(feedname);
+ fputs("] ", stdout);
+ }
+ printfield(fields[FieldTitle]);
+ fputs("\"", stdout);
+
+ if (fields[FieldLink][0]) {
+ fputs(",\n\t\"url\": \"", stdout);
+ printfield(fields[FieldLink]);
+ fputs("\"", stdout);
+ }
+
+ if (fields[FieldAuthor][0]) {
+ fputs(",\n\t\"authors\": [{\"name\": \"", stdout);
+ printfield(fields[FieldAuthor]);
+ fputs("\"}]", stdout);
+ }
+
+ if (fields[FieldCategory][0]) {
+ fputs(",\n\t\"tags\": [", stdout);
+
+ for (p = s = fields[FieldCategory]; ; s++) {
+ if (*s == '|' || *s == '\0') {
+ if (p != fields[FieldCategory])
+ fputs(", ", stdout);
+ ch = *s;
+ *s = '\0'; /* temporary NUL terminate */
+ fputs("\"", stdout);
+ printfield(p);
+ fputs("\"", stdout);
+ *s = ch; /* restore */
+ p = s + 1;
+ }
+ if (*s == '\0')
+ break;
+ }
+ fputs("]", stdout);
+ }
+
+ if (fields[FieldEnclosure][0]) {
+ fputs(",\n\t\"attachments\": [{\"url:\": \"", stdout);
+ printfield(fields[FieldEnclosure]);
+ fputs("\"}]", stdout);
+ }
+
+ if (!strcmp(fields[FieldContentType], "html"))
+ fputs(",\n\t\"content_html\": \"", stdout);
+ else
+ fputs(",\n\t\"content_text\": \"", stdout);
+ printcontent(fields[FieldContent]);
+ fputs("\"\n}", stdout);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ FILE *fp;
+ char *name;
+ int i;
+
+ if (pledge(argc == 1 ? "stdio" : "stdio rpath", NULL) == -1)
+ err(1, "pledge");
+
+ fputs("{\n"
+ "\"version\": \"https://jsonfeed.org/version/1.1\",\n"
+ "\"title\": \"Newsfeed\",\n"
+ "\"items\": [\n", stdout);
+
+ if (argc == 1) {
+ printfeed(stdin, "");
+ checkfileerror(stdin, "<stdin>", 'r');
+ } else {
+ for (i = 1; i < argc; i++) {
+ if (!(fp = fopen(argv[i], "r")))
+ err(1, "fopen: %s", argv[i]);
+ name = ((name = strrchr(argv[i], '/'))) ? name + 1 : argv[i];
+ printfeed(fp, name);
+ checkfileerror(fp, argv[i], 'r');
+ checkfileerror(stdout, "<stdout>", 'w');
+ fclose(fp);
+ }
+ }
+ fputs("]\n}\n", stdout);
+
+ checkfileerror(stdout, "<stdout>", 'w');
+
+ return 0;
+}
(DIR) diff --git a/sfeed/sfeed_jsonfeed.1 b/sfeed/sfeed_jsonfeed.1
@@ -1,42 +0,0 @@
-.Dd March 8, 2023
-.Dt SFEED_JSONFEED 1
-.Os
-.Sh NAME
-.Nm sfeed_jsonfeed
-.Nd format feed data to JSON Feed 1.1
-.Sh SYNOPSIS
-.Nm
-.Op Ar
-.Sh DESCRIPTION
-.Nm
-formats feed data (TSV) from
-.Xr sfeed 1
-from stdin or for each
-.Ar file
-to stdout as JSON Feed 1.1 data.
-If one or more
-.Ar file
-arguments are specified then the basename of the
-.Ar file
-is used as the feed name in the output.
-If no
-.Ar file
-arguments are specified and so the data is read from stdin then the feed name
-is empty.
-If
-.Nm
-is reading from one or more
-.Ar file
-arguments it will prefix the entry title with "[feed name] ".
-.Sh EXIT STATUS
-.Ex -std
-.Sh EXAMPLES
-.Bd -literal
-curl -s 'https://codemadness.org/atom.xml' | sfeed | sfeed_jsonfeed
-.Ed
-.Sh SEE ALSO
-.Xr sfeed 1 ,
-.Xr sfeed_atom 1 ,
-.Xr sfeed 5
-.Sh AUTHORS
-.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org
(DIR) diff --git a/sfeed/sfeed_jsonfeed.c b/sfeed/sfeed_jsonfeed.c
@@ -1,171 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "util.h"
-
-static char *line;
-static size_t linesize;
-static int firstitem = 1;
-
-/* Unescape / decode fields printed by string_print_encoded() */
-static void
-printcontent(const char *s)
-{
- for (; *s; s++) {
- switch (*s) {
- case '\\':
- s++;
- switch (*s) {
- case 'n': fputs("\\n", stdout); break;
- case '\\': fputs("\\\\", stdout); break;
- case 't': fputs("\\t", stdout); break;
- }
- break; /* ignore invalid escape sequence */
- case '"': fputs("\\\"", stdout); break;
- default:
- putchar(*s);
- break;
- }
- }
-}
-
-static void
-printfield(const char *s)
-{
- for (; *s; s++) {
- if (*s == '\\')
- fputs("\\\\", stdout);
- else if (*s == '"')
- fputs("\\\"", stdout);
- else
- putchar(*s);
- }
-}
-
-static void
-printfeed(FILE *fp, const char *feedname)
-{
- char *fields[FieldLast], timebuf[32];
- struct tm parsedtm, *tm;
- time_t parsedtime;
- ssize_t linelen;
- int ch;
- char *p, *s;
-
- while ((linelen = getline(&line, &linesize, fp)) > 0 &&
- !ferror(stdout)) {
- if (line[linelen - 1] == '\n')
- line[--linelen] = '\0';
- parseline(line, fields);
-
- if (!firstitem)
- fputs(",\n", stdout);
- firstitem = 0;
-
- fputs("{\n\t\"id\": \"", stdout);
- printfield(fields[FieldId]);
- fputs("\"", stdout);
-
- parsedtime = 0;
- if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) &&
- (tm = gmtime_r(&parsedtime, &parsedtm)) &&
- strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ", tm)) {
- fputs(",\n\t\"date_published\": \"", stdout);
- fputs(timebuf, stdout);
- fputs("\"", stdout);
- }
-
- fputs(",\n\t\"title\": \"", stdout);
- if (feedname[0]) {
- fputs("[", stdout);
- printfield(feedname);
- fputs("] ", stdout);
- }
- printfield(fields[FieldTitle]);
- fputs("\"", stdout);
-
- if (fields[FieldLink][0]) {
- fputs(",\n\t\"url\": \"", stdout);
- printfield(fields[FieldLink]);
- fputs("\"", stdout);
- }
-
- if (fields[FieldAuthor][0]) {
- fputs(",\n\t\"authors\": [{\"name\": \"", stdout);
- printfield(fields[FieldAuthor]);
- fputs("\"}]", stdout);
- }
-
- if (fields[FieldCategory][0]) {
- fputs(",\n\t\"tags\": [", stdout);
-
- for (p = s = fields[FieldCategory]; ; s++) {
- if (*s == '|' || *s == '\0') {
- if (p != fields[FieldCategory])
- fputs(", ", stdout);
- ch = *s;
- *s = '\0'; /* temporary NUL terminate */
- fputs("\"", stdout);
- printfield(p);
- fputs("\"", stdout);
- *s = ch; /* restore */
- p = s + 1;
- }
- if (*s == '\0')
- break;
- }
- fputs("]", stdout);
- }
-
- if (fields[FieldEnclosure][0]) {
- fputs(",\n\t\"attachments\": [{\"url:\": \"", stdout);
- printfield(fields[FieldEnclosure]);
- fputs("\"}]", stdout);
- }
-
- if (!strcmp(fields[FieldContentType], "html"))
- fputs(",\n\t\"content_html\": \"", stdout);
- else
- fputs(",\n\t\"content_text\": \"", stdout);
- printcontent(fields[FieldContent]);
- fputs("\"\n}", stdout);
- }
-}
-
-int
-main(int argc, char *argv[])
-{
- FILE *fp;
- char *name;
- int i;
-
- if (pledge(argc == 1 ? "stdio" : "stdio rpath", NULL) == -1)
- err(1, "pledge");
-
- fputs("{\n"
- "\"version\": \"https://jsonfeed.org/version/1.1\",\n"
- "\"title\": \"sfeed to jsonfeed 1.1\",\n"
- "\"items\": [\n", stdout);
-
- if (argc == 1) {
- printfeed(stdin, "");
- checkfileerror(stdin, "<stdin>", 'r');
- } else {
- for (i = 1; i < argc; i++) {
- if (!(fp = fopen(argv[i], "r")))
- err(1, "fopen: %s", argv[i]);
- name = ((name = strrchr(argv[i], '/'))) ? name + 1 : argv[i];
- printfeed(fp, name);
- checkfileerror(fp, argv[i], 'r');
- checkfileerror(stdout, "<stdout>", 'w');
- fclose(fp);
- }
- }
- fputs("]\n}\n", stdout);
-
- checkfileerror(stdout, "<stdout>", 'w');
-
- return 0;
-}