Update spaces events automatically in the background
This commit is contained in:
parent
9891b6bffe
commit
234ac79acc
7 changed files with 246 additions and 5 deletions
180
src/Utils.cpp
180
src/Utils.cpp
|
|
@ -16,6 +16,7 @@
|
|||
#include <QStringBuilder>
|
||||
#include <QTextBoundaryFinder>
|
||||
#include <QTextDocument>
|
||||
#include <QTimer>
|
||||
#include <QWindow>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
|
|
@ -28,11 +29,13 @@
|
|||
|
||||
#include "Cache.h"
|
||||
#include "Cache_p.h"
|
||||
#include "ChatPage.h"
|
||||
#include "Config.h"
|
||||
#include "EventAccessors.h"
|
||||
#include "Logging.h"
|
||||
#include "MatrixClient.h"
|
||||
#include "UserSettingsPage.h"
|
||||
#include "timeline/Permissions.h"
|
||||
|
||||
using TimelineEvent = mtx::events::collections::TimelineEvents;
|
||||
|
||||
|
|
@ -1294,8 +1297,6 @@ utils::roomVias(const std::string &roomid)
|
|||
deniedServers.reserve(acls->content.deny.size());
|
||||
for (const auto &s : acls->content.deny)
|
||||
allowedServers.push_back(globToRegexp(s));
|
||||
|
||||
nhlog::ui()->critical("ACL: {}", nlohmann::json(acls->content).dump(2));
|
||||
}
|
||||
|
||||
auto isHostAllowed = [&acls, &allowedServers, &deniedServers](const std::string &host) {
|
||||
|
|
@ -1423,3 +1424,178 @@ utils::roomVias(const std::string &roomid)
|
|||
|
||||
return vias;
|
||||
}
|
||||
|
||||
void
|
||||
utils::updateSpaceVias()
|
||||
{
|
||||
if (!UserSettings::instance()->updateSpaceVias())
|
||||
return;
|
||||
|
||||
nhlog::net()->info("update space vias called");
|
||||
|
||||
auto rooms = cache::roomInfo(false);
|
||||
|
||||
auto us = http::client()->user_id().to_string();
|
||||
|
||||
auto weekAgo = (uint64_t)QDateTime::currentDateTime().addDays(-7).toMSecsSinceEpoch();
|
||||
|
||||
struct ApplySpaceUpdatesState
|
||||
{
|
||||
std::vector<mtx::events::StateEvent<mtx::events::state::space::Child>> childrenToUpdate;
|
||||
std::vector<mtx::events::StateEvent<mtx::events::state::space::Parent>> parentsToUpdate;
|
||||
|
||||
static void next(std::shared_ptr<ApplySpaceUpdatesState> state)
|
||||
{
|
||||
if (!state->childrenToUpdate.empty()) {
|
||||
const auto &child = state->childrenToUpdate.back();
|
||||
|
||||
http::client()->send_state_event(
|
||||
child.room_id,
|
||||
child.state_key,
|
||||
child.content,
|
||||
[state = std::move(state)](const mtx::responses::EventId &,
|
||||
mtx::http::RequestErr e) mutable {
|
||||
const auto &child_ = state->childrenToUpdate.back();
|
||||
if (e) {
|
||||
if (e->status_code == 429 && e->matrix_error.retry_after.count() != 0) {
|
||||
ChatPage::instance()->callFunctionOnGuiThread(
|
||||
[state = std::move(state),
|
||||
interval = e->matrix_error.retry_after]() {
|
||||
QTimer::singleShot(interval,
|
||||
ChatPage::instance(),
|
||||
[self = std::move(state)]() mutable {
|
||||
next(std::move(self));
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
nhlog::net()->error("Failed to update space child {} -> {}: {}",
|
||||
child_.room_id,
|
||||
child_.state_key,
|
||||
*e);
|
||||
}
|
||||
nhlog::net()->info(
|
||||
"Updated space child {} -> {}", child_.room_id, child_.state_key);
|
||||
state->childrenToUpdate.pop_back();
|
||||
next(std::move(state));
|
||||
});
|
||||
return;
|
||||
} else if (!state->parentsToUpdate.empty()) {
|
||||
const auto &parent = state->parentsToUpdate.back();
|
||||
|
||||
http::client()->send_state_event(
|
||||
parent.room_id,
|
||||
parent.state_key,
|
||||
parent.content,
|
||||
[state = std::move(state)](const mtx::responses::EventId &,
|
||||
mtx::http::RequestErr e) mutable {
|
||||
const auto &parent_ = state->parentsToUpdate.back();
|
||||
if (e) {
|
||||
if (e->status_code == 429 && e->matrix_error.retry_after.count() != 0) {
|
||||
ChatPage::instance()->callFunctionOnGuiThread(
|
||||
[state = std::move(state),
|
||||
interval = e->matrix_error.retry_after]() {
|
||||
QTimer::singleShot(interval,
|
||||
ChatPage::instance(),
|
||||
[self = std::move(state)]() mutable {
|
||||
next(std::move(self));
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
nhlog::net()->error("Failed to update space parent {} -> {}: {}",
|
||||
parent_.room_id,
|
||||
parent_.state_key,
|
||||
*e);
|
||||
}
|
||||
nhlog::net()->info(
|
||||
"Updated space parent {} -> {}", parent_.room_id, parent_.state_key);
|
||||
state->parentsToUpdate.pop_back();
|
||||
next(std::move(state));
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto asus = std::make_shared<ApplySpaceUpdatesState>();
|
||||
|
||||
for (const auto &[roomid, info] : rooms.toStdMap()) {
|
||||
if (!info.is_space)
|
||||
continue;
|
||||
|
||||
auto spaceid = roomid.toStdString();
|
||||
|
||||
if (auto pl = cache::client()
|
||||
->getStateEvent<mtx::events::state::PowerLevels>(spaceid)
|
||||
.value_or(mtx::events::StateEvent<mtx::events::state::PowerLevels>{})
|
||||
.content;
|
||||
pl.user_level(us) < pl.state_level(to_string(mtx::events::EventType::SpaceChild)))
|
||||
continue;
|
||||
|
||||
auto children = cache::client()->getChildRoomIds(spaceid);
|
||||
|
||||
for (const auto &childid : children) {
|
||||
// only update children we are joined to
|
||||
if (!rooms.contains(QString::fromStdString(childid)))
|
||||
continue;
|
||||
|
||||
auto child =
|
||||
cache::client()->getStateEvent<mtx::events::state::space::Child>(spaceid, childid);
|
||||
if (child &&
|
||||
// don't update too often
|
||||
child->origin_server_ts < weekAgo &&
|
||||
// ignore unset spaces
|
||||
(child->content.via && !child->content.via->empty())) {
|
||||
auto newVias = utils::roomVias(childid);
|
||||
|
||||
if (!newVias.empty() && newVias != child->content.via) {
|
||||
nhlog::net()->info("Will update {} -> {} child relation from {} to {}",
|
||||
spaceid,
|
||||
childid,
|
||||
fmt::join(*child->content.via, ","),
|
||||
fmt::join(newVias, ","));
|
||||
|
||||
child->content.via = std::move(newVias);
|
||||
child->room_id = spaceid;
|
||||
asus->childrenToUpdate.push_back(*std::move(child));
|
||||
}
|
||||
}
|
||||
|
||||
auto parent =
|
||||
cache::client()->getStateEvent<mtx::events::state::space::Parent>(childid, spaceid);
|
||||
if (parent &&
|
||||
// don't update too often
|
||||
parent->origin_server_ts < weekAgo &&
|
||||
// ignore unset spaces
|
||||
(parent->content.via && !parent->content.via->empty())) {
|
||||
if (auto pl =
|
||||
cache::client()
|
||||
->getStateEvent<mtx::events::state::PowerLevels>(childid)
|
||||
.value_or(mtx::events::StateEvent<mtx::events::state::PowerLevels>{})
|
||||
.content;
|
||||
pl.user_level(us) <
|
||||
pl.state_level(to_string(mtx::events::EventType::SpaceParent)))
|
||||
continue;
|
||||
|
||||
auto newVias = utils::roomVias(spaceid);
|
||||
|
||||
if (!newVias.empty() && newVias != parent->content.via) {
|
||||
nhlog::net()->info("Will update {} -> {} parent relation from {} to {}",
|
||||
childid,
|
||||
spaceid,
|
||||
fmt::join(*parent->content.via, ","),
|
||||
fmt::join(newVias, ","));
|
||||
|
||||
parent->content.via = std::move(newVias);
|
||||
parent->room_id = childid;
|
||||
asus->parentsToUpdate.push_back(*std::move(parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApplySpaceUpdatesState::next(std::move(asus));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue