aboutsummaryrefslogtreecommitdiff
path: root/src/QuickMedia.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-11-22 01:44:39 +0100
committerdec05eba <dec05eba@protonmail.com>2022-11-22 01:44:39 +0100
commit89c41c1488854858e02ff6bd48a6518161fa05a5 (patch)
tree2161e26f342c4b2f9579b6521dc347a29e25fa6c /src/QuickMedia.cpp
parent52bc7111147dd3e87e4bf0ae57241c2b81892f78 (diff)
Allow launching directly into 4chan thread
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r--src/QuickMedia.cpp117
1 files changed, 96 insertions, 21 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 6f089be..2e7feff 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -317,9 +317,9 @@ namespace QuickMedia {
}
static void usage() {
- fprintf(stderr, "usage: quickmedia [plugin] [--no-video] [--upscale-images] [--upscale-images-always] [--dir <directory>] [--instance <instance>] [-e <window>] [--video-max-height <height>] [youtube-url] [youtube-channel-url]\n");
+ fprintf(stderr, "usage: quickmedia [plugin|url] [--no-video] [--upscale-images] [--upscale-images-always] [--dir <directory>] [--instance <instance>] [-e <window>] [--video-max-height <height>]\n");
fprintf(stderr, "OPTIONS:\n");
- fprintf(stderr, " plugin The plugin to use. Should be either launcher, 4chan, manga, manganelo, manganelos, mangatown, mangakatana, mangadex, readm, onimanga, local-manga, local-anime, youtube, peertube, lbry, soundcloud, nyaa.si, matrix, saucenao, hotexamples, anilist, dramacool, file-manager, stdin, pornhub, spankbang, xvideos or xhamster\n");
+ fprintf(stderr, " plugin|url The plugin to use. Should be either launcher, 4chan, manga, manganelo, manganelos, mangatown, mangakatana, mangadex, readm, onimanga, local-manga, local-anime, youtube, peertube, lbry, soundcloud, nyaa.si, matrix, saucenao, hotexamples, anilist, dramacool, file-manager, stdin, pornhub, spankbang, xvideos or xhamster. This can also be a youtube url, youtube channel url or a 4chan thread url\n");
fprintf(stderr, " --no-video Only play audio when playing a video. Disabled by default\n");
fprintf(stderr, " --upscale-images Upscale low-resolution manga pages using waifu2x-ncnn-vulkan. Disabled by default\n");
fprintf(stderr, " --upscale-images-always Upscale manga pages using waifu2x-ncnn-vulkan, no matter what the original image resolution is. Disabled by default\n");
@@ -368,6 +368,44 @@ namespace QuickMedia {
return true;
}
+ // |comment_id| is optional
+ static bool fourchan_extract_url(const std::string &url, std::string &board_id, std::string &thread_id, std::string &comment_id) {
+ size_t len = 10;
+ size_t index = url.find("4chan.org/");
+ if(index == std::string::npos) {
+ len = 13;
+ index = url.find("4channel.org/");
+ }
+
+ if(index == std::string::npos)
+ return false;
+
+ index += len;
+ size_t board_end = url.find('/', index);
+ if(board_end == std::string::npos)
+ return false;
+
+ board_id = url.substr(index, board_end - index);
+ index = board_end + 1;
+
+ const std::string_view remaining(url.data() + index, url.size() - index);
+ if(remaining.size() <= 7 || remaining.substr(0, 7) != "thread/")
+ return false;
+
+ index += 7;
+ size_t thread_id_end = url.find('#', index);
+ if(thread_id_end == std::string::npos)
+ thread_id_end = url.size();
+
+ thread_id = url.substr(index, thread_id_end - index);
+ if(thread_id.empty())
+ return false;
+
+ index = thread_id_end;
+ comment_id = url.substr(index);
+ return true;
+ }
+
int Program::run(int argc, char **argv) {
mgl_init();
@@ -390,14 +428,22 @@ namespace QuickMedia {
std::string youtube_url_converted = invidious_url_to_youtube_url(argv[i]);
std::string youtube_channel_id;
std::string youtube_video_id_dummy;
+ std::string fourchan_id_dummy;
- if(youtube_url_extract_channel_id(youtube_url_converted, youtube_channel_id, youtube_channel_url)) {
+ if(youtube_url_extract_channel_id(youtube_url_converted, youtube_channel_id, launch_url)) {
+ launch_url_type = LaunchUrlType::YOUTUBE_CHANNEL;
plugin_name = "youtube";
continue;
} else if(youtube_url_extract_id(youtube_url_converted, youtube_video_id_dummy)) {
- youtube_url = std::move(youtube_url_converted);
+ launch_url_type = LaunchUrlType::YOUTUBE_VIDEO;
+ launch_url = std::move(youtube_url_converted);
plugin_name = "youtube";
continue;
+ } else if(fourchan_extract_url(argv[i], fourchan_id_dummy, fourchan_id_dummy, fourchan_id_dummy)) {
+ launch_url_type = LaunchUrlType::FOURCHAN_THREAD;
+ launch_url = argv[i];
+ plugin_name = "4chan";
+ continue;
}
for(const auto &valid_plugin : valid_plugins) {
@@ -1283,20 +1329,32 @@ namespace QuickMedia {
categories_sukebei_body->set_items(body_items);
tabs.push_back(Tab{std::move(categories_sukebei_body), std::make_unique<NyaaSiCategoryPage>(this, true), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "4chan") == 0) {
- auto boards_page = std::make_unique<FourchanBoardsPage>(this, resources_root);
- FourchanBoardsPage *boards_page_ptr = boards_page.get();
+ if(launch_url_type == LaunchUrlType::FOURCHAN_THREAD) {
+ // TODO: Use comment id
+ std::string board_id, thread_id, comment_id;
+ fourchan_extract_url(launch_url, board_id, thread_id, comment_id);
+ auto body = create_body();
+ auto thread_page = std::make_unique<FourchanThreadPage>(this, std::move(board_id), std::move(thread_id), "");
+ page_stack.push(current_page);
+ current_page = PageType::IMAGE_BOARD_THREAD;
+ image_board_thread_page(thread_page.get(), body.get());
+ exit(0);
+ } else {
+ auto boards_page = std::make_unique<FourchanBoardsPage>(this, resources_root);
+ FourchanBoardsPage *boards_page_ptr = boards_page.get();
- auto boards_body = create_body();
- BodyItems body_items;
- boards_page->get_boards(body_items);
- boards_body->set_items(std::move(body_items));
- tabs.push_back(Tab{std::move(boards_body), std::move(boards_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+ auto boards_body = create_body();
+ BodyItems body_items;
+ boards_page->get_boards(body_items);
+ boards_body->set_items(std::move(body_items));
+ tabs.push_back(Tab{std::move(boards_body), std::move(boards_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
- auto login_page = std::make_unique<FourchanLoginPage>(this, "4chan pass login", boards_page_ptr, &tabs, 1);
- FourchanLoginPage *login_page_ptr = login_page.get();
+ auto login_page = std::make_unique<FourchanLoginPage>(this, "4chan pass login", boards_page_ptr, &tabs, 1);
+ FourchanLoginPage *login_page_ptr = login_page.get();
- tabs.push_back(Tab{ create_body(), std::move(login_page), nullptr, {} });
- login_page_ptr->login_inputs = &tabs.back().login_inputs;
+ tabs.push_back(Tab{ create_body(), std::move(login_page), nullptr, {} });
+ login_page_ptr->login_inputs = &tabs.back().login_inputs;
+ }
} else if(strcmp(plugin_name, "hotexamples") == 0) {
auto body = create_body();
BodyItems body_items;
@@ -1322,11 +1380,11 @@ namespace QuickMedia {
pipe_body->set_items(std::move(body_items));
tabs.push_back(Tab{std::move(pipe_body), std::make_unique<PipePage>(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "youtube") == 0) {
- if(!youtube_channel_url.empty()) {
- YoutubeChannelPage::create_each_type(this, youtube_channel_url, "", "Channel", tabs);
- } else if(!youtube_url.empty()) {
+ if(launch_url_type == LaunchUrlType::YOUTUBE_CHANNEL) {
+ YoutubeChannelPage::create_each_type(this, std::move(launch_url), "", "Channel", tabs);
+ } else if(launch_url_type == LaunchUrlType::YOUTUBE_VIDEO) {
current_page = PageType::VIDEO_CONTENT;
- auto youtube_video_page = std::make_unique<YoutubeVideoPage>(this, youtube_url, false);
+ auto youtube_video_page = std::make_unique<YoutubeVideoPage>(this, std::move(launch_url), false);
video_content_page(nullptr, youtube_video_page.get(), "", false, nullptr, 0);
} else {
start_tab_index = 1;
@@ -4479,6 +4537,22 @@ namespace QuickMedia {
void Program::image_board_thread_page(ImageBoardThreadPage *thread_page, Body *thread_body) {
AsyncImageLoader::get_instance().update();
+ BodyItems result_items;
+ const TaskResult load_result = run_task_with_loading_screen([&]() {
+ return thread_page->lazy_fetch(result_items) == PluginResult::OK;
+ });
+
+ if(load_result == TaskResult::CANCEL) {
+ current_page = pop_page_stack();
+ return;
+ } else if(load_result == TaskResult::FALSE) {
+ show_notification("QuickMedia", "Failed to load thread", Urgency::CRITICAL);
+ current_page = pop_page_stack();
+ return;
+ }
+
+ thread_body->set_items(std::move(result_items));
+
// TODO: Instead of using stage here, use different pages for each stage
enum class NavigationStage {
VIEWING_COMMENTS,
@@ -4697,9 +4771,10 @@ namespace QuickMedia {
page_stack.push(PageType::IMAGE_BOARD_THREAD);
current_page = PageType::VIDEO_CONTENT;
watched_videos.clear();
- thread_page->set_url(selected_item->url);
+ ImageBoardVideoPage video_page(this);
+ video_page.set_url(selected_item->url);
// TODO: Use real title
- video_content_page(thread_page, thread_page, "", true, thread_body, thread_body->get_selected_item());
+ video_content_page(thread_page, &video_page, "", true, thread_body, thread_body->get_selected_item());
redraw = true;
idle_active_handler();
} else {