From 189fba5a4b63706575f9287cd0b1760a331d636e Mon Sep 17 00:00:00 2001 From: Mole Shang <135e2@135e2.dev> Date: Sun, 6 Aug 2023 22:18:31 +0800 Subject: process_url: initial callback support --- src/extractors/bilibili.c | 31 +++++++++++++++++++++++++------ src/process_url.c | 35 +++++++++++++++++++++++++++-------- src/process_url.h | 12 ++++++++++-- src/ui.c | 2 +- 4 files changed, 63 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/extractors/bilibili.c b/src/extractors/bilibili.c index 14905b0..675a035 100644 --- a/src/extractors/bilibili.c +++ b/src/extractors/bilibili.c @@ -380,6 +380,16 @@ static void dash_cleanup(Dash *dash) { free_array(&dash->dashinfo.dash.video); } +static int ffmpeg_merge(callback_struct_t *cb_struct) { + char *filename = + malloc(strlen(cb_struct->title) + strlen(cb_struct->ext) + 2); + sprintf(filename, "%s.%s", cb_struct->title, cb_struct->ext); + DEBUG_PRINT("Callback gets filename: %s\n", filename); + free_and_nullify(cb_struct->title); + free_and_nullify(filename); + return 0; +} + static int download(Bilibili_options *bilibili_options) { Dash dash = {0}; char *resp; @@ -396,20 +406,29 @@ static int download(Bilibili_options *bilibili_options) { Dash_stream *audio = get_element(&dash.dashinfo.dash.audio, 0); const char *quality_desc = id2quality_desc(video->id); + static callback_struct_t callback_struct = {0}; + callback_struct.ext = mimeType2ext(video->mimeType); + callback_struct.title = + malloc(strlen(bilibili_options->title) + strlen(quality_desc) + 3); + sprintf(callback_struct.title, "%s[%s]", bilibili_options->title, + quality_desc); + DEBUG_PRINT("Outside the callback, title: %s ext: %s\n", + callback_struct.title, callback_struct.ext); + { char fn[USHRT_MAX]; sprintf(fn, "%s[%s]-%s.%s", bilibili_options->title, quality_desc, "video", - mimeType2ext(video->mimeType)); - add_url(video->baseUrl, NULL, fn, "https://www.bilibili.com"); + callback_struct.ext); + add_url(video->baseUrl, NULL, fn, "https://www.bilibili.com", NULL, NULL); } { char fn[USHRT_MAX]; - sprintf(fn, "%s[%s]-%s.%s", bilibili_options->title, - quality_desc, "audio", mimeType2ext(audio->mimeType)); - add_url(audio->baseUrl, NULL, fn, "https://www.bilibili.com"); + sprintf(fn, "%s[%s]-%s.%s", bilibili_options->title, quality_desc, "audio", + mimeType2ext(audio->mimeType)); + add_url(audio->baseUrl, NULL, fn, "https://www.bilibili.com", &ffmpeg_merge, + &callback_struct); } - free_and_nullify(resp); dash_cleanup(&dash); return 0; diff --git a/src/process_url.c b/src/process_url.c index e5ac12e..1b391f2 100644 --- a/src/process_url.c +++ b/src/process_url.c @@ -36,6 +36,8 @@ mtx_t mtx; cnd_t cnd; bool corrupted; static const char *outdir_g, *referer_g; +static callback_t callback_g; +static callback_struct_t *p_callback_struct_g; static CURLU *h; /*NOTE: Use logger(X) (defined as a generic macro) to log errors. */ @@ -412,6 +414,14 @@ static int download(curl_conf_t *curl_c) { return 0; } +static void replace_illegal_char(char *str) { + for (unsigned char i = 0; illegal_char[i] != '\0'; i++) { + if (repchr(str, illegal_char[i], ' ')) + DEBUG_PRINT("Found illegal character '%c', replacing ...\n", + illegal_char[i]); + } +} + void curl_init(curl_conf_t *curl) { curl_global_init(CURL_GLOBAL_ALL); h = curl_url(); @@ -473,6 +483,10 @@ void poll_status(status_t *stat) { thrd_join(tid[i], &r); } merge_and_cleanup(curl_conf); + // Perform the callback + if (is_empty_queue(&dl_queue) && callback_g) { + callback_g(p_callback_struct_g); + } append_log("Download %s finished.\n", curl_conf->outfn); curl_conf = NULL; } @@ -496,13 +510,17 @@ int get(const char *URL, char **pdstr) { return res; } -/* Add an URL to dl_queue. +/* Add an URL to dl_queue and register all the stuff. * - If outdir is NULL or a empty string, reuse the cached outdir_g * - If fn is NULL or a empty string, infer the filename from URL (otherwise * fail and quit') - * - If referer is NULL or a empty string, uses NULL */ + * - If referer is NULL or a empty string, uses NULL + * - If callback || callback_struct is valid, execute the callback function + * after download + */ void add_url(const char *URL, const char *outdir, const char *fn, - const char *referer) { + const char *referer, callback_t callback, + callback_struct_t *p_callback_struct) { if (outdir && outdir[0] != '\0') { outdir_g = outdir; } @@ -511,6 +529,11 @@ void add_url(const char *URL, const char *outdir, const char *fn, referer_g = NULL; } DEBUG_PRINT("referer_g: %s\n", referer_g); + callback_g = callback; + if (p_callback_struct) { + p_callback_struct_g = p_callback_struct; + replace_illegal_char(p_callback_struct_g->title); + } char *filename; if (fn == NULL || fn[0] == '\0') { @@ -518,11 +541,7 @@ void add_url(const char *URL, const char *outdir, const char *fn, } else { filename = malloc(strlen(fn) + 1); strcpy(filename, fn); - for (unsigned char i = 0; illegal_char[i] != '\0'; i++) { - if (repchr(filename, illegal_char[i], ' ')) - DEBUG_PRINT("Found illegal character '%c' in filename, replacing ...\n", - illegal_char[i]); - } + replace_illegal_char(filename); } // Pass our cache (outdir_g) to parse_url() diff --git a/src/process_url.h b/src/process_url.h index 704fc42..53d8ed3 100644 --- a/src/process_url.h +++ b/src/process_url.h @@ -5,8 +5,8 @@ #include #include -#include "utils.h" #include "constants.h" +#include "utils.h" #define ERRTOSTRING(err) curl_easy_strerror(err) #define logerr(X) \ @@ -44,6 +44,13 @@ typedef struct str_data { size_t len; } str_data_t; +typedef struct callback_struct { + char *title; + const char *ext; +} callback_struct_t; + +typedef int (*callback_t)(callback_struct_t *); + void curl_init(); void curl_cleanup(status_t *); @@ -52,6 +59,7 @@ void poll_status(status_t *); int get(const char *, char **); -void add_url(const char *, const char *, const char *, const char *); +void add_url(const char *, const char *, const char *, const char *, callback_t, + callback_struct_t *); #endif diff --git a/src/ui.c b/src/ui.c index da6fd1b..0692954 100644 --- a/src/ui.c +++ b/src/ui.c @@ -57,7 +57,7 @@ void load_ui(struct ui_struct *ui) { if (outPath) { DEBUG_PRINT("tinyfd gets outPath: %s\n", outPath); append_log("Got URL: %s\n", text); - add_url(text, outPath, NULL, NULL); + add_url(text, outPath, NULL, NULL, NULL, NULL); } else { LOG("NFD", "Please specify a valid file PATH to write to!\n"); } -- cgit v1.2.3