sfeed_frames.c - sfeed - RSS and Atom parser | |
git clone git://git.codemadness.org/sfeed | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
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 | |
8 static struct feed *feeds; | |
9 static char *line; | |
10 static size_t linesize; | |
11 static time_t comparetime; | |
12 static unsigned long totalnew, total; | |
13 | |
14 static void | |
15 printfeed(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 %02d:%02d … | |
48 tm->tm_year + 1900, tm->tm_mon + 1, tm->… | |
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 | |
74 int | |
75 main(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; … | |
107 "\t<link rel=\"stylesheet\" type=\"text/css\" href=\"style… | |
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 +… | |
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=\"tex… | |
135 "\t<link rel=\"stylesheet\" type=\"text/css\" href… | |
136 "</head>\n" | |
137 "<body class=\"frame\">\n<div id=\"sidebar\">\n", … | |
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#… | |
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; … | |
160 "\t<title>(", fpindex); | |
161 fprintf(fpindex, "%lu/%lu", totalnew, total); | |
162 fputs(") - Newsfeed</title>\n\t<link rel=\"stylesheet\" type=\"t… | |
163 "</head>\n", fpindex); | |
164 if (showsidebar) { | |
165 fputs("<frameset framespacing=\"0\" cols=\"250,*\" frame… | |
166 "\t<frame name=\"menu\" src=\"menu.html\" target=\… | |
167 } else { | |
168 fputs("<frameset framespacing=\"0\" cols=\"*\" framebord… | |
169 } | |
170 fputs( | |
171 "\t<frame name=\"items\" src=\"items.html\" target=\"items… | |
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 } |