summaryrefslogtreecommitdiff
path: root/transferengine-plugins/mastodontransferplugin/mastodonuploader.cpp
diff options
context:
space:
mode:
authorAndrew Branson <andrew.branson@jolla.com>2026-02-10 10:41:02 +0100
committerAndrew Branson <andrew.branson@jolla.com>2026-02-10 17:09:39 +0100
commit4351f4627ba9e71775438dd26c9acddd002c7e11 (patch)
tree3c72c980c5c81507109087bda67052b7ec8216b6 /transferengine-plugins/mastodontransferplugin/mastodonuploader.cpp
Initial commit
Diffstat (limited to 'transferengine-plugins/mastodontransferplugin/mastodonuploader.cpp')
-rw-r--r--transferengine-plugins/mastodontransferplugin/mastodonuploader.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/transferengine-plugins/mastodontransferplugin/mastodonuploader.cpp b/transferengine-plugins/mastodontransferplugin/mastodonuploader.cpp
new file mode 100644
index 0000000..9e2fa1a
--- /dev/null
+++ b/transferengine-plugins/mastodontransferplugin/mastodonuploader.cpp
@@ -0,0 +1,200 @@
+#include "mastodonuploader.h"
+#include "mastodonapi.h"
+
+#include <imageoperation.h>
+#include <mediaitem.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QMimeDatabase>
+#include <QtCore/QMimeType>
+
+#include <QtDebug>
+
+MastodonUploader::MastodonUploader(QNetworkAccessManager *qnam, QObject *parent)
+ : MediaTransferInterface(parent)
+ , m_api(0)
+ , m_mastodonShareServiceStatus(0)
+ , m_qnam(qnam)
+ , m_useTmpFile(false)
+{
+}
+
+MastodonUploader::~MastodonUploader()
+{
+}
+
+QString MastodonUploader::displayName() const
+{
+ return tr("Mastodon");
+}
+
+QUrl MastodonUploader::serviceIcon() const
+{
+ return QUrl(QStringLiteral("image://theme/graphic-s-service-mastodon"));
+}
+
+bool MastodonUploader::cancelEnabled() const
+{
+ return true;
+}
+
+bool MastodonUploader::restartEnabled() const
+{
+ return true;
+}
+
+void MastodonUploader::start()
+{
+ if (!mediaItem()) {
+ qWarning() << Q_FUNC_INFO << "NULL MediaItem. Can't continue";
+ setStatus(MediaTransferInterface::TransferInterrupted);
+ return;
+ }
+
+ if (!m_mastodonShareServiceStatus) {
+ m_mastodonShareServiceStatus = new MastodonShareServiceStatus(this);
+ connect(m_mastodonShareServiceStatus, &MastodonShareServiceStatus::serviceReady,
+ this, &MastodonUploader::startUploading);
+ connect(m_mastodonShareServiceStatus, &MastodonShareServiceStatus::serviceError,
+ this, [this] (const QString &) {
+ transferError();
+ });
+ }
+
+ m_mastodonShareServiceStatus->queryStatus();
+}
+
+void MastodonUploader::cancel()
+{
+ if (m_api) {
+ m_api->cancelUpload();
+ } else {
+ qWarning() << Q_FUNC_INFO << "Can't cancel. NULL MastodonApi object!";
+ }
+}
+
+void MastodonUploader::startUploading()
+{
+ if (!m_mastodonShareServiceStatus) {
+ qWarning() << Q_FUNC_INFO << "NULL MastodonShareServiceStatus object!";
+ return;
+ }
+
+ const quint32 accountId = mediaItem()->value(MediaItem::AccountId).toInt();
+ m_accountDetails = m_mastodonShareServiceStatus->detailsByIdentifier(accountId);
+ if (m_accountDetails.accountId <= 0 || m_accountDetails.accessToken.isEmpty()) {
+ qWarning() << Q_FUNC_INFO << "Mastodon account details missing for id" << accountId;
+ transferError();
+ return;
+ }
+
+ postImage();
+}
+
+void MastodonUploader::transferFinished()
+{
+ setStatus(MediaTransferInterface::TransferFinished);
+}
+
+void MastodonUploader::transferProgress(qreal progress)
+{
+ setProgress(progress);
+}
+
+void MastodonUploader::transferError()
+{
+ setStatus(MediaTransferInterface::TransferInterrupted);
+ qWarning() << Q_FUNC_INFO << "Transfer interrupted";
+}
+
+void MastodonUploader::transferCanceled()
+{
+ setStatus(MediaTransferInterface::TransferCanceled);
+}
+
+void MastodonUploader::credentialsExpired()
+{
+ const quint32 accountId = mediaItem()->value(MediaItem::AccountId).toInt();
+ m_mastodonShareServiceStatus->setCredentialsNeedUpdate(accountId, QStringLiteral("mastodon-sharing"));
+}
+
+void MastodonUploader::setStatus(MediaTransferInterface::TransferStatus status)
+{
+ const bool finished = (status == TransferCanceled
+ || status == TransferInterrupted
+ || status == TransferFinished);
+ if (m_useTmpFile && finished) {
+ QFile::remove(m_filePath);
+ m_useTmpFile = false;
+ m_filePath.clear();
+ }
+
+ MediaTransferInterface::setStatus(status);
+}
+
+void MastodonUploader::postImage()
+{
+ m_useTmpFile = false;
+ m_filePath.clear();
+ const QString sourceFile = mediaItem()->value(MediaItem::Url).toUrl().toLocalFile();
+ if (sourceFile.isEmpty()) {
+ qWarning() << Q_FUNC_INFO << "Empty source file";
+ setStatus(MediaTransferInterface::TransferInterrupted);
+ return;
+ }
+
+ QMimeDatabase db;
+ const QMimeType mime = db.mimeTypeForFile(sourceFile);
+ const bool isJpeg = mime.name() == QLatin1String("image/jpeg");
+
+ if (isJpeg && mediaItem()->value(MediaItem::MetadataStripped).toBool()) {
+ m_useTmpFile = true;
+ m_filePath = ImageOperation::removeImageMetadata(sourceFile);
+ if (m_filePath.isEmpty()) {
+ qWarning() << Q_FUNC_INFO << "Failed to remove metadata";
+ MediaTransferInterface::setStatus(MediaTransferInterface::TransferInterrupted);
+ return;
+ }
+ }
+
+ const qreal scale = mediaItem()->value(MediaItem::ScalePercent).toReal();
+ if (0 < scale && scale < 1) {
+ m_useTmpFile = true;
+ m_filePath = ImageOperation::scaleImage(sourceFile, scale, m_filePath);
+ if (m_filePath.isEmpty()) {
+ qWarning() << Q_FUNC_INFO << "Failed to scale image";
+ MediaTransferInterface::setStatus(MediaTransferInterface::TransferInterrupted);
+ return;
+ }
+ }
+
+ if (!m_useTmpFile) {
+ m_filePath = sourceFile;
+ }
+
+ if (!m_api) {
+ m_api = new MastodonApi(m_qnam, this);
+ connect(m_api, &MastodonApi::transferProgressUpdated,
+ this, &MastodonUploader::transferProgress);
+ connect(m_api, &MastodonApi::transferFinished,
+ this, &MastodonUploader::transferFinished);
+ connect(m_api, &MastodonApi::transferError,
+ this, &MastodonUploader::transferError);
+ connect(m_api, &MastodonApi::transferCanceled,
+ this, &MastodonUploader::transferCanceled);
+ connect(m_api, &MastodonApi::credentialsExpired,
+ this, &MastodonUploader::credentialsExpired);
+ }
+
+ const bool ok = m_api->uploadImage(m_filePath,
+ mediaItem()->value(MediaItem::Description).toString(),
+ mediaItem()->value(MediaItem::MimeType).toString(),
+ m_accountDetails.apiHost,
+ m_accountDetails.accessToken);
+ if (ok) {
+ setStatus(MediaTransferInterface::TransferStarted);
+ } else {
+ setStatus(MediaTransferInterface::TransferInterrupted);
+ qWarning() << Q_FUNC_INFO << "Failed to upload image";
+ }
+}