diff --git a/src/plugins/cpaster/pastebindotcomprotocol.cpp b/src/plugins/cpaster/pastebindotcomprotocol.cpp index 5615a273ab0..111f6a4a07c 100644 --- a/src/plugins/cpaster/pastebindotcomprotocol.cpp +++ b/src/plugins/cpaster/pastebindotcomprotocol.cpp @@ -230,10 +230,11 @@ void PasteBinDotComProtocol::list() QTC_ASSERT(!m_listReply, return;) // fire request - m_listReply = httpGet(QLatin1String("http://") + hostName(true)); + const QString url = QLatin1String("http://") + hostName(true) + QLatin1String("/archive"); + m_listReply = httpGet(url); connect(m_listReply, SIGNAL(finished()), this, SLOT(listFinished())); if (debug) - qDebug() << "list: sending " << m_listReply; + qDebug() << "list: sending " << url << m_listReply; } static inline void padString(QString *s, int len) @@ -243,85 +244,186 @@ static inline void padString(QString *s, int len) s->append(QString(missing, QLatin1Char(' '))); } -/* Quick & dirty: Parse the
-elements with the "Recent Posts" listing - * out of the page. +/* Quick & dirty: Parse out the 'archive' table as of 16.3.2011: \code -
Recent Posts
-
- -
Title
+ + + + + + + + + + + + + + + + + + \endcode */ +enum ParseState +{ + OutSideTable, WithinTable, WithinTableRow, WithinTableHeaderElement, + WithinTableElement, WithinTableElementAnchor, ParseError +}; + +static inline ParseState nextOpeningState(ParseState current, const QStringRef &element) +{ + switch (current) { + case OutSideTable: + if (element == QLatin1String("table")) + return WithinTable; + return OutSideTable; + case WithinTable: + if (element == QLatin1String("tr")) + return WithinTableRow; + break; + case WithinTableRow: + if (element == QLatin1String("td")) + return WithinTableElement; + if (element == QLatin1String("th")) + return WithinTableHeaderElement; + break; + case WithinTableElement: + if (element == QLatin1String("a")) + return WithinTableElementAnchor; + break; + case WithinTableHeaderElement: + case WithinTableElementAnchor: + case ParseError: + break; + } + return ParseError; +} + +static inline ParseState nextClosingState(ParseState current, const QStringRef &element) +{ + switch (current) { + case OutSideTable: + return OutSideTable; + case WithinTable: + if (element == QLatin1String("table")) + return OutSideTable; + break; + case WithinTableRow: + if (element == QLatin1String("tr")) + return WithinTable; + break; + case WithinTableElement: + if (element == QLatin1String("td")) + return WithinTableRow; + break; + case WithinTableHeaderElement: + if (element == QLatin1String("th")) + return WithinTableRow; + break; + case WithinTableElementAnchor: + if (element == QLatin1String("a")) + return WithinTableElement; + break; + case ParseError: + break; + } + return ParseError; +} + static inline QStringList parseLists(QIODevice *io) { - enum State { OutsideRecentPostList, InsideRecentPostList, - InsideRecentPostBox, InsideRecentPost }; + enum { maxEntries = 200 }; // Limit the archive, which can grow quite large. QStringList rc; QXmlStreamReader reader(io); + ParseState state = OutSideTable; + int tableRow = 0; + int tableColumn = 0; + + const QString hrefAttribute = QLatin1String("href"); + + QString link; + QString user; + QString description; - const QString classAttribute = QLatin1String("class"); - const QString divElement = QLatin1String("div"); - const QString anchorElement = QLatin1String("a"); - const QString spanElement = QLatin1String("span"); - State state = OutsideRecentPostList; while (!reader.atEnd()) { switch(reader.readNext()) { case QXmlStreamReader::StartElement: - // Inside a
of an entry: Anchor or description - if (state == InsideRecentPost) { - if (reader.name() == anchorElement) { // Anchor - // Strip host from link - QString link = reader.attributes().value(QLatin1String("href")).toString(); - const int slashPos = link.lastIndexOf(QLatin1Char('/')); - if (slashPos != -1) - link.remove(0, slashPos + 1); - const QString user = reader.readElementText(); - rc.push_back(link + QLatin1Char(' ') + user); - } else if (reader.name() == spanElement) { // with description - const QString description = reader.readElementText(); - QTC_ASSERT(!rc.isEmpty(), return rc; ) - padString(&rc.back(), 25); - rc.back() += QLatin1Char(' '); - rc.back() += description; + state = nextOpeningState(state, reader.name()); + switch (state) { + case WithinTableRow: + tableColumn = 0; + break; + case OutSideTable: + case WithinTable: + case WithinTableHeaderElement: + case WithinTableElement: + break; + case WithinTableElementAnchor: // 'href="/svb5K8wS"' + if (tableColumn == 0) { + link = reader.attributes().value(hrefAttribute).toString(); + if (link.startsWith(QLatin1Char('/'))) + link.remove(0, 1); } - } else if (reader.name() == divElement) { // "
" state switching - switch (state) { - // Check on the contents as there are several lists. - case OutsideRecentPostList: - if (reader.attributes().value(classAttribute) == QLatin1String("content_left_title") - && reader.readElementText() == QLatin1String("Recent Posts")) - state = InsideRecentPostList; - break; - case InsideRecentPostList: - if (reader.attributes().value(classAttribute) == QLatin1String("content_left_box")) - state = InsideRecentPostBox; - break; - case InsideRecentPostBox: - state = InsideRecentPost; - break; - default: - break; - } - } // divElement + break; + case ParseError: + return rc; + } // switch startelement state break; case QXmlStreamReader::EndElement: - if (reader.name() == divElement) { - switch (state) { - case InsideRecentPost: - state = InsideRecentPostBox; - break; - case InsideRecentPostBox: // Stop parsing when leaving the box. + state = nextClosingState(state, reader.name()); + switch (state) { + case OutSideTable: + if (tableRow) // Seen the table, bye. return rc; - break; - default: - break; + break; + case WithinTable: + if (tableRow && !user.isEmpty() && !link.isEmpty() && !description.isEmpty()) { + QString entry = link; + entry += QLatin1Char(' '); + entry += user; + entry += QLatin1Char(' '); + entry += description; + rc.push_back(entry); + if (rc.size() >= maxEntries) + return rc; } - } + tableRow++; + user.clear(); + link.clear(); + description.clear(); + break; + case WithinTableRow: + tableColumn++; + break; + case WithinTableHeaderElement: + case WithinTableElement: + case WithinTableElementAnchor: + break; + case ParseError: + return rc; + } // switch endelement state + break; + case QXmlStreamReader::Characters: + switch (state) { + break; + case WithinTableElement: + if (tableColumn == 5) + user = reader.text().toString(); + break; + case WithinTableElementAnchor: + if (tableColumn == 0) + description = reader.text().toString(); + break; + default: + break; + } // switch characters read state break; default: break; - } + } // switch reader state } return rc; }
Name / TitlePostedExpiresSizeSyntaxUser
Untitled2 sec agoNever9.41 KBNonea guest