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