aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/Storage.hpp1
-rw-r--r--plugins/Matrix.hpp2
-rw-r--r--src/Storage.cpp9
-rw-r--r--src/plugins/Matrix.cpp46
4 files changed, 57 insertions, 1 deletions
diff --git a/include/Storage.hpp b/include/Storage.hpp
index ae7db04..2e9d883 100644
--- a/include/Storage.hpp
+++ b/include/Storage.hpp
@@ -25,6 +25,7 @@ namespace QuickMedia {
int file_get_content(const Path &path, std::string &result);
int file_get_size(const Path &path, size_t *size);
int file_overwrite(const Path &path, const std::string &data);
+ int file_overwrite_atomic(const Path &path, const std::string &data);
void for_files_in_dir(const Path &path, FileIteratorCallback callback);
void for_files_in_dir_sort_last_modified(const Path &path, FileIteratorCallback callback);
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index bf9f715..f4a3200 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -472,6 +472,7 @@ namespace QuickMedia {
std::string get_next_batch();
void clear_sync_cache_for_new_sync();
std::shared_ptr<UserInfo> get_user_by_id(RoomData *room, const std::string &user_id);
+ std::string get_filter_cached();
DownloadResult download_json(rapidjson::Document &result, const std::string &url, std::vector<CommandArg> additional_args, bool use_browser_useragent = false, std::string *err_msg = nullptr) const;
private:
std::vector<std::unique_ptr<RoomData>> rooms;
@@ -494,5 +495,6 @@ namespace QuickMedia {
bool sync_is_cache = false;
std::string sync_fail_reason;
MatrixDelegate *delegate = nullptr;
+ std::optional<std::string> filter_cached;
};
} \ No newline at end of file
diff --git a/src/Storage.cpp b/src/Storage.cpp
index 086f6d8..dadff5b 100644
--- a/src/Storage.cpp
+++ b/src/Storage.cpp
@@ -157,6 +157,15 @@ namespace QuickMedia {
return file_overwrite(path, data.c_str(), data.size());
}
+ int file_overwrite_atomic(const Path &path, const std::string &data) {
+ Path tmp_path = path;
+ tmp_path.append(".tmp");
+ int res = file_overwrite(tmp_path, data.c_str(), data.size());
+ if(res != 0)
+ return res;
+ return rename(tmp_path.data.c_str(), path.data.c_str());
+ }
+
void for_files_in_dir(const Path &path, FileIteratorCallback callback) {
try {
for(auto &p : std::filesystem::directory_iterator(path.data)) {
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 11d0746..2736421 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -20,6 +20,7 @@
static const char* SERVICE_NAME = "matrix";
static const char* OTHERS_ROOM_TAG = "tld.name.others";
+static const char* FILTER = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"limit\":3,\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"limit\":1,\"types\":[\"m.fully_read\",\"m.tag\"],\"lazy_load_members\":true}}}";
static rapidjson::Value nullValue(rapidjson::kNullType);
static const rapidjson::Value& GetMember(const rapidjson::Value &obj, const char *key) {
@@ -850,7 +851,7 @@ namespace QuickMedia {
// Filter with account data
// {"presence":{"limit":0,"types":[""]},"account_data":{"not_types":["im.vector.setting.breadcrumbs","m.push_rules","im.vector.setting.allowed_widgets","io.element.recent_emoji"]},"room":{"state":{"limit":1,"not_types":["m.room.related_groups","m.room.power_levels","m.room.join_rules","m.room.history_visibility"],"lazy_load_members":true},"timeline":{"limit":3,"lazy_load_members":true},"ephemeral":{"limit":0,"types":[""],"lazy_load_members":true},"account_data":{"limit":1,"types":["m.fully_read"],"lazy_load_members":true}}}
// Filter without account data
- const char *filter = "{\"presence\":{\"limit\":0,\"types\":[\"\"]},\"account_data\":{\"limit\":0,\"types\":[\"\"]},\"room\":{\"state\":{\"not_types\":[\"m.room.related_groups\",\"m.room.power_levels\",\"m.room.join_rules\",\"m.room.history_visibility\"],\"lazy_load_members\":true},\"timeline\":{\"limit\":3,\"lazy_load_members\":true},\"ephemeral\":{\"limit\":0,\"types\":[\"\"],\"lazy_load_members\":true},\"account_data\":{\"limit\":1,\"types\":[\"m.fully_read\",\"m.tag\"],\"lazy_load_members\":true}}}";
+ std::string filter = get_filter_cached();
const std::string filter_encoded = url_param_encode(filter);
std::vector<CommandArg> additional_args = {
@@ -2753,6 +2754,8 @@ namespace QuickMedia {
Path matrix_sync_data_path = get_cache_dir().join("matrix").join("sync_data.json");
remove(matrix_sync_data_path.data.c_str());
+ Path filter_cache_path = get_storage_dir().join("matrix").join("filter");
+ remove(filter_cache_path.data.c_str());
if(!json_root.IsObject()) {
err_msg = "Failed to parse matrix login response";
@@ -2822,6 +2825,7 @@ namespace QuickMedia {
upload_limit.reset();
set_next_batch("");
invites.clear();
+ filter_cached.reset();
return PluginResult::OK;
}
@@ -3189,6 +3193,46 @@ namespace QuickMedia {
#endif
}
+ // TODO: GET the filter to check if its valid?
+ std::string Matrix::get_filter_cached() {
+ if(filter_cached)
+ return filter_cached.value();
+
+ Path filter_path = get_storage_dir().join("matrix").join("filter");
+ std::string file_content;
+ if(file_get_content(filter_path, file_content) == 0) {
+ fprintf(stderr, "Loaded filter from cache\n");
+ filter_cached = file_content;
+ return filter_cached.value();
+ }
+
+ fprintf(stderr, "Filter not available in cache, adding to server\n");
+
+ std::vector<CommandArg> additional_args = {
+ { "-X", "POST" },
+ { "-H", "Authorization: Bearer " + access_token },
+ { "--data-binary", FILTER }
+ };
+
+ char url[512];
+ snprintf(url, sizeof(url), "%s/_matrix/client/r0/user/%s/filter", homeserver.c_str(), user_id.c_str());
+
+ rapidjson::Document json_root;
+ DownloadResult download_result = download_json(json_root, url, std::move(additional_args), true);
+ if(download_result != DownloadResult::OK || !json_root.IsObject()) return FILTER;
+
+ const rapidjson::Value &filter_id_json = GetMember(json_root, "filter_id");
+ if(!filter_id_json.IsString())
+ return FILTER;
+
+ filter_cached = filter_id_json.GetString();
+ Path filter_dir = get_storage_dir().join("matrix");
+ if(create_directory_recursive(filter_dir) == 0) {
+ file_overwrite_atomic(filter_path, filter_cached.value());
+ }
+ return filter_cached.value();
+ }
+
DownloadResult Matrix::download_json(rapidjson::Document &result, const std::string &url, std::vector<CommandArg> additional_args, bool use_browser_useragent, std::string *err_msg) const {
if(download_to_json(url, result, std::move(additional_args), use_tor, use_browser_useragent, err_msg == nullptr) != DownloadResult::OK) {
// Cant get error since we parse directly to json. TODO: Make this work somehow?