diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-07-05 00:08:37 +0200 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-07-05 00:08:37 +0200 |
commit | ad6e4fef6407b9e39ab8ee329b4e8c12376c8494 (patch) | |
tree | bfa2634aabea625a1479817700c35d846273371b /src/Utils.cpp | |
parent | Add some event expiration function (diff) | |
download | nheko-ad6e4fef6407b9e39ab8ee329b4e8c12376c8494.tar.xz |
Add experimental event expiration
Currently disabled by default.
Diffstat (limited to 'src/Utils.cpp')
-rw-r--r-- | src/Utils.cpp | 84 |
1 files changed, 54 insertions, 30 deletions
diff --git a/src/Utils.cpp b/src/Utils.cpp index 7a412db0..663609fe 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -1610,8 +1610,7 @@ std::atomic<bool> event_expiration_running = false; void utils::removeExpiredEvents() { - // TODO(Nico): Add its own toggle... - if (!UserSettings::instance()->updateSpaceVias()) + if (!UserSettings::instance()->expireEvents()) return; if (event_expiration_running.exchange(true)) { @@ -1645,18 +1644,20 @@ utils::removeExpiredEvents() std::string currentRoom; std::uint64_t currentRoomCount = 0; std::string currentRoomPrevToken; + std::set<std::pair<std::string, std::string>> currentRoomStateEvents; std::vector<std::string> currentRoomRedactionQueue; mtx::events::account_data::nheko_extensions::EventExpiry currentExpiry; static void next(std::shared_ptr<ApplyEventExpiration> state) { if (!state->currentRoomRedactionQueue.empty()) { + auto evid = state->currentRoomRedactionQueue.back(); + auto room = state->currentRoom; http::client()->redact_event( - state->currentRoom, - state->currentRoomRedactionQueue.back(), - [state = std::move(state)](const mtx::responses::EventId &, - mtx::http::RequestErr e) mutable { - const auto &event_id = state->currentRoomRedactionQueue.back(); + room, + evid, + [state = std::move(state), evid](const mtx::responses::EventId &, + mtx::http::RequestErr e) mutable { if (e) { if (e->status_code == 429 && e->matrix_error.retry_after.count() != 0) { ChatPage::instance()->callFunctionOnGuiThread( @@ -1669,17 +1670,19 @@ utils::removeExpiredEvents() }); }); return; + } else { + nhlog::net()->error("Failed to redact event {} in {}: {}", + evid, + state->currentRoom, + *e); + state->currentRoomRedactionQueue.pop_back(); + next(std::move(state)); } - - nhlog::net()->error("Failed to redact event {} in {}: {}", - event_id, - state->currentRoom, - *e); + } else { + nhlog::net()->info("Redacted event {} in {}", evid, state->currentRoom); + state->currentRoomRedactionQueue.pop_back(); + next(std::move(state)); } - nhlog::net()->info( - "Redacted event {} in {}: {}", event_id, state->currentRoom, *e); - state->currentRoomRedactionQueue.pop_back(); - next(std::move(state)); }); } else if (!state->currentRoom.empty()) { mtx::http::MessagesOpts opts{}; @@ -1687,6 +1690,7 @@ utils::removeExpiredEvents() opts.from = state->currentRoomPrevToken; opts.limit = 1000; opts.filter = state->filter; + opts.room_id = state->currentRoom; http::client()->messages( opts, @@ -1708,6 +1712,19 @@ utils::removeExpiredEvents() mtx::events::RedactionEvent<mtx::events::msg::Redaction>>(e)) continue; + if (std::holds_alternative< + mtx::events::RoomEvent<mtx::events::msg::Redacted>>(e)) + continue; + + if (std::holds_alternative< + mtx::events::StateEvent<mtx::events::msg::Redacted>>(e)) + continue; + + // skip events we don't know to protect us from mistakes. + if (std::holds_alternative< + mtx::events::RoomEvent<mtx::events::Unknown>>(e)) + continue; + if (mtx::accessors::sender(e) != us) continue; @@ -1720,6 +1737,21 @@ utils::removeExpiredEvents() mtx::accessors::is_state_event(e)) continue; + if (mtx::accessors::is_state_event(e)) { + // skip the first state event of a type + if (std::visit( + [&state](const auto &se) { + if constexpr (requires { se.state_key; }) + return state->currentRoomStateEvents + .emplace(to_string(se.type), se.state_key) + .second; + else + return false; + }, + e)) + continue; + } + if (state->currentExpiry.keep_only_latest && state->currentRoomCount > state->currentExpiry.keep_only_latest) { state->currentRoomRedactionQueue.push_back( @@ -1738,6 +1770,7 @@ utils::removeExpiredEvents() state->currentRoom.clear(); state->currentRoomCount = 0; state->currentRoomPrevToken.clear(); + state->currentRoomStateEvents.clear(); } next(std::move(state)); @@ -1764,20 +1797,11 @@ utils::removeExpiredEvents() auto asus = std::make_shared<ApplyEventExpiration>(); - asus->filter = - nlohmann::json{ - "room", - nlohmann::json::object({ - { - "timeline", - nlohmann::json::object({ - {"senders", nlohmann::json::array({us})}, - {"not_types", nlohmann::json::array({"m.room.redaction"})}, - }), - }, - }), - } - .dump(); + nlohmann::json filter; + filter["timeline"]["senders"] = nlohmann::json::array({us}); + filter["timeline"]["not_types"] = nlohmann::json::array({"m.room.redaction"}); + + asus->filter = filter.dump(); asus->globalExpiry = getExpEv(); |