youtube: some cleanups, add option to list user videos - frontends - front-ends for some sites (experiment) (DIR) Log (DIR) Files (DIR) Refs (DIR) README (DIR) LICENSE --- (DIR) commit b407559e2ea372a5d16bd0b08c9088762fa9ce75 (DIR) parent 1752940aca51413222b22939b7c6ce5947960967 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Tue, 21 Feb 2023 20:31:42 +0100 youtube: some cleanups, add option to list user videos Diffstat: M json.c | 2 +- M xml.c | 2 +- M youtube/cli.c | 6 +++++- M youtube/youtube.c | 69 ++++++++++++++++++------------- M youtube/youtube.h | 3 +++ 5 files changed, 50 insertions(+), 32 deletions(-) --- (DIR) diff --git a/json.c b/json.c @@ -28,7 +28,7 @@ setjsondata(const char *s, size_t len) { json_data_off = 0; json_data_size = len; - json_data = s; + json_data = (unsigned char *)s; } static int (DIR) diff --git a/xml.c b/xml.c @@ -18,7 +18,7 @@ setxmldata(const char *s, size_t len) { xml_data_off = 0; xml_data_size = len; - xml_data_buf = s; + xml_data_buf = (unsigned char *)s; } static int (DIR) diff --git a/youtube/cli.c b/youtube/cli.c @@ -114,7 +114,7 @@ render(struct search_response *r) static void usage(const char *argv0) { - fprintf(stderr, "usage: %s <keyword> | <-c channelid>\n", argv0); + fprintf(stderr, "usage: %s <keyword> | <-c channelid> | <-u user>\n", argv0); exit(1); } @@ -143,6 +143,10 @@ main(int argc, char *argv[]) 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))) usage(argv[0]); (DIR) diff --git a/youtube/youtube.c b/youtube/youtube.c @@ -36,6 +36,20 @@ request_channel_videos(const char *channelid) } static char * +request_user_videos(const char *user) +{ + char path[4096]; + int r; + + r = snprintf(path, sizeof(path), "/user/%s/videos", user); + /* check if request is too long (truncation) */ + if (r < 0 || (size_t)r >= sizeof(path)) + return NULL; + + return youtube_request(path); +} + +static char * request_search(const char *s, const char *page, const char *order) { char path[4096]; @@ -66,8 +80,8 @@ request_search(const char *s, const char *page, const char *order) return youtube_request(path); } -int -extractjson(const char *s, char **start, char **end) +static int +extractjson(const char *s, const char **start, const char **end) { *start = strstr(s, "window[\"ytInitialData\"] = "); if (*start) { @@ -91,7 +105,7 @@ extractjson(const char *s, char **start, char **end) return 0; } -void +static void processnode(struct json_node *nodes, size_t depth, const char *value, void *pp) { @@ -191,16 +205,13 @@ processnode(struct json_node *nodes, size_t depth, const char *value, } } -struct search_response * -youtube_search(const char *rawsearch, const char *page, const char *order) +static struct search_response * +parse_search_response(const char *data) { struct search_response *r; - char *data, *s, *start, *end; + const char *s, *start, *end; int ret; - if (!(data = request_search(rawsearch, page, order))) - return NULL; - if (!(s = strstr(data, "\r\n\r\n"))) return NULL; /* invalid response */ /* skip header */ @@ -219,38 +230,38 @@ youtube_search(const char *rawsearch, const char *page, const char *order) free(r); return NULL; } - return r; } struct search_response * -youtube_channel_videos(const char *channelid) +youtube_search(const char *rawsearch, const char *page, const char *order) { - struct search_response *r; - char *data, *s, *start, *end; - int ret; + const char *data; - if (!(data = request_channel_videos(channelid))) + if (!(data = request_search(rawsearch, page, order))) return NULL; - if (!(s = strstr(data, "\r\n\r\n"))) - return NULL; /* invalid response */ - /* skip header */ - s += strlen("\r\n\r\n"); + return parse_search_response(data); +} - if (!(r = calloc(1, sizeof(*r)))) - return NULL; +struct search_response * +youtube_channel_videos(const char *channelid) +{ + const char *data; - if (extractjson(s, &start, &end) == -1) { - free(r); + if (!(data = request_channel_videos(channelid))) return NULL; - } - ret = parsejson(start, end - start, processnode, r); - if (ret < 0) { - free(r); + return parse_search_response(data); +} + +struct search_response * +youtube_user_videos(const char *user) +{ + const char *data; + + if (!(data = request_user_videos(user))) return NULL; - } - return r; + return parse_search_response(data); } (DIR) diff --git a/youtube/youtube.h b/youtube/youtube.h @@ -22,3 +22,6 @@ youtube_search(const char *rawsearch, const char *page, const char *order); struct search_response * youtube_channel_videos(const char *channelid); + +struct search_response * +youtube_user_videos(const char *user);