From c1929dc22c87ac61e5369cb752e6ddd0ef6a79bf Mon Sep 17 00:00:00 2001 From: Roman Plášil Date: Tue, 8 Aug 2017 15:52:52 +0800 Subject: WIP saving intermediate state to JSON --- connection.cpp | 43 ++++++++++++++++++++++++++++++++++++++ connection.h | 4 ++++ room.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ room.h | 2 ++ 4 files changed, 114 insertions(+) diff --git a/connection.cpp b/connection.cpp index f9f1490c..3ecabdc5 100644 --- a/connection.cpp +++ b/connection.cpp @@ -32,6 +32,8 @@ #include "jobs/mediathumbnailjob.h" #include +#include +#include using namespace QMatrixClient; @@ -320,3 +322,44 @@ QByteArray Connection::generateTxnId() { return d->data->generateTxnId(); } + +QFile Connection::getStateSaveFile() const { + return QFile(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/data.json"); +} + +void Connection::saveState() { + QJsonObject rooms; + + for (auto i : this->roomMap()) { + QJsonObject roomObj; + i->toJson(roomObj); + rooms[i->id()] = roomObj; + } + + QJsonObject rootObj{ + {"next_batch", QJsonValue(d->data->lastEvent())}, + {"presence", QJsonValue(QJsonObject())}, + {"rooms", QJsonValue({ + qMakePair(QString("leave"), QJsonValue(QJsonObject())), + qMakePair(QString("join"), QJsonValue(rooms)), + qMakePair(QString("invite"), QJsonValue(QJsonObject())) + })} + }; + QJsonDocument doc { rootObj }; + QByteArray data = doc.toJson(); + + QFile outfile = getStateSaveFile(); + outfile.open(QFile::WriteOnly); + qInfo() << "Writing state to file=" << outfile.fileName(); + //QFile outfile(path); + outfile.write(data.data(), data.size()); +} + +void Connection::loadState() { + QFile file = getStateSaveFile(); + if (!file.exists()) return; + file.open(QFile::ReadOnly); + QByteArray data = file.readAll(); + + QJsonDocument doc = QJsonDocument.fromJson(data.data(), data.size()); +} diff --git a/connection.h b/connection.h index e3f33155..f199ed35 100644 --- a/connection.h +++ b/connection.h @@ -83,6 +83,10 @@ namespace QMatrixClient Q_INVOKABLE SyncJob* syncJob() const; Q_INVOKABLE int millisToReconnect() const; + /** call this before first sync */ + Q_INVOKABLE void loadState(); + Q_INVOKABLE void saveState(); + template JobT* callApi(JobArgTs... jobArgs) const { diff --git a/room.cpp b/room.cpp index cfdd33ac..982ae47e 100644 --- a/room.cpp +++ b/room.cpp @@ -119,6 +119,8 @@ class Room::Private void setLastReadEvent(User* u, const QString& eventId); rev_iter_pair_t promoteReadMarker(User* u, rev_iter_t newMarker); + void toJson(QJsonObject &out); + private: QString calculateDisplayname() const; QString roomNameFromMemberNames(const QList& userlist) const; @@ -875,6 +877,69 @@ void Room::Private::updateDisplayname() emit q->displaynameChanged(q); } +void Room::Private::toJson(QJsonObject &out) { + QJsonValue nowTimestamp { QDateTime::currentMSecsSinceEpoch() }; + QJsonArray stateEvents; + + QJsonObject nameEvent { + {"type", QJsonValue("m.room.name")}, + {"content", QJsonValue({qMakePair(QString("name"), QJsonValue(this->name))})}}; + stateEvents.append(QJsonValue(nameEvent)); + + for (auto i : this->membersMap) { + QJsonObject content { + {"membership", QJsonValue("join")}, + {"displayname", QJsonValue(i->displayname())} + // avatar URL is not available + }; + QJsonObject memberEvent { + {"type", QJsonValue("m.room.member")}, + {"sender", QJsonValue(i->id())}, + {"state_key", QJsonValue(i->id())}, + {"content", QJsonValue(content)}, + {"membership", QJsonValue("join")}, + {"origin_server_ts", nowTimestamp} + }; + stateEvents.append(QJsonValue(memberEvent)); + } + + { + QJsonArray aliases; + for (auto i : this->aliases) { + aliases.append(QJsonValue(i)); + } + + QJsonObject content { + {"aliases", QJsonValue(aliases)} + }; + + QJsonObject aliasEvent { + {"type", QJsonValue("m.room.aliases")}, + {"origin_server_ts", nowTimestamp}, + {"content", QJsonValue(content)} + }; + + stateEvents.append(QJsonValue(aliasEvent)); + } + + { + QJsonObject content { + {"alias", QJsonValue(this->canonicalAlias)} + }; + QJsonObject canonicalAliasEvent { + {"type", QJsonValue("m.room.canonical_alias")}, + {"origin_server_ts", nowTimestamp} + }; + stateEvents.append(QJsonValue(canonicalAliasEvent)); + } + + out["state"] = QJsonValue({qMakePair(QString("events"), QJsonValue(stateEvents))}); +} + +void Room::toJson(QJsonObject &out) const { + d->toJson(out); +} + MemberSorter Room::memberSorter() const { return MemberSorter(this); diff --git a/room.h b/room.h index 03827a55..9e363556 100644 --- a/room.h +++ b/room.h @@ -142,6 +142,8 @@ namespace QMatrixClient MemberSorter memberSorter() const; + void toJson(QJsonObject &out) const; + public slots: void postMessage(const QString& plainText, MessageEventType type = MessageEventType::Text); -- cgit v1.2.3