Commit 7c9f163f authored by Alexander Lohnau's avatar Alexander Lohnau 💬

Remove dead mediawiki runner

parent 50564061
add_subdirectory(converter)
add_subdirectory(datetime)
add_subdirectory(katesessions)
# Disabled for now due to Milou not properly handling the bigger timeout, see kde bug #389611
# add_subdirectory(mediawiki)
add_subdirectory(spellchecker)
add_subdirectory(characters)
add_subdirectory(dictionary)
......
add_definitions(-DTRANSLATION_DOMAIN="plasma_runner_mediawiki")
set(krunner_mediawiki_SRCS
mediawikirunner.cpp
mediawiki.cpp
)
add_library(krunner_mediawiki MODULE ${krunner_mediawiki_SRCS})
target_link_libraries(krunner_mediawiki
KF5::Runner
KF5::I18n
Qt5::Network
)
install(TARGETS krunner_mediawiki DESTINATION ${KDE_INSTALL_PLUGINDIR} )
install(FILES
plasma-runner-wikipedia.desktop
plasma-runner-wikitravel.desktop
plasma-runner-techbase.desktop
plasma-runner-userbase.desktop
DESTINATION ${KDE_INSTALL_KSERVICES5DIR}
)
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/plasma_runner_mediawiki.pot
Wikipedia Runner
========================
This runner searches on Wikipedia for the term typed into KRunner.
Happy hacking!
--
rich@kde.org & sebas@kde.org
\ No newline at end of file
/*
* SPDX-FileCopyrightText: 2009 Richard Moore <rich@kde.org>
* SPDX-FileCopyrightText: 2009 Sebastian Kügler <sebas@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "mediawiki.h"
// KF
#include <KRunner/RunnerContext>
// Qt
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QXmlStreamReader>
#include <QTimer>
#include <QUrlQuery>
enum State {
StateApiChanged,
StateApiUpdating,
StateReady
};
struct MediaWikiPrivate {
int state;
QList<MediaWiki::Result> results;
QUrl apiUrl;
QUrl baseUrl;
QNetworkAccessManager *manager;
int maxItems;
QNetworkReply *reply;
int timeout;
QUrl query;
QByteArray userAgent;
};
MediaWiki::MediaWiki( QObject *parent )
: QObject( parent ),
d( new MediaWikiPrivate )
{
d->state = StateApiChanged;
// should be overwritten by the user
d->apiUrl = QUrl(QStringLiteral("https://en.wikipedia.org/w/api.php"));
//FIXME: at the moment KIO doesn't seem to work in threads
d->manager = new QNetworkAccessManager( this );
d->manager->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
//d->manager = new KIO::AccessManager( this );
d->maxItems = 10;
d->timeout = 30 * 1000; // 30 second
d->reply = nullptr;
d->userAgent = QByteArray("KDE Plasma Silk; MediaWikiRunner; 1.0");
connect(d->manager, &QNetworkAccessManager::finished, this, &MediaWiki::onNetworkRequestFinished);
}
MediaWiki::~MediaWiki()
{
delete d;
}
QList<MediaWiki::Result> MediaWiki::results() const
{
return d->results;
}
int MediaWiki::maxItems() const
{
return d->maxItems;
}
void MediaWiki::setMaxItems( int limit )
{
d->maxItems = limit;
}
QUrl MediaWiki::apiUrl() const
{
return d->apiUrl;
}
void MediaWiki::setApiUrl( const QUrl &url )
{
if ( d->apiUrl == url )
return;
d->apiUrl = url;
d->state = StateApiChanged;
}
int MediaWiki::timeout() const
{
return d->timeout;
}
void MediaWiki::setTimeout( int millis )
{
d->timeout = millis;
}
void MediaWiki::abort()
{
if ( !d->reply )
return;
d->reply->abort();
d->reply = nullptr;
}
void MediaWiki::search( const QString &searchTerm )
{
QUrl url = d->apiUrl;
QUrlQuery urlQuery(url);
urlQuery.addQueryItem(QStringLiteral("action"), QStringLiteral("query"));
urlQuery.addQueryItem(QStringLiteral("format"), QStringLiteral("xml"));
urlQuery.addQueryItem(QStringLiteral("list"), QStringLiteral("search"));
urlQuery.addQueryItem(QStringLiteral("srsearch"), searchTerm );
urlQuery.addQueryItem(QStringLiteral("srlimit"), QString::number(d->maxItems));
url.setQuery(urlQuery);
qDebug() << "Constructed search URL" << url;
if ( d->state == StateReady ) {
QNetworkRequest req(url);
req.setRawHeader( QByteArray("User-Agent"), d->userAgent );
qDebug() << "mediawiki User-Agent" << req.rawHeader(QByteArray("UserAgent"));
d->reply = d->manager->get( req );
QTimer::singleShot( d->timeout, this, SLOT(abort()) );
} else if ( d->state == StateApiChanged ) {
d->query = url;
findBase();
}
}
void MediaWiki::findBase()
{
// https://en.wikipedia.org/w/api.php?action=query&meta=siteinfo
QUrl url = d->apiUrl;
QUrlQuery urlQuery(url);
urlQuery.addQueryItem(QStringLiteral("action"), QStringLiteral("query"));
urlQuery.addQueryItem(QStringLiteral("format"), QStringLiteral("xml"));
urlQuery.addQueryItem(QStringLiteral("meta"), QStringLiteral("siteinfo"));
url.setQuery(urlQuery);
qDebug() << "Constructed base query URL" << url;
QNetworkRequest req(url);
req.setRawHeader( QByteArray("User-Agent"), d->userAgent );
d->reply = d->manager->get( req );
d->state = StateApiUpdating;
}
void MediaWiki::onNetworkRequestFinished(QNetworkReply *reply)
{
if ( reply->error() != QNetworkReply::NoError ) {
qDebug() << "Request failed, " << reply->errorString();
reply->deleteLater();
d->reply = nullptr;
emit finished(false);
return;
}
qDebug() << "Request succeeded" << d->apiUrl;
if ( d->state == StateApiUpdating ) {
bool ok = processBaseResult( reply );
Q_UNUSED ( ok );
reply->deleteLater();
reply= nullptr;
d->state = StateReady;
QNetworkRequest req(d->query);
req.setRawHeader( QByteArray("User-Agent"), d->userAgent );
d->reply = d->manager->get( req );
QTimer::singleShot( d->timeout, this, SLOT(abort()) );
} else {
bool ok = processSearchResult( reply );
emit finished( ok );
d->reply->deleteLater();
d->reply = nullptr;
}
}
bool MediaWiki::processBaseResult( QIODevice *source )
{
QXmlStreamReader reader( source );
while ( !reader.atEnd() ) {
QXmlStreamReader::TokenType tokenType = reader.readNext();
// qDebug() << "Token" << int(tokenType);
if ( tokenType == QXmlStreamReader::StartElement ) {
if (reader.name() == QLatin1String("general")) {
QXmlStreamAttributes attrs = reader.attributes();
d->baseUrl = QUrl(attrs.value(QStringLiteral("base")).toString());
return true;
}
} else if ( tokenType == QXmlStreamReader::Invalid )
return false;
}
return true;
}
bool MediaWiki::processSearchResult( QIODevice *source )
{
d->results.clear();
QXmlStreamReader reader( source );
while ( !reader.atEnd() ) {
QXmlStreamReader::TokenType tokenType = reader.readNext();
// qDebug() << "Token" << int(tokenType);
if ( tokenType == QXmlStreamReader::StartElement ) {
if (reader.name() == QLatin1String("p")) {
QXmlStreamAttributes attrs = reader.attributes();
Result r;
r.title = attrs.value(QStringLiteral("title")).toString();
r.url = d->baseUrl.resolved(QUrl(r.title));
qDebug() << "Got result: url=" << r.url << "title=" << r.title;
d->results.prepend( r );
}
} else if ( tokenType == QXmlStreamReader::Invalid ) {
return false;
}
}
return true;
}
/*
* SPDX-FileCopyrightText: 2009 Richard Moore <rich@kde.org>
* SPDX-FileCopyrightText: 2009 Sebastian Kügler <sebas@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef MEDIAWIKI_H
#define MEDIAWIKI_H
// Qt
#include <QObject>
#include <QList>
#include <QUrl>
class QNetworkReply;
class QIODevice;
/**
* Searches MediaWiki based wikis like wikipedia and techbase.
*
* @author Richard Moore, rich@kde.org
*/
class MediaWiki : public QObject
{
Q_OBJECT
public:
/**
* Contains information about a single match from the search.
*/
class Result {
public:
Result() {
}
Result( const Result &r ) {
this->title = r.title;
this->url = r.url;
}
Result &operator= (const Result &other) {
this->title = other.title;
this->url = other.url;
return *this;
}
/** The page title of the match. */
QString title;
/** The URL of the page containing the match. */
QUrl url;
};
/**
* Create a media wiki querying object with the specified parent. The querying
* object can be used for multiple queries, though only one can be performed at
* a time.
* @param parent The parent object
*/
explicit MediaWiki(QObject *parent = nullptr);
~MediaWiki() override;
/**
* @returns a list of matches.
*/
QList<MediaWiki::Result> results() const;
/** @returns the currently specified maximum number of results to return. */
int maxItems() const;
/** Sets the maximum number of results to return.
*
* @param limit Maximum number number of results to retrieve
*/
void setMaxItems( int limit );
/** @returns the currently specified API URL. */
QUrl apiUrl() const;
/**
* Sets the URL at which the wikis API page can be found. For example, wikipedia
* has the API file at https://en.wikipedia.org/w/api.php whilst techbase has the
*
* @param url The URL of the api.php file, for example https://techbase.kde.org/api.php
*/
void setApiUrl( const QUrl &url );
/** @returns the currently specified timeout in milliseconds. */
int timeout() const;
/**
* Sets timeout in milliseconds. Once the specified time has elapsed, the current
* query is aborted.
*
* @param millis Query timeout in milliseconds
*/
void setTimeout( int millis );
Q_SIGNALS:
/**
* Emitted when a search has been completed.
* @param success true if the search was completed successfully.
*/
void finished( bool success );
public Q_SLOTS:
/**
* Search the wiki for the specified search term.
*/
void search( const QString &searchTerm );
/**
* Aborts the currently running request.
*/
void abort();
private Q_SLOTS:
void onNetworkRequestFinished(QNetworkReply *reply);
private:
void findBase();
bool processBaseResult( QIODevice *source );
bool processSearchResult( QIODevice *source );
struct MediaWikiPrivate * const d;
};
#endif // MEDIAWIKI_H
/*
* SPDX-FileCopyrightText: 2009 Sebastian Kügler <sebas@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "mediawikirunner.h"
#include "mediawiki.h"
// KF
#include <KPluginInfo>
#include <KServiceTypeTrader>
#include <KLocalizedString>
// Qt
#include <QMutex>
#include <QEventLoop>
#include <QWaitCondition>
#include <QDesktopServices>
#include <QDebug>
MediaWikiRunner::MediaWikiRunner(QObject *parent, const QVariantList &args)
: Plasma::AbstractRunner(parent, args)
{
setObjectName(QStringLiteral("MediaWikiRunner"));
const QString constraint = QStringLiteral("[X-KDE-PluginInfo-Name] == '%1'").arg(id());
const KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("Plasma/Runner"), constraint);
foreach (const KPluginInfo &info, KPluginInfo::fromServices(offers)) {
const auto _urls = info.property(QStringLiteral("X-Plasma-Args")).toStringList();
qDebug() << info.name() << _urls << _urls.count();
if (_urls.count()) {
m_apiUrl = QUrl(_urls[0]);
} else {
qWarning() << "No X-Plasma-Args found in .desktop file";
}
m_name = info.name();
m_comment = info.comment();
m_iconName = info.icon();
}
addSyntax(Plasma::RunnerSyntax(QStringLiteral("wiki :q:"), i18n("Searches %1 for :q:.", m_name)));
setSpeed( SlowSpeed );
}
MediaWikiRunner::~MediaWikiRunner()
{
}
void MediaWikiRunner::match(Plasma::RunnerContext &context)
{
// Check for networkconnection
if (!m_networkConfigurationManager.isOnline() ||
!m_apiUrl.isValid()) {
return;
}
QString term = context.query();
if (!context.singleRunnerQueryMode()) {
if (!term.startsWith(QLatin1String("wiki "))) {
return;
}
term.remove(0, 5);
}
if (term.length() < 3) {
//qDebug() << "yours is too short" << term;
return;
}
QEventLoop loop;
// Wait a second, we don't want to query on every keypress
QMutex mutex;
QWaitCondition waiter;
mutex.lock();
waiter.wait(&mutex, 1000);
mutex.unlock();
if (!context.isValid()) {
return;
}
MediaWiki mediawiki;
if (context.singleRunnerQueryMode()) {
mediawiki.setMaxItems(10);
} else {
mediawiki.setMaxItems(3);
}
mediawiki.setApiUrl( m_apiUrl );
connect(&mediawiki, &MediaWiki::finished, &loop, &QEventLoop::quit);
mediawiki.search(term);
qDebug() << "Wikisearch:" << m_name << term;
loop.exec();
if (!context.isValid()) {
return;
}
qreal relevance = 0.5;
qreal stepRelevance = 0.1;
foreach(const MediaWiki::Result& res, mediawiki.results()) {
qDebug() << "Match:" << res.url << res.title;
Plasma::QueryMatch match(this);
match.setType(Plasma::QueryMatch::PossibleMatch);
match.setIconName(m_iconName);
match.setText(QStringLiteral("%1: %2").arg(m_name, res.title));
match.setData(res.url);
match.setRelevance(relevance);
relevance +=stepRelevance;
stepRelevance *=0.5;
context.addMatch(match);
}
}
void MediaWikiRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match)
{
Q_UNUSED(context)
const QString wikiurl = match.data().toUrl().toString();
qDebug() << "Open MediaWiki page " << wikiurl;
if (!wikiurl.isEmpty()) {
QDesktopServices::openUrl(QUrl(wikiurl));
}
}
K_EXPORT_PLASMA_RUNNER(mediawiki, MediaWikiRunner)
#include "mediawikirunner.moc"
/*
* SPDX-FileCopyrightText: 2008 Sebastian Kügler <sebas@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef MEDIAWIKIRUNNER_H
#define MEDIAWIKIRUNNER_H
// KF
#include <KRunner/AbstractRunner>
// Qt
#include <QNetworkConfigurationManager>
class MediaWikiRunner : public Plasma::AbstractRunner
{
Q_OBJECT
public:
explicit MediaWikiRunner(QObject *parent, const QVariantList &args);
~MediaWikiRunner() override;
void match(Plasma::RunnerContext &context) override;
void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) override;
private:
QString m_iconName;
QString m_name;
QString m_comment;
QUrl m_apiUrl;
QNetworkConfigurationManager m_networkConfigurationManager;
};
#endif
[Desktop Entry]
Name=TechBase
Name[ast]=TechBase
Name[bs]=TechBase
Name[ca]=TechBase
Name[ca@valencia]=TechBase
Name[cs]=TechBase
Name[da]=TechBase
Name[de]=TechBase
Name[el]=Τεχνική βάση
Name[en_GB]=TechBase
Name[es]=TechBase
Name[et]=TechBase
Name[eu]=TechBase
Name[fi]=TechBase
Name[fr]=TechBase
Name[gl]=TechBase
Name[hr]=TechBase
Name[hu]=TechBase
Name[ia]=TechBase (Base Technic)
Name[id]=TechBase
Name[it]=TechBase
Name[ja]=TechBase
Name[kk]=TechBase
Name[km]=TechBase
Name[ko]=TechBase
Name[lt]=Techn. žinynas
Name[lv]=TechBase