File indexing completed on 2025-01-05 05:01:15

0001 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0002 // SPDX-FileCopyrightText: 2022-2023 Harald Sitter <sitter@kde.org>
0003 
0004 #include "sentrypostbox.h"
0005 
0006 #include <QFile>
0007 #include <QJsonDocument>
0008 #include <QJsonObject>
0009 #include <QNetworkReply>
0010 
0011 #include "sentryconnection.h"
0012 #include "sentrypaths.h"
0013 
0014 using namespace Qt::StringLiterals;
0015 
0016 SentryPostbox::SentryPostbox(const QString &applicationName, std::shared_ptr<SentryConnection> connection, QObject *parent)
0017     : QObject(parent)
0018     , m_dsns(std::move(connection))
0019     , m_applicationName(applicationName)
0020 {
0021     connect(&m_dsns, &SentryDSNs::loaded, this, &SentryPostbox::onDSNsLoaded);
0022     m_dsns.load();
0023 }
0024 
0025 void SentryPostbox::onDSNsLoaded()
0026 {
0027     m_dsnContext = m_dsns.context(m_applicationName);
0028 
0029     m_envelope.setDSN(m_dsnContext.dsnUrl());
0030     m_dsnSet = true;
0031 }
0032 
0033 void SentryPostbox::addEventPayload(const QJsonDocument &document)
0034 {
0035     document.object().insert(u"event_id"_s, QJsonValue(m_envelope.eventId()));
0036     m_envelope.addItem(SentryEvent(document.toJson(QJsonDocument::Compact)));
0037 
0038     m_hasDelivered = false;
0039     Q_EMIT hasDeliveredChanged();
0040 }
0041 
0042 void SentryPostbox::addUserFeedback(const QString &feedbackString)
0043 {
0044     const QJsonObject feedbackObject = {
0045         {u"event_id"_s, m_envelope.eventId()},
0046         {QStringLiteral("name"), QStringLiteral("DrKonqi")},
0047         {QStringLiteral("email"), QStringLiteral("anonymous@kde.org")},
0048         {QStringLiteral("comments"), feedbackString},
0049     };
0050 
0051     m_envelope.addItem(SentryUserFeedback(QJsonDocument(feedbackObject).toJson(QJsonDocument::Compact)));
0052 
0053     m_hasDelivered = false;
0054     Q_EMIT hasDeliveredChanged();
0055 }
0056 
0057 void SentryPostbox::deliver()
0058 {
0059     Q_ASSERT(!m_envelope.eventId().isEmpty()); // requirement for path construction
0060     QFile file(SentryPaths::payloadPath(m_envelope.eventId()));
0061     if (file.open(QFile::WriteOnly | QFile::Truncate)) {
0062         file.write(m_envelope.toEnvelope());
0063     }
0064     m_hasDelivered = true;
0065     Q_EMIT hasDeliveredChanged();
0066 }
0067 
0068 bool SentryPostbox::hasDelivered() const
0069 {
0070     // NOTE: when items are added AFTER delivery we toggle back to not delivered, as the postbox has pending stuff again
0071     //   this enables us to send the event and then follow it up with sending the feedback if necessary.
0072     return m_hasDelivered;
0073 }
0074 
0075 bool SentryPostbox::isReadyToDeliver() const
0076 {
0077     return m_dsnSet && !m_envelope.isEmpty();
0078 }
0079 
0080 QString SentryPostbox::eventId() const
0081 {
0082     return m_envelope.eventId();
0083 }
0084 
0085 #include "moc_sentrypostbox.cpp"