diff --git a/plugins/akregator/CMakeLists.txt b/plugins/akregator/CMakeLists.txt index 2bae3ff66..1c978df35 100644 --- a/plugins/akregator/CMakeLists.txt +++ b/plugins/akregator/CMakeLists.txt @@ -1,34 +1,39 @@ ########### next target ############### add_definitions(-DTRANSLATION_DOMAIN=\"akregator_konqplugin\") MESSAGE(STATUS "akregator popupmenu plugin disabled. Doable via servicemenu or should we re-introduce ServiceMenusPlugin?") #set(akregatorkonqplugin_PART_SRCS akregatorplugin.cpp pluginbase.cpp ) # -#kde4_add_plugin(akregatorkonqplugin ${akregatorkonqplugin_PART_SRCS}) +#kde4_add_plugin(akregatorkonqplugin ${akregatorkonqplugin_PART_SRCS} ${akregatorplugin_DEBUG_SRCS}) # #target_link_libraries(akregatorkonqplugin ${KDE4_KDE3SUPPORT_LIBS} Qt5::Xml konq # KF5::KHtml ) # #install(TARGETS akregatorkonqplugin DESTINATION ${KDE_INSTALL_PLUGINDIR} ) +ecm_qt_declare_logging_category(akregatorplugin_DEBUG_SRCS HEADER akregatorplugindebug.h IDENTIFIER AKREGATORPLUGIN_LOG CATEGORY_NAME org.kde.konqueror.akregatorplugin) + ########### next target ############### set(akregatorkonqfeedicon_PART_SRCS konqfeedicon.cpp feeddetector.cpp pluginbase.cpp ) -add_library(akregatorkonqfeedicon MODULE ${akregatorkonqfeedicon_PART_SRCS}) +add_library(akregatorkonqfeedicon MODULE ${akregatorkonqfeedicon_PART_SRCS} ${akregatorplugin_DEBUG_SRCS}) target_compile_definitions(akregatorkonqfeedicon PRIVATE TRANSLATION_DOMAIN="akregator_konqplugin") -target_link_libraries(akregatorkonqfeedicon KF5::Parts KF5::KDELibs4Support) +target_link_libraries(akregatorkonqfeedicon KF5::Parts KF5::IconThemes) install(TARGETS akregatorkonqfeedicon DESTINATION ${KDE_INSTALL_PLUGINDIR} ) ########### install files ############### #install( FILES akregator_konqplugin.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) install( FILES akregator_konqfeedicon.desktop akregator_konqfeedicon.rc DESTINATION ${KDE_INSTALL_DATADIR}/khtml/kpartplugins ) install( FILES akregator_konqfeedicon.desktop akregator_konqfeedicon.rc DESTINATION ${KDE_INSTALL_DATADIR}/kwebkitpart/kpartplugins ) install( FILES feed.png DESTINATION ${KDE_INSTALL_DATADIR}/akregator/pics ) + +# contains list of debug categories, for kdebugsettings +install(FILES akregatorplugin.categories DESTINATION ${KDE_INSTALL_CONFDIR}) diff --git a/plugins/akregator/akregatorplugin.categories b/plugins/akregator/akregatorplugin.categories new file mode 100644 index 000000000..92030630e --- /dev/null +++ b/plugins/akregator/akregatorplugin.categories @@ -0,0 +1 @@ +org.kde.konqueror.akregatorplugin akregator feed plugin (akregator) diff --git a/plugins/akregator/feeddetector.cpp b/plugins/akregator/feeddetector.cpp index 951239528..1e9742fff 100644 --- a/plugins/akregator/feeddetector.cpp +++ b/plugins/akregator/feeddetector.cpp @@ -1,147 +1,148 @@ /* This file is part of Akregator. Copyright (C) 2004 Teemu Rytilahti This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include #include #include + #include #include "feeddetector.h" -#include +#include "akregatorplugindebug.h" using namespace Akregator; FeedDetectorEntryList FeedDetector::extractFromLinkTags(const QString &s) { //reduce all sequences of spaces, newlines etc. to one space: QString str = s.simplified(); // extracts tags QRegExp reLinkTag("<[\\s]?LINK[^>]*REL[\\s]?=[\\s]?\\\"[^\\\"]*(ALTERNATE|FEED|SERVICE\\.FEED)[^\\\"]*\\\"[^>]*>", Qt::CaseInsensitive); // extracts the URL (href="url") QRegExp reHref("HREF[\\s]?=[\\s]?\\\"([^\\\"]*)\\\"", Qt::CaseInsensitive); // extracts type attribute QRegExp reType("TYPE[\\s]?=[\\s]?\\\"([^\\\"]*)\\\"", Qt::CaseInsensitive); // extracts the title (title="title") QRegExp reTitle("TITLE[\\s]?=[\\s]?\\\"([^\\\"]*)\\\"", Qt::CaseInsensitive); int pos = 0; int matchpos = 0; // get all tags QStringList linkTags; //int strlength = str.length(); while (matchpos != -1) { matchpos = reLinkTag.indexIn(str, pos); if (matchpos != -1) { linkTags.append(str.mid(matchpos, reLinkTag.matchedLength())); pos = matchpos + reLinkTag.matchedLength(); } } FeedDetectorEntryList list; for (QStringList::Iterator it = linkTags.begin(); it != linkTags.end(); ++it) { QString type; int pos = reType.indexIn(*it, 0); if (pos != -1) { type = reType.cap(1).toLower(); } // we accept only type attributes indicating a feed if (type != QLatin1String("application/rss+xml") && type != QLatin1String("application/rdf+xml") && type != QLatin1String("application/atom+xml") && type != QLatin1String("application/xml")) { continue; } QString title; pos = reTitle.indexIn(*it, 0); if (pos != -1) { title = reTitle.cap(1); } title = KCharsets::resolveEntities(title); QString url; pos = reHref.indexIn(*it, 0); if (pos != -1) { url = reHref.cap(1); } url = KCharsets::resolveEntities(url); // if feed has no title, use the url as preliminary title (until feed is parsed) if (title.isEmpty()) { title = url; } if (!url.isEmpty()) { - kDebug() << "found feed:" << url << title; + qCDebug(AKREGATORPLUGIN_LOG) << "found feed:" << url << title; list.append(FeedDetectorEntry(url, title)); } } return list; } QStringList FeedDetector::extractBruteForce(const QString &s) { QString str = s.simplified(); QRegExp reAhrefTag("<[\\s]?A[^>]?HREF=[\\s]?\\\"[^\\\"]*\\\"[^>]*>", Qt::CaseInsensitive); // extracts the URL (href="url") QRegExp reHref("HREF[\\s]?=[\\s]?\\\"([^\\\"]*)\\\"", Qt::CaseInsensitive); QRegExp rssrdfxml(".*(RSS|RDF|XML)", Qt::CaseInsensitive); int pos = 0; int matchpos = 0; // get all tags and capture url QStringList list; //int strlength = str.length(); while (matchpos != -1) { matchpos = reAhrefTag.indexIn(str, pos); if (matchpos != -1) { QString ahref = str.mid(matchpos, reAhrefTag.matchedLength()); int hrefpos = reHref.indexIn(ahref, 0); if (hrefpos != -1) { QString url = reHref.cap(1); url = KCharsets::resolveEntities(url); if (rssrdfxml.exactMatch(url)) { list.append(url); } } pos = matchpos + reAhrefTag.matchedLength(); } } return list; } diff --git a/plugins/akregator/konqfeedicon.cpp b/plugins/akregator/konqfeedicon.cpp index ec5fe7421..dca444849 100644 --- a/plugins/akregator/konqfeedicon.cpp +++ b/plugins/akregator/konqfeedicon.cpp @@ -1,241 +1,229 @@ /* This file is part of Akregator. Copyright (C) 2004 Teemu Rytilahti This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "konqfeedicon.h" #include "feeddetector.h" #include "pluginbase.h" +#include "akregatorplugindebug.h" -#include #include #include #include #include #include #include #include #include #include -#include -#include #include - #include -#include -#include -#include -#include -#include -#include - -//KDELibs4Support -#include +#include using namespace Akregator; K_PLUGIN_FACTORY(KonqFeedIconFactory, registerPlugin();) -static KUrl baseUrl(KParts::ReadOnlyPart *part) +static QUrl baseUrl(KParts::ReadOnlyPart *part) { - KUrl url; + QUrl url; KParts::HtmlExtension *ext = KParts::HtmlExtension::childObject(part); if (ext) { url = ext->baseUrl(); } return url; } KonqFeedIcon::KonqFeedIcon(QObject *parent, const QVariantList &) : KParts::Plugin(parent), PluginBase(), m_part(0), m_feedIcon(0), m_statusBarEx(0), m_menu(0) { // make our icon foundable by the KIconLoader KIconLoader::global()->addAppDir(QStringLiteral("akregator")); KParts::ReadOnlyPart *part = qobject_cast(parent); if (part) { KParts::HtmlExtension *ext = KParts::HtmlExtension::childObject(part); KParts::SelectorInterface *selectorInterface = qobject_cast(ext); if (selectorInterface) { m_part = part; connect(m_part, SIGNAL(completed()), this, SLOT(addFeedIcon())); connect(m_part, SIGNAL(completed(bool)), this, SLOT(addFeedIcon())); connect(m_part, SIGNAL(started(KIO::Job*)), this, SLOT(removeFeedIcon())); } } } KonqFeedIcon::~KonqFeedIcon() { m_statusBarEx = KParts::StatusBarExtension::childObject(m_part); if (m_statusBarEx) { m_statusBarEx->removeStatusBarItem(m_feedIcon); // if the statusbar extension is deleted, the icon is deleted as well (being the child of the status bar) delete m_feedIcon; } // the icon is deleted in every case m_feedIcon = 0; delete m_menu; m_menu = 0; } bool KonqFeedIcon::feedFound() { // Ensure that it is safe to use the URL, before doing anything else with it - const KUrl partUrl(m_part->url()); + const QUrl partUrl(m_part->url()); if (!partUrl.isValid()) { return false; } // Since attempting to determine feed info for about:blank crashes khtml, // lets prevent such look up for local urls (about, file, man, etc...) if (KProtocolInfo::protocolClass(partUrl.scheme()).compare(QLatin1String(":local"), Qt::CaseInsensitive) == 0) { return false; } KParts::HtmlExtension *ext = KParts::HtmlExtension::childObject(m_part); KParts::SelectorInterface *selectorInterface = qobject_cast(ext); QString doc; if (selectorInterface) { QList linkNodes = selectorInterface->querySelectorAll(QStringLiteral("head > link[rel=\"alternate\"]"), KParts::SelectorInterface::EntireContent); - //kDebug() << linkNodes.length() << "links"; for (int i = 0; i < linkNodes.count(); i++) { const KParts::SelectorInterface::Element element = linkNodes.at(i); // TODO parse the attributes directly here, rather than re-assembling // and then re-parsing in extractFromLinkTags! doc += QLatin1String(""); } - kDebug() << doc; + qCDebug(AKREGATORPLUGIN_LOG) << doc; } m_feedList = FeedDetector::extractFromLinkTags(doc); return m_feedList.count() != 0; } void KonqFeedIcon::contextMenu() { delete m_menu; m_menu = new QMenu(m_part->widget()); if (m_feedList.count() == 1) { m_menu->setTitle(m_feedList.first().title()); m_menu->addAction(SmallIcon("bookmark-new"), i18n("Add Feed to Akregator"), this, SLOT(addFeeds())); } else { m_menu->setTitle(i18n("Add Feeds to Akregator")); int id = 0; for (FeedDetectorEntryList::Iterator it = m_feedList.begin(); it != m_feedList.end(); ++it) { QAction *action = m_menu->addAction(QIcon::fromTheme(QStringLiteral("bookmark-new")), (*it).title(), this, SLOT(addFeed())); action->setData(qVariantFromValue(id)); id++; } //disconnect(m_menu, SIGNAL(activated(int)), this, SLOT(addFeed(int))); m_menu->addSeparator(); m_menu->addAction(QIcon::fromTheme(QStringLiteral("bookmark-new")), i18n("Add All Found Feeds to Akregator"), this, SLOT(addFeeds())); } m_menu->popup(QCursor::pos()); } void KonqFeedIcon::addFeedIcon() { if (!feedFound() || m_feedIcon) { return; } m_statusBarEx = KParts::StatusBarExtension::childObject(m_part); if (!m_statusBarEx) { return; } m_feedIcon = new KUrlLabel(m_statusBarEx->statusBar()); // from khtmlpart's ualabel m_feedIcon->setFixedHeight(KIconLoader::global()->currentSize(KIconLoader::Small)); m_feedIcon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); m_feedIcon->setUseCursor(false); m_feedIcon->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("feed"), KIconLoader::User)); m_feedIcon->setToolTip(i18n("Subscribe to site updates (using news feed)")); m_statusBarEx->addStatusBarItem(m_feedIcon, 0, true); connect(m_feedIcon, SIGNAL(leftClickedUrl()), this, SLOT(contextMenu())); } void KonqFeedIcon::removeFeedIcon() { m_feedList.clear(); if (m_feedIcon && m_statusBarEx) { m_statusBarEx->removeStatusBarItem(m_feedIcon); delete m_feedIcon; m_feedIcon = 0; } // Close the popup if it's open, otherwise we crash delete m_menu; m_menu = 0; } void KonqFeedIcon::addFeed() { bool ok = false; const int id = sender() ? qobject_cast(sender())->data().toInt(&ok) : -1; if (!ok || id == -1) { return; } if (akregatorRunning()) { addFeedsViaDBUS(QStringList(fixRelativeURL(m_feedList[id].url(), baseUrl(m_part)))); } else { addFeedViaCmdLine(fixRelativeURL(m_feedList[id].url(), baseUrl(m_part))); } } // from akregatorplugin.cpp void KonqFeedIcon::addFeeds() { if (akregatorRunning()) { QStringList list; for (FeedDetectorEntryList::Iterator it = m_feedList.begin(); it != m_feedList.end(); ++it) { list.append(fixRelativeURL((*it).url(), baseUrl(m_part))); } addFeedsViaDBUS(list); } else { - kDebug() << "KonqFeedIcon::addFeeds(): use command line"; + qCDebug(AKREGATORPLUGIN_LOG) << "use command line"; KProcess proc; proc << QStringLiteral("akregator") << QStringLiteral("-g") << i18n("Imported Feeds"); for (FeedDetectorEntryList::Iterator it = m_feedList.begin(); it != m_feedList.end(); ++it) { proc << QStringLiteral("-a") << fixRelativeURL((*it).url(), baseUrl(m_part)); } proc.startDetached(); } } #include "konqfeedicon.moc" diff --git a/plugins/akregator/pluginbase.cpp b/plugins/akregator/pluginbase.cpp index b45b89412..31f711135 100644 --- a/plugins/akregator/pluginbase.cpp +++ b/plugins/akregator/pluginbase.cpp @@ -1,92 +1,96 @@ /* This file is part of Akregator. Copyright (C) 2004 Teemu Rytilahti This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ -#include #include #include +#include #include "feeddetector.h" #include "pluginbase.h" +#include "akregatorplugindebug.h" + #include -#include -#include -#include +#include +#include +#include +#include +#include + using namespace Akregator; PluginBase::PluginBase() {} PluginBase::~PluginBase() {} bool PluginBase::akregatorRunning() { //Laurent if akregator is registered into dbus so akregator is running return QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.akregator")); } void PluginBase::addFeedsViaDBUS(const QStringList &urls) { - kDebug() << "PluginBase::addFeedsViaDBUS"; + qCDebug(AKREGATORPLUGIN_LOG); QDBusInterface akregator(QStringLiteral("org.kde.akregator"), QStringLiteral("/Akregator"), QStringLiteral("org.kde.akregator.part")); QDBusReply reply = akregator.call(QStringLiteral("addFeedsToGroup"), urls, i18n("Imported Feeds")); if (!reply.isValid()) { KMessageBox::error(0, i18n("Akregator feed icon - DBus Call failed"), i18nc("@title:window", "The DBus call addFeedToGroup failed")); } } void PluginBase::addFeedViaCmdLine(const QString &url) { KProcess proc; proc << QStringLiteral("akregator") << QStringLiteral("-g") << i18n("Imported Feeds"); proc << QStringLiteral("-a") << url; proc.startDetached(); } -// handle all the wild stuff that KUrl doesn't handle -QString PluginBase::fixRelativeURL(const QString &s, const KUrl &baseurl) +// handle all the wild stuff that QUrl doesn't handle +QString PluginBase::fixRelativeURL(const QString &s, const QUrl &baseurl) { QString s2 = s; - KUrl u; - if (KUrl::isRelativeUrl(s2)) { + QUrl u; + if (QUrl(s2).isRelative()) { if (s2.startsWith(QLatin1String("//"))) { - s2 = s2.prepend(baseurl.protocol() + ':'); - u = s2; + s2.prepend(baseurl.scheme() + ':'); + u.setUrl(s2); } else if (s2.startsWith(QLatin1String("/"))) { - KUrl b2(baseurl); - b2.setPath(QString()); // delete path and query, so that only protocol://host remains - b2.setQuery(QString()); - u = KUrl(b2, s2.remove(0, 1)); // remove leading "/" + // delete path/query/fragment, so that only protocol://host remains + QUrl b2(baseurl.adjusted(QUrl::RemovePath|QUrl::RemoveQuery|QUrl::RemoveFragment)); + u = b2.resolved(QUrl(s2.mid(1))); // remove leading "/" } else { - u = KUrl(baseurl, s2); + u = baseurl.resolved(QUrl(s2)); } } else { - u = s2; + u.setUrl(s2); } - u.cleanPath(); - //kDebug() << "AKREGATOR_PLUGIN_FIXURL: " << "url=" << s << " baseurl=" << baseurl.url() << " fixed=" << u.url(); + u = u.adjusted(QUrl::NormalizePathSegments); + //qCDebug(AKREGATORPLUGIN_LOG) << "url=" << s << " baseurl=" << baseurl << "fixed=" << u; return u.url(); } diff --git a/plugins/akregator/pluginbase.h b/plugins/akregator/pluginbase.h index 3930fd4cc..d72bf58b7 100644 --- a/plugins/akregator/pluginbase.h +++ b/plugins/akregator/pluginbase.h @@ -1,59 +1,59 @@ /* This file is part of Akregator. Copyright (C) 2004 Teemu Rytilahti This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef PLUGINBASE_H #define PLUGINBASE_H class QString; class QStringList; -class KUrl; +class QUrl; namespace Akregator { class PluginBase { public: PluginBase(); ~PluginBase(); public: /** * Tells you if aKregator is running. * @return true when aKregator is running */ bool akregatorRunning(); /** * Adds feed to aKregator via DBUS. */ void addFeedsViaDBUS(const QStringList &urls); /** * Adds feed to aKregator via command line. */ void addFeedViaCmdLine(const QString &url); - QString fixRelativeURL(const QString &s, const KUrl &baseurl); + QString fixRelativeURL(const QString &s, const QUrl &baseurl); }; } #endif