youtube/cli: add TSV option and -u option, remove channel2tsv - frontends - front-ends for some sites (experiment) (DIR) Log (DIR) Files (DIR) Refs (DIR) README (DIR) LICENSE --- (DIR) commit eec1de3aa027fd3e75101a4829658c2af844fb25 (DIR) parent b407559e2ea372a5d16bd0b08c9088762fa9ce75 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 21 Feb 2023 20:46:42 +0100 youtube/cli: add TSV option and -u option, remove channel2tsv Diffstat: M Makefile | 6 +----- D youtube/channel2tsv.c | 108 ------------------------------- M youtube/cli.c | 103 ++++++++++++++++++++++++++----- 3 files changed, 89 insertions(+), 128 deletions(-) --- (DIR) diff --git a/Makefile b/Makefile @@ -25,7 +25,6 @@ BIN = \ reddit/cli \ reddit/gopher \ youtube/cgi \ - youtube/channel2tsv \ youtube/cli \ youtube/gopher @@ -98,14 +97,11 @@ twitch/cgi: ${LIB} twitch/twitch.o twitch/cgi.o twitch/gopher: ${LIB} twitch/twitch.o twitch/gopher.o ${CC} -o $@ twitch/gopher.o twitch/twitch.o ${LIB} ${LDFLAGS} ${LIBTLS_LDFLAGS_STATIC} -youtube: youtube/cgi youtube/channel2tsv youtube/cli youtube/gopher +youtube: youtube/cgi youtube/cli youtube/gopher youtube/cgi: ${LIB} youtube/youtube.o youtube/cgi.o ${CC} -o $@ youtube/cgi.o youtube/youtube.o ${LIB} ${LDFLAGS} ${LIBTLS_LDFLAGS_STATIC} -youtube/channel2tsv: ${LIB} youtube/youtube.o youtube/channel2tsv.o - ${CC} -o $@ youtube/channel2tsv.o youtube/youtube.o ${LIB} ${LDFLAGS} ${LIBTLS_LDFLAGS} - youtube/cli: ${LIB} youtube/youtube.o youtube/cli.o ${CC} -o $@ youtube/cli.o youtube/youtube.o ${LIB} ${LDFLAGS} ${LIBTLS_LDFLAGS} (DIR) diff --git a/youtube/channel2tsv.c b/youtube/channel2tsv.c @@ -1,108 +0,0 @@ -#include <sys/socket.h> -#include <sys/types.h> - -#include <ctype.h> -#include <errno.h> -#include <netdb.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "https.h" -#include "util.h" -#include "youtube.h" - -#define OUT(s) fputs((s), stdout) -#define OUTESCAPE(s) printescape((s)) - -/* print: ignore control-characters */ -void -printescape(const char *s) -{ - for (; *s; ++s) - if (!iscntrl((unsigned char)*s)) - fputc(*s, stdout); -} - -int -render(struct search_response *r) -{ - struct item *videos = r->items; - size_t i; - - if (pledge("stdio", NULL) == -1) { - fprintf(stderr, "pledge: %s\n", strerror(errno)); - exit(1); - } - - for (i = 0; i < r->nitems; i++) { - switch (videos[i].linktype) { - case Channel: - case Movie: - case Playlist: - continue; - default: - break; - } - - OUTESCAPE(videos[i].id); - OUT("\t"); - if (videos[i].id[0]) { - OUT("https://www.youtube.com/embed/"); - OUTESCAPE(videos[i].id); - } - OUT("\t"); - OUTESCAPE(videos[i].title); - OUT("\t"); - OUTESCAPE(videos[i].publishedat); - OUT("\t"); - OUTESCAPE(videos[i].viewcount); - OUT("\t"); - OUTESCAPE(videos[i].duration); - OUT("\n"); - } - - return 0; -} - -static void -usage(const char *argv0) -{ - fprintf(stderr, "usage: %s <channelid>\n", argv0); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - struct search_response *r; - char channelid[1024]; - - if (pledge("stdio dns inet rpath unveil", NULL) == -1) { - fprintf(stderr, "pledge: %s\n", strerror(errno)); - exit(1); - } - if (unveil(TLS_CA_CERT_FILE, "r") == -1) { - fprintf(stderr, "unveil: %s\n", strerror(errno)); - exit(1); - } - if (unveil(NULL, NULL) == -1) { - fprintf(stderr, "unveil: %s\n", strerror(errno)); - exit(1); - } - - if (argc < 2 || !argv[1][0]) - usage(argv[0]); - if (!uriencode(argv[1], channelid, sizeof(channelid))) - usage(argv[0]); - - r = youtube_channel_videos(channelid); - if (!r || r->nitems == 0) - exit(1); - - render(r); - - return 0; -} (DIR) diff --git a/youtube/cli.c b/youtube/cli.c @@ -27,7 +27,7 @@ printescape(const char *s) } int -render(struct search_response *r) +render_tsv(struct search_response *r) { struct item *videos = r->items; size_t i; @@ -38,7 +38,47 @@ render(struct search_response *r) } for (i = 0; i < r->nitems; i++) { - /* TODO: better printing of other types */ + OUTESCAPE(videos[i].id); + OUT("\t"); + if (videos[i].id[0]) { + OUT("https://www.youtube.com/embed/"); + OUTESCAPE(videos[i].id); + } + OUT("\t"); + OUTESCAPE(videos[i].title); + OUT("\t"); + OUTESCAPE(videos[i].publishedat); + OUT("\t"); + OUTESCAPE(videos[i].viewcount); + OUT("\t"); + OUTESCAPE(videos[i].duration); + OUT("\t"); + switch (videos[i].linktype) { + case Channel: OUT("channel"); break; + case Movie: OUT("movie"); break; + case Playlist: OUT("playlist"); break; + default: break; + } + OUT("\t"); + OUTESCAPE(videos[i].channelid); + OUT("\t"); + OUTESCAPE(videos[i].channeltitle); + OUT("\t"); + OUTESCAPE(videos[i].userid); + OUT("\t"); + OUT("\n"); + } + + return 0; +} + +int +render(struct search_response *r) +{ + struct item *videos = r->items; + size_t i; + + for (i = 0; i < r->nitems; i++) { switch (videos[i].linktype) { case Channel: OUT("[Channel] "); @@ -114,20 +154,49 @@ render(struct search_response *r) static void usage(const char *argv0) { - fprintf(stderr, "usage: %s <keyword> | <-c channelid> | <-u user>\n", argv0); + fprintf(stderr, "usage: %s [-t] <keyword> | <-c channelid> | <-u user>\n", argv0); exit(1); } int main(int argc, char *argv[]) { - struct search_response *r; + struct search_response *r = NULL; char search[1024]; + const char *keywords = NULL, *channelid = NULL, *user = NULL; + int i, usetsv = 0; if (pledge("stdio dns inet rpath unveil", NULL) == -1) { fprintf(stderr, "pledge: %s\n", strerror(errno)); exit(1); } + + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 'c': + if (i + 1 >= argc) + usage(argv[0]); + channelid = argv[i + 1]; + i++; + break; + case 'u': + if (i + 1 >= argc) + usage(argv[0]); + user = argv[i + 1]; + i++; + break; + case 't': + usetsv = 1; + break; + default: + usage(argv[0]); + } + continue; + } + keywords = argv[i]; + } + if (unveil(TLS_CA_CERT_FILE, "r") == -1) { fprintf(stderr, "unveil: %s\n", strerror(errno)); exit(1); @@ -139,16 +208,12 @@ main(int argc, char *argv[]) if (argc < 2 || !argv[1][0]) usage(argv[0]); - if (!strcmp(argv[1], "-c")) { - if (argc < 3) - usage(argv[0]); - r = youtube_channel_videos(argv[2]); - } else if (!strcmp(argv[1], "-u")) { - if (argc < 3) - usage(argv[0]); - r = youtube_user_videos(argv[2]); - } else { - if (!uriencode(argv[1], search, sizeof(search))) + if (channelid) { + r = youtube_channel_videos(channelid); + } else if (user) { + r = youtube_user_videos(user); + } else if (keywords) { + if (!uriencode(keywords, search, sizeof(search))) usage(argv[0]); r = youtube_search(search, "", "relevance"); } @@ -157,7 +222,15 @@ main(int argc, char *argv[]) exit(1); } - render(r); + if (pledge("stdio", NULL) == -1) { + fprintf(stderr, "pledge: %s\n", strerror(errno)); + exit(1); + } + + if (usetsv) + render_tsv(r); + else + render(r); return 0; }