diff options
Diffstat (limited to 'buteo-plugins')
| -rw-r--r-- | buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp | 130 |
1 files changed, 126 insertions, 4 deletions
diff --git a/buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp b/buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp index d5d1766..c2fa7c6 100644 --- a/buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp +++ b/buteo-plugins/buteo-sync-plugin-mastodon-notifications/mastodonnotificationssyncadaptor.cpp @@ -120,11 +120,89 @@ namespace { return QStringLiteral("posted"); } else if (type == QLatin1String("update")) { return QStringLiteral("updated a post"); + } else if (type == QLatin1String("admin.sign_up")) { + return QStringLiteral("signed up"); + } else if (type == QLatin1String("admin.report")) { + return QStringLiteral("reported an account"); + } else if (type == QLatin1String("moderation_warning")) { + return QStringLiteral("received a moderation warning"); + } else if (type == QLatin1String("quote")) { + return QStringLiteral("quoted your post"); + } else if (type == QLatin1String("quoted_update")) { + return QStringLiteral("updated a post that quoted you"); } return QStringLiteral("sent you a notification"); } + bool useSystemSummary(const QString ¬ificationType) + { + return notificationType == QLatin1String("severed_relationships") + || notificationType == QLatin1String("moderation_warning"); + } + + QString severedRelationshipsText(const QJsonObject &eventObject) + { + const QString eventType = eventObject.value(QStringLiteral("type")).toString(); + const QString targetName = eventObject.value(QStringLiteral("target_name")).toString().trimmed(); + const int followersCount = eventObject.value(QStringLiteral("followers_count")).toInt(); + const int followingCount = eventObject.value(QStringLiteral("following_count")).toInt(); + + QString action; + if (eventType == QLatin1String("domain_block")) { + action = targetName.isEmpty() + ? QStringLiteral("An admin blocked an instance") + : QStringLiteral("An admin blocked %1").arg(targetName); + } else if (eventType == QLatin1String("user_domain_block")) { + action = targetName.isEmpty() + ? QStringLiteral("You blocked an instance") + : QStringLiteral("You blocked %1").arg(targetName); + } else if (eventType == QLatin1String("account_suspension")) { + action = targetName.isEmpty() + ? QStringLiteral("An account was suspended") + : QStringLiteral("%1 was suspended").arg(targetName); + } else { + action = QStringLiteral("Some follow relationships were severed"); + } + + const int affectedCount = followersCount + followingCount; + if (affectedCount <= 0) { + return action; + } + + return QStringLiteral("%1 (%2 followers, %3 following removed)") + .arg(action) + .arg(followersCount) + .arg(followingCount); + } + + QString moderationWarningText(const QJsonObject &warningObject) + { + const QString warningText = warningObject.value(QStringLiteral("text")).toString().trimmed(); + if (!warningText.isEmpty()) { + return warningText; + } + + const QString action = warningObject.value(QStringLiteral("action")).toString(); + if (action == QLatin1String("none")) { + return QStringLiteral("A moderator sent you a warning"); + } else if (action == QLatin1String("disable")) { + return QStringLiteral("A moderator disabled your account"); + } else if (action == QLatin1String("mark_statuses_as_sensitive")) { + return QStringLiteral("A moderator marked specific posts as sensitive"); + } else if (action == QLatin1String("delete_statuses")) { + return QStringLiteral("A moderator deleted specific posts"); + } else if (action == QLatin1String("sensitive")) { + return QStringLiteral("A moderator marked all your posts as sensitive"); + } else if (action == QLatin1String("silence")) { + return QStringLiteral("A moderator limited your account"); + } else if (action == QLatin1String("suspend")) { + return QStringLiteral("A moderator suspended your account"); + } + + return QString(); + } + bool hasActiveNotificationsForAccount(int accountId) { bool hasActiveNotifications = false; @@ -143,6 +221,34 @@ namespace { return hasActiveNotifications; } + QString authorizeInteractionUrl(const QString &apiHost, const QString &targetUrl) + { + const QUrl parsedApiHost(apiHost); + const QUrl parsedTargetUrl(targetUrl); + if (!parsedApiHost.isValid() + || parsedApiHost.scheme().isEmpty() + || parsedApiHost.host().isEmpty() + || !parsedTargetUrl.isValid() + || parsedTargetUrl.scheme().isEmpty() + || parsedTargetUrl.host().isEmpty()) { + return targetUrl; + } + + // Links on the account's own instance should open directly. + const bool sameScheme = QString::compare(parsedApiHost.scheme(), parsedTargetUrl.scheme(), Qt::CaseInsensitive) == 0; + const bool sameHost = QString::compare(parsedApiHost.host(), parsedTargetUrl.host(), Qt::CaseInsensitive) == 0; + const int apiPort = parsedApiHost.port(parsedApiHost.scheme() == QLatin1String("https") ? 443 : 80); + const int targetPort = parsedTargetUrl.port(parsedTargetUrl.scheme() == QLatin1String("https") ? 443 : 80); + if (sameScheme && sameHost && apiPort == targetPort) { + return targetUrl; + } + + QUrl authorizeUrl(parsedApiHost); + authorizeUrl.setPath(QStringLiteral("/authorize_interaction")); + authorizeUrl.setQuery(QStringLiteral("uri=") + QString::fromUtf8(QUrl::toPercentEncoding(targetUrl))); + return authorizeUrl.toString(); + } + } MastodonNotificationsSyncAdaptor::MastodonNotificationsSyncAdaptor(QObject *parent) @@ -502,6 +608,8 @@ void MastodonNotificationsSyncAdaptor::finishedNotificationsHandler() const QJsonObject statusObject = statusValue.isObject() && !statusValue.isNull() ? statusValue.toObject() : QJsonObject(); + const QJsonObject eventObject = notificationObject.value(QStringLiteral("event")).toObject(); + const QJsonObject warningObject = notificationObject.value(QStringLiteral("moderation_warning")).toObject(); QDateTime eventTimestamp = parseTimestamp(notificationObject.value(QStringLiteral("created_at")).toString()); if (!eventTimestamp.isValid()) { @@ -517,9 +625,18 @@ void MastodonNotificationsSyncAdaptor::finishedNotificationsHandler() const QString statusBody = sanitizeContent(statusObject.value(QStringLiteral("content")).toString()); const QString action = actionText(notificationType); QString body; - if (notificationType == QLatin1String("mention") + if (notificationType == QLatin1String("severed_relationships")) { + body = severedRelationshipsText(eventObject); + } else if (notificationType == QLatin1String("moderation_warning")) { + const QString warningText = moderationWarningText(warningObject); + body = warningText.isEmpty() + ? action + : QStringLiteral("%1: %2").arg(action, warningText); + } else if (notificationType == QLatin1String("mention") || notificationType == QLatin1String("status") - || notificationType == QLatin1String("update")) { + || notificationType == QLatin1String("update") + || notificationType == QLatin1String("quote") + || notificationType == QLatin1String("quoted_update")) { body = statusBody.isEmpty() ? action : statusBody; } else { body = statusBody.isEmpty() ? action : QStringLiteral("%1: %2").arg(action, statusBody); @@ -539,10 +656,15 @@ void MastodonNotificationsSyncAdaptor::finishedNotificationsHandler() } else if (url.isEmpty() && !accountName.isEmpty()) { url = QStringLiteral("%1/@%2").arg(apiHost(accountId), accountName); } + if (useSystemSummary(notificationType)) { + url.clear(); + } PendingNotification pendingNotification; pendingNotification.notificationId = notificationId; - pendingNotification.summary = displayName; + pendingNotification.summary = useSystemSummary(notificationType) + ? QStringLiteral("Mastodon") + : displayName; pendingNotification.body = body; pendingNotification.link = url; pendingNotification.timestamp = eventTimestamp; @@ -655,7 +777,7 @@ void MastodonNotificationsSyncAdaptor::publishSystemNotification(int accountId, && !parsedOpenUrl.host().isEmpty() ? openUrl : fallbackUrl; - notification->setRemoteAction(OPEN_URL_ACTION(safeOpenUrl)); + notification->setRemoteAction(OPEN_URL_ACTION(authorizeInteractionUrl(apiHost(accountId), safeOpenUrl))); notification->publish(); if (notification->replacesId() == 0) { qCWarning(lcSocialPlugin) << "failed to publish Mastodon notification" |
