From b2a017303a34e248873b2e47e560a41dc4c5111c Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 2 Oct 2017 12:16:36 +0900 Subject: All jobs: Drop ConnectionData parameter from the constructor Having to pass ConnectionData to each and every job class was nothing but boilerplate since the very beginning. Removing it required to prepend BaseJob::start() with ConnectionData-setting code, and to provide a way to alter the request configuration depending on the (late-coming) ConnectionData object. This is a new responsibility of BaseJob::start(); the previous BaseJob::start() contents have moved to BaseJob::sendRequest() (which is now invoked on retries, instead of start()). --- connection.h | 8 ++++++-- jobs/basejob.cpp | 38 ++++++++++++++++++++++++++------------ jobs/basejob.h | 12 +++++++----- jobs/checkauthmethods.cpp | 6 +++--- jobs/checkauthmethods.h | 2 +- jobs/generated/inviting.cpp | 18 +++++------------- jobs/generated/inviting.h | 10 +--------- jobs/generated/kicking.cpp | 13 ++----------- jobs/generated/kicking.h | 12 +----------- jobs/joinroomjob.cpp | 4 ++-- jobs/joinroomjob.h | 2 +- jobs/leaveroomjob.cpp | 4 ++-- jobs/leaveroomjob.h | 2 +- jobs/logoutjob.cpp | 4 ++-- jobs/logoutjob.h | 2 +- jobs/mediathumbnailjob.cpp | 11 ++++++----- jobs/mediathumbnailjob.h | 10 +++++----- jobs/passwordlogin.cpp | 10 +++++----- jobs/passwordlogin.h | 9 ++++----- jobs/postreceiptjob.cpp | 8 ++++---- jobs/postreceiptjob.h | 3 +-- jobs/roommessagesjob.cpp | 10 ++++------ jobs/roommessagesjob.h | 6 +++--- jobs/sendeventjob.cpp | 12 ++++++++---- jobs/sendeventjob.h | 16 ++++++++-------- jobs/setroomstatejob.h | 11 +++++------ jobs/syncjob.cpp | 8 ++++---- jobs/syncjob.h | 21 +++++++++++---------- 28 files changed, 129 insertions(+), 143 deletions(-) diff --git a/connection.h b/connection.h index 4ca6fbc5..213bf26f 100644 --- a/connection.h +++ b/connection.h @@ -72,6 +72,9 @@ namespace QMatrixClient Q_INVOKABLE void sync(int timeout = -1); Q_INVOKABLE void stopSync(); + + // Old API that will be abolished any time soon. DO NOT USE. + /** @deprecated Use callApi() or Room::postMessage() instead */ Q_INVOKABLE virtual void postMessage(Room* room, const QString& type, const QString& message) const; @@ -82,6 +85,7 @@ namespace QMatrixClient Q_INVOKABLE virtual JoinRoomJob* joinRoom(const QString& roomAlias); /** @deprecated Use callApi() or Room::leaveRoom() instead */ Q_INVOKABLE virtual void leaveRoom( Room* room ); + /** @deprecated User callApi() or Room::getPreviousContent() instead */ Q_INVOKABLE virtual RoomMessagesJob* getMessages(Room* room, const QString& from) const; /** @deprecated Use callApi() instead */ @@ -142,8 +146,8 @@ namespace QMatrixClient template JobT* callApi(JobArgTs... jobArgs) const { - auto job = new JobT(connectionData(), jobArgs...); - job->start(); + auto job = new JobT(jobArgs...); + job->start(connectionData()); return job; } diff --git a/jobs/basejob.cpp b/jobs/basejob.cpp index ea1a7158..240192d9 100644 --- a/jobs/basejob.cpp +++ b/jobs/basejob.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +//#include #include @@ -45,16 +45,15 @@ class BaseJob::Private public: // Using an idiom from clang-tidy: // http://clang.llvm.org/extra/clang-tidy/checks/modernize-pass-by-value.html - Private(const ConnectionData* c, HttpVerb v, - QString endpoint, QUrlQuery q, Data data, bool nt) - : connection(c), verb(v), apiEndpoint(std::move(endpoint)) + Private(HttpVerb v, QString endpoint, QUrlQuery q, Data data, bool nt) + : verb(v), apiEndpoint(std::move(endpoint)) , requestQuery(std::move(q)), requestData(std::move(data)) , needsToken(nt) { } void sendRequest(); - const ConnectionData* connection; + const ConnectionData* connection = nullptr; // Contents for the network request HttpVerb verb; @@ -80,16 +79,15 @@ inline QDebug operator<<(QDebug dbg, const BaseJob* j) return dbg << j->objectName(); } -BaseJob::BaseJob(const ConnectionData* connection, HttpVerb verb, - const QString& name, const QString& endpoint, +BaseJob::BaseJob(HttpVerb verb, const QString& name, const QString& endpoint, const Query& query, const Data& data, bool needsToken) - : d(new Private(connection, verb, endpoint, query, data, needsToken)) + : d(new Private(verb, endpoint, query, data, needsToken)) { setObjectName(name); d->timer.setSingleShot(true); connect (&d->timer, &QTimer::timeout, this, &BaseJob::timeout); d->retryTimer.setSingleShot(true); - connect (&d->retryTimer, &QTimer::timeout, this, &BaseJob::start); + connect (&d->retryTimer, &QTimer::timeout, this, &BaseJob::sendRequest); } BaseJob::~BaseJob() @@ -98,9 +96,14 @@ BaseJob::~BaseJob() qCDebug(d->logCat) << this << "destroyed"; } -const ConnectionData* BaseJob::connection() const +const QString& BaseJob::apiEndpoint() const { - return d->connection; + return d->apiEndpoint; +} + +void BaseJob::setApiEndpoint(const QString& apiEndpoint) +{ + d->apiEndpoint = apiEndpoint; } const QUrlQuery& BaseJob::query() const @@ -155,7 +158,18 @@ void BaseJob::Private::sendRequest() } } -void BaseJob::start() +void BaseJob::beforeStart(const ConnectionData* connData) +{ +} + +void BaseJob::start(const ConnectionData* connData) +{ + d->connection = connData; + beforeStart(connData); + sendRequest(); +} + +void BaseJob::sendRequest() { emit aboutToStart(); d->retryTimer.stop(); // In case we were counting down at the moment diff --git a/jobs/basejob.h b/jobs/basejob.h index b8cc9511..2f7bd9cd 100644 --- a/jobs/basejob.h +++ b/jobs/basejob.h @@ -118,8 +118,7 @@ namespace QMatrixClient using duration_t = int; // milliseconds public: - BaseJob(const ConnectionData* connection, HttpVerb verb, - const QString& name, const QString& endpoint, + BaseJob(HttpVerb verb, const QString& name, const QString& endpoint, const Query& query = {}, const Data& data = {}, bool needsToken = true); @@ -135,7 +134,7 @@ namespace QMatrixClient Q_INVOKABLE duration_t millisToRetry() const; public slots: - void start(); + void start(const ConnectionData* connData); /** * Abandons the result of this job, arrived or unarrived. @@ -205,13 +204,15 @@ namespace QMatrixClient void failure(BaseJob*); protected: - const ConnectionData* connection() const; - + const QString& apiEndpoint() const; + void setApiEndpoint(const QString& apiEndpoint); const QUrlQuery& query() const; void setRequestQuery(const QUrlQuery& query); const Data& requestData() const; void setRequestData(const Data& data); + virtual void beforeStart(const ConnectionData* connData); + /** * Used by gotReply() to check the received reply for general * issues such as network errors or access denial. @@ -260,6 +261,7 @@ namespace QMatrixClient void sslErrors(const QList& errors); private slots: + void sendRequest(); void gotReply(); private: diff --git a/jobs/checkauthmethods.cpp b/jobs/checkauthmethods.cpp index 95b9a8f2..117def89 100644 --- a/jobs/checkauthmethods.cpp +++ b/jobs/checkauthmethods.cpp @@ -29,9 +29,9 @@ class CheckAuthMethods::Private QString session; }; -CheckAuthMethods::CheckAuthMethods(const ConnectionData* connection) - : BaseJob(connection, HttpVerb::Get, "CheckAuthMethods", - "_matrix/client/r0/login", Query(), Data(), false) +CheckAuthMethods::CheckAuthMethods() + : BaseJob(HttpVerb::Get, "CheckAuthMethods", + QStringLiteral("_matrix/client/r0/login"), Query(), Data(), false) , d(new Private) { } diff --git a/jobs/checkauthmethods.h b/jobs/checkauthmethods.h index 7d7dc40f..647f3db6 100644 --- a/jobs/checkauthmethods.h +++ b/jobs/checkauthmethods.h @@ -25,7 +25,7 @@ namespace QMatrixClient class CheckAuthMethods : public BaseJob { public: - CheckAuthMethods(const ConnectionData* connection); + CheckAuthMethods(); virtual ~CheckAuthMethods(); QString session(); diff --git a/jobs/generated/inviting.cpp b/jobs/generated/inviting.cpp index e5e7f410..1e0c29a3 100644 --- a/jobs/generated/inviting.cpp +++ b/jobs/generated/inviting.cpp @@ -16,19 +16,11 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); - -InviteUserJob::InviteUserJob(const ConnectionData* connection, - QString roomId - , - QString user_id - ) - : BaseJob(connection, HttpVerb::Post, "InviteUserJob" - , basePath % "/rooms/" % roomId % "/invite" - , Query { } - , Data { - { "user_id", toJson(user_id) } - } - +InviteUserJob::InviteUserJob(QString roomId, QString user_id) + : BaseJob(HttpVerb::Post, "InviteUserJob", + basePath % "/rooms/" % roomId % "/invite", + Query {}, + Data { { "user_id", toJson(user_id) } } ) { } diff --git a/jobs/generated/inviting.h b/jobs/generated/inviting.h index af5a426d..84cce06e 100644 --- a/jobs/generated/inviting.h +++ b/jobs/generated/inviting.h @@ -27,15 +27,7 @@ namespace QMatrixClient class InviteUserJob : public BaseJob { public: - InviteUserJob(const ConnectionData* connection - - , - QString roomId - - , - QString user_id - ); - + InviteUserJob(QString roomId, QString user_id); }; diff --git a/jobs/generated/kicking.cpp b/jobs/generated/kicking.cpp index 726f6fb0..4f9d6580 100644 --- a/jobs/generated/kicking.cpp +++ b/jobs/generated/kicking.cpp @@ -16,23 +16,14 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); - -KickJob::KickJob(const ConnectionData* connection, - QString roomId - , - QString user_id - , - QString reason - ) - : BaseJob(connection, HttpVerb::Post, "KickJob" +KickJob::KickJob(QString roomId, QString user_id, QString reason) + : BaseJob(HttpVerb::Post, "KickJob" , basePath % "/rooms/" % roomId % "/kick" , Query { } , Data { { "user_id", toJson(user_id) }, - { "reason", toJson(reason) } } - ) { } diff --git a/jobs/generated/kicking.h b/jobs/generated/kicking.h index 7b183b08..a746db8b 100644 --- a/jobs/generated/kicking.h +++ b/jobs/generated/kicking.h @@ -27,17 +27,7 @@ namespace QMatrixClient class KickJob : public BaseJob { public: - KickJob(const ConnectionData* connection - - , - QString roomId - - , - QString user_id - - , - QString reason - ); + KickJob(QString roomId, QString user_id, QString reason); }; diff --git a/jobs/joinroomjob.cpp b/jobs/joinroomjob.cpp index 6278c18b..d465dd42 100644 --- a/jobs/joinroomjob.cpp +++ b/jobs/joinroomjob.cpp @@ -27,8 +27,8 @@ class JoinRoomJob::Private QString roomId; }; -JoinRoomJob::JoinRoomJob(const ConnectionData* data, const QString& roomAlias) - : BaseJob(data, HttpVerb::Post, "JoinRoomJob", +JoinRoomJob::JoinRoomJob(const QString& roomAlias) + : BaseJob(HttpVerb::Post, "JoinRoomJob", QString("_matrix/client/r0/join/%1").arg(roomAlias)) , d(new Private) { diff --git a/jobs/joinroomjob.h b/jobs/joinroomjob.h index 7cf90fd5..f3ba216f 100644 --- a/jobs/joinroomjob.h +++ b/jobs/joinroomjob.h @@ -25,7 +25,7 @@ namespace QMatrixClient class JoinRoomJob: public BaseJob { public: - JoinRoomJob(const ConnectionData* data, const QString& roomAlias); + explicit JoinRoomJob(const QString& roomAlias); virtual ~JoinRoomJob(); QString roomId(); diff --git a/jobs/leaveroomjob.cpp b/jobs/leaveroomjob.cpp index f73919ac..54e7f307 100644 --- a/jobs/leaveroomjob.cpp +++ b/jobs/leaveroomjob.cpp @@ -20,7 +20,7 @@ using namespace QMatrixClient; -LeaveRoomJob::LeaveRoomJob(const ConnectionData* data, const QString& roomId) - : BaseJob(data, HttpVerb::Post, "LeaveRoomJob", +LeaveRoomJob::LeaveRoomJob(const QString& roomId) + : BaseJob(HttpVerb::Post, "LeaveRoomJob", QStringLiteral("_matrix/client/r0/rooms/%1/leave").arg(roomId)) { } diff --git a/jobs/leaveroomjob.h b/jobs/leaveroomjob.h index 70883b68..9224c1c8 100644 --- a/jobs/leaveroomjob.h +++ b/jobs/leaveroomjob.h @@ -25,6 +25,6 @@ namespace QMatrixClient class LeaveRoomJob: public BaseJob { public: - LeaveRoomJob(const ConnectionData* data, const QString& roomId); + explicit LeaveRoomJob(const QString& roomId); }; } // namespace QMatrixClient diff --git a/jobs/logoutjob.cpp b/jobs/logoutjob.cpp index 84e88760..5ea5cf4d 100644 --- a/jobs/logoutjob.cpp +++ b/jobs/logoutjob.cpp @@ -20,7 +20,7 @@ using namespace QMatrixClient; -LogoutJob::LogoutJob(const ConnectionData* connection) - : BaseJob(connection, HttpVerb::Post, "LogoutJob", "/_matrix/client/r0/logout") +LogoutJob::LogoutJob() + : BaseJob(HttpVerb::Post, "LogoutJob", "/_matrix/client/r0/logout") { } diff --git a/jobs/logoutjob.h b/jobs/logoutjob.h index 780719e4..e1b988dc 100644 --- a/jobs/logoutjob.h +++ b/jobs/logoutjob.h @@ -25,6 +25,6 @@ namespace QMatrixClient class LogoutJob: public BaseJob { public: - explicit LogoutJob(const ConnectionData* connection); + LogoutJob(); }; } diff --git a/jobs/mediathumbnailjob.cpp b/jobs/mediathumbnailjob.cpp index 9579f6b2..5945493a 100644 --- a/jobs/mediathumbnailjob.cpp +++ b/jobs/mediathumbnailjob.cpp @@ -23,10 +23,11 @@ using namespace QMatrixClient; -MediaThumbnailJob::MediaThumbnailJob(const ConnectionData* data, QUrl url, QSize requestedSize, +MediaThumbnailJob::MediaThumbnailJob(QUrl url, QSize requestedSize, ThumbnailType thumbnailType) - : BaseJob(data, HttpVerb::Get, "MediaThumbnailJob", - QString("/_matrix/media/v1/thumbnail/%1%2").arg(url.host(), url.path()), + : BaseJob(HttpVerb::Get, "MediaThumbnailJob", + QStringLiteral("/_matrix/media/v1/thumbnail/%1%2") + .arg(url.host(), url.path()), Query( { { "width", QString::number(requestedSize.width()) } , { "height", QString::number(requestedSize.height()) } @@ -35,12 +36,12 @@ MediaThumbnailJob::MediaThumbnailJob(const ConnectionData* data, QUrl url, QSize })) { } -QPixmap MediaThumbnailJob::thumbnail() +QPixmap MediaThumbnailJob::thumbnail() const { return pixmap; } -QPixmap MediaThumbnailJob::scaledThumbnail(QSize toSize) +QPixmap MediaThumbnailJob::scaledThumbnail(QSize toSize) const { return pixmap.scaled(toSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); } diff --git a/jobs/mediathumbnailjob.h b/jobs/mediathumbnailjob.h index 186da829..292e7f14 100644 --- a/jobs/mediathumbnailjob.h +++ b/jobs/mediathumbnailjob.h @@ -29,11 +29,11 @@ namespace QMatrixClient class MediaThumbnailJob: public BaseJob { public: - MediaThumbnailJob(const ConnectionData* data, QUrl url, QSize requestedSize, - ThumbnailType thumbnailType=ThumbnailType::Scale); + MediaThumbnailJob(QUrl url, QSize requestedSize, + ThumbnailType thumbnailType = ThumbnailType::Scale); - QPixmap thumbnail(); - QPixmap scaledThumbnail(QSize toSize); + QPixmap thumbnail() const; + QPixmap scaledThumbnail(QSize toSize) const; protected: Status parseReply(QByteArray data) override; @@ -41,4 +41,4 @@ namespace QMatrixClient private: QPixmap pixmap; }; -} +} // namespace QMatrixClient diff --git a/jobs/passwordlogin.cpp b/jobs/passwordlogin.cpp index 09108215..9af025e6 100644 --- a/jobs/passwordlogin.cpp +++ b/jobs/passwordlogin.cpp @@ -28,8 +28,8 @@ class PasswordLogin::Private QString returned_token; }; -PasswordLogin::PasswordLogin(const ConnectionData* connection, QString user, QString password) - : BaseJob(connection, HttpVerb::Post, "PasswordLogin" +PasswordLogin::PasswordLogin(QString user, QString password) + : BaseJob(HttpVerb::Post, "PasswordLogin" , "_matrix/client/r0/login" , Query() , Data( @@ -48,17 +48,17 @@ PasswordLogin::~PasswordLogin() delete d; } -QString PasswordLogin::token() +QString PasswordLogin::token() const { return d->returned_token; } -QString PasswordLogin::id() +QString PasswordLogin::id() const { return d->returned_id; } -QString PasswordLogin::server() +QString PasswordLogin::server() const { return d->returned_server; } diff --git a/jobs/passwordlogin.h b/jobs/passwordlogin.h index 6b7db0b3..fb8777a3 100644 --- a/jobs/passwordlogin.h +++ b/jobs/passwordlogin.h @@ -25,13 +25,12 @@ namespace QMatrixClient class PasswordLogin : public BaseJob { public: - PasswordLogin(const ConnectionData* connection, - QString user, QString password); + PasswordLogin(QString user, QString password); virtual ~PasswordLogin(); - QString token(); - QString id(); - QString server(); + QString token() const; + QString id() const; + QString server() const; protected: Status parseJson(const QJsonDocument& data) override; diff --git a/jobs/postreceiptjob.cpp b/jobs/postreceiptjob.cpp index 00926de6..4572d74c 100644 --- a/jobs/postreceiptjob.cpp +++ b/jobs/postreceiptjob.cpp @@ -20,8 +20,8 @@ using namespace QMatrixClient; -PostReceiptJob::PostReceiptJob(const ConnectionData* connection, - const QString& roomId, const QString& eventId) - : BaseJob(connection, HttpVerb::Post, "PostReceiptJob", - QString("/_matrix/client/r0/rooms/%1/receipt/m.read/%2").arg(roomId, eventId)) +PostReceiptJob::PostReceiptJob(const QString& roomId, const QString& eventId) + : BaseJob(HttpVerb::Post, "PostReceiptJob", + QStringLiteral("/_matrix/client/r0/rooms/%1/receipt/m.read/%2") + .arg(roomId, eventId)) { } diff --git a/jobs/postreceiptjob.h b/jobs/postreceiptjob.h index 1c84f411..23df7c05 100644 --- a/jobs/postreceiptjob.h +++ b/jobs/postreceiptjob.h @@ -25,7 +25,6 @@ namespace QMatrixClient class PostReceiptJob: public BaseJob { public: - PostReceiptJob(const ConnectionData* connection, const QString& roomId, - const QString& eventId); + PostReceiptJob(const QString& roomId, const QString& eventId); }; } diff --git a/jobs/roommessagesjob.cpp b/jobs/roommessagesjob.cpp index 3e603a50..078c692a 100644 --- a/jobs/roommessagesjob.cpp +++ b/jobs/roommessagesjob.cpp @@ -18,8 +18,6 @@ #include "roommessagesjob.h" -#include "util.h" - using namespace QMatrixClient; class RoomMessagesJob::Private @@ -29,9 +27,9 @@ class RoomMessagesJob::Private QString end; }; -RoomMessagesJob::RoomMessagesJob(const ConnectionData* data, const QString& roomId, - const QString& from, int limit, FetchDirection dir) - : BaseJob(data, HttpVerb::Get, "RoomMessagesJob", +RoomMessagesJob::RoomMessagesJob(const QString& roomId, const QString& from, + int limit, FetchDirection dir) + : BaseJob(HttpVerb::Get, "RoomMessagesJob", QString("/_matrix/client/r0/rooms/%1/messages").arg(roomId), Query( { { "from", from } @@ -53,7 +51,7 @@ RoomEvents RoomMessagesJob::releaseEvents() return d->events.release(); } -QString RoomMessagesJob::end() +QString RoomMessagesJob::end() const { return d->end; } diff --git a/jobs/roommessagesjob.h b/jobs/roommessagesjob.h index a029c27c..9680d52c 100644 --- a/jobs/roommessagesjob.h +++ b/jobs/roommessagesjob.h @@ -29,13 +29,13 @@ namespace QMatrixClient class RoomMessagesJob: public BaseJob { public: - RoomMessagesJob(const ConnectionData* data, const QString& roomId, - const QString& from, int limit = 10, + RoomMessagesJob(const QString& roomId, const QString& from, + int limit = 10, FetchDirection dir = FetchDirection::Backward); virtual ~RoomMessagesJob(); RoomEvents releaseEvents(); - QString end(); + QString end() const; protected: Status parseJson(const QJsonDocument& data) override; diff --git a/jobs/sendeventjob.cpp b/jobs/sendeventjob.cpp index f3c95fe8..7e33e089 100644 --- a/jobs/sendeventjob.cpp +++ b/jobs/sendeventjob.cpp @@ -22,13 +22,17 @@ using namespace QMatrixClient; -SendEventJob::SendEventJob(const ConnectionData* connection, - const QString& roomId, const QString& type, +SendEventJob::SendEventJob(const QString& roomId, const QString& type, const QString& plainText) - : SendEventJob(connection, roomId, - new RoomMessageEvent(plainText, type)) + : SendEventJob(roomId, new RoomMessageEvent(plainText, type)) { } +void SendEventJob::beforeStart(const ConnectionData* connData) +{ + BaseJob::beforeStart(connData); + setApiEndpoint(apiEndpoint() + connData->generateTxnId()); +} + BaseJob::Status SendEventJob::parseJson(const QJsonDocument& data) { _eventId = data.object().value("event_id").toString(); diff --git a/jobs/sendeventjob.h b/jobs/sendeventjob.h index 42948cc2..7b10b3d4 100644 --- a/jobs/sendeventjob.h +++ b/jobs/sendeventjob.h @@ -29,12 +29,10 @@ namespace QMatrixClient public: /** Constructs a job that sends an arbitrary room event */ template - SendEventJob(const ConnectionData* connection, const QString& roomId, - const EvT* event) - : BaseJob(connection, HttpVerb::Put, "SendEventJob", - QStringLiteral("_matrix/client/r0/rooms/%1/send/%2/%3") - .arg(roomId, EvT::TypeId, - connection->generateTxnId()), + SendEventJob(const QString& roomId, const EvT* event) + : BaseJob(HttpVerb::Put, QStringLiteral("SendEventJob"), + QStringLiteral("_matrix/client/r0/rooms/%1/send/%2/") + .arg(roomId, EvT::TypeId), // See also beforeStart() Query(), Data(event->toJson())) { } @@ -43,8 +41,8 @@ namespace QMatrixClient * Constructs a plain text message job (for compatibility with * the old PostMessageJob API). */ - SendEventJob(const ConnectionData* connection, const QString& roomId, - const QString& type, const QString& plainText); + SendEventJob(const QString& roomId, const QString& type, + const QString& plainText); QString eventId() const { return _eventId; } @@ -53,5 +51,7 @@ namespace QMatrixClient private: QString _eventId; + + void beforeStart(const ConnectionData* connData) override; }; } // namespace QMatrixClient diff --git a/jobs/setroomstatejob.h b/jobs/setroomstatejob.h index 1c72f31c..ddc271b9 100644 --- a/jobs/setroomstatejob.h +++ b/jobs/setroomstatejob.h @@ -32,9 +32,9 @@ namespace QMatrixClient * with a state key. */ template - SetRoomStateJob(const ConnectionData* connection, const QString& roomId, - const EvT* event, const QString& stateKey) - : BaseJob(connection, HttpVerb::Put, "SetRoomStateJob", + SetRoomStateJob(const QString& roomId, const QString& stateKey, + const EvT* event) + : BaseJob(HttpVerb::Put, "SetRoomStateJob", QStringLiteral("_matrix/client/r0/rooms/%1/state/%2/%3") .arg(roomId, EvT::TypeId, stateKey), Query(), @@ -45,9 +45,8 @@ namespace QMatrixClient * without a state key. */ template - SetRoomStateJob(const ConnectionData* connection, const QString& roomId, - const EvT* event) - : BaseJob(connection, HttpVerb::Put, "SetRoomStateJob", + SetRoomStateJob(const QString& roomId, const EvT* event) + : BaseJob(HttpVerb::Put, "SetRoomStateJob", QStringLiteral("_matrix/client/r0/rooms/%1/state/%2") .arg(roomId, EvT::TypeId), Query(), diff --git a/jobs/syncjob.cpp b/jobs/syncjob.cpp index f679e6f4..6d37db5c 100644 --- a/jobs/syncjob.cpp +++ b/jobs/syncjob.cpp @@ -24,10 +24,10 @@ using namespace QMatrixClient; static size_t jobId = 0; -SyncJob::SyncJob(const ConnectionData* connection, const QString& since, - const QString& filter, int timeout, const QString& presence) - : BaseJob(connection, HttpVerb::Get, QString("SyncJob-%1").arg(++jobId), - "_matrix/client/r0/sync") +SyncJob::SyncJob(const QString& since, const QString& filter, int timeout, + const QString& presence) + : BaseJob(HttpVerb::Get, QStringLiteral("SyncJob-%1").arg(++jobId), + QStringLiteral("_matrix/client/r0/sync")) { setLoggingCategory(SYNCJOB); QUrlQuery query; diff --git a/jobs/syncjob.h b/jobs/syncjob.h index 6697a265..b1db914d 100644 --- a/jobs/syncjob.h +++ b/jobs/syncjob.h @@ -68,21 +68,22 @@ namespace QMatrixClient // QVector cannot work with non-copiable objects, std::vector can. using SyncDataList = std::vector; - class SyncData { - public: - BaseJob::Status parseJson(const QJsonDocument &data); - SyncDataList&& takeRoomData(); - QString nextBatch() const; - - private: - QString nextBatch_; - SyncDataList roomData; + class SyncData + { + public: + BaseJob::Status parseJson(const QJsonDocument &data); + SyncDataList&& takeRoomData(); + QString nextBatch() const; + + private: + QString nextBatch_; + SyncDataList roomData; }; class SyncJob: public BaseJob { public: - explicit SyncJob(const ConnectionData* connection, const QString& since = {}, + explicit SyncJob(const QString& since = {}, const QString& filter = {}, int timeout = -1, const QString& presence = {}); -- cgit v1.2.3 From 8207ef24c0e71133f3cfe115a4652767b4a63f9d Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 10 Oct 2017 12:19:31 +0900 Subject: Extend the number of types supported by fromJson<>() Template function cannot have partial specializations, and we need to deserialise QVector<> objects. So fromJson<>() is now a wrapper around FromJson<> template class that does all the dispatching stuff in its operator(). --- jobs/converters.h | 88 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/jobs/converters.h b/jobs/converters.h index f9ab0269..f6e850c6 100644 --- a/jobs/converters.h +++ b/jobs/converters.h @@ -18,10 +18,9 @@ #pragma once -#include -#include +#include +#include // Includes #include -#include namespace QMatrixClient { @@ -45,45 +44,78 @@ namespace QMatrixClient return QJsonArray::fromStringList(strings); } + template + struct FromJson + { + T operator()(QJsonValue jv) const { return static_cast(jv); } + }; + template inline T fromJson(const QJsonValue& jv) { - return QVariant(jv).value(); + return FromJson()(jv); } - template <> - inline int fromJson(const QJsonValue& jv) + template <> struct FromJson { - return jv.toInt(); - } + bool operator()(QJsonValue jv) const { return jv.toBool(); } + }; - template <> - inline qint64 fromJson(const QJsonValue& jv) + template <> struct FromJson { - return static_cast(jv.toDouble()); - } + int operator()(QJsonValue jv) const { return jv.toInt(); } + }; - template <> - inline double fromJson(const QJsonValue& jv) + template <> struct FromJson { - return jv.toDouble(); - } + double operator()(QJsonValue jv) const { return jv.toDouble(); } + }; - template <> - inline QString fromJson(const QJsonValue& jv) + template <> struct FromJson { - return jv.toString(); - } + qint64 operator()(QJsonValue jv) const { return qint64(jv.toDouble()); } + }; - template <> - inline QDateTime fromJson(const QJsonValue& jv) + template <> struct FromJson { - return QDateTime::fromMSecsSinceEpoch(fromJson(jv), Qt::UTC); - } + QString operator()(QJsonValue jv) const { return jv.toString(); } + }; - template <> - inline QDate fromJson(const QJsonValue& jv) + template <> struct FromJson { - return fromJson(jv).date(); - } + QDateTime operator()(QJsonValue jv) const + { + return QDateTime::fromMSecsSinceEpoch(fromJson(jv), Qt::UTC); + } + }; + + template <> struct FromJson + { + QDate operator()(QJsonValue jv) const + { + return fromJson(jv).date(); + } + }; + + template <> struct FromJson + { + QJsonObject operator()(QJsonValue jv) const { return jv.toObject(); } + }; + + template <> struct FromJson + { + QJsonArray operator()(QJsonValue jv) const { return jv.toArray(); } + }; + + template struct FromJson> + { + QVector operator()(QJsonValue jv) const + { + const auto jsonArray = jv.toArray(); + QVector vect; vect.resize(jsonArray.size()); + std::transform(jsonArray.begin(), jsonArray.end(), + vect.begin(), FromJson()); + return vect; + } + }; } // namespace QMatrixClient -- cgit v1.2.3 From 360fa9c8a053d8b0888c5d2a8cda6c7672cdd5a1 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 10 Oct 2017 16:35:00 +0900 Subject: Cleaner generated files --- jobs/generated/inviting.cpp | 17 ++++++----------- jobs/generated/inviting.h | 15 +++------------ jobs/generated/kicking.cpp | 23 ++++++++--------------- jobs/generated/kicking.h | 16 +++------------- 4 files changed, 20 insertions(+), 51 deletions(-) diff --git a/jobs/generated/inviting.cpp b/jobs/generated/inviting.cpp index 1e0c29a3..95ba658d 100644 --- a/jobs/generated/inviting.cpp +++ b/jobs/generated/inviting.cpp @@ -5,25 +5,20 @@ #include "inviting.h" - -#include "../converters.h" - +#include "jobs/converters.h" #include using namespace QMatrixClient; - - static const auto basePath = QStringLiteral("/_matrix/client/r0"); InviteUserJob::InviteUserJob(QString roomId, QString user_id) : BaseJob(HttpVerb::Post, "InviteUserJob", - basePath % "/rooms/" % roomId % "/invite", - Query {}, - Data { { "user_id", toJson(user_id) } } + basePath % "/rooms/" % roomId % "/invite", + Query { }, + Data { + { "user_id", toJson(user_id) } + } ) { } - - - diff --git a/jobs/generated/inviting.h b/jobs/generated/inviting.h index 84cce06e..ac0fd5fa 100644 --- a/jobs/generated/inviting.h +++ b/jobs/generated/inviting.h @@ -5,30 +5,21 @@ #pragma once - #include "../basejob.h" - - #include - - namespace QMatrixClient { - // Operations - - /** - - */ + class InviteUserJob : public BaseJob { public: - InviteUserJob(QString roomId, QString user_id); + explicit InviteUserJob(QString roomId, QString user_id); + }; - } // namespace QMatrixClient diff --git a/jobs/generated/kicking.cpp b/jobs/generated/kicking.cpp index 4f9d6580..2e6797d6 100644 --- a/jobs/generated/kicking.cpp +++ b/jobs/generated/kicking.cpp @@ -5,28 +5,21 @@ #include "kicking.h" - -#include "../converters.h" - +#include "jobs/converters.h" #include using namespace QMatrixClient; - - static const auto basePath = QStringLiteral("/_matrix/client/r0"); KickJob::KickJob(QString roomId, QString user_id, QString reason) - : BaseJob(HttpVerb::Post, "KickJob" - , basePath % "/rooms/" % roomId % "/kick" - , Query { } - , Data { - { "user_id", toJson(user_id) }, - { "reason", toJson(reason) } - } + : BaseJob(HttpVerb::Post, "KickJob", + basePath % "/rooms/" % roomId % "/kick", + Query { }, + Data { + { "user_id", toJson(user_id) }, + { "reason", toJson(reason) } + } ) { } - - - diff --git a/jobs/generated/kicking.h b/jobs/generated/kicking.h index a746db8b..658193d5 100644 --- a/jobs/generated/kicking.h +++ b/jobs/generated/kicking.h @@ -5,31 +5,21 @@ #pragma once - #include "../basejob.h" - - #include - - namespace QMatrixClient { - // Operations - - /** - - */ + class KickJob : public BaseJob { public: - KickJob(QString roomId, QString user_id, QString reason); - + explicit KickJob(QString roomId, QString user_id, QString reason = {}); + }; - } // namespace QMatrixClient -- cgit v1.2.3 From d27d2ab396f92b7d5139f43afe52be6e0470eaea Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Fri, 13 Oct 2017 00:02:46 +0200 Subject: Support banning and unbanning Closes #38. Also rearranged #includes --- jobs/generated/banning.cpp | 35 +++++++++++++++++++++++++++++++++++ jobs/generated/banning.h | 31 +++++++++++++++++++++++++++++++ room.cpp | 31 ++++++++++++++++++++----------- room.h | 5 ++++- 4 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 jobs/generated/banning.cpp create mode 100644 jobs/generated/banning.h diff --git a/jobs/generated/banning.cpp b/jobs/generated/banning.cpp new file mode 100644 index 00000000..9fc5810a --- /dev/null +++ b/jobs/generated/banning.cpp @@ -0,0 +1,35 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + + +#include "banning.h" + +#include "jobs/converters.h" +#include + +using namespace QMatrixClient; + +static const auto basePath = QStringLiteral("/_matrix/client/r0"); + +BanJob::BanJob(QString roomId, QString user_id, QString reason) + : BaseJob(HttpVerb::Post, "BanJob", + basePath % "/rooms/" % roomId % "/ban", + Query { }, + Data { + { "user_id", toJson(user_id) }, + { "reason", toJson(reason) } + } + ) +{ } + +UnbanJob::UnbanJob(QString roomId, QString user_id) + : BaseJob(HttpVerb::Post, "UnbanJob", + basePath % "/rooms/" % roomId % "/unban", + Query { }, + Data { + { "user_id", toJson(user_id) } + } + ) +{ } + diff --git a/jobs/generated/banning.h b/jobs/generated/banning.h new file mode 100644 index 00000000..b9d5b8db --- /dev/null +++ b/jobs/generated/banning.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + + +#pragma once + +#include "../basejob.h" + +#include + + +namespace QMatrixClient +{ + + // Operations + + class BanJob : public BaseJob + { + public: + explicit BanJob(QString roomId, QString user_id, QString reason = {}); + + }; + class UnbanJob : public BaseJob + { + public: + explicit UnbanJob(QString roomId, QString user_id); + + }; + +} // namespace QMatrixClient diff --git a/room.cpp b/room.cpp index 05b16b65..79168d85 100644 --- a/room.cpp +++ b/room.cpp @@ -20,17 +20,8 @@ #include "jobs/generated/kicking.h" #include "jobs/generated/inviting.h" - -#include - -#include -#include // for efficient string concats (operator%) -#include -#include - -#include "connection.h" -#include "state.h" -#include "user.h" +#include "jobs/generated/banning.h" +#include "jobs/setroomstatejob.h" #include "events/roomnameevent.h" #include "events/roomaliasesevent.h" #include "events/roomcanonicalaliasevent.h" @@ -42,6 +33,14 @@ #include "jobs/roommessagesjob.h" #include "jobs/postreceiptjob.h" #include "jobs/leaveroomjob.h" +#include "connection.h" +#include "user.h" + +#include +#include // for efficient string concats (operator%) +#include + +#include using namespace QMatrixClient; @@ -639,6 +638,16 @@ void Room::kickMember(const QString& memberId, const QString& reason) const connection()->callApi(id(), memberId, reason); } +void Room::ban(const QString& userId, const QString& reason) const +{ + connection()->callApi(id(), userId, reason); +} + +void Room::unban(const QString& userId) const +{ + connection()->callApi(id(), userId); +} + void Room::Private::dropDuplicateEvents(RoomEvents* events) const { // Collect all duplicate events at the end of the container diff --git a/room.h b/room.h index 455ef6cc..d62d160f 100644 --- a/room.h +++ b/room.h @@ -159,7 +159,10 @@ namespace QMatrixClient void inviteToRoom(const QString& memberId) const; void leaveRoom() const; - void kickMember(const QString& memberId, const QString& reason) const; + void kickMember(const QString& memberId, + const QString& reason = {}) const; + void ban(const QString& userId, const QString& reason = {}) const; + void unban(const QString& userId) const; void userRenamed(User* user, QString oldName); -- cgit v1.2.3 From 2d3590dbdb23c82f1960327ffbd78e778231b9c8 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Fri, 13 Oct 2017 23:17:06 +0200 Subject: Pass universal references in Connection::callApi<>; fixed a typo in util.h So that even uncopyable types could be used for parameters; also fixed a typo in util.h that prevented dispatch() from using with multiple argument functions. --- connection.h | 4 ++-- util.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/connection.h b/connection.h index 213bf26f..dbb50b9a 100644 --- a/connection.h +++ b/connection.h @@ -144,9 +144,9 @@ namespace QMatrixClient * argument - callApi() will pass it automatically. */ template - JobT* callApi(JobArgTs... jobArgs) const + JobT* callApi(JobArgTs&&... jobArgs) const { - auto job = new JobT(jobArgs...); + auto job = new JobT(std::forward(jobArgs)...); job->start(connectionData()); return job; } diff --git a/util.h b/util.h index 1f9e3f0b..0c8f3640 100644 --- a/util.h +++ b/util.h @@ -231,7 +231,7 @@ namespace QMatrixClient template Dispatch dispatch(ArgTs&& ... args) { - return Dispatch(std::forward(args)...); + return Dispatch(std::forward(args)...); } // The below enables pretty-printing of enums in logs -- cgit v1.2.3 From 76c42a9863b83229e6afaf4be32e9582e3d97d3f Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 14 Oct 2017 01:22:04 +0200 Subject: Cleanup around Room (potentially breaks API compatibility, beware) Notably: * API for SendEventJob and SetRoomStateJob has been altered to accept references, not pointers. * Methods on Room that invoke requests to the server, have lost const, because they may be reflecting the changed state on the fly, within themselves --- connection.cpp | 1 - events/roommemberevent.cpp | 8 +++++--- jobs/sendeventjob.cpp | 2 +- jobs/sendeventjob.h | 4 ++-- jobs/setroomstatejob.h | 8 ++++---- room.cpp | 27 +++++++++++---------------- room.h | 15 ++++++--------- 7 files changed, 29 insertions(+), 36 deletions(-) diff --git a/connection.cpp b/connection.cpp index e20f843f..c7492868 100644 --- a/connection.cpp +++ b/connection.cpp @@ -26,7 +26,6 @@ #include "jobs/sendeventjob.h" #include "jobs/postreceiptjob.h" #include "jobs/joinroomjob.h" -#include "jobs/leaveroomjob.h" #include "jobs/roommessagesjob.h" #include "jobs/syncjob.h" #include "jobs/mediathumbnailjob.h" diff --git a/events/roommemberevent.cpp b/events/roommemberevent.cpp index 5973acc7..19f116d2 100644 --- a/events/roommemberevent.cpp +++ b/events/roommemberevent.cpp @@ -22,6 +22,9 @@ using namespace QMatrixClient; +static const auto membershipStrings = + { "invite", "join", "knock", "leave", "ban" }; + RoomMemberEvent::RoomMemberEvent(const QJsonObject& obj) : RoomEvent(Type::RoomMember, obj), _userId(obj["state_key"].toString()) { @@ -29,11 +32,10 @@ RoomMemberEvent::RoomMemberEvent(const QJsonObject& obj) _displayName = contentObj["displayname"].toString(); _avatarUrl = contentObj["avatar_url"].toString(); QString membershipString = contentObj["membership"].toString(); - const auto supportedStrings = { "invite", "join", "knock", "leave", "ban" }; - for (auto it = supportedStrings.begin(); it != supportedStrings.end(); ++it) + for (auto it = membershipStrings.begin(); it != membershipStrings.end(); ++it) if (membershipString == *it) { - _membership = MembershipType(it - supportedStrings.begin()); + _membership = MembershipType(it - membershipStrings.begin()); return; } qCWarning(EVENTS) << "Unknown MembershipType: " << membershipString; diff --git a/jobs/sendeventjob.cpp b/jobs/sendeventjob.cpp index 7e33e089..f5190d4b 100644 --- a/jobs/sendeventjob.cpp +++ b/jobs/sendeventjob.cpp @@ -24,7 +24,7 @@ using namespace QMatrixClient; SendEventJob::SendEventJob(const QString& roomId, const QString& type, const QString& plainText) - : SendEventJob(roomId, new RoomMessageEvent(plainText, type)) + : SendEventJob(roomId, RoomMessageEvent(plainText, type)) { } void SendEventJob::beforeStart(const ConnectionData* connData) diff --git a/jobs/sendeventjob.h b/jobs/sendeventjob.h index 7b10b3d4..3a11eb6a 100644 --- a/jobs/sendeventjob.h +++ b/jobs/sendeventjob.h @@ -29,12 +29,12 @@ namespace QMatrixClient public: /** Constructs a job that sends an arbitrary room event */ template - SendEventJob(const QString& roomId, const EvT* event) + SendEventJob(const QString& roomId, const EvT& event) : BaseJob(HttpVerb::Put, QStringLiteral("SendEventJob"), QStringLiteral("_matrix/client/r0/rooms/%1/send/%2/") .arg(roomId, EvT::TypeId), // See also beforeStart() Query(), - Data(event->toJson())) + Data(event.toJson())) { } /** diff --git a/jobs/setroomstatejob.h b/jobs/setroomstatejob.h index ddc271b9..b7e6d4a1 100644 --- a/jobs/setroomstatejob.h +++ b/jobs/setroomstatejob.h @@ -33,24 +33,24 @@ namespace QMatrixClient */ template SetRoomStateJob(const QString& roomId, const QString& stateKey, - const EvT* event) + const EvT& event) : BaseJob(HttpVerb::Put, "SetRoomStateJob", QStringLiteral("_matrix/client/r0/rooms/%1/state/%2/%3") .arg(roomId, EvT::TypeId, stateKey), Query(), - Data(event->toJson())) + Data(event.toJson())) { } /** * Constructs a job that sets a state using an arbitrary room event * without a state key. */ template - SetRoomStateJob(const QString& roomId, const EvT* event) + SetRoomStateJob(const QString& roomId, const EvT& event) : BaseJob(HttpVerb::Put, "SetRoomStateJob", QStringLiteral("_matrix/client/r0/rooms/%1/state/%2") .arg(roomId, EvT::TypeId), Query(), - Data(event->toJson())) + Data(event.toJson())) { } QString eventId() const { return _eventId; } diff --git a/room.cpp b/room.cpp index 79168d85..53d8fef1 100644 --- a/room.cpp +++ b/room.cpp @@ -445,7 +445,8 @@ void Room::Private::addMember(User *u) if (!hasMember(u)) { insertMemberIntoMap(u); - connect(u, &User::nameChanged, q, &Room::userRenamed); + connect(u, &User::nameChanged, q, + [=] (User* u, const QString& newName) { renameMember(u, newName); }); emit q->userAdded(u); } } @@ -490,11 +491,6 @@ void Room::Private::removeMember(User* u) } } -void Room::userRenamed(User* user, QString oldName) -{ - d->renameMember(user, std::move(oldName)); -} - QString Room::roomMembername(User *u) const { // See the CS spec, section 11.2.2.3 @@ -581,16 +577,15 @@ void Room::updateData(SyncRoomData&& data) void Room::postMessage(const QString& type, const QString& plainText) { - connection()->callApi(id(), type, plainText); + postMessage(RoomMessageEvent { plainText, type }); } void Room::postMessage(const QString& plainText, MessageEventType type) { - RoomMessageEvent rme(plainText, type); - postMessage(&rme); + postMessage(RoomMessageEvent { plainText, type }); } -void Room::postMessage(RoomMessageEvent* event) +void Room::postMessage(const RoomMessageEvent& event) { connection()->callApi(id(), event); } @@ -598,7 +593,7 @@ void Room::postMessage(RoomMessageEvent* event) void Room::setTopic(const QString& newTopic) { RoomTopicEvent evt(newTopic); - connection()->callApi(id(), &evt); + connection()->callApi(id(), evt); } void Room::getPreviousContent(int limit) @@ -623,27 +618,27 @@ void Room::Private::getPreviousContent(int limit) } } -void Room::inviteToRoom(const QString& memberId) const +void Room::inviteToRoom(const QString& memberId) { connection()->callApi(id(), memberId); } -void Room::leaveRoom() const +void Room::leaveRoom() { connection()->callApi(id()); } -void Room::kickMember(const QString& memberId, const QString& reason) const +void Room::kickMember(const QString& memberId, const QString& reason) { connection()->callApi(id(), memberId, reason); } -void Room::ban(const QString& userId, const QString& reason) const +void Room::ban(const QString& userId, const QString& reason) { connection()->callApi(id(), userId, reason); } -void Room::unban(const QString& userId) const +void Room::unban(const QString& userId) { connection()->callApi(id(), userId); } diff --git a/room.h b/room.h index d62d160f..00d4c333 100644 --- a/room.h +++ b/room.h @@ -150,21 +150,18 @@ namespace QMatrixClient public slots: void postMessage(const QString& plainText, MessageEventType type = MessageEventType::Text); - void postMessage(RoomMessageEvent* event); + void postMessage(const RoomMessageEvent& event); /** @deprecated */ void postMessage(const QString& type, const QString& plainText); void setTopic(const QString& newTopic); void getPreviousContent(int limit = 10); - void inviteToRoom(const QString& memberId) const; - void leaveRoom() const; - void kickMember(const QString& memberId, - const QString& reason = {}) const; - void ban(const QString& userId, const QString& reason = {}) const; - void unban(const QString& userId) const; - - void userRenamed(User* user, QString oldName); + void inviteToRoom(const QString& memberId); + void leaveRoom(); + void kickMember(const QString& memberId, const QString& reason = {}); + void ban(const QString& userId, const QString& reason = {}); + void unban(const QString& userId); /** Mark all messages in the room as read */ void markAllMessagesAsRead(); -- cgit v1.2.3 From ee214de7b829b08155bc223ea64c61c9ce2bcdf3 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Fri, 13 Oct 2017 23:55:35 +0200 Subject: Make JoinState (de)serializable library-wide --- jobs/syncjob.cpp | 12 +++--------- joinstate.h | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/jobs/syncjob.cpp b/jobs/syncjob.cpp index 6d37db5c..ce5dd894 100644 --- a/jobs/syncjob.cpp +++ b/jobs/syncjob.cpp @@ -69,19 +69,13 @@ BaseJob::Status SyncData::parseJson(const QJsonDocument &data) // TODO: account_data QJsonObject rooms = json.value("rooms").toObject(); - static const struct { QString jsonKey; JoinState enumVal; } roomStates[] + for (size_t i = 0; i < JoinStateStrings.size(); ++i) { - { "join", JoinState::Join }, - { "invite", JoinState::Invite }, - { "leave", JoinState::Leave } - }; - for (const auto& roomState: roomStates) - { - const QJsonObject rs = rooms.value(roomState.jsonKey).toObject(); + const auto rs = rooms.value(JoinStateStrings[i]).toObject(); // We have a Qt container on the right and an STL one on the left roomData.reserve(static_cast(rs.size())); for(auto roomIt = rs.begin(); roomIt != rs.end(); ++roomIt) - roomData.emplace_back(roomIt.key(), roomState.enumVal, + roomData.emplace_back(roomIt.key(), JoinState(i), roomIt.value().toObject()); } qCDebug(PROFILER) << "*** SyncData::parseJson():" << et.elapsed() << "ms"; diff --git a/joinstate.h b/joinstate.h index 348ca8a6..cfdb90f2 100644 --- a/joinstate.h +++ b/joinstate.h @@ -18,12 +18,24 @@ #pragma once +#include + namespace QMatrixClient { enum class JoinState { - Join, + Join = 0, Invite, Leave }; -} + + // We cannot use REGISTER_ENUM outside of a Q_OBJECT and besides, we want + // to use strings that match respective JSON keys. + static constexpr std::array JoinStateStrings + { { "join", "invite", "leave" } }; + + inline constexpr const char* toCString(JoinState js) + { + return JoinStateStrings[size_t(js)]; + } +} // namespace QMatrixClient -- cgit v1.2.3 From 8058139171897eea4a35325b98ba2f72a8c7303f Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 14 Oct 2017 05:22:37 +0200 Subject: Leaving a room now uses a generated Job file --- CMakeLists.txt | 1 - jobs/generated/leaving.cpp | 30 ++++++++++++++++++++++++++++++ jobs/generated/leaving.h | 31 +++++++++++++++++++++++++++++++ jobs/leaveroomjob.cpp | 26 -------------------------- jobs/leaveroomjob.h | 30 ------------------------------ room.cpp | 6 +++--- room.h | 3 ++- 7 files changed, 66 insertions(+), 61 deletions(-) create mode 100644 jobs/generated/leaving.cpp create mode 100644 jobs/generated/leaving.h delete mode 100644 jobs/leaveroomjob.cpp delete mode 100644 jobs/leaveroomjob.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 35eec50e..ca00ce4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,6 @@ set(libqmatrixclient_SRCS jobs/setroomstatejob.cpp jobs/postreceiptjob.cpp jobs/joinroomjob.cpp - jobs/leaveroomjob.cpp jobs/roommessagesjob.cpp jobs/syncjob.cpp jobs/mediathumbnailjob.cpp diff --git a/jobs/generated/leaving.cpp b/jobs/generated/leaving.cpp new file mode 100644 index 00000000..7fed347b --- /dev/null +++ b/jobs/generated/leaving.cpp @@ -0,0 +1,30 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + + +#include "leaving.h" + +#include "jobs/converters.h" +#include + +using namespace QMatrixClient; + +static const auto basePath = QStringLiteral("/_matrix/client/r0"); + +LeaveRoomJob::LeaveRoomJob(QString roomId) + : BaseJob(HttpVerb::Post, "LeaveRoomJob", + basePath % "/rooms/" % roomId % "/leave", + Query { }, + Data { } + ) +{ } + +ForgetRoomJob::ForgetRoomJob(QString roomId) + : BaseJob(HttpVerb::Post, "ForgetRoomJob", + basePath % "/rooms/" % roomId % "/forget", + Query { }, + Data { } + ) +{ } + diff --git a/jobs/generated/leaving.h b/jobs/generated/leaving.h new file mode 100644 index 00000000..96304084 --- /dev/null +++ b/jobs/generated/leaving.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + + +#pragma once + +#include "../basejob.h" + +#include + + +namespace QMatrixClient +{ + + // Operations + + class LeaveRoomJob : public BaseJob + { + public: + explicit LeaveRoomJob(QString roomId); + + }; + class ForgetRoomJob : public BaseJob + { + public: + explicit ForgetRoomJob(QString roomId); + + }; + +} // namespace QMatrixClient diff --git a/jobs/leaveroomjob.cpp b/jobs/leaveroomjob.cpp deleted file mode 100644 index 54e7f307..00000000 --- a/jobs/leaveroomjob.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2015 Felix Rohrbach - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "leaveroomjob.h" - -using namespace QMatrixClient; - -LeaveRoomJob::LeaveRoomJob(const QString& roomId) - : BaseJob(HttpVerb::Post, "LeaveRoomJob", - QStringLiteral("_matrix/client/r0/rooms/%1/leave").arg(roomId)) -{ } diff --git a/jobs/leaveroomjob.h b/jobs/leaveroomjob.h deleted file mode 100644 index 9224c1c8..00000000 --- a/jobs/leaveroomjob.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2015 Felix Rohrbach - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include "basejob.h" - -namespace QMatrixClient -{ - class LeaveRoomJob: public BaseJob - { - public: - explicit LeaveRoomJob(const QString& roomId); - }; -} // namespace QMatrixClient diff --git a/room.cpp b/room.cpp index 53d8fef1..50faae3e 100644 --- a/room.cpp +++ b/room.cpp @@ -21,6 +21,7 @@ #include "jobs/generated/kicking.h" #include "jobs/generated/inviting.h" #include "jobs/generated/banning.h" +#include "jobs/generated/leaving.h" #include "jobs/setroomstatejob.h" #include "events/roomnameevent.h" #include "events/roomaliasesevent.h" @@ -32,7 +33,6 @@ #include "jobs/sendeventjob.h" #include "jobs/roommessagesjob.h" #include "jobs/postreceiptjob.h" -#include "jobs/leaveroomjob.h" #include "connection.h" #include "user.h" @@ -623,9 +623,9 @@ void Room::inviteToRoom(const QString& memberId) connection()->callApi(id(), memberId); } -void Room::leaveRoom() +LeaveRoomJob* Room::leaveRoom() { - connection()->callApi(id()); + return connection()->callApi(id()); } void Room::kickMember(const QString& memberId, const QString& reason) diff --git a/room.h b/room.h index 00d4c333..2d0453bc 100644 --- a/room.h +++ b/room.h @@ -36,6 +36,7 @@ namespace QMatrixClient class Connection; class User; class MemberSorter; + class LeaveRoomJob; class TimelineItem { @@ -158,7 +159,7 @@ namespace QMatrixClient void getPreviousContent(int limit = 10); void inviteToRoom(const QString& memberId); - void leaveRoom(); + LeaveRoomJob* leaveRoom(); void kickMember(const QString& memberId, const QString& reason = {}); void ban(const QString& userId, const QString& reason = {}); void unban(const QString& userId); -- cgit v1.2.3 From 608e7a7163583e2e30cd6c3e9de7449c41651ca4 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 14 Oct 2017 05:23:22 +0200 Subject: Connection::forgetRoom() --- connection.cpp | 37 +++++++++++++++++++++++++++++++++++++ connection.h | 14 ++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/connection.cpp b/connection.cpp index c7492868..7f1bbec4 100644 --- a/connection.cpp +++ b/connection.cpp @@ -237,6 +237,43 @@ MediaThumbnailJob* Connection::getThumbnail(const QUrl& url, int requestedWidth, return getThumbnail(url, QSize(requestedWidth, requestedHeight)); } +ForgetRoomJob* Connection::forgetRoom(const QString& id) const +{ + // To forget is hard :) First we should ensure the local user is not + // in the room (by leaving it, if necessary); once it's done, the /forget + // endpoint can be called; and once this is through, the local Room object + // (if any existed) is deleted. At the same time, we still have to + // (basically immediately) return a pointer to ForgetRoomJob. Therefore + // a ForgetRoomJob is created in advance and can be returned in a probably + // not-yet-started state (it will start once /leave completes). + auto forgetJob = new ForgetRoomJob(id); + auto joinedRoom = d->roomMap.value({id, false}); + if (joinedRoom && joinedRoom->joinState() == JoinState::Join) + { + auto leaveJob = joinedRoom->leaveRoom(); + connect(leaveJob, &BaseJob::success, + this, [=] { forgetJob->start(connectionData()); }); + connect(leaveJob, &BaseJob::failure, + this, [=] { forgetJob->abandon(); }); + } + else + forgetJob->start(connectionData()); + connect(forgetJob, &BaseJob::success, this, [=] + { + // If the room happens to be in the map (possible in both forms), + // delete the found object(s). + for (auto f: {false, true}) + if (auto r = d->roomMap.take({ id, f })) + { + qCDebug(MAIN) << "Room" << id + << "in join state" << toCString(r->joinState()) + << "will be deleted"; + r->deleteLater(); + } + }); + return forgetJob; +} + QUrl Connection::homeserver() const { return d->data->baseUrl(); diff --git a/connection.h b/connection.h index dbb50b9a..4afae08f 100644 --- a/connection.h +++ b/connection.h @@ -18,6 +18,7 @@ #pragma once +#include "jobs/generated/leaving.h" #include "joinstate.h" #include @@ -94,6 +95,19 @@ namespace QMatrixClient /** @deprecated Use callApi() instead */ MediaThumbnailJob* getThumbnail(const QUrl& url, int requestedWidth, int requestedHeight) const; + /** Sends /forget to the server and also deletes room locally. + * This method is in Connection, not in Room, since it's a + * room lifecycle operation, and Connection is an acting room manager. + * It ensures that the local user is not a member of a room (running /leave, + * if necessary) then issues a /forget request and if that one doesn't fail + * deletion of the local Room object is ensured. + * \param id - the room id to forget + * \return - the ongoing /forget request to the server; note that the + * success() signal of this request is connected to deleteLater() + * of a respective room so by the moment this finishes, there might be no + * Room object anymore. + */ + ForgetRoomJob* forgetRoom(const QString& id) const; Q_INVOKABLE QUrl homeserver() const; Q_INVOKABLE User* user(const QString& userId); -- cgit v1.2.3 From 2bf912d6e6ddd9ff81a92ff28ac8c4c1d8f2d7e1 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 14 Oct 2017 01:13:13 +0200 Subject: Support of changing the display name Note that although the mechanism is generic enough to change any user's display name, The Spec states that power rules are very strict about it. --- user.cpp | 36 +++++++++++++++++++++++++----------- user.h | 4 ++++ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/user.cpp b/user.cpp index 12eb2e0b..7caf54e2 100644 --- a/user.cpp +++ b/user.cpp @@ -22,7 +22,7 @@ #include "events/event.h" #include "events/roommemberevent.h" #include "jobs/mediathumbnailjob.h" -#include "util.h" +#include "jobs/generated/profile.h" #include #include @@ -80,6 +80,22 @@ QString User::name() const return d->name; } +void User::setName(const QString& newName) +{ + const auto oldName = name(); + if (d->name != oldName) + { + d->name = newName; + emit nameChanged(this, oldName); + } +} + +void User::rename(const QString& newName) +{ + auto job = d->connection->callApi(id(), newName); + connect(job, &BaseJob::success, this, [=] { setName(newName); }); +} + QString User::displayname() const { if( !d->name.isEmpty() ) @@ -140,18 +156,15 @@ void User::processEvent(Event* event) if (e->membership() == MembershipType::Leave) return; - if( d->name != e->displayName() ) + auto newName = e->displayName(); + QRegularExpression reSuffix(" \\((IRC|Gitter)\\)$"); + auto match = reSuffix.match(d->name); + if (match.hasMatch()) { - const auto oldName = d->name; - d->name = e->displayName(); - QRegularExpression reSuffix(" \\((IRC|Gitter)\\)$"); - auto match = reSuffix.match(d->name); - if (match.hasMatch()) { - d->bridged = match.captured(1); - d->name = d->name.left(match.capturedStart(0)); - } - emit nameChanged(this, oldName); + d->bridged = match.captured(1); + newName.truncate(match.capturedStart(0)); } + setName(newName); if( d->avatarUrl != e->avatarUrl() ) { d->avatarUrl = e->avatarUrl(); @@ -176,3 +189,4 @@ void User::Private::requestAvatar() emit q->avatarChanged(q); }); } + diff --git a/user.h b/user.h index a2d58908..cf7d4e0a 100644 --- a/user.h +++ b/user.h @@ -60,11 +60,15 @@ namespace QMatrixClient public slots: void requestAvatar(); + void rename(const QString& newName); signals: void nameChanged(User*, QString); void avatarChanged(User* user); + private slots: + void setName(const QString& newName); + private: class Private; Private* d; -- cgit v1.2.3 From b231ed76210405e670d6aad53350faab1ae18d3b Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 14 Oct 2017 02:01:01 +0200 Subject: LogoutJob is supplied by generated code --- CMakeLists.txt | 1 - connection.cpp | 2 +- jobs/generated/logout.cpp | 22 ++++++++++++++++++++++ jobs/generated/logout.h | 24 ++++++++++++++++++++++++ jobs/logoutjob.cpp | 26 -------------------------- jobs/logoutjob.h | 30 ------------------------------ 6 files changed, 47 insertions(+), 58 deletions(-) create mode 100644 jobs/generated/logout.cpp create mode 100644 jobs/generated/logout.h delete mode 100644 jobs/logoutjob.cpp delete mode 100644 jobs/logoutjob.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ca00ce4f..2abf7e69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,7 +81,6 @@ set(libqmatrixclient_SRCS jobs/roommessagesjob.cpp jobs/syncjob.cpp jobs/mediathumbnailjob.cpp - jobs/logoutjob.cpp ) aux_source_directory(jobs/generated libqmatrixclient_job_SRCS) diff --git a/connection.cpp b/connection.cpp index 7f1bbec4..749d2062 100644 --- a/connection.cpp +++ b/connection.cpp @@ -21,8 +21,8 @@ #include "user.h" #include "events/event.h" #include "room.h" +#include "jobs/generated/logout.h" #include "jobs/passwordlogin.h" -#include "jobs/logoutjob.h" #include "jobs/sendeventjob.h" #include "jobs/postreceiptjob.h" #include "jobs/joinroomjob.h" diff --git a/jobs/generated/logout.cpp b/jobs/generated/logout.cpp new file mode 100644 index 00000000..b750efe2 --- /dev/null +++ b/jobs/generated/logout.cpp @@ -0,0 +1,22 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + + +#include "logout.h" + +#include "jobs/converters.h" +#include + +using namespace QMatrixClient; + +static const auto basePath = QStringLiteral("/_matrix/client/r0"); + +LogoutJob::LogoutJob() + : BaseJob(HttpVerb::Post, "LogoutJob", + basePath % "/logout", + Query { }, + Data { } + ) +{ } + diff --git a/jobs/generated/logout.h b/jobs/generated/logout.h new file mode 100644 index 00000000..28e85d8f --- /dev/null +++ b/jobs/generated/logout.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + + +#pragma once + +#include "../basejob.h" + + + +namespace QMatrixClient +{ + + // Operations + + class LogoutJob : public BaseJob + { + public: + explicit LogoutJob(); + + }; + +} // namespace QMatrixClient diff --git a/jobs/logoutjob.cpp b/jobs/logoutjob.cpp deleted file mode 100644 index 5ea5cf4d..00000000 --- a/jobs/logoutjob.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2016 Kitsune Ral - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "logoutjob.h" - -using namespace QMatrixClient; - -LogoutJob::LogoutJob() - : BaseJob(HttpVerb::Post, "LogoutJob", "/_matrix/client/r0/logout") -{ -} diff --git a/jobs/logoutjob.h b/jobs/logoutjob.h deleted file mode 100644 index e1b988dc..00000000 --- a/jobs/logoutjob.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2016 Kitsune Ral - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#pragma once - -#include "basejob.h" - -namespace QMatrixClient -{ - class LogoutJob: public BaseJob - { - public: - LogoutJob(); - }; -} -- cgit v1.2.3 From c2b84e41fba24f32270c24c0a6f679a1c4de0eea Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 14 Oct 2017 09:41:41 +0200 Subject: Actually added generated/profile.* files, needed to change display name --- jobs/generated/profile.cpp | 144 +++++++++++++++++++++++++++++++++++++++++++++ jobs/generated/profile.h | 80 +++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 jobs/generated/profile.cpp create mode 100644 jobs/generated/profile.h diff --git a/jobs/generated/profile.cpp b/jobs/generated/profile.cpp new file mode 100644 index 00000000..9d20a480 --- /dev/null +++ b/jobs/generated/profile.cpp @@ -0,0 +1,144 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + + +#include "profile.h" + +#include "jobs/converters.h" +#include + +using namespace QMatrixClient; + +static const auto basePath = QStringLiteral("/_matrix/client/r0"); + +SetDisplayNameJob::SetDisplayNameJob(QString userId, QString displayname) + : BaseJob(HttpVerb::Put, "SetDisplayNameJob", + basePath % "/profile/" % userId % "/displayname", + Query { }, + Data { + { "displayname", toJson(displayname) } + } + ) +{ } + +class GetDisplayNameJob::Private +{ + public: + QString displayname; + +}; + +GetDisplayNameJob::GetDisplayNameJob(QString userId) + : BaseJob(HttpVerb::Get, "GetDisplayNameJob", + basePath % "/profile/" % userId % "/displayname", + Query { }, + Data { } + ), d(new Private) +{ } + +GetDisplayNameJob::~GetDisplayNameJob() +{ + delete d; +} + +const QString& GetDisplayNameJob::displayname() const +{ + return d->displayname; +} + +BaseJob::Status GetDisplayNameJob::parseJson(const QJsonDocument& data) +{ + auto json = data.object(); + + d->displayname = fromJson(json.value("displayname")); + + return Success; +} + +SetAvatarUrlJob::SetAvatarUrlJob(QString userId, QString avatar_url) + : BaseJob(HttpVerb::Put, "SetAvatarUrlJob", + basePath % "/profile/" % userId % "/avatar_url", + Query { }, + Data { + { "avatar_url", toJson(avatar_url) } + } + ) +{ } + +class GetAvatarUrlJob::Private +{ + public: + QString avatar_url; + +}; + +GetAvatarUrlJob::GetAvatarUrlJob(QString userId) + : BaseJob(HttpVerb::Get, "GetAvatarUrlJob", + basePath % "/profile/" % userId % "/avatar_url", + Query { }, + Data { } + ), d(new Private) +{ } + +GetAvatarUrlJob::~GetAvatarUrlJob() +{ + delete d; +} + +const QString& GetAvatarUrlJob::avatar_url() const +{ + return d->avatar_url; +} + +BaseJob::Status GetAvatarUrlJob::parseJson(const QJsonDocument& data) +{ + auto json = data.object(); + + d->avatar_url = fromJson(json.value("avatar_url")); + + return Success; +} + +class GetUserProfileJob::Private +{ + public: + QString avatar_url; + QString displayname; + +}; + +GetUserProfileJob::GetUserProfileJob(QString userId) + : BaseJob(HttpVerb::Get, "GetUserProfileJob", + basePath % "/profile/" % userId, + Query { }, + Data { } + ), d(new Private) +{ } + +GetUserProfileJob::~GetUserProfileJob() +{ + delete d; +} + +const QString& GetUserProfileJob::avatar_url() const +{ + return d->avatar_url; +} + +const QString& GetUserProfileJob::displayname() const +{ + return d->displayname; +} + +BaseJob::Status GetUserProfileJob::parseJson(const QJsonDocument& data) +{ + auto json = data.object(); + + d->avatar_url = fromJson(json.value("avatar_url")); + + d->displayname = fromJson(json.value("displayname")); + + return Success; +} + diff --git a/jobs/generated/profile.h b/jobs/generated/profile.h new file mode 100644 index 00000000..8e2b195b --- /dev/null +++ b/jobs/generated/profile.h @@ -0,0 +1,80 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + + +#pragma once + +#include "../basejob.h" + +#include + + +namespace QMatrixClient +{ + + // Operations + + class SetDisplayNameJob : public BaseJob + { + public: + explicit SetDisplayNameJob(QString userId, QString displayname = {}); + + }; + class GetDisplayNameJob : public BaseJob + { + public: + explicit GetDisplayNameJob(QString userId); + + ~GetDisplayNameJob() override; + + const QString& displayname() const; + + protected: + Status parseJson(const QJsonDocument& data) override; + + private: + class Private; + Private* d; + }; + class SetAvatarUrlJob : public BaseJob + { + public: + explicit SetAvatarUrlJob(QString userId, QString avatar_url = {}); + + }; + class GetAvatarUrlJob : public BaseJob + { + public: + explicit GetAvatarUrlJob(QString userId); + + ~GetAvatarUrlJob() override; + + const QString& avatar_url() const; + + protected: + Status parseJson(const QJsonDocument& data) override; + + private: + class Private; + Private* d; + }; + class GetUserProfileJob : public BaseJob + { + public: + explicit GetUserProfileJob(QString userId); + + ~GetUserProfileJob() override; + + const QString& avatar_url() const; + const QString& displayname() const; + + protected: + Status parseJson(const QJsonDocument& data) override; + + private: + class Private; + Private* d; + }; + +} // namespace QMatrixClient -- cgit v1.2.3 From 4aa8eb029737f536a6ad3b1e3eaf296a68a3b926 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 15 Oct 2017 15:36:14 +0200 Subject: Fixed building with clang+libcpp (used on OS X) libcpp has pessimistic definition of array that only engages constexpr in C++14 mode and newer; so one cannot use std::array<> in constexpr code. --- joinstate.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/joinstate.h b/joinstate.h index cfdb90f2..d6c374d2 100644 --- a/joinstate.h +++ b/joinstate.h @@ -31,10 +31,10 @@ namespace QMatrixClient // We cannot use REGISTER_ENUM outside of a Q_OBJECT and besides, we want // to use strings that match respective JSON keys. - static constexpr std::array JoinStateStrings + static const std::array JoinStateStrings { { "join", "invite", "leave" } }; - inline constexpr const char* toCString(JoinState js) + inline const char* toCString(JoinState js) { return JoinStateStrings[size_t(js)]; } -- cgit v1.2.3 From 1ae42237adcc5486e526ff3a9e93d0901940a74b Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 15 Oct 2017 23:03:03 +0900 Subject: Connection::forgetRoom(): Minor fixes --- connection.cpp | 3 ++- connection.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/connection.cpp b/connection.cpp index 749d2062..84a52149 100644 --- a/connection.cpp +++ b/connection.cpp @@ -237,7 +237,7 @@ MediaThumbnailJob* Connection::getThumbnail(const QUrl& url, int requestedWidth, return getThumbnail(url, QSize(requestedWidth, requestedHeight)); } -ForgetRoomJob* Connection::forgetRoom(const QString& id) const +ForgetRoomJob* Connection::forgetRoom(const QString& id) { // To forget is hard :) First we should ensure the local user is not // in the room (by leaving it, if necessary); once it's done, the /forget @@ -265,6 +265,7 @@ ForgetRoomJob* Connection::forgetRoom(const QString& id) const for (auto f: {false, true}) if (auto r = d->roomMap.take({ id, f })) { + emit aboutToDeleteRoom(r); qCDebug(MAIN) << "Room" << id << "in join state" << toCString(r->joinState()) << "will be deleted"; diff --git a/connection.h b/connection.h index 4afae08f..b7d049f1 100644 --- a/connection.h +++ b/connection.h @@ -107,7 +107,7 @@ namespace QMatrixClient * of a respective room so by the moment this finishes, there might be no * Room object anymore. */ - ForgetRoomJob* forgetRoom(const QString& id) const; + ForgetRoomJob* forgetRoom(const QString& id); Q_INVOKABLE QUrl homeserver() const; Q_INVOKABLE User* user(const QString& userId); -- cgit v1.2.3 From c1049d374a3c6d79750c57d2e1751d440df3d8cc Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 17 Oct 2017 17:11:25 +0900 Subject: Fixed a blunder leading to users not having names If all users suddenly don't have names, update to this commit, delete your cache and run again. Issue since 2bf912d6e6ddd9ff81a92ff28ac8c4c1d8f2d7e1. --- user.cpp | 10 ++++++---- user.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/user.cpp b/user.cpp index 7caf54e2..171d6d6c 100644 --- a/user.cpp +++ b/user.cpp @@ -80,11 +80,13 @@ QString User::name() const return d->name; } -void User::setName(const QString& newName) +void User::updateName(const QString& newName) { const auto oldName = name(); - if (d->name != oldName) + if (d->name != newName) { + qCDebug(MAIN) << "Renaming" << id() + << "from" << oldName << "to" << newName; d->name = newName; emit nameChanged(this, oldName); } @@ -93,7 +95,7 @@ void User::setName(const QString& newName) void User::rename(const QString& newName) { auto job = d->connection->callApi(id(), newName); - connect(job, &BaseJob::success, this, [=] { setName(newName); }); + connect(job, &BaseJob::success, this, [=] { updateName(newName); }); } QString User::displayname() const @@ -164,7 +166,7 @@ void User::processEvent(Event* event) d->bridged = match.captured(1); newName.truncate(match.capturedStart(0)); } - setName(newName); + updateName(newName); if( d->avatarUrl != e->avatarUrl() ) { d->avatarUrl = e->avatarUrl(); diff --git a/user.h b/user.h index cf7d4e0a..79a6f5db 100644 --- a/user.h +++ b/user.h @@ -67,7 +67,7 @@ namespace QMatrixClient void avatarChanged(User* user); private slots: - void setName(const QString& newName); + void updateName(const QString& newName); private: class Private; -- cgit v1.2.3 From 614917ad7c1c0beec847094369a2b3bd383562ca Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 17 Oct 2017 17:12:55 +0900 Subject: Cache the actual user name, not the display name Display name is a calculated thing, name is received from the server. --- room.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/room.cpp b/room.cpp index 50faae3e..65cf2d2a 100644 --- a/room.cpp +++ b/room.cpp @@ -969,7 +969,7 @@ QJsonObject Room::Private::toJson() const { QJsonObject content; content.insert("membership", QStringLiteral("join")); - content.insert("displayname", i->displayname()); + content.insert("displayname", i->name()); content.insert("avatar_url", i->avatarUrl().toString()); QJsonObject memberEvent; -- cgit v1.2.3 From f2f85ba093df5dcd991fd206af4d79d57f4c7fc8 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 17 Oct 2017 17:13:31 +0900 Subject: Avoid leaking access_token in the logs Closes #102. --- jobs/basejob.cpp | 13 +++++++++---- jobs/basejob.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/jobs/basejob.cpp b/jobs/basejob.cpp index 240192d9..eb78dec8 100644 --- a/jobs/basejob.cpp +++ b/jobs/basejob.cpp @@ -24,6 +24,7 @@ #include #include #include +#include //#include #include @@ -79,6 +80,13 @@ inline QDebug operator<<(QDebug dbg, const BaseJob* j) return dbg << j->objectName(); } +QDebug QMatrixClient::operator<<(QDebug dbg, const BaseJob::Status& s) +{ + QRegularExpression filter { "(access_token)=[-_A-Za-z0-9]+" }; + return dbg << s.code << ':' + << QString(s.message).replace(filter, "\1=HIDDEN"); +} + BaseJob::BaseJob(HttpVerb verb, const QString& name, const QString& endpoint, const Query& query, const Data& data, bool needsToken) : d(new Private(verb, endpoint, query, data, needsToken)) @@ -331,10 +339,7 @@ void BaseJob::setStatus(Status s) { d->status = s; if (!s.good()) - { - qCWarning(d->logCat) << this << "status" << s.code - << ":" << s.message; - } + qCWarning(d->logCat) << this << "status" << s; } void BaseJob::setStatus(int code, QString message) diff --git a/jobs/basejob.h b/jobs/basejob.h index 2f7bd9cd..f8b367c6 100644 --- a/jobs/basejob.h +++ b/jobs/basejob.h @@ -110,6 +110,7 @@ namespace QMatrixClient Status(int c, QString m) : code(c), message(std::move(m)) { } bool good() const { return code < ErrorLevel; } + friend QDebug operator<<(QDebug dbg, const Status& s); int code; QString message; -- cgit v1.2.3