From 76241cb772bb53901cdd3308262f76ba718d9a47 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 31 Aug 2016 17:49:43 +0900 Subject: Dismiss ConnectionPrivate, long live Connection::Private Closer investigation found out that there are only two actually used member functions in ConnectionPrivate - provideRoom() and resolveServer(). These two have been transferred to Connection; and data members from ConnectionPrivate found new home in Connection::Private. Factoring out room management and user management from Connection is still a pending task. --- connection.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 13 deletions(-) (limited to 'connection.cpp') diff --git a/connection.cpp b/connection.cpp index 904649bc..d357599b 100644 --- a/connection.cpp +++ b/connection.cpp @@ -18,7 +18,7 @@ #include "connection.h" #include "connectiondata.h" -#include "connectionprivate.h" +//#include "connectionprivate.h" #include "user.h" #include "events/event.h" #include "room.h" @@ -33,15 +33,39 @@ #include "jobs/syncjob.h" #include "jobs/mediathumbnailjob.h" +#include #include using namespace QMatrixClient; +class Connection::Private +{ + public: + explicit Private(QUrl serverUrl) + : q(nullptr) + , data(new ConnectionData(serverUrl)) + , isConnected(false) + { } + Private(Private&) = delete; + ~Private() { delete data; } + + Room* provideRoom( QString id ); + + Connection* q; + ConnectionData* data; + QHash roomMap; + QHash userMap; + bool isConnected; + QString username; + QString password; + QString userId; +}; + Connection::Connection(QUrl server, QObject* parent) : QObject(parent) + , d(new Private(server)) { - d = new ConnectionPrivate(this); - d->data = new ConnectionData(server); + d->q = this; // All d initialization should occur before this line } Connection::Connection() @@ -56,7 +80,26 @@ Connection::~Connection() void Connection::resolveServer(QString domain) { - d->resolveServer( domain ); + // Find the Matrix server for the given domain. + QScopedPointer dns { new QDnsLookup() }; + dns->setType(QDnsLookup::SRV); + dns->setName("_matrix._tcp." + domain); + + dns->lookup(); + connect(dns.data(), &QDnsLookup::finished, [&]() { + // Check the lookup succeeded. + if (dns->error() != QDnsLookup::NoError || + dns->serviceRecords().isEmpty()) { + emit resolveError("DNS lookup failed"); + return; + } + + // Handle the results. + auto record = dns->serviceRecords().front(); + d->data->setHost(record.target()); + d->data->setPort(record.port()); + emit resolved(); + }); } void Connection::connectToServer(QString user, QString password) @@ -113,9 +156,9 @@ SyncJob* Connection::sync(int timeout) syncJob->setTimeout(timeout); connect( syncJob, &SyncJob::success, [=] () { d->data->setLastEvent(syncJob->nextBatch()); - for( const auto roomData: syncJob->roomData() ) + for( const auto& roomData: syncJob->roomData() ) { - if ( Room* r = d->provideRoom(roomData.roomId) ) + if ( Room* r = provideRoom(roomData.roomId) ) r->updateData(roomData); } emit syncDone(); @@ -147,7 +190,7 @@ void Connection::joinRoom(QString roomAlias) { JoinRoomJob* job = new JoinRoomJob(d->data, roomAlias); connect( job, &SyncJob::success, [=] () { - if ( Room* r = d->provideRoom(job->roomId()) ) + if ( Room* r = provideRoom(job->roomId()) ) emit joinedRoom(r); }); job->start(); @@ -159,12 +202,12 @@ void Connection::leaveRoom(Room* room) job->start(); } -void Connection::getMembers(Room* room) -{ - RoomMembersJob* job = new RoomMembersJob(d->data, room); - connect( job, &RoomMembersJob::result, d, &ConnectionPrivate::gotRoomMembers ); - job->start(); -} +//void Connection::getMembers(Room* room) +//{ +// RoomMembersJob* job = new RoomMembersJob(d->data, room); +// connect( job, &RoomMembersJob::result, d, &ConnectionPrivate::gotRoomMembers ); +// job->start(); +//} RoomMessagesJob* Connection::getMessages(Room* room, QString from) { @@ -221,6 +264,30 @@ ConnectionData* Connection::connectionData() return d->data; } +Room* Connection::provideRoom(QString id) +{ + if (id.isEmpty()) + { + qDebug() << "ConnectionPrivate::provideRoom() with empty id, doing nothing"; + return nullptr; + } + + if (d->roomMap.contains(id)) + return d->roomMap.value(id); + + // Not yet in the map, create a new one. + Room* room = createRoom(id); + if (room) + { + d->roomMap.insert( id, room ); + emit newRoom(room); + } else { + qCritical() << "Failed to create a room!!!" << id; + } + + return room; +} + User* Connection::createUser(QString userId) { return new User(userId, this); -- cgit v1.2.3 From 4e70dd91bb70fa2b9b338686e4d5ab2560947723 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 6 Sep 2016 12:02:56 +0900 Subject: Connection: homeserver(); Connection and ConnectionData: accessToken(); accessors de-virtualized Details: - New: Connection::homeserver(), returns the homeserver URL from inside ConnectionData - New/Modify: Connection::accessToken() and ConnectionData::accessToken() - because we will also have refresh tokens eventually; deprecate token() for the same reason - Modify: Connection::user(), token(), accessToken() are no more virtual (they should have never been, these are plain accessors, after all) --- connection.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'connection.cpp') diff --git a/connection.cpp b/connection.cpp index d357599b..f7f09c04 100644 --- a/connection.cpp +++ b/connection.cpp @@ -106,7 +106,6 @@ void Connection::connectToServer(QString user, QString password) { PasswordLogin* loginJob = new PasswordLogin(d->data, user, password); connect( loginJob, &PasswordLogin::success, [=] () { - qDebug() << "Our user ID: " << loginJob->id(); connectWithToken(loginJob->id(), loginJob->token()); }); connect( loginJob, &PasswordLogin::failure, [=] () { @@ -122,7 +121,9 @@ void Connection::connectWithToken(QString userId, QString token) d->isConnected = true; d->userId = userId; d->data->setToken(token); - qDebug() << "Connected with token:"; + qDebug() << "Accessing" << d->data->baseUrl() + << "by user" << userId + << "with the following access token:"; qDebug() << token; emit connected(); } @@ -223,6 +224,11 @@ MediaThumbnailJob* Connection::getThumbnail(QUrl url, int requestedWidth, int re return job; } +QUrl Connection::homeserver() const +{ + return d->data->baseUrl(); +} + User* Connection::user(QString userId) { if( d->userMap.contains(userId) ) @@ -239,14 +245,19 @@ User *Connection::user() return user(d->userId); } -QString Connection::userId() +QString Connection::userId() const { return d->userId; } -QString Connection::token() +QString Connection::token() const +{ + return accessToken(); +} + +QString Connection::accessToken() const { - return d->data->token(); + return d->data->accessToken(); } QHash< QString, Room* > Connection::roomMap() const -- cgit v1.2.3 From 334e4ba4ce410c8426abcd78a361b9a23b14eec7 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 6 Sep 2016 16:09:46 +0900 Subject: Cleanup after moving ConnectionPrivate::provideRoom() --- connection.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'connection.cpp') diff --git a/connection.cpp b/connection.cpp index f7f09c04..f13026fc 100644 --- a/connection.cpp +++ b/connection.cpp @@ -49,8 +49,6 @@ class Connection::Private Private(Private&) = delete; ~Private() { delete data; } - Room* provideRoom( QString id ); - Connection* q; ConnectionData* data; QHash roomMap; @@ -279,7 +277,7 @@ Room* Connection::provideRoom(QString id) { if (id.isEmpty()) { - qDebug() << "ConnectionPrivate::provideRoom() with empty id, doing nothing"; + qDebug() << "Connection::provideRoom() with empty id, doing nothing"; return nullptr; } -- cgit v1.2.3 From 866cb97668fadff50dea8d16792c3b6736d531dc Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 6 Sep 2016 16:12:11 +0900 Subject: Remember the current SyncJob and allow to explicitly abandon it --- connection.cpp | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'connection.cpp') diff --git a/connection.cpp b/connection.cpp index f13026fc..98ff914a 100644 --- a/connection.cpp +++ b/connection.cpp @@ -45,6 +45,7 @@ class Connection::Private : q(nullptr) , data(new ConnectionData(serverUrl)) , isConnected(false) + , syncJob(nullptr) { } Private(Private&) = delete; ~Private() { delete data; } @@ -57,6 +58,10 @@ class Connection::Private QString username; QString password; QString userId; + + SyncJob* syncJob; + + SyncJob* startSyncJob(const QString& filter, int timeout); }; Connection::Connection(QUrl server, QObject* parent) @@ -140,6 +145,12 @@ void Connection::reconnect() loginJob->start(); } +void Connection::disconnectFromServer() +{ + d->syncJob->abandon(); + d->isConnected = false; +} + void Connection::logout() { auto job = new LogoutJob(d->data); @@ -149,27 +160,39 @@ void Connection::logout() SyncJob* Connection::sync(int timeout) { - QString filter = "{\"room\": { \"timeline\": { \"limit\": 100 } } }"; - SyncJob* syncJob = new SyncJob(d->data, d->data->lastEvent()); - syncJob->setFilter(filter); - syncJob->setTimeout(timeout); - connect( syncJob, &SyncJob::success, [=] () { - d->data->setLastEvent(syncJob->nextBatch()); - for( const auto& roomData: syncJob->roomData() ) + if (d->syncJob) + return d->syncJob; + + const QString filter = "{\"room\": { \"timeline\": { \"limit\": 100 } } }"; + auto job = d->startSyncJob(filter, timeout); + connect( job, &SyncJob::success, [=] () { + d->data->setLastEvent(job->nextBatch()); + for( const auto& roomData: job->roomData() ) { if ( Room* r = provideRoom(roomData.roomId) ) r->updateData(roomData); } + d->syncJob = nullptr; emit syncDone(); }); - connect( syncJob, &SyncJob::failure, [=] () { - if (syncJob->error() == BaseJob::ContentAccessError) - emit loginError(syncJob->errorString()); + connect( job, &SyncJob::failure, [=] () { + d->syncJob = nullptr; + if (job->error() == BaseJob::ContentAccessError) + emit loginError(job->errorString()); else - emit connectionError(syncJob->errorString()); + emit connectionError(job->errorString()); }); + return job; +} + +SyncJob* Connection::Private::startSyncJob(const QString& filter, int timeout) +{ + syncJob = new SyncJob(data, data->lastEvent()); + syncJob->setFilter(filter); + syncJob->setTimeout(timeout); syncJob->start(); return syncJob; + } void Connection::postMessage(Room* room, QString type, QString message) -- cgit v1.2.3