diff --git a/CMakeLists.txt b/CMakeLists.txt index 2af0aa71..91119b2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,9 +68,6 @@ set(Launcher_NOTIFICATION_URL "" CACHE STRING "URL for checking for notification # The metadata server set(Launcher_META_URL "https://meta.multimc.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.") -# paste.ee API key -set(Launcher_PASTE_EE_API_KEY "utLvciUouSURFzfjPxLBf5W4ISsUX4pwBDF7N1AfZ" CACHE STRING "API key you can get from paste.ee when you register an account") - # Imgur API Client ID set(Launcher_IMGUR_CLIENT_ID "5b97b0713fba4a3" CACHE STRING "Client ID you can get from Imgur when you register an application") diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index af8845dc..2595f78b 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -42,7 +42,6 @@ Config::Config() VERSION_STR = "@Launcher_VERSION_STRING@"; NEWS_RSS_URL = "@Launcher_NEWS_RSS_URL@"; - PASTE_EE_KEY = "@Launcher_PASTE_EE_API_KEY@"; IMGUR_CLIENT_ID = "@Launcher_IMGUR_CLIENT_ID@"; MSA_CLIENT_ID = "@Launcher_MSA_CLIENT_ID@"; META_URL = "@Launcher_META_URL@"; diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index 009fb2bc..d09d5288 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -67,11 +67,6 @@ public: */ QString NEWS_RSS_URL; - /** - * API key you can get from paste.ee when you register an account - */ - QString PASTE_EE_KEY; - /** * Client ID you can get from Imgur when you register an application */ diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 8d1c4d62..b605e54b 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -14,7 +14,7 @@ #include "ui/pages/global/ProxyPage.h" #include "ui/pages/global/ExternalToolsPage.h" #include "ui/pages/global/AccountListPage.h" -#include "ui/pages/global/PasteEEPage.h" +#include "ui/pages/global/PastePage.h" #include "ui/pages/global/CustomCommandsPage.h" #include "ui/themes/ITheme.h" @@ -714,8 +714,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_settings->registerSetting("UpdateDialogGeometry", ""); - // paste.ee API key - m_settings->registerSetting("PasteEEAPIKey", "multimc"); + // pastebin URL + m_settings->registerSetting("PastebinURL", "https://0x0.st"); // Init page provider { @@ -728,7 +728,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); } qDebug() << "<> Settings loaded."; } diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index b5c52afa..c49b68b2 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -707,8 +707,8 @@ SET(LAUNCHER_SOURCES ui/pages/global/LauncherPage.h ui/pages/global/ProxyPage.cpp ui/pages/global/ProxyPage.h - ui/pages/global/PasteEEPage.cpp - ui/pages/global/PasteEEPage.h + ui/pages/global/PastePage.cpp + ui/pages/global/PastePage.h # GUI - platform pages ui/pages/modplatform/VanillaPage.cpp @@ -842,7 +842,7 @@ qt5_wrap_ui(LAUNCHER_UI ui/pages/global/AccountListPage.ui ui/pages/global/JavaPage.ui ui/pages/global/LauncherPage.ui - ui/pages/global/PasteEEPage.ui + ui/pages/global/PastePage.ui ui/pages/global/ProxyPage.ui ui/pages/global/MinecraftPage.ui ui/pages/global/ExternalToolsPage.ui diff --git a/launcher/net/PasteUpload.cpp b/launcher/net/PasteUpload.cpp index 4b69b68a..52b82a0e 100644 --- a/launcher/net/PasteUpload.cpp +++ b/launcher/net/PasteUpload.cpp @@ -8,44 +8,34 @@ #include #include -PasteUpload::PasteUpload(QWidget *window, QString text, QString key) : m_window(window) +PasteUpload::PasteUpload(QWidget *window, QString text, QString url) : m_window(window), m_uploadUrl(url), m_text(text.toUtf8()) { - m_key = key; - QByteArray temp; - QJsonObject topLevelObj; - QJsonObject sectionObject; - sectionObject.insert("contents", text); - QJsonArray sectionArray; - sectionArray.append(sectionObject); - topLevelObj.insert("description", "Log Upload"); - topLevelObj.insert("sections", sectionArray); - QJsonDocument docOut; - docOut.setObject(topLevelObj); - m_jsonContent = docOut.toJson(); } PasteUpload::~PasteUpload() { } -bool PasteUpload::validateText() -{ - return m_jsonContent.size() <= maxSize(); -} - void PasteUpload::executeTask() { - QNetworkRequest request(QUrl("https://api.paste.ee/v1/pastes")); + QNetworkRequest request{QUrl(m_uploadUrl)}; request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED); - request.setRawHeader("Content-Type", "application/json"); - request.setRawHeader("Content-Length", QByteArray::number(m_jsonContent.size())); - request.setRawHeader("X-Auth-Token", m_key.toStdString().c_str()); + QHttpMultiPart *multiPart = new QHttpMultiPart{QHttpMultiPart::FormDataType}; - QNetworkReply *rep = APPLICATION->network()->post(request, m_jsonContent); + QHttpPart filePart; + filePart.setBody(m_text); + filePart.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain"); + filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"file\"; filename=\"log.txt\""); + + multiPart->append(filePart); + + QNetworkReply *rep = APPLICATION->network()->post(request, multiPart); + multiPart->setParent(rep); m_reply = std::shared_ptr(rep); - setStatus(tr("Uploading to paste.ee")); + setStatus(tr("Uploading to %1").arg(m_uploadUrl)); + connect(rep, &QNetworkReply::uploadProgress, this, &Task::setProgress); connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError))); connect(rep, SIGNAL(finished()), this, SLOT(downloadFinished())); @@ -61,45 +51,23 @@ void PasteUpload::downloadError(QNetworkReply::NetworkError error) void PasteUpload::downloadFinished() { QByteArray data = m_reply->readAll(); - // if the download succeeded - if (m_reply->error() == QNetworkReply::NetworkError::NoError) + int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (m_reply->error() != QNetworkReply::NetworkError::NoError) { - m_reply.reset(); - QJsonParseError jsonError; - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if (jsonError.error != QJsonParseError::NoError) - { - emitFailed(jsonError.errorString()); - return; - } - if (!parseResult(doc)) - { - emitFailed(tr("paste.ee returned an error. Please consult the logs for more information")); - return; - } - } - // else the download failed - else - { - emitFailed(QString("Network error: %1").arg(m_reply->errorString())); + emitFailed(tr("Network error: %1").arg(m_reply->errorString())); m_reply.reset(); return; } + else if (statusCode != 200 && statusCode != 201) + { + QString reasonPhrase = m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); + emitFailed(tr("Error: %1 returned unexpected status code %2 %3").arg(m_uploadUrl).arg(statusCode).arg(reasonPhrase)); + qCritical() << m_uploadUrl << " returned unexpected status code " << statusCode << " with body: " << data; + m_reply.reset(); + return; + } + + m_pasteLink = QString::fromUtf8(data).trimmed(); emitSucceeded(); } - -bool PasteUpload::parseResult(QJsonDocument doc) -{ - auto object = doc.object(); - auto status = object.value("success").toBool(); - if (!status) - { - qCritical() << "paste.ee reported error:" << QString(object.value("error").toString()); - return false; - } - m_pasteLink = object.value("link").toString(); - m_pasteID = object.value("id").toString(); - qDebug() << m_pasteLink; - return true; -} - diff --git a/launcher/net/PasteUpload.h b/launcher/net/PasteUpload.h index 5514e058..62b2dc36 100644 --- a/launcher/net/PasteUpload.h +++ b/launcher/net/PasteUpload.h @@ -8,37 +8,21 @@ class PasteUpload : public Task { Q_OBJECT public: - PasteUpload(QWidget *window, QString text, QString key = "public"); + PasteUpload(QWidget *window, QString text, QString url); virtual ~PasteUpload(); QString pasteLink() { return m_pasteLink; } - QString pasteID() - { - return m_pasteID; - } - int maxSize() - { - // 2MB for paste.ee - public - if(m_key == "public") - return 1024*1024*2; - // 12MB for paste.ee - with actual key - return 1024*1024*12; - } - bool validateText(); protected: virtual void executeTask(); private: - bool parseResult(QJsonDocument doc); - QString m_error; QWidget *m_window; - QString m_pasteID; QString m_pasteLink; - QString m_key; - QByteArray m_jsonContent; + QString m_uploadUrl; + QByteArray m_text; std::shared_ptr m_reply; public slots: diff --git a/launcher/ui/GuiUtil.cpp b/launcher/ui/GuiUtil.cpp index efb1a4df..9eb658e2 100644 --- a/launcher/ui/GuiUtil.cpp +++ b/launcher/ui/GuiUtil.cpp @@ -16,21 +16,8 @@ QString GuiUtil::uploadPaste(const QString &text, QWidget *parentWidget) { ProgressDialog dialog(parentWidget); - auto APIKeySetting = APPLICATION->settings()->get("PasteEEAPIKey").toString(); - if(APIKeySetting == "multimc") - { - APIKeySetting = BuildConfig.PASTE_EE_KEY; - } - std::unique_ptr paste(new PasteUpload(parentWidget, text, APIKeySetting)); - - if (!paste->validateText()) - { - CustomMessageBox::selectable( - parentWidget, QObject::tr("Upload failed"), - QObject::tr("The log file is too big. You'll have to upload it manually."), - QMessageBox::Warning)->exec(); - return QString(); - } + auto pasteUrlSetting = APPLICATION->settings()->get("PastebinURL").toString(); + std::unique_ptr paste(new PasteUpload(parentWidget, text, pasteUrlSetting)); dialog.execWithTask(paste.get()); if (!paste->wasSuccessful()) diff --git a/launcher/ui/pages/global/PasteEEPage.cpp b/launcher/ui/pages/global/PastePage.cpp similarity index 51% rename from launcher/ui/pages/global/PasteEEPage.cpp rename to launcher/ui/pages/global/PastePage.cpp index 4b375d9a..7c69e1a4 100644 --- a/launcher/ui/pages/global/PasteEEPage.cpp +++ b/launcher/ui/pages/global/PastePage.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2021 MultiMC Contributors +/* Copyright 2013-2021 MultiMC & PolyMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,69 +13,51 @@ * limitations under the License. */ -#include "PasteEEPage.h" -#include "ui_PasteEEPage.h" +#include "PastePage.h" +#include "ui_PastePage.h" #include #include #include #include +#include #include "settings/SettingsObject.h" #include "tools/BaseProfiler.h" #include "Application.h" -PasteEEPage::PasteEEPage(QWidget *parent) : +PastePage::PastePage(QWidget *parent) : QWidget(parent), - ui(new Ui::PasteEEPage) + ui(new Ui::PastePage) { + static QRegularExpression validUrlRegExp("https?://.+"); ui->setupUi(this); + ui->urlChoices->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->urlChoices)); ui->tabWidget->tabBar()->hide();\ - connect(ui->customAPIkeyEdit, &QLineEdit::textEdited, this, &PasteEEPage::textEdited); loadSettings(); } -PasteEEPage::~PasteEEPage() +PastePage::~PastePage() { delete ui; } -void PasteEEPage::loadSettings() +void PastePage::loadSettings() { auto s = APPLICATION->settings(); - QString keyToUse = s->get("PasteEEAPIKey").toString(); - if(keyToUse == "multimc") - { - ui->multimcButton->setChecked(true); - } - else - { - ui->customButton->setChecked(true); - ui->customAPIkeyEdit->setText(keyToUse); - } + QString pastebinURL = s->get("PastebinURL").toString(); + ui->urlChoices->setCurrentText(pastebinURL); } -void PasteEEPage::applySettings() +void PastePage::applySettings() { auto s = APPLICATION->settings(); - - QString pasteKeyToUse; - if (ui->customButton->isChecked()) - pasteKeyToUse = ui->customAPIkeyEdit->text(); - else - { - pasteKeyToUse = "multimc"; - } - s->set("PasteEEAPIKey", pasteKeyToUse); + QString pastebinURL = ui->urlChoices->currentText(); + s->set("PastebinURL", pastebinURL); } -bool PasteEEPage::apply() +bool PastePage::apply() { applySettings(); return true; } - -void PasteEEPage::textEdited(const QString& text) -{ - ui->customButton->setChecked(true); -} diff --git a/launcher/ui/pages/global/PasteEEPage.h b/launcher/ui/pages/global/PastePage.h similarity index 84% rename from launcher/ui/pages/global/PasteEEPage.h rename to launcher/ui/pages/global/PastePage.h index a1c7d434..d475dfd9 100644 --- a/launcher/ui/pages/global/PasteEEPage.h +++ b/launcher/ui/pages/global/PastePage.h @@ -21,16 +21,16 @@ #include namespace Ui { -class PasteEEPage; +class PastePage; } -class PasteEEPage : public QWidget, public BasePage +class PastePage : public QWidget, public BasePage { Q_OBJECT public: - explicit PasteEEPage(QWidget *parent = 0); - ~PasteEEPage(); + explicit PastePage(QWidget *parent = 0); + ~PastePage(); QString displayName() const override { @@ -54,9 +54,7 @@ private: void loadSettings(); void applySettings(); -private slots: - void textEdited(const QString &text); - private: - Ui::PasteEEPage *ui; + Ui::PastePage *ui; }; + diff --git a/launcher/ui/pages/global/PasteEEPage.ui b/launcher/ui/pages/global/PastePage.ui similarity index 61% rename from launcher/ui/pages/global/PasteEEPage.ui rename to launcher/ui/pages/global/PastePage.ui index 10883781..2d13a765 100644 --- a/launcher/ui/pages/global/PasteEEPage.ui +++ b/launcher/ui/pages/global/PastePage.ui @@ -1,7 +1,7 @@ - PasteEEPage - + PastePage + 0 @@ -36,39 +36,9 @@ - paste.ee API key + Pastebin URL - - - - - MultiMC key - 12MB &upload limit - - - pasteButtonGroup - - - - - - - &Your own key - 12MB upload limit: - - - pasteButtonGroup - - - - - - - QLineEdit::Password - - - Paste your API key here! - - - + @@ -76,10 +46,45 @@ + + + + + 10 + + + + <html><head/><body><p>Note: only input that starts with <span style=" font-weight:600;">http://</span> or <span style=" font-weight:600;">https://</span> will be accepted.</p></body></html> + + + false + + + + + + + true + + + QComboBox::NoInsert + + + + https://0x0.st + + + + + https://paste.polymc.org + + + + - <html><head/><body><p><a href="https://paste.ee">paste.ee</a> is used by MultiMC for log uploads. If you have a <a href="https://paste.ee">paste.ee</a> account, you can add your API key here and have your uploaded logs paired with your account.</p></body></html> + <html><head/><body><p>Here you can choose from a predefined list of paste services, or input the URL of a different paste service of your choice, provided it supports the same protocol as 0x0.st, that is POST a file parameter to the URL and return a link in the response body.</p></body></html> Qt::RichText @@ -116,13 +121,7 @@ tabWidget - multimcButton - customButton - customAPIkeyEdit - - - diff --git a/launcher/ui/pages/instance/LogPage.ui b/launcher/ui/pages/instance/LogPage.ui index ccfc1551..31bb368c 100644 --- a/launcher/ui/pages/instance/LogPage.ui +++ b/launcher/ui/pages/instance/LogPage.ui @@ -100,7 +100,7 @@ - Upload the log to paste.ee - it will stay online for a month + Upload the log to the paste service configured in preferences Upload diff --git a/launcher/ui/pages/instance/OtherLogsPage.ui b/launcher/ui/pages/instance/OtherLogsPage.ui index 56ff3b62..77f3e647 100644 --- a/launcher/ui/pages/instance/OtherLogsPage.ui +++ b/launcher/ui/pages/instance/OtherLogsPage.ui @@ -84,7 +84,7 @@ - Upload the log to paste.ee - it will stay online for a month + Upload the log to the paste service configured in preferences. Upload