From 9182ffb1573c77367ad6b5e4b1f3e4f52b3c3ea4 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Mon, 9 Mar 2026 09:43:54 +0100 Subject: Fix Mastodon sync and transfer reliability edge cases --- .../mastodonshareservicestatus.cpp | 6 ++- .../mastodontransferplugin/mastodonapi.cpp | 47 ++++++++-------------- .../mastodontransferplugin/mastodonapi.h | 2 +- 3 files changed, 23 insertions(+), 32 deletions(-) (limited to 'transferengine-plugins') diff --git a/transferengine-plugins/mastodonshareservicestatus.cpp b/transferengine-plugins/mastodonshareservicestatus.cpp index f3c96ca..3ac05d5 100644 --- a/transferengine-plugins/mastodonshareservicestatus.cpp +++ b/transferengine-plugins/mastodonshareservicestatus.cpp @@ -186,7 +186,7 @@ void MastodonShareServiceStatus::queryStatus(QueryStatusMode mode) bool signInActive = false; Q_FOREACH (Accounts::AccountId id, m_accountManager->accountList()) { - Accounts::Account *acc = m_accountManager->account(id); + Accounts::Account *acc = Accounts::Account::fromId(m_accountManager, id, this); if (!acc) { qWarning() << Q_FUNC_INFO << "Failed to get account for id:" << id; @@ -206,6 +206,7 @@ void MastodonShareServiceStatus::queryStatus(QueryStatusMode mode) } if (!service.isValid() || !serviceFound) { + acc->deleteLater(); continue; } @@ -214,12 +215,14 @@ void MastodonShareServiceStatus::queryStatus(QueryStatusMode mode) const bool shareServiceEnabled = acc->enabled(); if (!accountEnabled || !shareServiceEnabled) { acc->selectService(Accounts::Service()); + acc->deleteLater(); continue; } if (acc->value(QStringLiteral("CredentialsNeedUpdate")).toBool()) { qWarning() << Q_FUNC_INFO << "Credentials need update for account id:" << id; acc->selectService(Accounts::Service()); + acc->deleteLater(); continue; } @@ -256,6 +259,7 @@ void MastodonShareServiceStatus::queryStatus(QueryStatusMode mode) } acc->selectService(Accounts::Service()); + acc->deleteLater(); } if (!signInActive) { diff --git a/transferengine-plugins/mastodontransferplugin/mastodonapi.cpp b/transferengine-plugins/mastodontransferplugin/mastodonapi.cpp index baf9dd8..24bc6f5 100644 --- a/transferengine-plugins/mastodontransferplugin/mastodonapi.cpp +++ b/transferengine-plugins/mastodontransferplugin/mastodonapi.cpp @@ -3,6 +3,7 @@ */ #include "mastodonapi.h" +#include "mastodonauthutils.h" #include #include @@ -18,6 +19,7 @@ MastodonApi::MastodonApi(QNetworkAccessManager *qnam, QObject *parent) : QObject(parent) + , m_cancelRequested(false) , m_qnam(qnam) { } @@ -26,33 +28,6 @@ MastodonApi::~MastodonApi() { } -QString MastodonApi::normalizeApiHost(const QString &rawHost) -{ - QString host = rawHost.trimmed(); - if (host.isEmpty()) { - host = QStringLiteral("https://mastodon.social"); - } - - if (!host.startsWith(QLatin1String("https://")) - && !host.startsWith(QLatin1String("http://"))) { - host.prepend(QStringLiteral("https://")); - } - - QUrl url(host); - if (!url.isValid() || url.host().isEmpty()) { - return QStringLiteral("https://mastodon.social"); - } - - QString normalized = QString::fromLatin1(url.toEncoded(QUrl::RemovePath - | QUrl::RemoveQuery - | QUrl::RemoveFragment)); - if (normalized.endsWith(QLatin1Char('/'))) { - normalized.chop(1); - } - - return normalized; -} - bool MastodonApi::uploadImage(const QString &filePath, const QString &statusText, const QString &mimeType, @@ -65,7 +40,8 @@ bool MastodonApi::uploadImage(const QString &filePath, return false; } - m_apiHost = normalizeApiHost(apiHost); + m_cancelRequested = false; + m_apiHost = MastodonAuthUtils::normalizeApiHost(apiHost); m_accessToken = accessToken; m_statusText = statusText; @@ -116,7 +92,8 @@ bool MastodonApi::postStatus(const QString &statusText, const QString &apiHost, const QString &accessToken) { - m_apiHost = normalizeApiHost(apiHost); + m_cancelRequested = false; + m_apiHost = MastodonAuthUtils::normalizeApiHost(apiHost); m_accessToken = accessToken; m_statusText = statusText; @@ -172,11 +149,11 @@ void MastodonApi::cancelUpload() return; } + m_cancelRequested = true; const QList replies = m_replies.keys(); Q_FOREACH (QNetworkReply *reply, replies) { reply->abort(); } - m_replies.clear(); } void MastodonApi::replyError(QNetworkReply::NetworkError error) @@ -205,6 +182,14 @@ void MastodonApi::finished() reply->deleteLater(); + if (m_cancelRequested && error == QNetworkReply::OperationCanceledError) { + if (m_replies.isEmpty()) { + m_cancelRequested = false; + emit transferCanceled(); + } + return; + } + if (apiCall == UPLOAD_MEDIA) { if (error != QNetworkReply::NoError || httpCode < 200 || httpCode >= 300) { finishTransfer(error == QNetworkReply::NoError ? QNetworkReply::UnknownNetworkError : error, @@ -241,6 +226,8 @@ void MastodonApi::finished() void MastodonApi::finishTransfer(QNetworkReply::NetworkError error, int httpCode, const QByteArray &data) { + m_cancelRequested = false; + if (httpCode == 401) { emit credentialsExpired(); } diff --git a/transferengine-plugins/mastodontransferplugin/mastodonapi.h b/transferengine-plugins/mastodontransferplugin/mastodonapi.h index 4ac3d80..e24914d 100644 --- a/transferengine-plugins/mastodontransferplugin/mastodonapi.h +++ b/transferengine-plugins/mastodontransferplugin/mastodonapi.h @@ -49,11 +49,11 @@ private Q_SLOTS: void uploadProgress(qint64 received, qint64 total); private: - static QString normalizeApiHost(const QString &rawHost); bool postStatusInternal(const QString &mediaId); void finishTransfer(QNetworkReply::NetworkError error, int httpCode, const QByteArray &data); QMap m_replies; + bool m_cancelRequested; QNetworkAccessManager *m_qnam; QString m_accessToken; QString m_apiHost; -- cgit v1.2.3