diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2018-08-30 17:13:54 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2018-08-31 08:53:53 +0000 |
commit | fc1ecd6f8291f6082598fdc6b7a7eccd20f3a06a (patch) | |
tree | a7b6f96eea19866727ae3513d9c3126fb35b16ff /src/plugins/cpaster | |
parent | 06f3e959d353ec228b827721db57e48b678084d3 (diff) | |
download | qt-creator-fc1ecd6f8291f6082598fdc6b7a7eccd20f3a06a.tar.gz |
CodePaster: Add support for pastecode.xyz
Our users are running out of choices for code pasting: KDE has required
an account for quite a while now, and pastebin.ca appears to be offline,
leaving them only with the ad-heavy pastebin.com.
Therefore, we add support for a new site: pastecode.xyz seems
responsive enough, has a simple API and has been around for a bit.
[ChangeLog] Added support for the pastecode.xyz code pasting service
Change-Id: I9b622853df24c28d65c6e388f953c82fc5380fae
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src/plugins/cpaster')
-rw-r--r-- | src/plugins/cpaster/cpaster.pro | 2 | ||||
-rw-r--r-- | src/plugins/cpaster/cpaster.qbs | 2 | ||||
-rw-r--r-- | src/plugins/cpaster/cpasterplugin.cpp | 4 | ||||
-rw-r--r-- | src/plugins/cpaster/frontend/frontend.pro | 2 | ||||
-rw-r--r-- | src/plugins/cpaster/frontend/frontend.qbs | 1 | ||||
-rw-r--r-- | src/plugins/cpaster/frontend/main.cpp | 6 | ||||
-rw-r--r-- | src/plugins/cpaster/pastecodedotxyzprotocol.cpp | 147 | ||||
-rw-r--r-- | src/plugins/cpaster/pastecodedotxyzprotocol.h | 57 |
8 files changed, 219 insertions, 2 deletions
diff --git a/src/plugins/cpaster/cpaster.pro b/src/plugins/cpaster/cpaster.pro index 20c85c596b..6a06056530 100644 --- a/src/plugins/cpaster/cpaster.pro +++ b/src/plugins/cpaster/cpaster.pro @@ -7,6 +7,7 @@ HEADERS += cpasterplugin.h \ cpasterconstants.h \ pastebindotcomprotocol.h \ pastebindotcaprotocol.h \ + pastecodedotxyzprotocol.h \ settings.h \ pasteselectdialog.h \ columnindicatortextedit.h \ @@ -23,6 +24,7 @@ SOURCES += cpasterplugin.cpp \ pasteview.cpp \ pastebindotcomprotocol.cpp \ pastebindotcaprotocol.cpp \ + pastecodedotxyzprotocol.cpp \ settings.cpp \ pasteselectdialog.cpp \ columnindicatortextedit.cpp \ diff --git a/src/plugins/cpaster/cpaster.qbs b/src/plugins/cpaster/cpaster.qbs index 694e495f43..35bb876034 100644 --- a/src/plugins/cpaster/cpaster.qbs +++ b/src/plugins/cpaster/cpaster.qbs @@ -31,6 +31,8 @@ QtcPlugin { "pastebindotcomprotocol.cpp", "pastebindotcomprotocol.h", "pastebindotcomsettings.ui", + "pastecodedotxyzprotocol.cpp", + "pastecodedotxyzprotocol.h", "pasteselect.ui", "pasteselectdialog.cpp", "pasteselectdialog.h", diff --git a/src/plugins/cpaster/cpasterplugin.cpp b/src/plugins/cpaster/cpasterplugin.cpp index ef3d4cae5a..4a512c2edf 100644 --- a/src/plugins/cpaster/cpasterplugin.cpp +++ b/src/plugins/cpaster/cpasterplugin.cpp @@ -29,6 +29,7 @@ #include "kdepasteprotocol.h" #include "pastebindotcomprotocol.h" #include "pastebindotcaprotocol.h" +#include "pastecodedotxyzprotocol.h" #include "fileshareprotocol.h" #include "pasteselectdialog.h" #include "settingspage.h" @@ -122,7 +123,8 @@ bool CodepasterPlugin::initialize(const QStringList &arguments, QString *errorMe Protocol *protos[] = {new PasteBinDotComProtocol, new PasteBinDotCaProtocol, new KdePasteProtocol, - new FileShareProtocol + new FileShareProtocol, + new PasteCodeDotXyzProtocol, }; const int count = sizeof(protos) / sizeof(Protocol *); for (int i = 0; i < count; ++i) { diff --git a/src/plugins/cpaster/frontend/frontend.pro b/src/plugins/cpaster/frontend/frontend.pro index d414abce9b..70d2e4339d 100644 --- a/src/plugins/cpaster/frontend/frontend.pro +++ b/src/plugins/cpaster/frontend/frontend.pro @@ -14,6 +14,7 @@ HEADERS = ../protocol.h \ ../cpasterconstants.h \ ../pastebindotcomprotocol.h \ ../pastebindotcaprotocol.h \ + ../pastecodedotxyzprotocol.h \ ../kdepasteprotocol.h \ ../urlopenprotocol.h \ argumentscollector.h @@ -21,6 +22,7 @@ HEADERS = ../protocol.h \ SOURCES += ../protocol.cpp \ ../pastebindotcomprotocol.cpp \ ../pastebindotcaprotocol.cpp \ + ../pastecodedotxyzprotocol.cpp \ ../kdepasteprotocol.cpp \ ../urlopenprotocol.cpp \ argumentscollector.cpp \ diff --git a/src/plugins/cpaster/frontend/frontend.qbs b/src/plugins/cpaster/frontend/frontend.qbs index 552ac57375..385c2121a1 100644 --- a/src/plugins/cpaster/frontend/frontend.qbs +++ b/src/plugins/cpaster/frontend/frontend.qbs @@ -26,6 +26,7 @@ QtcTool { "kdepasteprotocol.h", "kdepasteprotocol.cpp", "pastebindotcaprotocol.h", "pastebindotcaprotocol.cpp", "pastebindotcomprotocol.h", "pastebindotcomprotocol.cpp", + "pastecodedotxyzprotocol.h", "pastecodedotxyzprotocol.cpp", "protocol.h", "protocol.cpp", "urlopenprotocol.h", "urlopenprotocol.cpp", ] diff --git a/src/plugins/cpaster/frontend/main.cpp b/src/plugins/cpaster/frontend/main.cpp index 2789ebdb51..05faa18845 100644 --- a/src/plugins/cpaster/frontend/main.cpp +++ b/src/plugins/cpaster/frontend/main.cpp @@ -27,6 +27,7 @@ #include "../kdepasteprotocol.h" #include "../pastebindotcaprotocol.h" #include "../pastebindotcomprotocol.h" +#include "../pastecodedotxyzprotocol.h" #include <QFile> #include <QObject> @@ -52,6 +53,8 @@ public: m_protocol.reset(new PasteBinDotCaProtocol); else if (protocol == PasteBinDotComProtocol::protocolName().toLower()) m_protocol.reset(new PasteBinDotComProtocol); + else if (protocol == PasteCodeDotXyzProtocol::protocolName().toLower()) + m_protocol.reset(new PasteCodeDotXyzProtocol); else qFatal("Internal error: Invalid protocol."); } @@ -93,7 +96,8 @@ int main(int argc, char *argv[]) const QStringList protocols = {KdePasteProtocol::protocolName().toLower(), PasteBinDotCaProtocol::protocolName().toLower(), - PasteBinDotComProtocol::protocolName().toLower()}; + PasteBinDotComProtocol::protocolName().toLower(), + PasteCodeDotXyzProtocol::protocolName().toLower()}; ArgumentsCollector argsCollector(protocols); QStringList arguments = QCoreApplication::arguments(); arguments.removeFirst(); diff --git a/src/plugins/cpaster/pastecodedotxyzprotocol.cpp b/src/plugins/cpaster/pastecodedotxyzprotocol.cpp new file mode 100644 index 0000000000..e2ed3a1b04 --- /dev/null +++ b/src/plugins/cpaster/pastecodedotxyzprotocol.cpp @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "pastecodedotxyzprotocol.h" + +#include <coreplugin/messagemanager.h> + +#include <QJsonArray> +#include <QJsonDocument> +#include <QJsonObject> +#include <QJsonParseError> +#include <QJsonValue> +#include <QNetworkReply> +#include <QUrl> + +namespace CodePaster { + +static QString baseUrl() { return "https://pastecode.xyz"; } +static QString apiUrl() { return baseUrl() + "/api"; } + +QString PasteCodeDotXyzProtocol::protocolName() { return "Pastecode.Xyz"; } + +unsigned PasteCodeDotXyzProtocol::capabilities() const +{ + return ListCapability | PostDescriptionCapability | PostUserNameCapability; +} + +void PasteCodeDotXyzProtocol::fetch(const QString &id) +{ + QNetworkReply * const reply = httpGet(baseUrl() + "/view/raw/" + id); + connect(reply, &QNetworkReply::finished, this, [this, id, reply] { + QString title; + QString content; + const bool error = reply->error(); + if (error) { + content = reply->errorString(); + } else { + title = name() + ": " + id; + content = QString::fromUtf8(reply->readAll()); + } + reply->deleteLater(); + emit fetchDone(title, content, error); + }); +} + +void PasteCodeDotXyzProtocol::paste(const QString &text, Protocol::ContentType ct, int expiryDays, + const QString &username, const QString &comment, + const QString &description) +{ + QByteArray data; + data += "text=" + QUrl::toPercentEncoding(fixNewLines(text)); + data += "&expire=" + QUrl::toPercentEncoding(QString::number(expiryDays * 24 * 60)); + data += "&title=" + QUrl::toPercentEncoding(description); + data += "&name=" + QUrl::toPercentEncoding(username); + static const auto langValue = [](Protocol::ContentType type) -> QByteArray { + switch (type) { + case Protocol::Text: return "text"; + case Protocol::C: return "c"; + case Protocol::Cpp: return "cpp"; + case Protocol::JavaScript: return "javascript"; + case Protocol::Diff: return "diff"; + case Protocol::Xml: return "xml"; + } + return QByteArray(); // Crutch for compiler. + }; + data += "&lang=" + langValue(ct); + Q_UNUSED(comment); + + QNetworkReply * const reply = httpPost(apiUrl() + "/create", data); + connect(reply, &QNetworkReply::finished, this, [this, reply] { + QString data; + if (reply->error()) { + reportError(reply->errorString()); // FIXME: Why can't we properly emit an error here? + } else { + data = QString::fromUtf8(reply->readAll()); + if (!data.startsWith(baseUrl())) { + reportError(data); + data.clear(); + } + } + reply->deleteLater(); + emit pasteDone(data); + }); +} + +void PasteCodeDotXyzProtocol::list() +{ + QNetworkReply * const reply = httpGet(apiUrl() + "/recent"); + connect(reply, &QNetworkReply::finished, this, [this, reply] { + QStringList ids; + if (reply->error()) { + reportError(reply->errorString()); + } else { + QJsonParseError parseError; + const QJsonDocument jsonData = QJsonDocument::fromJson(reply->readAll(), &parseError); + if (parseError.error != QJsonParseError::NoError) { + reportError(parseError.errorString()); + } else { + const QJsonArray jsonList = jsonData.array(); + for (auto it = jsonList.constBegin(); it != jsonList.constEnd(); ++it) { + const QString id = it->toObject().value("pid").toString(); + if (!id.isEmpty()) + ids << id; + } + } + } + emit listDone(name(), ids); + reply->deleteLater(); + }); +} + +bool PasteCodeDotXyzProtocol::checkConfiguration(QString *errorMessage) +{ + if (!m_hostKnownOk) + m_hostKnownOk = httpStatus(apiUrl(), errorMessage); + return m_hostKnownOk; +} + +void PasteCodeDotXyzProtocol::reportError(const QString &message) +{ + const QString fullMessage = tr("%1: %2").arg(protocolName(), message); + Core::MessageManager::write(fullMessage, Core::MessageManager::ModeSwitch); +} + +} // namespace CodePaster diff --git a/src/plugins/cpaster/pastecodedotxyzprotocol.h b/src/plugins/cpaster/pastecodedotxyzprotocol.h new file mode 100644 index 0000000000..7988ad9dc8 --- /dev/null +++ b/src/plugins/cpaster/pastecodedotxyzprotocol.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "protocol.h" + +namespace CodePaster { + +class PasteCodeDotXyzProtocol : public NetworkProtocol +{ + Q_OBJECT +public: + static QString protocolName(); + +private: + QString name() const override { return protocolName(); } + bool hasSettings() const override { return false; } + unsigned capabilities() const override; + void fetch(const QString &id) override; + void paste(const QString &text, + ContentType ct = Text, + int expiryDays = 1, + const QString &username = QString(), + const QString &comment = QString(), + const QString &description = QString()) override; + void list() override; + bool checkConfiguration(QString *errorMessage) override; + + static void reportError(const QString &message); + + bool m_hostKnownOk = false; +}; + +} // namespace CodePaster |