From b1683641d46c885975bbe0f1a2c0c494fcd95148 Mon Sep 17 00:00:00 2001
From: Tobias Hunger <tobias.hunger@nokia.com>
Date: Mon, 5 Mar 2012 11:47:16 +0100
Subject: [PATCH] CPaster: Fix pastebin.com

* Update to new API
* remove unnecessary settings page (pastebin no longer offers subdomains)
* Set post expiration to one month

Change-Id: Ic9947e7227858b87e5dab15c3ce15366004a10c7
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
---
 src/plugins/cpaster/cpaster.pro               |   2 -
 .../cpaster/pastebindotcomprotocol.cpp        | 189 +++++++-----------
 src/plugins/cpaster/pastebindotcomprotocol.h  |   9 -
 .../cpaster/pastebindotcomsettings.cpp        | 108 ----------
 src/plugins/cpaster/pastebindotcomsettings.h  |  73 -------
 5 files changed, 76 insertions(+), 305 deletions(-)
 delete mode 100644 src/plugins/cpaster/pastebindotcomsettings.cpp
 delete mode 100644 src/plugins/cpaster/pastebindotcomsettings.h

diff --git a/src/plugins/cpaster/cpaster.pro b/src/plugins/cpaster/cpaster.pro
index 0d5e29929a3..407075b1df9 100644
--- a/src/plugins/cpaster/cpaster.pro
+++ b/src/plugins/cpaster/cpaster.pro
@@ -12,7 +12,6 @@ HEADERS += cpasterplugin.h \
     cpasterconstants.h \
     codepastersettings.h \
     pastebindotcomprotocol.h \
-    pastebindotcomsettings.h \
     pastebindotcaprotocol.h \
     settings.h \
     pasteselectdialog.h \
@@ -28,7 +27,6 @@ SOURCES += cpasterplugin.cpp \
     pasteview.cpp \
     codepastersettings.cpp \
     pastebindotcomprotocol.cpp \
-    pastebindotcomsettings.cpp \
     pastebindotcaprotocol.cpp \
     settings.cpp \
     pasteselectdialog.cpp \
diff --git a/src/plugins/cpaster/pastebindotcomprotocol.cpp b/src/plugins/cpaster/pastebindotcomprotocol.cpp
index c94358fe0b3..9cd8dc6ed0d 100644
--- a/src/plugins/cpaster/pastebindotcomprotocol.cpp
+++ b/src/plugins/cpaster/pastebindotcomprotocol.cpp
@@ -31,13 +31,13 @@
 **************************************************************************/
 
 #include "pastebindotcomprotocol.h"
-#include "pastebindotcomsettings.h"
 
 #include <coreplugin/icore.h>
 
 #include <utils/qtcassert.h>
 
 #include <QDebug>
+#include <QStringList>
 #include <QTextStream>
 #include <QXmlStreamReader>
 #include <QXmlStreamAttributes>
@@ -47,13 +47,16 @@
 
 enum { debug = 0 };
 
-static const char pastePhpScriptpC[] = "api_public.php";
-static const char fetchPhpScriptpC[] = "raw.php";
+static const char PASTEBIN_BASE[]="http://pastebin.com/";
+static const char PASTEBIN_API[]="api/api_post.php";
+static const char PASTEBIN_RAW[]="raw.php";
+static const char PASTEBIN_ARCHIVE[]="archive";
+
+static const char API_KEY[]="api_dev_key=516686fc461fb7f9341fd7cf2af6f829&"; // user: qtcreator_apikey
 
 namespace CodePaster {
 PasteBinDotComProtocol::PasteBinDotComProtocol(const NetworkAccessManagerProxyPtr &nw) :
     NetworkProtocol(nw),
-    m_settings(new PasteBinDotComSettings),
     m_fetchReply(0),
     m_pasteReply(0),
     m_listReply(0),
@@ -73,83 +76,59 @@ unsigned PasteBinDotComProtocol::capabilities() const
     return ListCapability;
 }
 
-bool PasteBinDotComProtocol::checkConfiguration(QString *errorMessage)
-{
-    if (m_hostChecked)  // Check the host once.
-        return true;
-    const bool ok = httpStatus(hostName(false), errorMessage);
-    if (ok)
-        m_hostChecked = true;
-    return ok;
-}
-
-QString PasteBinDotComProtocol::hostName(bool withSubDomain) const
-{
-
-    QString rc;
-    if (withSubDomain) {
-        rc = m_settings->hostPrefix();
-        if (!rc.isEmpty())
-            rc.append(QLatin1Char('.'));
-    }
-    rc.append(QLatin1String("pastebin.com"));
-    return rc;
-}
-
 static inline QByteArray format(Protocol::ContentType ct)
 {
+    QByteArray format = "api_paste_format=";
     switch (ct) {
-    case Protocol::Text:
-        break;
     case Protocol::C:
-    case Protocol::Cpp:
-        return "paste_format=cpp";
+        format += 'c';
         break;
+    case Protocol::Cpp:
+        format += "cpp-qt";
     case Protocol::JavaScript:
-        return "paste_format=javascript";
+        format += "javascript";
         break;
     case Protocol::Diff:
-        return "paste_format=diff"; // v3.X 'dff' -> 'diff'
+        format += "diff";
         break;
     case Protocol::Xml:
-        return "paste_format=xml";
+        format += "xml";
         break;
+    case Protocol::Text:
+        // fallthrough!
+    default:
+        format += "text";
     }
-    return QByteArray();
+    format += '&';
+    return format;
 }
 
 void PasteBinDotComProtocol::paste(const QString &text,
                                    ContentType ct,
                                    const QString &username,
-                                   const QString & /* comment */,
-                                   const QString & /* description */)
+                                   const QString &comment,
+                                   const QString &description)
 {
-    QTC_ASSERT(!m_pasteReply, return;)
+    Q_UNUSED(comment);
+    Q_UNUSED(description);
+    QTC_ASSERT(!m_pasteReply, return);
 
     // Format body
-    QByteArray pasteData = format(ct);
-    if (!pasteData.isEmpty())
-        pasteData.append('&');
-    pasteData += "paste_name=";
+    QByteArray pasteData = API_KEY;
+    pasteData += "api_option=paste&";
+    pasteData += "api_paste_expire_date=1M&";
+    pasteData += format(ct);
+    pasteData += "api_paste_name=";
     pasteData += QUrl::toPercentEncoding(username);
 
-    const QString subDomain = m_settings->hostPrefix();
-    if (!subDomain.isEmpty()) {
-        pasteData += "&paste_subdomain=";
-        pasteData += QUrl::toPercentEncoding(subDomain);
-    }
-
-    pasteData += "&paste_code=";
+    pasteData += "&api_paste_code=";
     pasteData += QUrl::toPercentEncoding(fixNewLines(text));
 
     // fire request
-    QString link;
-    QTextStream(&link) << "http://" << hostName(false) << '/' << pastePhpScriptpC;
-
-    m_pasteReply = httpPost(link, pasteData);
+    m_pasteReply = httpPost(QLatin1String(PASTEBIN_BASE) + QLatin1String(PASTEBIN_API), pasteData);
     connect(m_pasteReply, SIGNAL(finished()), this, SLOT(pasteFinished()));
     if (debug)
-        qDebug() << "paste: sending " << m_pasteReply << link << pasteData;
+        qDebug() << "paste: sending " << m_pasteReply << pasteData;
 }
 
 void PasteBinDotComProtocol::pasteFinished()
@@ -166,21 +145,14 @@ void PasteBinDotComProtocol::pasteFinished()
 
 void PasteBinDotComProtocol::fetch(const QString &id)
 {
-    const QString httpProtocolPrefix = QLatin1String("http://");
-
-    QTC_ASSERT(!m_fetchReply, return;)
-
     // Did we get a complete URL or just an id. Insert a call to the php-script
-    QString link;
-    if (id.startsWith(httpProtocolPrefix)) {
-        // Change "http://host/id" -> "http://host/script?i=id".
-        const int lastSlashPos = id.lastIndexOf(QLatin1Char('/'));
-        link = id.mid(0, lastSlashPos);
-        QTextStream(&link) << '/' << fetchPhpScriptpC<< "?i=" << id.mid(lastSlashPos + 1);
-    } else {
-        // format "http://host/script?i=id".
-        QTextStream(&link) << "http://" << hostName(true) << '/' << fetchPhpScriptpC<< "?i=" << id;
-    }
+    QString link = QLatin1String(PASTEBIN_BASE) + QLatin1String(PASTEBIN_RAW);
+    link.append(QLatin1String("?i="));
+
+    if (id.startsWith(QLatin1String("http://")))
+        link.append(id.mid(id.lastIndexOf(QLatin1Char('/')) + 1));
+    else
+        link.append(id);
 
     if (debug)
         qDebug() << "fetch: sending " << link;
@@ -227,10 +199,9 @@ void PasteBinDotComProtocol::fetchFinished()
 
 void PasteBinDotComProtocol::list()
 {
-    QTC_ASSERT(!m_listReply, return;)
+    QTC_ASSERT(!m_listReply, return);
 
-    // fire request
-    const QString url = QLatin1String("http://") + hostName(true) + QLatin1String("/archive");
+    const QString url = QLatin1String(PASTEBIN_BASE) + QLatin1String(PASTEBIN_ARCHIVE);
     m_listReply = httpGet(url);
     connect(m_listReply, SIGNAL(finished()), this, SLOT(listFinished()));
     if (debug)
@@ -245,27 +216,20 @@ static inline void padString(QString *s, int len)
 }
 
 /* Quick & dirty: Parse out the 'archive' table as of 16.3.2011:
-\code
- <table class="maintable" cellspacing="0">
-   <tr class="top">
-    <th scope="col" align="left">Name / Title</th>
-    <th scope="col" align="left">Posted</th>
-    <th scope="col" align="left">Expires</th>
-    <th scope="col" align="left">Size</th>
-    <th scope="col" align="left">Syntax</th>
-    <th scope="col" align="left">User</th>
-   </tr>
-   <tr class="g">
-    <td class="icon"><a href="/8ZRqkcaP">Untitled</a></td>
-    <td>2 sec ago</td>
-    <td>Never</td>
-    <td>9.41 KB</td>
-    <td><a href="/archive/text">None</a></td>
-    <td>a guest</td>
-   </tr>
-   <tr>
-\endcode */
-
+ \code
+<table class="maintable" cellspacing="0">
+    <tr class="top">
+        <th scope="col" align="left">Name / Title</th>
+        <th scope="col" align="left">Posted</th>
+        <th scope="col" align="right">Syntax</th>
+    </tr>
+    <tr>
+        <td><img src="/i/t.gif"  class="i_p0" alt="" border="0" /><a href="/cvWciF4S">Vector 1</a></td>
+        <td>2 sec ago</td>
+        <td align="right"><a href="/archive/cpp">C++</a></td>
+    </tr>
+    ...
+-\endcode */
 enum ParseState
 {
     OutSideTable, WithinTable, WithinTableRow, WithinTableHeaderElement,
@@ -282,7 +246,7 @@ QDebug operator<<(QDebug d, const QXmlStreamAttributes &al)
 
 static inline ParseState nextOpeningState(ParseState current, const QXmlStreamReader &reader)
 {
-    const QStringRef element = reader.name();
+    const QStringRef &element = reader.name();
     switch (current) {
     case OutSideTable:
         // Trigger on main table only.
@@ -301,6 +265,8 @@ static inline ParseState nextOpeningState(ParseState current, const QXmlStreamRe
             return WithinTableHeaderElement;
         break;
     case WithinTableElement:
+        if (element == QLatin1String("img"))
+            return WithinTableElement;
         if (element == QLatin1String("a"))
             return WithinTableElementAnchor;
         break;
@@ -328,6 +294,8 @@ static inline ParseState nextClosingState(ParseState current, const QStringRef &
     case WithinTableElement:
         if (element == QLatin1String("td"))
             return WithinTableRow;
+        if (element == QLatin1String("img"))
+            return WithinTableElement;
         break;
     case WithinTableHeaderElement:
         if (element == QLatin1String("th"))
@@ -337,10 +305,10 @@ static inline ParseState nextClosingState(ParseState current, const QStringRef &
         if (element == QLatin1String("a"))
             return WithinTableElement;
         break;
-    case ParseError:
+   case ParseError:
         break;
-    }
-    return ParseError;
+   }
+   return ParseError;
 }
 
 static inline QStringList parseLists(QIODevice *io)
@@ -355,10 +323,9 @@ static inline QStringList parseLists(QIODevice *io)
 
     const QString hrefAttribute = QLatin1String("href");
     //: Unknown user of paste.
-    const QString unknownUser = PasteBinDotComProtocol::tr("<Unknown>");
     QString link;
-    QString user;
-    QString description;
+    QString title;
+    QString age;
 
     while (!reader.atEnd()) {
         switch(reader.readNext()) {
@@ -393,20 +360,21 @@ static inline QStringList parseLists(QIODevice *io)
                 break;
             case WithinTable:
                 // User can occasionally be empty.
-                if (tableRow && !link.isEmpty() && !description.isEmpty()) {
+                if (tableRow && !link.isEmpty() && !title.isEmpty() && !age.isEmpty()) {
                     QString entry = link;
                     entry += QLatin1Char(' ');
-                    entry += user.isEmpty() ? unknownUser : user;
-                    entry += QLatin1Char(' ');
-                    entry += description;
+                    entry += title;
+                    entry += QLatin1String(" (");
+                    entry += age;
+                    entry += QLatin1Char(')');
                     rc.push_back(entry);
                     if (rc.size() >= maxEntries)
                         return rc;
                 }
                 tableRow++;
-                user.clear();
+                age.clear();
                 link.clear();
-                description.clear();
+                title.clear();
                 break;
             case WithinTableRow:
                 tableColumn++;
@@ -421,14 +389,13 @@ static inline QStringList parseLists(QIODevice *io)
             break;
         case QXmlStreamReader::Characters:
             switch (state) {
-                break;
             case WithinTableElement:
-                if (tableColumn == 5)
-                    user = reader.text().toString();
+                if (tableColumn == 1)
+                    age = reader.text().toString();
                 break;
             case WithinTableElementAnchor:
                 if (tableColumn == 0)
-                    description = reader.text().toString();
+                    title = reader.text().toString();
                 break;
             default:
                 break;
@@ -457,8 +424,4 @@ void PasteBinDotComProtocol::listFinished()
     m_listReply = 0;
 }
 
-Core::IOptionsPage *PasteBinDotComProtocol::settingsPage() const
-{
-    return m_settings;
-}
 } // namespace CodePaster
diff --git a/src/plugins/cpaster/pastebindotcomprotocol.h b/src/plugins/cpaster/pastebindotcomprotocol.h
index d2ec9a69760..6a75f7070d3 100644
--- a/src/plugins/cpaster/pastebindotcomprotocol.h
+++ b/src/plugins/cpaster/pastebindotcomprotocol.h
@@ -36,7 +36,6 @@
 #include "protocol.h"
 
 namespace CodePaster {
-class PasteBinDotComSettings;
 
 class PasteBinDotComProtocol : public NetworkProtocol
 {
@@ -48,8 +47,6 @@ public:
     QString name() const { return protocolName(); }
 
     virtual unsigned capabilities() const;
-    bool hasSettings() const { return true; }
-    Core::IOptionsPage *settingsPage() const;
 
     virtual void fetch(const QString &id);
     virtual void paste(const QString &text,
@@ -64,13 +61,7 @@ public slots:
     void pasteFinished();
     void listFinished();
 
-protected:
-    virtual bool checkConfiguration(QString *errorMessage = 0);
-
 private:
-    QString hostName(bool withSubDomain) const;
-
-    PasteBinDotComSettings *m_settings;
     QNetworkReply *m_fetchReply;
     QNetworkReply *m_pasteReply;
     QNetworkReply *m_listReply;
diff --git a/src/plugins/cpaster/pastebindotcomsettings.cpp b/src/plugins/cpaster/pastebindotcomsettings.cpp
deleted file mode 100644
index f3d47bb7820..00000000000
--- a/src/plugins/cpaster/pastebindotcomsettings.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
-**
-**************************************************************************/
-
-#include "pastebindotcomsettings.h"
-#include "cpasterconstants.h"
-#include "ui_pastebindotcomsettings.h"
-
-#include <coreplugin/icore.h>
-#include <QSettings>
-#include <QCoreApplication>
-
-static const char groupC[] = "PasteBinDotComSettings";
-static const char prefixKeyC[] = "Prefix";
-
-namespace CodePaster {
-PasteBinDotComSettings::PasteBinDotComSettings()
-{
-    m_settings = Core::ICore::settings();
-    if (m_settings) {
-        const QString rootKey = QLatin1String(groupC) + QLatin1Char('/');
-        m_hostPrefix = m_settings->value(rootKey + QLatin1String(prefixKeyC), QString()).toString();
-    }
-}
-
-QString PasteBinDotComSettings::id() const
-{
-    return QLatin1String("B.Pastebin.com");
-}
-
-QString PasteBinDotComSettings::displayName() const
-{
-    return tr("Pastebin.com");
-}
-
-QString PasteBinDotComSettings::category() const
-{
-    return QLatin1String(CodePaster::Constants::CPASTER_SETTINGS_CATEGORY);
-}
-
-QString PasteBinDotComSettings::displayCategory() const
-{
-    return QCoreApplication::translate("CodePaster", CodePaster::Constants::CPASTER_SETTINGS_TR_CATEGORY);
-}
-
-QIcon PasteBinDotComSettings::categoryIcon() const
-{
-    return QIcon(); // TODO: Icon for CodePaster
-}
-
-QWidget *PasteBinDotComSettings::createPage(QWidget *parent)
-{
-    Internal::Ui::PasteBinComSettingsWidget ui;
-    QWidget *w = new QWidget(parent);
-    ui.setupUi(w);
-    ui.lineEdit->setText(hostPrefix());
-    connect(ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(serverChanged(QString)));
-    return w;
-}
-
-void PasteBinDotComSettings::apply()
-{
-    if (!m_settings)
-        return;
-
-    m_settings->beginGroup(QLatin1String(groupC));
-    m_settings->setValue(QLatin1String(prefixKeyC), m_hostPrefix);
-    m_settings->endGroup();
-}
-
-void PasteBinDotComSettings::serverChanged(const QString &prefix)
-{
-    m_hostPrefix = prefix;
-}
-
-QString PasteBinDotComSettings::hostPrefix() const
-{
-    return m_hostPrefix;
-}
-} //namespace CodePaster
diff --git a/src/plugins/cpaster/pastebindotcomsettings.h b/src/plugins/cpaster/pastebindotcomsettings.h
deleted file mode 100644
index c66574f4ed6..00000000000
--- a/src/plugins/cpaster/pastebindotcomsettings.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
-**
-**************************************************************************/
-
-#ifndef PASTEBINDOTCOMSETTINGS_H
-#define PASTEBINDOTCOMSETTINGS_H
-
-#include <coreplugin/dialogs/ioptionspage.h>
-
-#include <QStringList>
-#include <QUrl>
-#include <QWidget>
-
-QT_BEGIN_NAMESPACE
-class QSettings;
-QT_END_NAMESPACE
-
-namespace CodePaster {
-class PasteBinDotComSettings : public Core::IOptionsPage
-{
-    Q_OBJECT
-
-public:
-    PasteBinDotComSettings();
-
-    QString id() const;
-    QString displayName() const;
-    QString category() const;
-    QString displayCategory() const;
-    QIcon categoryIcon() const;
-
-    QWidget *createPage(QWidget *parent);
-    void apply();
-    void finish() { }
-
-    QString hostPrefix() const;
-public slots:
-    void serverChanged(const QString &host);
-
-private:
-    QSettings *m_settings;
-    QString m_hostPrefix;
-};
-} // namespace CodePaster
-#endif
-- 
GitLab