From b2e4168ece2e6f378e06d3833c179299e82254fc Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 15 Jul 2020 20:36:51 +0200 Subject: Add the ability to add rss from episode name --- src/rss.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 156 insertions(+), 4 deletions(-) (limited to 'src/rss.c') diff --git a/src/rss.c b/src/rss.c index 442fb58..9486e6e 100644 --- a/src/rss.c +++ b/src/rss.c @@ -4,6 +4,7 @@ #include "stringutils.h" #include "fileutils.h" #include "buffer.h" +#include "episode.h" #include "rss_html_common.h" #include "json.h" #include "alloc.h" @@ -165,6 +166,139 @@ static int rss_parse_add_callback(char *title, char *link, void *userdata) { return 0; } +static const char hex_characters[] = "0123456789ABCDEF"; +/* TODO: Also support unicode escape characters */ +static void url_escape(const char *str, char *output) { + int index = 0; + for(;;) { + char c = *str; + if(c == '\0') { + output[index] = '\0'; + break; + } else if(c < 32) { + output[index++] = '%'; + output[index++] = hex_characters[(c>>4) & 0x0F]; + output[index++] = hex_characters[c&0x0F]; + } else { + switch(c) { + case '!': + case '#': + case '$': + case '%': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case '/': + case ':': + case ';': + case '=': + case '?': + case '@': + case '[': + case ']': + case '"': + case '-': + case '.': + case '<': + case '>': + case '\\': + case '^': + case '_': + case '`': + case '{': + case '|': + case '}': + case '~': + case ' ': + output[index++] = '%'; + output[index++] = hex_characters[(c>>4) & 0x0F]; + output[index++] = hex_characters[c&0x0F]; + break; + default: + output[index++] = c; + break; + } + } + ++str; + } +} + +static int get_rss_url_from_episode_info(const char *episode_name, EpisodeInfo *episode_info, char *rss_url) { + char *selected_submitter = NULL; + char response[512]; + char group_name_escaped[1536]; + + for(;;) { + printf("Enter the name of the submitter (leave empty to choose \"%s\" or type \"anon\" to choose all submitters: ", episode_info->group_name); + if(!fgets(response, sizeof(response), stdin)) { + fprintf(stderr, "Failed to read response from stdin\n"); + return -1; + } + fprintf(stderr, "response: %s\n", response); + char *response_str = strip(response); + + if(strcmp(response, "anon") == 0) { + break; + } else { + if(strlen(response_str) == 0) + response_str = episode_info->group_name; + + url_escape(response, group_name_escaped); + char url[4096]; + if(snprintf(url, sizeof(url), "https://nyaa.si/user/%s", group_name_escaped) >= (int)sizeof(url)) { + fprintf(stderr, "Error: url is too long!\n"); + return -1; + } + + if(is_header_response_ok(url) == 0) { + selected_submitter = response_str; + break; + } else { + printf("The submitter \"%s\" doesn't exist on nyaa.si, please choose another submitter.\n", response_str); + } + } + } + + char generic_name[2048]; + if(episode_info_get_generic_name(episode_info, generic_name, sizeof(generic_name)) != 0) { + fprintf(stderr, "Failed to get name for episode!\n"); + return -1; + } + + for(;;) { + if(selected_submitter) + printf("Are you sure you want to track \"%s\" by %s after \"%s\" ? (Y)es/No: ", generic_name, selected_submitter, episode_name); + else + printf("Are you sure you want to track \"%s\" by all submitters after \"%s\" ? (Y)es/No: ", generic_name, episode_name); + + char sresp[128]; + if(!fgets(sresp, sizeof(sresp), stdin)) { + fprintf(stderr, "Failed to read response from stdin\n"); + return -1; + } + char *response_str = strip(response); + int response_len = strlen(response_str); + + if(response_len > 0 && (response_str[0] == 'n' || response_str[0] == 'N')) { + rss_url[0] = '\0'; + return 0; + } else if(response_len == 0 || response_str[0] == 'y' || response_str[0] == 'Y') { + break; + } + } + + if(selected_submitter) + sprintf(rss_url, "https://nyaa.si/?page=rss&q=%s&c=0_0&f=0&u=%s", group_name_escaped, selected_submitter); + else + sprintf(rss_url, "https://nyaa.si/?page=rss&q=%s&c=0_0&f=0", group_name_escaped); + + return 0; +} + int add_rss(const char *name, const char *url, char *rss_config_dir, const char *start_after) { int result = 0; @@ -172,8 +306,28 @@ int add_rss(const char *name, const char *url, char *rss_config_dir, const char buffer_init(&buffer); result = download_to_buffer(url, &buffer); if(result != 0) { - fprintf(stderr, "Failed to download rss: %s\n", url); - goto cleanup; + EpisodeInfo episode_info; + if(episode_info_create_from_episode_name(&episode_info, url) != 0) { + fprintf(stderr, "Failed to download rss: %s\n", url); + goto cleanup; + } + + char rss_url[4096]; + if(get_rss_url_from_episode_info(url, &episode_info, rss_url) != 0) + goto cleanup; + + /* User didn't want to track rss */ + if(rss_url[0] == '\0') { + result = 0; + goto cleanup; + } + + buffer_clear(&buffer); + result = download_to_buffer(url, &buffer); + if(result != 0) { + fprintf(stderr, "Failed to download rss: %s\n", url); + goto cleanup; + } } RssParseUserdata rss_parse_userdata; @@ -194,8 +348,6 @@ int add_rss(const char *name, const char *url, char *rss_config_dir, const char goto cleanup; } - /* TODO: Add (add rss ) here */ - if(!name) { if(!rss_title) { fprintf(stderr, "Failed to find rss title and --name was not provided\n"); -- cgit v1.2.3