aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--include/Notification.hpp2
-rw-r--r--include/QuickMedia.hpp4
-rw-r--r--plugins/Dmenu.hpp20
-rw-r--r--plugins/Plugin.hpp2
-rw-r--r--src/QuickMedia.cpp42
-rw-r--r--src/VideoPlayer.cpp2
-rw-r--r--src/plugins/Dmenu.cpp23
-rw-r--r--src/plugins/Pornhub.cpp13
9 files changed, 70 insertions, 41 deletions
diff --git a/README.md b/README.md
index 941b70b..1b9b9c3 100644
--- a/README.md
+++ b/README.md
@@ -11,11 +11,12 @@ Config data, including manga progress is stored under `$HOME/.config/quickmedia`
```
usage: QuickMedia <plugin> [--tor]
OPTIONS:
-plugin The plugin to use. Should be either 4chan, manganelo, mangadex or youtube
+plugin The plugin to use. Should be either 4chan, manganelo, mangadex, youtube or dmenu
--tor Use tor. Disabled by default
EXAMPLES:
QuickMedia manganelo
QuickMedia youtube --tor
+echo "hello\nworld" | QuickMedia dmenu
```
## Controls
Press `arrow up` and `arrow down` to navigate the menu and also to go to the previous/next image when viewing manga.\
diff --git a/include/Notification.hpp b/include/Notification.hpp
index 22f2f77..4f7fcc2 100644
--- a/include/Notification.hpp
+++ b/include/Notification.hpp
@@ -27,6 +27,6 @@ namespace QuickMedia {
static void show_notification(const std::string &title, const std::string &description, Urgency urgency = Urgency::NORMAL) {
const char *args[] = { "notify-send", "-u", urgency_string(urgency), "--", title.c_str(), description.c_str(), nullptr };
exec_program_async(args, nullptr);
- printf("Notification: title: %s, description: %s\n", title.c_str(), description.c_str());
+ fprintf(stderr, "Notification: title: %s, description: %s\n", title.c_str(), description.c_str());
}
} \ No newline at end of file
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp
index 19d84a8..cd410c3 100644
--- a/include/QuickMedia.hpp
+++ b/include/QuickMedia.hpp
@@ -12,6 +12,8 @@
#include <unordered_set>
#include <future>
#include <stack>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
namespace QuickMedia {
class Plugin;
@@ -49,6 +51,7 @@ namespace QuickMedia {
// Returns Page::EXIT if empty
Page pop_page_stack();
private:
+ Display *disp;
sf::RenderWindow window;
sf::Vector2f window_size;
sf::Font font;
@@ -77,5 +80,6 @@ namespace QuickMedia {
std::future<void> image_download_future;
std::string downloading_chapter_url;
bool image_download_cancel = false;
+ int exit_code = 0;
};
} \ No newline at end of file
diff --git a/plugins/Dmenu.hpp b/plugins/Dmenu.hpp
new file mode 100644
index 0000000..84614cc
--- /dev/null
+++ b/plugins/Dmenu.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "Plugin.hpp"
+
+namespace QuickMedia {
+ class Dmenu : public Plugin {
+ public:
+ Dmenu();
+ bool search_is_filter() override { return true; }
+ bool search_suggestions_has_thumbnails() const override { return false; }
+ bool search_results_has_thumbnails() const override { return false; }
+ int get_search_delay() const override { return 0; }
+ bool search_suggestion_is_search() const override { return true; }
+ Page get_page_after_search() const override { return Page::EXIT; }
+ PluginResult get_front_page(BodyItems &result_items) override;
+ SearchResult search(const std::string &text, BodyItems &result_items) override;
+ private:
+ std::vector<std::string> stdin_data;
+ };
+} \ No newline at end of file
diff --git a/plugins/Plugin.hpp b/plugins/Plugin.hpp
index b430d57..be70684 100644
--- a/plugins/Plugin.hpp
+++ b/plugins/Plugin.hpp
@@ -43,6 +43,8 @@ namespace QuickMedia {
virtual bool is_image_board() { return false; }
virtual bool is_manga() { return false; }
+ // Return true if searching should update the search result (which could be a remote server search) or filter the existing list locally
+ virtual bool search_is_filter() { return false; }
virtual PluginResult get_front_page(BodyItems &result_items) {
(void)result_items; return PluginResult::OK;
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 5a13179..8fdedb3 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -4,6 +4,7 @@
#include "../plugins/Youtube.hpp"
#include "../plugins/Pornhub.hpp"
#include "../plugins/Fourchan.hpp"
+#include "../plugins/Dmenu.hpp"
#include "../include/Scale.hpp"
#include "../include/Program.h"
#include "../include/VideoPlayer.hpp"
@@ -21,8 +22,6 @@
#include <assert.h>
#include <cmath>
#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
#include <signal.h>
static const sf::Color back_color(30, 32, 34);
@@ -44,6 +43,7 @@ static int x_io_error_handler(Display *display) {
namespace QuickMedia {
Program::Program() :
+ disp(nullptr),
window(sf::VideoMode(800, 600), "QuickMedia"),
window_size(800, 600),
body(nullptr),
@@ -51,6 +51,10 @@ namespace QuickMedia {
current_page(Page::SEARCH_SUGGESTION),
image_index(0)
{
+ disp = XOpenDisplay(NULL);
+ if (!disp)
+ throw std::runtime_error("Failed to open display to X11 server");
+
window.setVerticalSyncEnabled(true);
if(!font.loadFromFile("../../../fonts/Lato-Regular.ttf")) {
fprintf(stderr, "Failed to load font: Lato-Regular.ttf\n");
@@ -75,6 +79,8 @@ namespace QuickMedia {
Program::~Program() {
delete body;
delete current_plugin;
+ if(disp)
+ XCloseDisplay(disp);
}
static SearchResult search_selected_suggestion(Body *input_body, Body *output_body, Plugin *plugin, std::string &selected_title, std::string &selected_url) {
@@ -93,11 +99,12 @@ namespace QuickMedia {
static void usage() {
fprintf(stderr, "usage: QuickMedia <plugin> [--tor]\n");
fprintf(stderr, "OPTIONS:\n");
- fprintf(stderr, "plugin The plugin to use. Should be either 4chan, manganelo, mangadex, pornhub or youtube\n");
+ fprintf(stderr, "plugin The plugin to use. Should be either 4chan, manganelo, mangadex, pornhub, youtube or dmenu\n");
fprintf(stderr, "--tor Use tor. Disabled by default\n");
fprintf(stderr, "EXAMPLES:\n");
fprintf(stderr, "QuickMedia manganelo\n");
fprintf(stderr, "QuickMedia youtube --tor\n");
+ fprintf(stderr, "echo \"hello\nworld\" | QuickMedia dmenu\n");
}
static bool is_program_executable_by_name(const char *name) {
@@ -146,6 +153,8 @@ namespace QuickMedia {
} else if(strcmp(argv[i], "4chan") == 0) {
current_plugin = new Fourchan();
plugin_logo_path = "../../../images/4chan_logo.png";
+ } else if(strcmp(argv[i], "dmenu") == 0) {
+ current_plugin = new Dmenu();
}
}
@@ -237,7 +246,7 @@ namespace QuickMedia {
}
}
- return 0;
+ return exit_code;
}
void Program::base_event_handler(sf::Event &event, Page previous_page, bool handle_keypress, bool clear_on_escape, bool handle_searchbar) {
@@ -357,7 +366,7 @@ namespace QuickMedia {
}
search_bar->onTextUpdateCallback = [&update_search_text, this, &tabs, &selected_tab](const std::string &text) {
- if(tabs[selected_tab].body == body)
+ if(tabs[selected_tab].body == body && !current_plugin->search_is_filter())
update_search_text = text;
else {
tabs[selected_tab].body->filter_search_fuzzy(text);
@@ -438,6 +447,7 @@ namespace QuickMedia {
tabs[selected_tab].body->select_next_item();
} else if(event.key.code == sf::Keyboard::Escape) {
current_page = Page::EXIT;
+ exit_code = 1;
} else if(event.key.code == sf::Keyboard::Left) {
selected_tab = std::max(0, selected_tab - 1);
search_bar->clear();
@@ -578,19 +588,6 @@ namespace QuickMedia {
#endif
}
- struct XDisplayScope {
- XDisplayScope(Display *_display) : display(_display) {
-
- }
-
- ~XDisplayScope() {
- if(display)
- XCloseDisplay(display);
- }
-
- Display *display;
- };
-
enum class WindowFullscreenState {
UNSET,
SET,
@@ -631,13 +628,8 @@ namespace QuickMedia {
Page previous_page = pop_page_stack();
- Display* disp = XOpenDisplay(NULL);
- if (!disp)
- throw std::runtime_error("Failed to open display to X11 server");
- XDisplayScope display_scope(disp);
-
std::unique_ptr<sf::RenderWindow> video_player_ui_window;
- auto on_window_create = [disp, &video_player_ui_window](sf::WindowHandle video_player_window) {
+ auto on_window_create = [this, &video_player_ui_window](sf::WindowHandle video_player_window) {
int screen = DefaultScreen(disp);
Window ui_window = XCreateWindow(disp, RootWindow(disp, screen),
0, 0, 1, 1, 0,
@@ -705,7 +697,7 @@ namespace QuickMedia {
}, on_window_create);
load_video_error_check();
- auto on_doubleclick = [this, disp]() {
+ auto on_doubleclick = [this]() {
window_set_fullscreen(disp, window.getSystemHandle(), WindowFullscreenState::TOGGLE);
};
diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp
index 165e6e7..08ecc7e 100644
--- a/src/VideoPlayer.cpp
+++ b/src/VideoPlayer.cpp
@@ -84,7 +84,7 @@ namespace QuickMedia {
if(exec_program_async(args.data(), &video_process_id) != 0)
return Error::FAIL_TO_LAUNCH_PROCESS;
- printf("mpv input ipc server: %s\n", ipc_server_path);
+ fprintf(stderr, "mpv input ipc server: %s\n", ipc_server_path);
if((ipc_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("Failed to create socket for video player");
diff --git a/src/plugins/Dmenu.cpp b/src/plugins/Dmenu.cpp
new file mode 100644
index 0000000..a3b354b
--- /dev/null
+++ b/src/plugins/Dmenu.cpp
@@ -0,0 +1,23 @@
+#include "../../plugins/Dmenu.hpp"
+#include <iostream>
+
+namespace QuickMedia {
+ Dmenu::Dmenu() : Plugin("dmenu") {
+ std::string line;
+ while(std::getline(std::cin, line)) {
+ stdin_data.push_back(std::move(line));
+ }
+ }
+
+ PluginResult Dmenu::get_front_page(BodyItems &result_items) {
+ for(const std::string &line_data : stdin_data) {
+ result_items.push_back(std::make_unique<BodyItem>(line_data));
+ }
+ return PluginResult::OK;
+ }
+
+ SearchResult Dmenu::search(const std::string &text, BodyItems &result_items) {
+ std::cout << text << std::endl;
+ return SearchResult::OK;
+ }
+} \ No newline at end of file
diff --git a/src/plugins/Pornhub.cpp b/src/plugins/Pornhub.cpp
index c94532b..9a7242a 100644
--- a/src/plugins/Pornhub.cpp
+++ b/src/plugins/Pornhub.cpp
@@ -12,19 +12,6 @@ namespace QuickMedia {
return strstr(str, substr);
}
- static void iterate_suggestion_result(const Json::Value &value, BodyItems &result_items, int &iterate_count) {
- ++iterate_count;
- if(value.isArray()) {
- for(const Json::Value &child : value) {
- iterate_suggestion_result(child, result_items, iterate_count);
- }
- } else if(value.isString() && iterate_count > 2) {
- std::string title = value.asString();
- auto item = std::make_unique<BodyItem>(title);
- result_items.push_back(std::move(item));
- }
- }
-
// TODO: Speed this up by using string.find instead of parsing html
SuggestionResult Pornhub::update_search_suggestions(const std::string &text, BodyItems &result_items) {
std::string url = "https://www.pornhub.com/video/search?search=";