aboutsummaryrefslogtreecommitdiff
path: root/lib/jobs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/jobs')
-rw-r--r--lib/jobs/basejob.cpp19
-rw-r--r--lib/jobs/basejob.h14
-rw-r--r--lib/jobs/mediathumbnailjob.cpp8
-rw-r--r--lib/jobs/syncjob.cpp112
-rw-r--r--lib/jobs/syncjob.h48
5 files changed, 39 insertions, 162 deletions
diff --git a/lib/jobs/basejob.cpp b/lib/jobs/basejob.cpp
index b21173ae..4a7780b1 100644
--- a/lib/jobs/basejob.cpp
+++ b/lib/jobs/basejob.cpp
@@ -426,8 +426,8 @@ BaseJob::Status BaseJob::parseReply(QNetworkReply* reply)
const auto& json = QJsonDocument::fromJson(d->rawResponse, &error);
if( error.error == QJsonParseError::NoError )
return parseJson(json);
- else
- return { IncorrectResponseError, error.errorString() };
+
+ return { IncorrectResponseError, error.errorString() };
}
BaseJob::Status BaseJob::parseJson(const QJsonDocument&)
@@ -519,8 +519,19 @@ BaseJob::Status BaseJob::status() const
QByteArray BaseJob::rawData(int bytesAtMost) const
{
- return bytesAtMost > 0 && d->rawResponse.size() > bytesAtMost ?
- d->rawResponse.left(bytesAtMost) + "...(truncated)" : d->rawResponse;
+ return bytesAtMost > 0 && d->rawResponse.size() > bytesAtMost
+ ? d->rawResponse.left(bytesAtMost) : d->rawResponse;
+}
+
+QString BaseJob::rawDataSample(int bytesAtMost) const
+{
+ auto data = rawData(bytesAtMost);
+ Q_ASSERT(data.size() <= d->rawResponse.size());
+ return data.size() == d->rawResponse.size()
+ ? data : data + tr("...(truncated, %Ln bytes in total)",
+ "Comes after trimmed raw network response",
+ d->rawResponse.size());
+
}
QString BaseJob::statusCaption() const
diff --git a/lib/jobs/basejob.h b/lib/jobs/basejob.h
index 4ef25ab8..3d50344d 100644
--- a/lib/jobs/basejob.h
+++ b/lib/jobs/basejob.h
@@ -138,8 +138,20 @@ namespace QMatrixClient
Status status() const;
/** Short human-friendly message on the job status */
QString statusCaption() const;
- /** Raw response body as received from the server */
+ /** Get raw response body as received from the server
+ * \param bytesAtMost return this number of leftmost bytes, or -1
+ * to return the entire response
+ */
QByteArray rawData(int bytesAtMost = -1) const;
+ /** Get UI-friendly sample of raw data
+ *
+ * This is almost the same as rawData but appends the "truncated"
+ * suffix if not all data fit in bytesAtMost. This call is
+ * recommended to present a sample of raw data as "details" next to
+ * error messages. Note that the default \p bytesAtMost value is
+ * also tailored to UI cases.
+ */
+ QString rawDataSample(int bytesAtMost = 65535) const;
/** Error (more generally, status) code
* Equivalent to status().code
diff --git a/lib/jobs/mediathumbnailjob.cpp b/lib/jobs/mediathumbnailjob.cpp
index 8dfb6094..aeb49839 100644
--- a/lib/jobs/mediathumbnailjob.cpp
+++ b/lib/jobs/mediathumbnailjob.cpp
@@ -23,7 +23,8 @@ using namespace QMatrixClient;
QUrl MediaThumbnailJob::makeRequestUrl(QUrl baseUrl,
const QUrl& mxcUri, QSize requestedSize)
{
- return makeRequestUrl(baseUrl, mxcUri.authority(), mxcUri.path().mid(1),
+ return makeRequestUrl(std::move(baseUrl),
+ mxcUri.authority(), mxcUri.path().mid(1),
requestedSize.width(), requestedSize.height());
}
@@ -34,9 +35,8 @@ MediaThumbnailJob::MediaThumbnailJob(const QString& serverName,
{ }
MediaThumbnailJob::MediaThumbnailJob(const QUrl& mxcUri, QSize requestedSize)
- : GetContentThumbnailJob(mxcUri.authority(),
- mxcUri.path().mid(1), // sans leading '/'
- requestedSize.width(), requestedSize.height())
+ : MediaThumbnailJob(mxcUri.authority(), mxcUri.path().mid(1), // sans leading '/'
+ requestedSize)
{ }
QImage MediaThumbnailJob::thumbnail() const
diff --git a/lib/jobs/syncjob.cpp b/lib/jobs/syncjob.cpp
index 9cbac71b..ac0f6685 100644
--- a/lib/jobs/syncjob.cpp
+++ b/lib/jobs/syncjob.cpp
@@ -18,10 +18,6 @@
#include "syncjob.h"
-#include "events/eventloader.h"
-
-#include <QtCore/QElapsedTimer>
-
using namespace QMatrixClient;
static size_t jobId = 0;
@@ -46,110 +42,14 @@ SyncJob::SyncJob(const QString& since, const QString& filter, int timeout,
setMaxRetries(std::numeric_limits<int>::max());
}
-QString SyncData::nextBatch() const
-{
- return nextBatch_;
-}
-
-SyncDataList&& SyncData::takeRoomData()
-{
- return std::move(roomData);
-}
-
-Events&& SyncData::takePresenceData()
-{
- return std::move(presenceData);
-}
-
-Events&& SyncData::takeAccountData()
-{
- return std::move(accountData);
-}
-
-Events&&SyncData::takeToDeviceEvents()
-{
- return std::move(toDeviceEvents);
-}
-
-template <typename EventsArrayT, typename StrT>
-inline EventsArrayT load(const QJsonObject& batches, StrT keyName)
-{
- return fromJson<EventsArrayT>(batches[keyName].toObject().value("events"_ls));
-}
-
BaseJob::Status SyncJob::parseJson(const QJsonDocument& data)
{
- return d.parseJson(data);
-}
-
-BaseJob::Status SyncData::parseJson(const QJsonDocument &data)
-{
- QElapsedTimer et; et.start();
-
- auto json = data.object();
- nextBatch_ = json.value("next_batch"_ls).toString();
- presenceData = load<Events>(json, "presence"_ls);
- accountData = load<Events>(json, "account_data"_ls);
- toDeviceEvents = load<Events>(json, "to_device"_ls);
+ d.parseJson(data.object());
+ if (d.unresolvedRooms().isEmpty())
+ return BaseJob::Success;
- auto rooms = json.value("rooms"_ls).toObject();
- JoinStates::Int ii = 1; // ii is used to make a JoinState value
- auto totalRooms = 0;
- auto totalEvents = 0;
- for (size_t i = 0; i < JoinStateStrings.size(); ++i, ii <<= 1)
- {
- 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<size_t>(rs.size()));
- for(auto roomIt = rs.begin(); roomIt != rs.end(); ++roomIt)
- {
- roomData.emplace_back(roomIt.key(), JoinState(ii),
- roomIt.value().toObject());
- const auto& r = roomData.back();
- totalEvents += r.state.size() + r.ephemeral.size() +
- r.accountData.size() + r.timeline.size();
- }
- totalRooms += roomData.size();
- }
- qCDebug(PROFILER) << "*** SyncData::parseJson(): batch with"
- << totalRooms << "room(s),"
- << totalEvents << "event(s) in" << et;
- return BaseJob::Success;
+ qCCritical(MAIN).noquote() << "Incomplete sync response, missing rooms:"
+ << d.unresolvedRooms().join(',');
+ return BaseJob::IncorrectResponseError;
}
-const QString SyncRoomData::UnreadCountKey =
- QStringLiteral("x-qmatrixclient.unread_count");
-
-SyncRoomData::SyncRoomData(const QString& roomId_, JoinState joinState_,
- const QJsonObject& room_)
- : roomId(roomId_)
- , joinState(joinState_)
- , state(load<StateEvents>(room_,
- joinState == JoinState::Invite ? "invite_state"_ls : "state"_ls))
-{
- switch (joinState) {
- case JoinState::Join:
- ephemeral = load<Events>(room_, "ephemeral"_ls);
- FALLTHROUGH;
- case JoinState::Leave:
- {
- accountData = load<Events>(room_, "account_data"_ls);
- timeline = load<RoomEvents>(room_, "timeline"_ls);
- const auto timelineJson = room_.value("timeline"_ls).toObject();
- timelineLimited = timelineJson.value("limited"_ls).toBool();
- timelinePrevBatch = timelineJson.value("prev_batch"_ls).toString();
-
- break;
- }
- default: /* nothing on top of state */;
- }
-
- const auto unreadJson = room_.value("unread_notifications"_ls).toObject();
- unreadCount = unreadJson.value(UnreadCountKey).toInt(-2);
- highlightCount = unreadJson.value("highlight_count"_ls).toInt();
- notificationCount = unreadJson.value("notification_count"_ls).toInt();
- if (highlightCount > 0 || notificationCount > 0)
- qCDebug(SYNCJOB) << "Room" << roomId_
- << "has highlights:" << highlightCount
- << "and notifications:" << notificationCount;
-}
diff --git a/lib/jobs/syncjob.h b/lib/jobs/syncjob.h
index 6b9bedfa..a0a3c026 100644
--- a/lib/jobs/syncjob.h
+++ b/lib/jobs/syncjob.h
@@ -20,56 +20,10 @@
#include "basejob.h"
-#include "joinstate.h"
-#include "events/stateevent.h"
-#include "util.h"
+#include "../syncdata.h"
namespace QMatrixClient
{
- class SyncRoomData
- {
- public:
- QString roomId;
- JoinState joinState;
- StateEvents state;
- RoomEvents timeline;
- Events ephemeral;
- Events accountData;
-
- bool timelineLimited;
- QString timelinePrevBatch;
- int unreadCount;
- int highlightCount;
- int notificationCount;
-
- SyncRoomData(const QString& roomId, JoinState joinState_,
- const QJsonObject& room_);
- SyncRoomData(SyncRoomData&&) = default;
- SyncRoomData& operator=(SyncRoomData&&) = default;
-
- static const QString UnreadCountKey;
- };
- // QVector cannot work with non-copiable objects, std::vector can.
- using SyncDataList = std::vector<SyncRoomData>;
-
- class SyncData
- {
- public:
- BaseJob::Status parseJson(const QJsonDocument &data);
- Events&& takePresenceData();
- Events&& takeAccountData();
- Events&& takeToDeviceEvents();
- SyncDataList&& takeRoomData();
- QString nextBatch() const;
-
- private:
- QString nextBatch_;
- Events presenceData;
- Events accountData;
- Events toDeviceEvents;
- SyncDataList roomData;
- };
-
class SyncJob: public BaseJob
{
public: