diff --git a/src/plugins/cpaster/cpaster.pro b/src/plugins/cpaster/cpaster.pro index 38c0a6e9d13..6760aeef5c2 100644 --- a/src/plugins/cpaster/cpaster.pro +++ b/src/plugins/cpaster/cpaster.pro @@ -17,7 +17,9 @@ HEADERS += cpasterplugin.h \ pasteselectdialog.h \ columnindicatortextedit.h \ fileshareprotocol.h \ - fileshareprotocolsettingspage.h + fileshareprotocolsettingspage.h \ + kdepasteprotocol.h + SOURCES += cpasterplugin.cpp \ settingspage.cpp \ protocol.cpp \ @@ -31,7 +33,9 @@ SOURCES += cpasterplugin.cpp \ pasteselectdialog.cpp \ columnindicatortextedit.cpp \ fileshareprotocol.cpp \ - fileshareprotocolsettingspage.cpp + fileshareprotocolsettingspage.cpp \ + kdepasteprotocol.cpp + FORMS += settingspage.ui \ pasteselect.ui \ pasteview.ui \ diff --git a/src/plugins/cpaster/cpasterplugin.cpp b/src/plugins/cpaster/cpasterplugin.cpp index 8d7a9d44189..9308be349b4 100644 --- a/src/plugins/cpaster/cpasterplugin.cpp +++ b/src/plugins/cpaster/cpasterplugin.cpp @@ -35,6 +35,7 @@ #include "splitter.h" #include "pasteview.h" #include "codepasterprotocol.h" +#include "kdepasteprotocol.h" #include "pastebindotcomprotocol.h" #include "pastebindotcaprotocol.h" #include "fileshareprotocol.h" @@ -136,6 +137,7 @@ bool CodepasterPlugin::initialize(const QStringList &arguments, QString *errorMe const QSharedPointer networkAccessMgrProxy(new NetworkAccessManagerProxy); Protocol *protos[] = { new PasteBinDotComProtocol(networkAccessMgrProxy), new PasteBinDotCaProtocol(networkAccessMgrProxy), + new KdePasteProtocol(networkAccessMgrProxy), new CodePasterProtocol(networkAccessMgrProxy), new FileShareProtocol }; diff --git a/src/plugins/cpaster/kdepasteprotocol.cpp b/src/plugins/cpaster/kdepasteprotocol.cpp new file mode 100644 index 00000000000..0b366b793bb --- /dev/null +++ b/src/plugins/cpaster/kdepasteprotocol.cpp @@ -0,0 +1,242 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "kdepasteprotocol.h" + +#include + +#include +#include +#include +#include +#include + +#include + +enum { debug = 0 }; + +static const char hostNameC[]= "paste.kde.org"; +static const char hostUrlC[]= "http://paste.kde.org/"; +static const char formatC[]= "xml"; +static const char showPhpScriptpC[] = "show.php"; + +enum { expirySeconds = 86400 }; + +namespace CodePaster { +KdePasteProtocol::KdePasteProtocol(const NetworkAccessManagerProxyPtr &nw) : + NetworkProtocol(nw), + m_fetchReply(0), + m_pasteReply(0), + m_listReply(0), + m_fetchId(-1), + m_postId(-1), + m_hostChecked(false) +{ +} + +QString KdePasteProtocol::protocolName() +{ + return QLatin1String("Paste.KDE.Org"); +} + +unsigned KdePasteProtocol::capabilities() const +{ + return ListCapability; +} + +bool KdePasteProtocol::checkConfiguration(QString *errorMessage) +{ + if (m_hostChecked) // Check the host once. + return true; + const bool ok = httpStatus(QLatin1String(hostNameC), errorMessage); + if (ok) + m_hostChecked = true; + return ok; +} + +static inline QByteArray pasteLanguage(Protocol::ContentType ct) +{ + switch (ct) { + case Protocol::Text: + break; + case Protocol::C: + return "paste_lang=c++"; + break; + case Protocol::JavaScript: + return "paste_lang=Javascript"; + break; + case Protocol::Diff: + return "paste_lang=Diff"; + case Protocol::Xml: + return "paste_lang=XML"; + } + return QByteArray("paste_lang=text"); +} + +void KdePasteProtocol::paste(const QString &text, + ContentType ct, + const QString &username, + const QString & /* comment */, + const QString & /* description */) +{ + QTC_ASSERT(!m_pasteReply, return;) + + // Format body + QByteArray pasteData = "api_submit=true&mode="; + pasteData += formatC; + if (!username.isEmpty()) { + pasteData += "&paste_user="; + pasteData += QUrl::toPercentEncoding(username); + } + pasteData += "&paste_data="; + pasteData += QUrl::toPercentEncoding(fixNewLines(text)); + pasteData += "&paste_expire="; + pasteData += QByteArray::number(expirySeconds); + pasteData += '&'; + pasteData += pasteLanguage(ct); + + m_pasteReply = httpPost(QLatin1String(hostUrlC), pasteData); + connect(m_pasteReply, SIGNAL(finished()), this, SLOT(pasteFinished())); + if (debug) + qDebug() << "paste: sending " << m_pasteReply << pasteData; +} + +// Parse for an element and return its contents +static QString parseElement(QIODevice *device, const QString &elementName) +{ + QXmlStreamReader reader(device); + while (!reader.atEnd()) { + if (reader.readNext() == QXmlStreamReader::StartElement + && reader.name() == elementName) + return reader.readElementText(); + } + return QString(); +} + +void KdePasteProtocol::pasteFinished() +{ + if (m_pasteReply->error()) { + qWarning("%s protocol error: %s", qPrintable(protocolName()),qPrintable(m_pasteReply->errorString())); + } else { + // Parse id from '143204' + // No useful error reports have been observed. + const QString id = parseElement(m_pasteReply, QLatin1String("id")); + if (id.isEmpty()) { + qWarning("%s protocol error: Could not send entry.", qPrintable(protocolName())); + } else { + emit pasteDone(QLatin1String(hostUrlC) + id); + } + } + + m_pasteReply->deleteLater(); + m_pasteReply = 0; +} + +void KdePasteProtocol::fetch(const QString &id) +{ + QTC_ASSERT(!m_fetchReply, return;) + + // Did we get a complete URL or just an id? + m_fetchId = id; + const int lastSlashPos = m_fetchId.lastIndexOf(QLatin1Char('/')); + if (lastSlashPos != -1) + m_fetchId.remove(0, lastSlashPos + 1); + QString url; + QTextStream(&url) << hostUrlC << showPhpScriptpC + << "?format=" << formatC << "&id=" << m_fetchId; + if (debug) + qDebug() << "fetch: sending " << url; + + m_fetchReply = httpGet(url); + connect(m_fetchReply, SIGNAL(finished()), this, SLOT(fetchFinished())); +} + +// Parse: '143228foo1320661026text +// bar' + +void KdePasteProtocol::fetchFinished() +{ + const QString title = protocolName() + QLatin1String(": ") + m_fetchId; + QString content; + const bool error = m_fetchReply->error(); + if (error) { + content = m_fetchReply->errorString(); + if (debug) + qDebug() << "fetchFinished: error" << m_fetchId << content; + } else { + content = parseElement(m_fetchReply, QLatin1String("data")); + content.remove(QLatin1Char('\r')); + } + m_fetchReply->deleteLater(); + m_fetchReply = 0; + emit fetchDone(title, content, error); +} + +void KdePasteProtocol::list() +{ + QTC_ASSERT(!m_listReply, return;) + + QString url; + QTextStream(&url) << hostUrlC << "api/" << formatC << "/all?format=" << formatC; + m_listReply = httpGet(url); + connect(m_listReply, SIGNAL(finished()), this, SLOT(listFinished())); + if (debug) + qDebug() << "list: sending " << url << m_listReply; +} + +// Parse 'result>id1id2...' +static inline QStringList parseList(QIODevice *device) +{ + QStringList result; + QXmlStreamReader reader(device); + const QString pasteElementPrefix = QLatin1String("paste_"); + while (!reader.atEnd()) { + if (reader.readNext() == QXmlStreamReader::StartElement && reader.name().startsWith(pasteElementPrefix)) + result.append(reader.readElementText()); + } + return result; +} + +void KdePasteProtocol::listFinished() +{ + const bool error = m_listReply->error(); + if (error) { + if (debug) + qDebug() << "listFinished: error" << m_listReply->errorString(); + } else { + emit listDone(name(), parseList(m_listReply)); + } + m_listReply->deleteLater(); + m_listReply = 0; +} + +} // namespace CodePaster diff --git a/src/plugins/cpaster/kdepasteprotocol.h b/src/plugins/cpaster/kdepasteprotocol.h new file mode 100644 index 00000000000..982cd5813f1 --- /dev/null +++ b/src/plugins/cpaster/kdepasteprotocol.h @@ -0,0 +1,79 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef KDEPASTE_H +#define KDEPASTE_H + +#include "protocol.h" + +namespace CodePaster { + +class KdePasteProtocol : public NetworkProtocol +{ + Q_OBJECT +public: + explicit KdePasteProtocol(const NetworkAccessManagerProxyPtr &nw); + + static QString protocolName(); + QString name() const { return protocolName(); } + + virtual unsigned capabilities() const; + + virtual void fetch(const QString &id); + virtual void paste(const QString &text, + ContentType ct = Text, + const QString &username = QString(), + const QString &comment = QString(), + const QString &description = QString()); + virtual void list(); + +public slots: + void fetchFinished(); + void pasteFinished(); + void listFinished(); + +protected: + virtual bool checkConfiguration(QString *errorMessage = 0); + +private: + QNetworkReply *m_fetchReply; + QNetworkReply *m_pasteReply; + QNetworkReply *m_listReply; + + QString m_fetchId; + int m_postId; + bool m_hostChecked; +}; + +} // namespace CodePaster + +#endif // KDEPASTE_H