small cleanups and comments. Still some weirdness
This commit is contained in:
parent
7471971c46
commit
dbe29d4a7b
@ -4,7 +4,7 @@
|
||||
<title>Recoll Kio Slave</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a href="recoll:///welcome">Recoll search</a>
|
||||
<h3>Recoll kio slave</h3>
|
||||
|
||||
<p>Use this module to perform Recoll searches from any program with
|
||||
@ -58,5 +58,7 @@
|
||||
selection, copies, and other file operations on the results, which
|
||||
may be useful in some cases (or not :))</p>
|
||||
|
||||
<p><a href="recoll:///welcome">Recoll Search</a></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: dirif.cpp,v 1.4 2008-12-01 15:36:52 dockes Exp $ (C) 2008 J.F.Dockes";
|
||||
static char rcsid[] = "@(#$Id: dirif.cpp,v 1.5 2008-12-01 18:42:52 dockes Exp $ (C) 2008 J.F.Dockes";
|
||||
#endif
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -39,7 +39,6 @@ static char rcsid[] = "@(#$Id: dirif.cpp,v 1.4 2008-12-01 15:36:52 dockes Exp $
|
||||
#include <kurl.h>
|
||||
#include <kio/global.h>
|
||||
#include <kstandarddirs.h>
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
#include "kio_recoll.h"
|
||||
@ -49,18 +48,24 @@ using namespace KIO;
|
||||
|
||||
static const QString resultBaseName("recollResult");
|
||||
|
||||
//
|
||||
// Check if the input URL is of the form that konqueror builds by
|
||||
// appending one of our result file names to the directory name (which
|
||||
// is the search string). If it is, extract return the result document
|
||||
// number. Possibly restart the search if the search string does not
|
||||
// match the current one
|
||||
bool RecollProtocol::isRecollResult(const KUrl &url, int *num)
|
||||
{
|
||||
*num = -1;
|
||||
kDebug() << "url" << url << "m_srchStr" << m_srchStr;
|
||||
// Does the url look like a recoll search result ??
|
||||
|
||||
// Basic checks
|
||||
if (!url.host().isEmpty() || url.path().isEmpty() ||
|
||||
url.protocol().compare("recoll"))
|
||||
return false;
|
||||
QString path = url.path();
|
||||
if (!path.startsWith("/"))
|
||||
return false;
|
||||
|
||||
// Look for the last '/' and check if it is followed by
|
||||
// resultBaseName (riiiight...)
|
||||
int slashpos = path.lastIndexOf("/");
|
||||
@ -72,6 +77,7 @@ bool RecollProtocol::isRecollResult(const KUrl &url, int *num)
|
||||
if (path.mid(slashpos, resultBaseName.length()).compare(resultBaseName))
|
||||
return false;
|
||||
|
||||
// Extract the result number
|
||||
QString snum = path.mid(slashpos + resultBaseName.length());
|
||||
sscanf(snum.toAscii(), "%d", num);
|
||||
if (*num == -1)
|
||||
@ -84,7 +90,6 @@ bool RecollProtocol::isRecollResult(const KUrl &url, int *num)
|
||||
QString searchstring = path.mid(1, slashpos-2);
|
||||
kDebug() << "Comparing search strings" << m_srchStr << "and" << searchstring;
|
||||
if (searchstring.compare(m_srchStr)) {
|
||||
kDebug() << "Starting new search";
|
||||
if (!doSearch(searchstring))
|
||||
return false;
|
||||
}
|
||||
@ -92,6 +97,7 @@ bool RecollProtocol::isRecollResult(const KUrl &url, int *num)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Translate rcldoc result into directory entry
|
||||
static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num)
|
||||
{
|
||||
UDSEntry entry;
|
||||
@ -186,7 +192,9 @@ void RecollProtocol::stat(const KUrl & url)
|
||||
entry = resultToUDSEntry(doc, num);
|
||||
}
|
||||
} else {
|
||||
// ??
|
||||
// Don't return an error here, we get stat() on yet unperformed searches
|
||||
// ie stat("recoll:/some search string")
|
||||
// Would have to perform the search, better to return bogus ok
|
||||
}
|
||||
|
||||
entry.insert(KIO::UDSEntry::UDS_TARGET_URL, url.url());
|
||||
@ -202,8 +210,8 @@ void RecollProtocol::listDir(const KUrl& url)
|
||||
// autocompletion it comes with a / at the end, which offers
|
||||
// an opportunity to not perform it.
|
||||
if (url.path() != "/" && url.path().endsWith("/")) {
|
||||
kDebug() << "Endswith/" << endl;
|
||||
error(-1, "");
|
||||
kDebug() << "EndsWith /" << endl;
|
||||
error(ERR_SLAVE_DEFINED, "Autocompletion search aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -255,7 +263,6 @@ void RecollProtocol::listDir(const KUrl& url)
|
||||
|
||||
vector<ResListEntry> page;
|
||||
int pagelen = m_source->getSeqSlice(0, numentries, page);
|
||||
kDebug() << "Got " << pagelen << " results.";
|
||||
UDSEntryList entries;
|
||||
for (int i = 0; i < pagelen; i++) {
|
||||
entries.append(resultToUDSEntry(page[i].doc, i));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: htmlif.cpp,v 1.3 2008-12-01 15:36:52 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||
static char rcsid[] = "@(#$Id: htmlif.cpp,v 1.4 2008-12-01 18:42:52 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||
#endif
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -47,7 +47,8 @@ using namespace KIO;
|
||||
|
||||
bool RecollKioPager::append(const string& data)
|
||||
{
|
||||
if (!m_parent) return false;
|
||||
if (!m_parent)
|
||||
return false;
|
||||
m_parent->data(QByteArray(data.c_str()));
|
||||
return true;
|
||||
}
|
||||
@ -65,7 +66,7 @@ const static string parformat =
|
||||
"<a href=\"%U\">Open</a> <b>%T</b><br>"
|
||||
"%M %D <i>%U</i><br>"
|
||||
"%A %K";
|
||||
const string &RecollKioPager::parFormat()
|
||||
const string& RecollKioPager::parFormat()
|
||||
{
|
||||
return parformat;
|
||||
}
|
||||
@ -108,7 +109,7 @@ static string welcomedata;
|
||||
|
||||
void RecollProtocol::welcomePage()
|
||||
{
|
||||
kDebug() << endl;
|
||||
kDebug();
|
||||
mimeType("text/html");
|
||||
if (welcomedata.empty()) {
|
||||
QString location =
|
||||
@ -128,12 +129,11 @@ void RecollProtocol::welcomePage()
|
||||
subs['Q'] = "";
|
||||
pcSubst(welcomedata, tmp, subs);
|
||||
data(tmp.c_str());
|
||||
kDebug() << "done" << endl;
|
||||
}
|
||||
|
||||
void RecollProtocol::queryDetails()
|
||||
{
|
||||
kDebug() << endl;
|
||||
kDebug();
|
||||
mimeType("text/html");
|
||||
QByteArray array;
|
||||
QTextStream os(&array, QIODevice::WriteOnly);
|
||||
@ -149,12 +149,13 @@ void RecollProtocol::queryDetails()
|
||||
"\">Return to results</a>" << endl;
|
||||
os << "</body></html>" << endl;
|
||||
data(array);
|
||||
kDebug() << "done" << endl;
|
||||
}
|
||||
|
||||
void RecollProtocol::htmlDoSearch(const QString& q, const QString &opt, int page)
|
||||
{
|
||||
kDebug();
|
||||
kDebug() << "q" << q << "opt" << opt << "page" << page;
|
||||
if (m_source.isNull())
|
||||
kDebug() << "Null source";
|
||||
// Check if same search or need to start new
|
||||
if (q.compare(m_srchStr) || opt.compare(m_opt)) {
|
||||
if (!doSearch(q, opt))
|
||||
@ -177,23 +178,5 @@ void RecollProtocol::htmlDoSearch(const QString& q, const QString &opt, int page
|
||||
// Display
|
||||
mimeType("text/html");
|
||||
m_pager.displayPage();
|
||||
kDebug() << "done" << endl;
|
||||
}
|
||||
|
||||
void RecollProtocol::outputError(const QString& errmsg)
|
||||
{
|
||||
mimeType("text/html");
|
||||
QByteArray array;
|
||||
QTextStream os(&array, QIODevice::WriteOnly);
|
||||
|
||||
os << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Strict//EN\">" << endl;
|
||||
os << "<html><head>" << endl;
|
||||
os << "<meta http-equiv=\"Content-Type\" content=\"text/html;"
|
||||
"charset=utf-8\">" << endl;
|
||||
os << "<title>" << "Recoll error" << "</title>\n" << endl;
|
||||
os << "</head>" << endl;
|
||||
os << "<body><p><b>Recoll error: </b>" << errmsg << "</p>" << endl;
|
||||
os << "<p><a href=\"recoll:///\">New query</a></p>"<< endl;
|
||||
os << "</body></html>" << endl;
|
||||
data(array);
|
||||
kDebug() << "done";
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: kio_recoll.cpp,v 1.19 2008-12-01 15:36:52 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||
static char rcsid[] = "@(#$Id: kio_recoll.cpp,v 1.20 2008-12-01 18:42:52 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||
#endif
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -24,23 +24,14 @@ static char rcsid[] = "@(#$Id: kio_recoll.cpp,v 1.19 2008-12-01 15:36:52 dockes
|
||||
#include <errno.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
#include <qglobal.h>
|
||||
|
||||
#if (QT_VERSION < 0x040000)
|
||||
#include <qglobal.h>
|
||||
#include <qfile.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qstring.h>
|
||||
#else
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QByteArray>
|
||||
#endif
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
//#include <kinstance.h>
|
||||
#include <kcomponentdata.h>
|
||||
#include <kstandarddirs.h>
|
||||
|
||||
@ -60,6 +51,7 @@ using namespace std;
|
||||
using namespace KIO;
|
||||
|
||||
RclConfig *RecollProtocol::o_rclconfig;
|
||||
|
||||
RclConfig *RclConfig::getMainConfig()
|
||||
{
|
||||
return RecollProtocol::o_rclconfig;
|
||||
@ -78,7 +70,8 @@ RecollProtocol::RecollProtocol(const QByteArray &pool, const QByteArray &app)
|
||||
}
|
||||
if (o_rclconfig->getDbDir().empty()) {
|
||||
// Note: this will have to be replaced by a call to a
|
||||
// configuration buildin dialog for initial configuration
|
||||
// configuration building dialog for initial configuration? Or
|
||||
// do we assume that the QT GUO is always used for this ?
|
||||
m_reason = "No db directory in configuration ??";
|
||||
return;
|
||||
}
|
||||
@ -97,7 +90,7 @@ RecollProtocol::RecollProtocol(const QByteArray &pool, const QByteArray &app)
|
||||
// Doesn't seem needed in the kio context.
|
||||
RecollProtocol::~RecollProtocol()
|
||||
{
|
||||
kDebug() << endl;
|
||||
kDebug();
|
||||
delete m_rcldb;
|
||||
}
|
||||
|
||||
@ -116,6 +109,7 @@ bool RecollProtocol::maybeOpenDb(string &reason)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Not sure this is ever used
|
||||
void RecollProtocol::mimetype(const KUrl &url)
|
||||
{
|
||||
kDebug() << url << endl;
|
||||
@ -126,6 +120,7 @@ void RecollProtocol::mimetype(const KUrl &url)
|
||||
bool RecollProtocol::URLToQuery(const KUrl &url, QString& q, QString& opt,
|
||||
int *page)
|
||||
{
|
||||
// "recoll:/some query/" or "recoll:/some query"
|
||||
if (url.host().isEmpty()) {
|
||||
q = url.path();
|
||||
opt = "l";
|
||||
@ -141,7 +136,7 @@ bool RecollProtocol::URLToQuery(const KUrl &url, QString& q, QString& opt,
|
||||
if (page) {
|
||||
QString p = url.queryItem("p");
|
||||
if (p.isEmpty()) {
|
||||
page = 0;
|
||||
*page = 0;
|
||||
} else {
|
||||
sscanf(p.toAscii(), "%d", page);
|
||||
}
|
||||
@ -149,9 +144,14 @@ bool RecollProtocol::URLToQuery(const KUrl &url, QString& q, QString& opt,
|
||||
}
|
||||
if (q.startsWith("/"))
|
||||
q.remove(0,1);
|
||||
if (q.endsWith("/"))
|
||||
q.chop(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is used by the html interface, but also by the directory one
|
||||
// when doing file copies for exemple. This is the central dispatcher
|
||||
// for requests, it has to know a little about both models.
|
||||
void RecollProtocol::get(const KUrl & url)
|
||||
{
|
||||
kDebug() << url << endl;
|
||||
@ -199,13 +199,12 @@ void RecollProtocol::get(const KUrl & url)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
kDebug() << "Unrecognized URL: " << url << endl;
|
||||
error(KIO::ERR_SLAVE_DEFINED, "Unrecognized URL");
|
||||
out:
|
||||
finished();
|
||||
kDebug() << "done" << endl;
|
||||
}
|
||||
|
||||
// Execute Recoll search, and set the docsource etc.
|
||||
bool RecollProtocol::doSearch(const QString& q, const QString &qopt)
|
||||
{
|
||||
kDebug() << "query" << q << "opt" << qopt;
|
||||
@ -234,11 +233,9 @@ bool RecollProtocol::doSearch(const QString& q, const QString &qopt)
|
||||
if (sd && clp)
|
||||
sd->addClause(clp);
|
||||
} else {
|
||||
kDebug() << "Parsing query: " << qs.c_str();
|
||||
sd = wasaStringToRcl(qs, m_reason);
|
||||
}
|
||||
if (!sd) {
|
||||
kDebug() << "Could not build search data from user string";
|
||||
m_reason = "Internal Error: cant build search";
|
||||
error(KIO::ERR_SLAVE_DEFINED, m_reason.c_str());
|
||||
finished();
|
||||
@ -247,26 +244,21 @@ bool RecollProtocol::doSearch(const QString& q, const QString &qopt)
|
||||
|
||||
RefCntr<Rcl::SearchData> sdata(sd);
|
||||
sdata->setStemlang("english");
|
||||
kDebug() << "Executing query";
|
||||
RefCntr<Rcl::Query>query(new Rcl::Query(m_rcldb));
|
||||
if (!query->setQuery(sdata)) {
|
||||
m_reason = "Query execute failed. Invalid query or syntax error?";
|
||||
error(KIO::ERR_SLAVE_DEFINED, m_reason.c_str());
|
||||
finished();
|
||||
kDebug() << "setQuery failed, returning";
|
||||
return false;
|
||||
}
|
||||
|
||||
kDebug() << "Building docsequence";
|
||||
DocSequenceDb *src =
|
||||
new DocSequenceDb(RefCntr<Rcl::Query>(query), "Query results", sdata);
|
||||
if (src == 0) {
|
||||
kDebug() << "Cant' build result sequence";
|
||||
error(KIO::ERR_SLAVE_DEFINED, "Can't build result sequence");
|
||||
finished();
|
||||
return false;
|
||||
}
|
||||
kDebug() << "Setting source";
|
||||
m_source = RefCntr<DocSequence>(src);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef _RECOLL_H
|
||||
/* @(#$Id: kio_recoll.h,v 1.10 2008-12-01 15:36:52 dockes Exp $ (C) 2005 J.F.Dockes */
|
||||
/* @(#$Id: kio_recoll.h,v 1.11 2008-12-01 18:42:52 dockes Exp $ (C) 2005 J.F.Dockes */
|
||||
#define _RECOLL_H
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -22,12 +22,7 @@
|
||||
using std::string;
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
#if (QT_VERSION < 0x040000)
|
||||
#include <qstring.h>
|
||||
#else
|
||||
#include <QString>
|
||||
#endif
|
||||
|
||||
#include <kurl.h>
|
||||
#include <kio/global.h>
|
||||
@ -42,6 +37,7 @@ using std::string;
|
||||
|
||||
class RecollProtocol;
|
||||
|
||||
/** Specialize the recoll html pager for the kind of links we use etc. */
|
||||
class RecollKioPager : public ResListPager {
|
||||
public:
|
||||
RecollKioPager() : m_parent(0) {}
|
||||
@ -53,16 +49,44 @@ public:
|
||||
virtual string nextUrl();
|
||||
virtual string prevUrl();
|
||||
virtual string pageTop();
|
||||
|
||||
private:
|
||||
RecollProtocol *m_parent;
|
||||
};
|
||||
|
||||
/**
|
||||
* A KIO slave to execute and display Recoll searches.
|
||||
*
|
||||
* Things are made a little complicated because KIO slaves can't hope
|
||||
* that their internal state will remain consistent with their user
|
||||
* application state: slaves die, are restarted, reused, at random
|
||||
* between requests.
|
||||
* In our case, this means that any request has to be processed
|
||||
* without reference to the last operation performed. Ie, if the
|
||||
* search parameters are not those from the last request, the search
|
||||
* must be restarted anew. This happens for example with different
|
||||
* searches in 2 konqueror screens: typically only one kio_slave will
|
||||
* be used.
|
||||
* The fact that we check if the search is the same as the last one,
|
||||
* to avoid restarting is an optimization, not the base mechanism
|
||||
* (contrary to what was initially assumed, and may have left a few
|
||||
* crumbs around).
|
||||
*
|
||||
* We have two modes of operation, one based on html forms and result
|
||||
* pages, which can potentially be developped to the full Recoll
|
||||
* functionality, and one based on a directory listing model, which
|
||||
* will always be more limited, but may be useful in some cases to
|
||||
* allow easy copying of files etc. Which one is in use is decided by
|
||||
* the form of the URL.
|
||||
*/
|
||||
class RecollProtocol : public KIO::SlaveBase {
|
||||
public:
|
||||
RecollProtocol(const QByteArray &pool, const QByteArray &app );
|
||||
virtual ~RecollProtocol();
|
||||
virtual void mimetype(const KUrl & url );
|
||||
virtual void get(const KUrl & url );
|
||||
virtual void mimetype(const KUrl& url);
|
||||
virtual void get(const KUrl& url);
|
||||
// The directory mode is not available with KDE 4.0, I could find
|
||||
// no way to avoid crashing kdirmodel
|
||||
#if KDE_IS_VERSION(4,1,0)
|
||||
virtual void stat(const KUrl & url);
|
||||
virtual void listDir(const KUrl& url);
|
||||
@ -71,29 +95,30 @@ class RecollProtocol : public KIO::SlaveBase {
|
||||
static RclConfig *o_rclconfig;
|
||||
|
||||
friend class RecollKioPager;
|
||||
|
||||
private:
|
||||
bool maybeOpenDb(string &reason);
|
||||
void outputError(const QString& errmsg);
|
||||
bool maybeOpenDb(string& reason);
|
||||
bool URLToQuery(const KUrl &url, QString& q, QString& opt, int *page=0);
|
||||
bool doSearch(const QString& q, const QString& opt = "l");
|
||||
|
||||
void welcomePage();
|
||||
void queryDetails();
|
||||
void htmlDoSearch(const QString& q, const QString& opt, int page);
|
||||
bool URLToQuery(const KUrl &url, QString& q, QString& opt, int *page=0);
|
||||
bool isRecollResult(const KUrl &url, int *num);
|
||||
string makeQueryUrl(int page);
|
||||
void htmlDoSearch(const QString& q, const QString& opt, int page);
|
||||
|
||||
bool isRecollResult(const KUrl &url, int *num);
|
||||
|
||||
bool m_initok;
|
||||
Rcl::Db *m_rcldb;
|
||||
std::string m_reason;
|
||||
string m_reason;
|
||||
|
||||
// All details about the current search state: because of how the
|
||||
// KIO slaves are used / reused, we can't be sure that the next
|
||||
// request will be for the same search, and we need to check and
|
||||
// restart one if the data changes. This is very wasteful of
|
||||
// course but hopefully won't happen too much in actual use. One
|
||||
// possible workaround for some scenarios (one slave several
|
||||
// konqueror windows) would be to have a small cache of recent
|
||||
// searches kept open.
|
||||
// Search state: because of how the KIO slaves are used / reused,
|
||||
// we can't be sure that the next request will be for the same
|
||||
// search, and we need to check and restart one if the data
|
||||
// changes. This is very wasteful but hopefully won't happen too
|
||||
// much in actual use. One possible workaround for some scenarios
|
||||
// (one slave several konqueror windows) would be to have a small
|
||||
// cache of recent searches kept open.
|
||||
RecollKioPager m_pager;
|
||||
RefCntr<DocSequence> m_source;
|
||||
QString m_srchStr;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user