sfeed_json.c - sfeed - RSS and Atom parser
 (HTM) git clone git://git.codemadness.org/sfeed
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       sfeed_json.c (3719B)
       ---
            1 #include <stdio.h>
            2 #include <string.h>
            3 #include <time.h>
            4 
            5 #include "util.h"
            6 
            7 static char *line;
            8 static size_t linesize;
            9 static int firstitem = 1;
           10 
           11 /* Unescape / decode fields printed by string_print_encoded() */
           12 static void
           13 printcontent(const char *s)
           14 {
           15         for (; *s; s++) {
           16                 switch (*s) {
           17                 case '\\':
           18                         if (*(s + 1) == '\0')
           19                                 break;
           20                         s++;
           21                         switch (*s) {
           22                         case 'n':  fputs("\\n",  stdout); break;
           23                         case '\\': fputs("\\\\", stdout); break;
           24                         case 't':  fputs("\\t",  stdout); break;
           25                         }
           26                         break; /* ignore invalid escape sequence */
           27                 case '"': fputs("\\\"", stdout); break;
           28                 default:
           29                         putchar(*s);
           30                         break;
           31                 }
           32         }
           33 }
           34 
           35 static void
           36 printfield(const char *s)
           37 {
           38         for (; *s; s++) {
           39                 if (*s == '\\')
           40                         fputs("\\\\", stdout);
           41                 else if (*s == '"')
           42                         fputs("\\\"", stdout);
           43                 else
           44                         putchar(*s);
           45         }
           46 }
           47 
           48 static void
           49 printfeed(FILE *fp, const char *feedname)
           50 {
           51         char *fields[FieldLast], timebuf[32];
           52         struct tm parsedtm, *tm;
           53         time_t parsedtime;
           54         ssize_t linelen;
           55         int ch;
           56         char *p, *s;
           57 
           58         while ((linelen = getline(&line, &linesize, fp)) > 0 &&
           59                !ferror(stdout)) {
           60                 if (line[linelen - 1] == '\n')
           61                         line[--linelen] = '\0';
           62                 parseline(line, fields);
           63 
           64                 if (!firstitem)
           65                         fputs(",\n", stdout);
           66                 firstitem = 0;
           67 
           68                 fputs("{\n\t\"id\": \"", stdout);
           69                 printfield(fields[FieldId]);
           70                 fputs("\"", stdout);
           71 
           72                 parsedtime = 0;
           73                 if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) &&
           74                     (tm = gmtime_r(&parsedtime, &parsedtm)) &&
           75                     strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ", tm)) {
           76                         fputs(",\n\t\"date_published\": \"", stdout);
           77                         fputs(timebuf, stdout);
           78                         fputs("\"", stdout);
           79                 }
           80 
           81                 fputs(",\n\t\"title\": \"", stdout);
           82                 if (feedname[0]) {
           83                         fputs("[", stdout);
           84                         printfield(feedname);
           85                         fputs("] ", stdout);
           86                 }
           87                 printfield(fields[FieldTitle]);
           88                 fputs("\"", stdout);
           89 
           90                 if (fields[FieldLink][0]) {
           91                         fputs(",\n\t\"url\": \"", stdout);
           92                         printfield(fields[FieldLink]);
           93                         fputs("\"", stdout);
           94                 }
           95 
           96                 if (fields[FieldAuthor][0]) {
           97                         fputs(",\n\t\"authors\": [{\"name\": \"", stdout);
           98                         printfield(fields[FieldAuthor]);
           99                         fputs("\"}]", stdout);
          100                 }
          101 
          102                 if (fields[FieldCategory][0]) {
          103                         fputs(",\n\t\"tags\": [", stdout);
          104 
          105                         for (p = s = fields[FieldCategory]; ; s++) {
          106                                 if (*s == '|' || *s == '\0') {
          107                                         if (p != fields[FieldCategory])
          108                                                 fputs(", ", stdout);
          109                                         ch = *s;
          110                                         *s = '\0'; /* temporary NUL terminate */
          111                                         fputs("\"", stdout);
          112                                         printfield(p);
          113                                         fputs("\"", stdout);
          114                                         *s = ch; /* restore */
          115                                         p = s + 1;
          116                                 }
          117                                 if (*s == '\0')
          118                                         break;
          119                         }
          120                         fputs("]", stdout);
          121                 }
          122 
          123                 if (fields[FieldEnclosure][0]) {
          124                         fputs(",\n\t\"attachments\": [{\"url\": \"", stdout);
          125                         printfield(fields[FieldEnclosure]);
          126                         fputs("\"}]", stdout);
          127                 }
          128 
          129                 if (!strcmp(fields[FieldContentType], "html"))
          130                         fputs(",\n\t\"content_html\": \"", stdout);
          131                 else
          132                         fputs(",\n\t\"content_text\": \"", stdout);
          133                 printcontent(fields[FieldContent]);
          134                 fputs("\"\n}", stdout);
          135         }
          136 }
          137 
          138 int
          139 main(int argc, char *argv[])
          140 {
          141         FILE *fp;
          142         char *name;
          143         int i;
          144 
          145         if (pledge(argc <= 1 ? "stdio" : "stdio rpath", NULL) == -1)
          146                 err(1, "pledge");
          147 
          148         fputs("{\n"
          149               "\"version\": \"https://jsonfeed.org/version/1.1\",\n"
          150               "\"title\": \"Newsfeed\",\n"
          151               "\"items\": [\n", stdout);
          152 
          153         if (argc <= 1) {
          154                 printfeed(stdin, "");
          155                 checkfileerror(stdin, "<stdin>", 'r');
          156         } else {
          157                 for (i = 1; i < argc; i++) {
          158                         if (!(fp = fopen(argv[i], "r")))
          159                                 err(1, "fopen: %s", argv[i]);
          160                         name = ((name = strrchr(argv[i], '/'))) ? name + 1 : argv[i];
          161                         printfeed(fp, name);
          162                         checkfileerror(fp, argv[i], 'r');
          163                         checkfileerror(stdout, "<stdout>", 'w');
          164                         fclose(fp);
          165                 }
          166         }
          167         fputs("]\n}\n", stdout);
          168 
          169         checkfileerror(stdout, "<stdout>", 'w');
          170 
          171         return 0;
          172 }