add gopher mode and twtxt output format - frontends - front-ends for some sites… | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit ee630780f97caacdc83bbbf29c60be757394f017 | |
parent 5e29f7c0a3a955816bdc5e3b418726ec68d5e0b4 | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Sun, 14 May 2023 00:06:50 +0200 | |
add gopher mode and twtxt output format | |
Diffstat: | |
M youtube/feed.c | 73 ++++++++++++++++++++++++++---… | |
1 file changed, 62 insertions(+), 11 deletions(-) | |
--- | |
diff --git a/youtube/feed.c b/youtube/feed.c | |
@@ -90,6 +90,7 @@ static void json_header(void); | |
static void json_item(void); | |
static void json_footer(void); | |
static void sfeed_item(void); /* TSV / sfeed */ | |
+static void twtxt_item(void); | |
static void string_append(String *, const char *, size_t); | |
static void string_buffer_realloc(String *, size_t); | |
@@ -151,7 +152,8 @@ static String attrrel, tmpstr; | |
static struct search_response *search_res = NULL; | |
static void (*printfields)(void) = sfeed_item; | |
-static int cgimode = 0; | |
+static int cgimode = 0, godmode = 0; | |
+static const char *server_name = "127.0.0.1", *server_port = "70"; | |
static int | |
tagcmp(const void *v1, const void *v2) | |
@@ -631,6 +633,39 @@ sfeed_item(void) | |
putchar('\n'); | |
} | |
+static void | |
+twtxt_item(void) | |
+{ | |
+ struct item *v, *found = NULL; | |
+ size_t i; | |
+ | |
+ /* must have a video id */ | |
+ if (!ctx.fields[FeedFieldYoutubeId].str.len) | |
+ return; | |
+ | |
+ for (i = 0; i < search_res->nitems; i++) { | |
+ v = &(search_res->items[i]); | |
+ if (!strcmp(ctx.fields[FeedFieldYoutubeId].str.data, v->id)) | |
+ found = v; | |
+ } | |
+ /* Only print the video if it was found in the feed aswell. | |
+ This way it filters away shorts too. */ | |
+ if (!found) | |
+ return; | |
+ | |
+ string_print(&ctx.fields[FeedFieldTime].str); | |
+ putchar(FieldSeparator); | |
+ string_print(&ctx.fields[FeedFieldTitle].str); | |
+ if (found->duration[0]) { | |
+ fputs(" [", stdout); | |
+ fputs(found->duration, stdout); | |
+ fputs("]", stdout); | |
+ } | |
+ fputs(": ", stdout); | |
+ string_print(&ctx.fields[FeedFieldLink].str); | |
+ putchar('\n'); | |
+} | |
+ | |
static int | |
istag(const char *name, size_t len, const char *name2, size_t len2) | |
{ | |
@@ -888,9 +923,13 @@ void | |
usage(void) | |
{ | |
if (cgimode) { | |
- fputs("Status: 400 Bad Request\r\n", stdout); | |
- fputs("Content-Type: text/plain; charset=utf-8\r\n\r\n", stdou… | |
- fputs("400 Bad Request\n", stdout); | |
+ if (godmode) { | |
+ printf("3Bad Request\tErr\t%s\t%s\r\n", server_name, s… | |
+ } else { | |
+ fputs("Status: 400 Bad Request\r\n", stdout); | |
+ fputs("Content-Type: text/plain; charset=utf-8\r\n\r\n… | |
+ fputs("400 Bad Request\n", stdout); | |
+ } | |
exit(0); | |
} else { | |
fputs("usage: feed <channelid> [atom|json|tsv]\n", stderr); | |
@@ -903,19 +942,23 @@ main(int argc, char *argv[]) | |
{ | |
char buf[256]; | |
const char *channelid = NULL; | |
- char *data, *format = "tsv", *p, *requesturi, *tmp; | |
+ char *data, *format = "tsv", *p, *path = NULL, *tmp; | |
size_t i; | |
if (pledge("stdio dns inet rpath unveil", NULL) == -1) | |
err(1, "pledge"); | |
- if ((tmp = getenv("REQUEST_URI"))) { | |
- cgimode = 1; | |
+ if ((tmp = getenv("REQUEST_URI"))) | |
+ path = tmp; | |
+ else if ((tmp = getenv("REQUEST"))) | |
+ path = tmp; | |
- strlcpy(buf, tmp, sizeof(buf)); | |
- requesturi = buf; | |
+ if (path) { | |
+ cgimode = 1; | |
+ strlcpy(buf, path, sizeof(buf)); | |
+ path = buf; | |
- if (!(p = strrchr(requesturi, '/'))) | |
+ if (!(p = strrchr(path, '/'))) | |
usage(); | |
channelid = p + 1; | |
@@ -923,6 +966,12 @@ main(int argc, char *argv[]) | |
*p = '\0'; /* NULL terminate */ | |
format = p + 1; | |
} | |
+ if ((tmp = getenv("SERVER_NAME"))) | |
+ server_name = tmp; | |
+ if ((tmp = getenv("SERVER_PORT"))) | |
+ server_port = tmp; | |
+ if ((tmp = getenv("SERVER_PROTOCOL")) && strstr(tmp, "gopher")) | |
+ godmode = 1; | |
} else { | |
if (argc <= 1) | |
usage(); | |
@@ -940,6 +989,8 @@ main(int argc, char *argv[]) | |
printfields = json_item; | |
else if (!strcmp(format, "tsv") || !strcmp(format, "sfeed")) | |
printfields = sfeed_item; | |
+ else if (!strcmp(format, "txt") || !strcmp(format, "twtxt")) | |
+ printfields = twtxt_item; | |
else | |
usage(); | |
@@ -975,7 +1026,7 @@ main(int argc, char *argv[]) | |
string_clear(&(ctx.fields[i].str)); | |
} | |
- if (cgimode) { | |
+ if (cgimode && !godmode) { | |
fputs("Status: 200 OK\r\n", stdout); | |
if (!strcmp(format, "atom") || !strcmp(format, "xml")) | |
fputs("Content-Type: text/xml; charset=utf-8\r\n\r\n",… |