aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-09-10 22:17:34 +0200
committerdec05eba <dec05eba@protonmail.com>2022-09-10 22:17:34 +0200
commit0ea083cbd4013cf2e709a3e3810ae96167585a74 (patch)
tree119f1fb52c94442d7d01d1a7992ac1a9f3b387a6
parent1c150eeb1d530e19976c945e69410c0cf26a3cb0 (diff)
Matrix: better name for clipboard file (with extension), give pantalaimon files proper filenames when downloading
-rw-r--r--include/DownloadUtils.hpp2
-rw-r--r--include/QuickMedia.hpp4
-rw-r--r--plugins/Matrix.hpp10
-rw-r--r--plugins/Page.hpp1
-rw-r--r--src/DownloadUtils.cpp7
-rw-r--r--src/Program.cpp2
-rw-r--r--src/QuickMedia.cpp74
-rw-r--r--src/plugins/Matrix.cpp6
8 files changed, 73 insertions, 33 deletions
diff --git a/include/DownloadUtils.hpp b/include/DownloadUtils.hpp
index 7e46d8b..48ee309 100644
--- a/include/DownloadUtils.hpp
+++ b/include/DownloadUtils.hpp
@@ -32,6 +32,6 @@ namespace QuickMedia {
// Note: if |cloudflare_bypass| is set to true then tls is limited to version 1.1 and the user agent is changed.
DownloadResult download_to_file(const std::string &url, const std::string &destination_filepath, const std::vector<CommandArg> &additional_args, bool use_browser_useragent = false, bool cloudflare_bypass = false);
// Returns false if there was an error trying to create the download process
- bool download_async_gui(const std::string &url, const std::string &file_manager_start_dir, bool no_video);
+ bool download_async_gui(const std::string &url, const std::string &file_manager_start_dir, bool no_video, const std::string &filename);
DownloadResult download_to_json(const std::string &url, rapidjson::Document &result, const std::vector<CommandArg> &additional_args, bool use_browser_useragent = false, bool fail_on_error = true);
} \ No newline at end of file
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp
index 4011ca0..8dca09e 100644
--- a/include/QuickMedia.hpp
+++ b/include/QuickMedia.hpp
@@ -134,7 +134,7 @@ namespace QuickMedia {
bool page_loop(std::vector<Tab> &tabs, int start_tab_index = 0, PageLoopSubmitHandler after_submit_handler = nullptr, bool go_to_previous_on_escape = true);
void redirect_focus_to_video_player_window(mgl::WindowHandle video_player_window);
void show_video_player_window(mgl::WindowHandle video_player_window);
- void video_page_download_video(const std::string &url, mgl::WindowHandle video_player_window = 0);
+ void video_page_download_video(const std::string &url, const std::string &filename, mgl::WindowHandle video_player_window = 0);
bool video_download_if_non_streamable(std::string &video_url, std::string &audio_url, bool &is_audio_only, bool &has_embedded_audio, PageType previous_page);
int video_get_max_height();
void video_content_page(Page *parent_page, VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, Body *parent_body, int play_index, int *parent_body_page = nullptr, const std::string &parent_page_search = "");
@@ -147,7 +147,7 @@ namespace QuickMedia {
void chat_login_page();
bool chat_page(MatrixChatPage *matrix_chat_page, RoomData *current_room);
void after_matrix_login_page();
- void download_page(std::string url);
+ void download_page(std::string url, std::string download_filename);
// Returns the full path where the file should be saved, or an empty string if the operation was cancelled
std::string file_save_page(const std::string &filename);
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index 0c12831..45dd1f7 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -412,11 +412,14 @@ namespace QuickMedia {
const std::string title;
};
- // Dummy, only play one video. TODO: Play all videos in room, as related videos?
+ // Only play one video. TODO: Play all videos in room, as related videos?
class MatrixVideoPage : public VideoPage {
public:
- MatrixVideoPage(Program *program) : VideoPage(program, "") {}
+ MatrixVideoPage(Program *program, std::string filename) : VideoPage(program, ""), filename(std::move(filename)) {}
const char* get_title() const override { return ""; }
+ std::string get_filename() override { return filename; }
+ private:
+ std::string filename;
};
class MatrixChatPage : public Page {
@@ -543,7 +546,8 @@ namespace QuickMedia {
// |relates_to| is from |BodyItem.userdata| and is of type |Message*|
PluginResult post_reaction(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response);
- PluginResult post_file(RoomData *room, const std::string &filepath, std::string &event_id_response, std::string &err_msg);
+ // If filename is empty then the filename is extracted from filepath
+ PluginResult post_file(RoomData *room, const std::string &filepath, std::string filename, std::string &event_id_response, std::string &err_msg);
PluginResult login(const std::string &username, const std::string &password, const std::string &homeserver, std::string &err_msg);
PluginResult logout();
diff --git a/plugins/Page.hpp b/plugins/Page.hpp
index 2fa2b6c..97b0340 100644
--- a/plugins/Page.hpp
+++ b/plugins/Page.hpp
@@ -184,6 +184,7 @@ namespace QuickMedia {
virtual void mark_watched() {};
// Should not do any network request to not slow down video loading
virtual void get_subtitles(SubtitleData &subtitle_data) { (void)subtitle_data; }
+ virtual std::string get_filename() { return ""; }
virtual bool is_local() const { return false; }
diff --git a/src/DownloadUtils.cpp b/src/DownloadUtils.cpp
index 8685662..484afeb 100644
--- a/src/DownloadUtils.cpp
+++ b/src/DownloadUtils.cpp
@@ -318,7 +318,7 @@ namespace QuickMedia {
return DownloadResult::OK;
}
- bool download_async_gui(const std::string &url, const std::string &file_manager_start_dir, bool no_video) {
+ bool download_async_gui(const std::string &url, const std::string &file_manager_start_dir, bool no_video, const std::string &filename) {
char quickmedia_path[PATH_MAX];
ssize_t bytes_written = readlink("/proc/self/exe", quickmedia_path, sizeof(quickmedia_path) - 1);
if(bytes_written == -1)
@@ -327,7 +327,10 @@ namespace QuickMedia {
quickmedia_path[bytes_written] = '\0';
std::vector<const char*> args = { quickmedia_path, "download", "-u", url.c_str(), "--dir", file_manager_start_dir.c_str() };
- if(no_video) args.push_back("--no-video");
+ if(no_video)
+ args.push_back("--no-video");
+ if(!filename.empty())
+ args.insert(args.end(), { "--download-filename", filename.c_str() });
args.push_back(nullptr);
return exec_program_async(args.data(), nullptr) == 0;
}
diff --git a/src/Program.cpp b/src/Program.cpp
index 513ce8c..c66611d 100644
--- a/src/Program.cpp
+++ b/src/Program.cpp
@@ -219,6 +219,8 @@ int wait_program_non_blocking(pid_t process_id, int *status) {
return 1;
}
+// TODO: Verify if this can cause issues when |result_process_id| is null, because |args| may be deallocated
+// by the time its used in the last execvp.
int exec_program_async(const char **args, pid_t *result_process_id) {
/* 1 arguments */
if(args[0] == NULL)
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 97eb939..fa8dd66 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -387,6 +387,7 @@ namespace QuickMedia {
const char *url = nullptr;
std::string program_path = dirname(argv[0]);
std::string instance;
+ std::string download_filename;
for(int i = 1; i < argc; ++i) {
if(!plugin_name) {
@@ -469,6 +470,15 @@ namespace QuickMedia {
usage();
return -1;
}
+ } else if(strcmp(argv[i], "--download-filename") == 0) {
+ if(i < argc - 1) {
+ download_filename = argv[i + 1];
+ ++i;
+ } else {
+ fprintf(stderr, "Missing filename after --download-filename argument\n");
+ usage();
+ return -1;
+ }
} else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
usage();
return 0;
@@ -559,7 +569,7 @@ namespace QuickMedia {
usage();
return -1;
}
- download_page(url);
+ download_page(url, download_filename);
return exit_code;
}
@@ -2984,7 +2994,7 @@ namespace QuickMedia {
redirect_focus_to_video_player_window(video_player_window);
}
- void Program::video_page_download_video(const std::string &url, mgl::WindowHandle video_player_window) {
+ void Program::video_page_download_video(const std::string &url, const std::string &filename, mgl::WindowHandle video_player_window) {
bool separate_audio_option = url_should_download_with_youtube_dl(url);
std::string video_id;
separate_audio_option |= youtube_url_extract_id(url, video_id);
@@ -2993,7 +3003,7 @@ namespace QuickMedia {
separate_audio_option = false;
if(!separate_audio_option) {
- download_async_gui(url, file_manager_start_dir.string(), no_video);
+ download_async_gui(url, file_manager_start_dir.string(), no_video, filename);
return;
}
@@ -3023,7 +3033,7 @@ namespace QuickMedia {
if(!selected)
return;
- download_async_gui(url, file_manager_start_dir.string(), audio_only);
+ download_async_gui(url, file_manager_start_dir.string(), audio_only, filename);
}
bool Program::video_download_if_non_streamable(std::string &video_url, std::string &audio_url, bool &is_audio_only, bool &has_embedded_audio, PageType previous_page) {
@@ -3487,7 +3497,7 @@ namespace QuickMedia {
} else if(pressed_keysym == XK_f && pressing_ctrl) {
video_player->cycle_fullscreen();
} else if(pressed_keysym == XK_s && pressing_ctrl && !video_page->is_local()) {
- video_page_download_video(video_page->get_download_url(video_get_max_height()), video_player_window);
+ video_page_download_video(video_page->get_download_url(video_get_max_height()), video_page->get_filename(), video_player_window);
} else if(pressed_keysym == XK_F5 && !video_page->is_local()) {
double resume_start_time = 0.0;
video_player->get_time_in_file(&resume_start_time);
@@ -4654,7 +4664,7 @@ namespace QuickMedia {
} else if(event.key.code == mgl::Keyboard::S && event.key.control) {
BodyItem *selected_item = thread_body->get_selected();
if(selected_item && !selected_item->url.empty())
- download_async_gui(selected_item->url, file_manager_start_dir.string(), false);
+ download_async_gui(selected_item->url, file_manager_start_dir.string(), false, "");
}
BodyItem *selected_item = thread_body->get_selected();
@@ -4782,7 +4792,7 @@ namespace QuickMedia {
redraw = true;
frame_skip_text_entry = true;
} else if(event.key.code == mgl::Keyboard::S && event.key.control) {
- download_async_gui(attached_image_url, file_manager_start_dir.string(), false);
+ download_async_gui(attached_image_url, file_manager_start_dir.string(), false, "");
}
}
}
@@ -5331,7 +5341,6 @@ namespace QuickMedia {
}
window.set_title(("QuickMedia - matrix - " + current_room->get_name()).c_str());
- auto video_page = std::make_unique<MatrixVideoPage>(this);
bool move_room = false;
std::vector<ChatTab> tabs;
@@ -5751,15 +5760,15 @@ namespace QuickMedia {
}
};
- auto upload_file = [this, &current_room](const std::string &filepath) {
- run_task_with_loading_screen([this, &current_room, filepath]() {
+ auto upload_file = [this, &current_room](const std::string &filepath, const std::string &filename) {
+ run_task_with_loading_screen([this, &current_room, filepath, filename]() {
std::string filepath_mod = filepath;
if(string_starts_with(filepath_mod, "file://"))
filepath_mod.erase(filepath_mod.begin(), filepath_mod.begin() + 7);
std::string event_id_response;
std::string err_msg;
- if(matrix->post_file(current_room, filepath_mod, event_id_response, err_msg) == PluginResult::OK) {
+ if(matrix->post_file(current_room, filepath_mod, filename, event_id_response, err_msg) == PluginResult::OK) {
return true;
} else {
show_notification("QuickMedia", "Failed to upload media to room, error: " + err_msg, Urgency::CRITICAL);
@@ -6379,7 +6388,7 @@ namespace QuickMedia {
tabs[MESSAGES_TAB_INDEX].body->select_last_item();
};
- auto display_url_or_image = [this, matrix_chat_page, &ui_tabs, &redraw, &video_page, &launch_url, &chat_state, &url_selection_body, &avatar_applied, PINNED_TAB_INDEX, MESSAGES_TAB_INDEX](BodyItem *selected) {
+ auto display_url_or_image = [this, matrix_chat_page, &ui_tabs, &redraw, &launch_url, &chat_state, &url_selection_body, &avatar_applied, PINNED_TAB_INDEX, MESSAGES_TAB_INDEX](BodyItem *selected) {
if(!selected)
return false;
@@ -6401,6 +6410,7 @@ namespace QuickMedia {
bool is_audio = (message_type == MessageType::AUDIO);
bool prev_no_video = no_video;
no_video = is_audio;
+ auto video_page = std::make_unique<MatrixVideoPage>(this, selected_item_message->body);
video_page->set_url(selected->url);
video_content_page(matrix_chat_page, video_page.get(), selected_item_message->body, message_type == MessageType::VIDEO || message_type == MessageType::AUDIO, nullptr, 0);
no_video = prev_no_video;
@@ -6408,7 +6418,7 @@ namespace QuickMedia {
avatar_applied = false;
return true;
} else if(message_type == MessageType::FILE) {
- download_async_gui(selected->url, file_manager_start_dir.string(), no_video);
+ download_async_gui(selected->url, file_manager_start_dir.string(), no_video, selected_item_message->body);
return true;
}
@@ -6449,7 +6459,7 @@ namespace QuickMedia {
if(selected_item_message) {
MessageType message_type = selected_item_message->type;
if(!selected->url.empty() && message_type >= MessageType::IMAGE && message_type <= MessageType::FILE) {
- download_async_gui(selected->url, file_manager_start_dir.string(), no_video);
+ download_async_gui(selected->url, file_manager_start_dir.string(), no_video, selected_item_message->body);
return true;
}
}
@@ -6763,8 +6773,9 @@ namespace QuickMedia {
std::string clipboard_text;
char tmp_filename[] = "/tmp/quickmedia_clipboard_XXXXXX";
int tmp_file = -1;
+ std::string file_ext;
- const bool clipboard_success = window.get_clipboard([&first_part, &clipboard_text, &tmp_filename, &tmp_file](const unsigned char *data, size_t size, mgl_clipboard_type clipboard_type) {
+ const bool clipboard_success = window.get_clipboard([&first_part, &clipboard_text, &tmp_filename, &tmp_file, &file_ext](const unsigned char *data, size_t size, mgl_clipboard_type clipboard_type) {
if(first_part) {
first_part = false;
if(clipboard_type != MGL_CLIPBOARD_TYPE_STRING) {
@@ -6773,6 +6784,13 @@ namespace QuickMedia {
show_notification("QuickMedia", "Failed to create temporary file " + std::string(tmp_filename) + " from clipboard (failed to create file)", Urgency::CRITICAL);
return false;
}
+
+ if(clipboard_type == MGL_CLIPBOARD_TYPE_IMAGE_PNG)
+ file_ext = ".png";
+ else if(clipboard_type == MGL_CLIPBOARD_TYPE_IMAGE_JPG)
+ file_ext = ".jpg";
+ else if(clipboard_type == MGL_CLIPBOARD_TYPE_IMAGE_GIF)
+ file_ext = ".gif";
}
}
@@ -6792,8 +6810,14 @@ namespace QuickMedia {
if(tmp_file != -1)
clipboard_text = tmp_filename;
- if(clipboard_success && !clipboard_text.empty() && get_file_type(clipboard_text) == FileType::REGULAR)
- upload_file(clipboard_text);
+ if(clipboard_success && !clipboard_text.empty() && get_file_type(clipboard_text) == FileType::REGULAR) {
+ const time_t now = time(nullptr);
+ const struct tm *t = localtime(&now);
+ char filename[256];
+ strftime(filename, sizeof(filename)-1, "Clipboard_%Y-%m-%d_%H-%M-%S", t);
+ strcat(filename, file_ext.c_str());
+ upload_file(clipboard_text, filename);
+ }
if(tmp_file != -1) {
close(tmp_file);
@@ -7034,7 +7058,7 @@ namespace QuickMedia {
fprintf(stderr, "No files selected!\n");
} else {
// TODO: Upload multiple files.
- upload_file(selected_files[0]);
+ upload_file(selected_files[0], "");
}
redraw = true;
avatar_applied = false;
@@ -7621,7 +7645,7 @@ namespace QuickMedia {
return 0;
}
- void Program::download_page(std::string url) {
+ void Program::download_page(std::string url, std::string download_filename) {
window.set_title(("QuickMedia - Select where you want to save " + std::string(url)).c_str());
url = invidious_url_to_youtube_url(url);
@@ -7636,7 +7660,7 @@ namespace QuickMedia {
int64_t video_content_length = 0;
int64_t audio_content_length = 0;
- TaskResult task_result;
+ TaskResult task_result = TaskResult::TRUE;
if(download_use_youtube_dl) {
if(!is_program_executable_by_name("youtube-dl")) {
show_notification("QuickMedia", "youtube-dl needs to be installed to download the video/music", Urgency::CRITICAL);
@@ -7753,9 +7777,13 @@ namespace QuickMedia {
return;
}
} else {
- task_result = run_task_with_loading_screen([url, &filename]{
- return url_get_remote_name(url, filename, true) == DownloadResult::OK;
- });
+ if(download_filename.empty()) {
+ task_result = run_task_with_loading_screen([url, &filename]{
+ return url_get_remote_name(url, filename, true) == DownloadResult::OK;
+ });
+ } else {
+ filename = std::move(download_filename);
+ }
}
if(task_result == TaskResult::CANCEL) {
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index f8ee2a2..00009fd 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -3671,7 +3671,7 @@ namespace QuickMedia {
return filepath.c_str() + index + 1;
}
- PluginResult Matrix::post_file(RoomData *room, const std::string &filepath, std::string &event_id_response, std::string &err_msg) {
+ PluginResult Matrix::post_file(RoomData *room, const std::string &filepath, std::string filename, std::string &event_id_response, std::string &err_msg) {
UploadInfo file_info;
UploadInfo thumbnail_info;
PluginResult upload_file_result = upload_file(room, filepath, file_info, thumbnail_info, err_msg);
@@ -3683,7 +3683,9 @@ namespace QuickMedia {
if(!thumbnail_info.content_uri.empty())
thumbnail_info_opt = std::move(thumbnail_info);
- const char *filename = file_get_filename(filepath);
+ if(filename.empty())
+ filename = file_get_filename(filepath);
+
return post_message(room, filename, event_id_response, file_info_opt, thumbnail_info_opt);
}