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;
}