File indexing completed on 2025-01-12 04:33:57

0001 /*
0002    SPDX-FileCopyrightText: 2019-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "emojicustomcreatejob.h"
0008 
0009 #include "restapimethod.h"
0010 #include "rocketchatqtrestapi_debug.h"
0011 #include <KLocalizedString>
0012 #include <QFile>
0013 #include <QHttpMultiPart>
0014 #include <QJsonDocument>
0015 #include <QJsonObject>
0016 #include <QMimeDatabase>
0017 #include <QNetworkReply>
0018 using namespace RocketChatRestApi;
0019 EmojiCustomCreateJob::EmojiCustomCreateJob(QObject *parent)
0020     : RestApiAbstractJob(parent)
0021 {
0022 }
0023 
0024 EmojiCustomCreateJob::~EmojiCustomCreateJob() = default;
0025 
0026 bool EmojiCustomCreateJob::start()
0027 {
0028     if (!canStart()) {
0029         deleteLater();
0030         return false;
0031     }
0032     addStartRestApiInfo("EmojiCustomCreateJob::start");
0033     const QString fileNameAsLocalFile = mEmojiInfo.fileNameUrl.toLocalFile();
0034     auto file = new QFile(fileNameAsLocalFile);
0035     if (!file->open(QIODevice::ReadOnly)) {
0036         qCWarning(ROCKETCHATQTRESTAPI_LOG) << " Impossible to open filename " << mEmojiInfo.fileNameUrl;
0037         Q_EMIT failed(i18n("File not found \'%1\'", fileNameAsLocalFile));
0038         delete file;
0039         deleteLater();
0040         return false;
0041     }
0042     QMimeDatabase db;
0043     const QMimeType mimeType = db.mimeTypeForFile(fileNameAsLocalFile);
0044 
0045     auto multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
0046 
0047     if (!mEmojiInfo.fileNameUrl.isEmpty()) {
0048         QHttpPart filePart;
0049         filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(mimeType.name()));
0050         const QString filePartInfo = QStringLiteral("form-data; name=\"emoji\"; filename=\"%1\"").arg(mEmojiInfo.fileNameUrl.fileName());
0051         filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(filePartInfo));
0052 
0053         filePart.setBodyDevice(file);
0054         file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
0055         multiPart->append(filePart);
0056     }
0057 
0058     QHttpPart namePart;
0059     namePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QLatin1String("form-data; name=\"name\"")));
0060     namePart.setBody(mEmojiInfo.name.toUtf8());
0061     multiPart->append(std::move(namePart));
0062 
0063     QHttpPart aliasesPart;
0064     aliasesPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QLatin1String("form-data; name=\"aliases\"")));
0065     aliasesPart.setBody(mEmojiInfo.alias.toUtf8());
0066     multiPart->append(std::move(aliasesPart));
0067 
0068     mReply = networkAccessManager()->post(request(), multiPart);
0069     connect(mReply.data(), &QNetworkReply::finished, this, &EmojiCustomCreateJob::slotEmojiCustomCreateFinished);
0070     multiPart->setParent(mReply); // delete the multiPart with the reply
0071     return true;
0072 }
0073 
0074 void EmojiCustomCreateJob::slotEmojiCustomCreateFinished()
0075 {
0076     auto reply = qobject_cast<QNetworkReply *>(sender());
0077 
0078     if (reply) {
0079         const QJsonDocument replyJson = convertToJsonDocument(reply);
0080         const QJsonObject replyObject = replyJson.object();
0081 
0082         if (replyObject[QLatin1String("success")].toBool()) {
0083             addLoggerInfo(QByteArrayLiteral("EmojiCustomCreateJob success: ") + replyJson.toJson(QJsonDocument::Indented));
0084             Q_EMIT emojiCustomCreateDone(replyObject);
0085         } else {
0086             emitFailedMessage(reply->errorString(), replyObject);
0087             addLoggerWarning(QByteArrayLiteral("EmojiCustomCreateJob problem: ") + replyJson.toJson(QJsonDocument::Indented));
0088         }
0089         reply->deleteLater();
0090     }
0091     deleteLater();
0092 }
0093 
0094 const EmojiCustomCreateJob::EmojiInfo &EmojiCustomCreateJob::emojiInfo() const
0095 {
0096     return mEmojiInfo;
0097 }
0098 
0099 void EmojiCustomCreateJob::setEmojiInfo(const EmojiInfo &newEmojiInfo)
0100 {
0101     mEmojiInfo = newEmojiInfo;
0102 }
0103 
0104 bool EmojiCustomCreateJob::requireHttpAuthentication() const
0105 {
0106     return true;
0107 }
0108 
0109 bool EmojiCustomCreateJob::canStart() const
0110 {
0111     if (!mEmojiInfo.isValid()) {
0112         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "EmojiCustomCreateJob: mEmojiInfo is not valid";
0113         return false;
0114     }
0115     if (!RestApiAbstractJob::canStart()) {
0116         return false;
0117     }
0118     return true;
0119 }
0120 
0121 QNetworkRequest EmojiCustomCreateJob::request() const
0122 {
0123     const QUrl url = mRestApiMethod->generateUrl(RestApiUtil::RestApiUrlType::EmojiCustomCreate);
0124     QNetworkRequest request(url);
0125     addAuthRawHeader(request);
0126     addRequestAttribute(request, false);
0127     return request;
0128 }
0129 
0130 bool EmojiCustomCreateJob::EmojiInfo::isValid() const
0131 {
0132     // Alias is optional
0133     return !name.isEmpty() && !fileNameUrl.isEmpty();
0134 }
0135 
0136 QString EmojiCustomCreateJob::errorMessage(const QString &str, const QJsonObject &details)
0137 {
0138     if (str == QLatin1String("Custom_Emoji_Error_Name_Or_Alias_Already_In_Use")) {
0139         return i18n("The custom emoji or one of its aliases is already in use.");
0140     }
0141     return RestApiAbstractJob::errorMessage(str, details);
0142 }
0143 
0144 #include "moc_emojicustomcreatejob.cpp"