added basic facility for result path translation

This commit is contained in:
Jean-Francois Dockes 2013-03-26 10:42:46 +01:00
parent dcbdf6c8fb
commit 9627f84e3c
5 changed files with 132 additions and 46 deletions

View file

@ -95,6 +95,7 @@ void RclConfig::zeroMe() {
mimeconf = 0; mimeconf = 0;
mimeview = 0; mimeview = 0;
m_fields = 0; m_fields = 0;
m_ptrans = 0;
m_stopsuffixes = 0; m_stopsuffixes = 0;
m_maxsufflen = 0; m_maxsufflen = 0;
m_stpsuffstate.init(this, 0, "recoll_noindex"); m_stpsuffstate.init(this, 0, "recoll_noindex");
@ -217,6 +218,8 @@ RclConfig::RclConfig(const string *argcnf)
if (!readFieldsConfig(cnferrloc)) if (!readFieldsConfig(cnferrloc))
return; return;
m_ptrans = new ConfSimple(path_cat(m_confdir, "ptrans").c_str(), 1);
m_ok = true; m_ok = true;
setKeyDir(cstr_null); setKeyDir(cstr_null);
@ -744,7 +747,7 @@ bool RclConfig::getFieldTraits(const string& _fld, const FieldTraits **ftpp)
_fld.c_str(), pit->second.pfx.c_str())); _fld.c_str(), pit->second.pfx.c_str()));
return true; return true;
} else { } else {
LOGDEB1(("RclConfig::readFieldsConfig: no prefix for field [%s]\n", LOGDEB1(("RclConfig::getFieldTraits: no prefix for field [%s]\n",
fld.c_str())); fld.c_str()));
*ftpp = 0; *ftpp = 0;
return false; return false;
@ -936,6 +939,41 @@ string RclConfig::getDbDir() const
return path_canon(dbdir); return path_canon(dbdir);
} }
void RclConfig::urlrewrite(const string& dbdir, string& url) const
{
LOGDEB2(("RclConfig::urlrewrite: dbdir [%s] url [%s]\n",
dbdir.c_str(), url.c_str()));
// Do path translations exist for this index ?
if (m_ptrans == 0 || !m_ptrans->hasSubKey(dbdir)) {
LOGDEB2(("RclConfig::urlrewrite: no paths translations (m_ptrans %p)\n",
m_ptrans));
return;
}
string path = fileurltolocalpath(url);
if (path.empty()) {
LOGDEB2(("RclConfig::urlrewrite: not file url\n"));
return;
}
// For each translation check if the prefix matches the input path,
// replace and return the result if it does.
vector<string> opaths = m_ptrans->getNames(dbdir);
for (vector<string>::const_iterator it = opaths.begin();
it != opaths.end(); it++) {
if (it->size() <= path.size() && !path.compare(0, it->size(), *it)) {
string npath;
// This call always succeeds because the key comes from getNames()
if (m_ptrans->get(*it, npath, dbdir)) {
path = path.replace(0, it->size(), npath);
url = "file://" + path;
}
break;
}
}
}
bool RclConfig::sourceChanged() const bool RclConfig::sourceChanged() const
{ {
if (m_conf && m_conf->sourceChanged()) if (m_conf && m_conf->sourceChanged())
@ -948,6 +986,8 @@ bool RclConfig::sourceChanged() const
return true; return true;
if (m_fields && m_fields->sourceChanged()) if (m_fields && m_fields->sourceChanged())
return true; return true;
if (m_ptrans && m_ptrans->sourceChanged())
return true;
return false; return false;
} }
@ -1179,6 +1219,7 @@ void RclConfig::freeAll()
delete mimeconf; delete mimeconf;
delete mimeview; delete mimeview;
delete m_fields; delete m_fields;
delete m_ptrans;
delete STOPSUFFIXES; delete STOPSUFFIXES;
// just in case // just in case
zeroMe(); zeroMe();
@ -1204,6 +1245,8 @@ void RclConfig::initFrom(const RclConfig& r)
mimeview = new ConfStack<ConfSimple>(*(r.mimeview)); mimeview = new ConfStack<ConfSimple>(*(r.mimeview));
if (r.m_fields) if (r.m_fields)
m_fields = new ConfStack<ConfSimple>(*(r.m_fields)); m_fields = new ConfStack<ConfSimple>(*(r.m_fields));
if (r.m_ptrans)
m_ptrans = new ConfSimple(*(r.m_ptrans));
m_fldtotraits = r.m_fldtotraits; m_fldtotraits = r.m_fldtotraits;
m_aliastocanon = r.m_aliastocanon; m_aliastocanon = r.m_aliastocanon;
m_storedFields = r.m_storedFields; m_storedFields = r.m_storedFields;

View file

@ -150,6 +150,8 @@ class RclConfig {
string getPidfile() const; string getPidfile() const;
/** Get indexing status file name */ /** Get indexing status file name */
string getIdxStatusFile() const; string getIdxStatusFile() const;
/** Do path translation according to the ptrans table */
void urlrewrite(const string& dbdir, string& url) const;
/** Get Web Queue directory name */ /** Get Web Queue directory name */
string getWebQueueDir() const; string getWebQueueDir() const;
@ -279,6 +281,7 @@ class RclConfig {
ConfStack<ConfSimple> *mimeconf; // but their content may depend on it. ConfStack<ConfSimple> *mimeconf; // but their content may depend on it.
ConfStack<ConfSimple> *mimeview; // ConfStack<ConfSimple> *mimeview; //
ConfStack<ConfSimple> *m_fields; ConfStack<ConfSimple> *m_fields;
ConfSimple *m_ptrans; // Paths translations
map<string, FieldTraits> m_fldtotraits; // Field to field params map<string, FieldTraits> m_fldtotraits; // Field to field params
map<string, string> m_aliastocanon; map<string, string> m_aliastocanon;
set<string> m_storedFields; set<string> m_storedFields;

View file

@ -233,8 +233,21 @@ bool Db::Native::dbDataToRclDoc(Xapian::docid docid, std::string &data,
if (!parms.ok()) if (!parms.ok())
return false; return false;
// Special cases: // Compute what index this comes from, and check for path translations
string dbdir = m_rcldb->m_basedir;
if (!m_rcldb->m_extraDbs.empty()) {
// As per trac.xapian.org/wiki/FAQ/MultiDatabaseDocumentID
unsigned int idxi = (docid-1) % (m_rcldb->m_extraDbs.size()+1);
// idxi is in [0, extraDbs.size()]. 0 is the base index, 1-n index
// into the additional dbs array
if (idxi) {
dbdir = m_rcldb->m_extraDbs[idxi - 1];
}
}
parms.get(Doc::keyurl, doc.url); parms.get(Doc::keyurl, doc.url);
m_rcldb->m_config->urlrewrite(dbdir, doc.url);
// Special cases:
parms.get(Doc::keytp, doc.mimetype); parms.get(Doc::keytp, doc.mimetype);
parms.get(Doc::keyfmt, doc.fmtime); parms.get(Doc::keyfmt, doc.fmtime);
parms.get(Doc::keydmt, doc.dmtime); parms.get(Doc::keydmt, doc.dmtime);
@ -264,6 +277,7 @@ bool Db::Native::dbDataToRclDoc(Xapian::docid docid, std::string &data,
if (doc.meta.find(*it) == doc.meta.end()) if (doc.meta.find(*it) == doc.meta.end())
parms.get(*it, doc.meta[*it]); parms.get(*it, doc.meta[*it]);
} }
doc.meta[Doc::keyurl] = doc.url;
doc.meta[Doc::keymt] = doc.dmtime.empty() ? doc.fmtime : doc.dmtime; doc.meta[Doc::keymt] = doc.dmtime.empty() ? doc.fmtime : doc.dmtime;
return true; return true;
} }
@ -579,14 +593,16 @@ int Db::termDocCnt(const string& _term)
return res; return res;
} }
bool Db::addQueryDb(const string &dir) bool Db::addQueryDb(const string &_dir)
{ {
LOGDEB(("Db::addQueryDb: ndb %p iswritable %d db [%s]\n", m_ndb, string dir = _dir;
LOGDEB0(("Db::addQueryDb: ndb %p iswritable %d db [%s]\n", m_ndb,
(m_ndb)?m_ndb->m_iswritable:0, dir.c_str())); (m_ndb)?m_ndb->m_iswritable:0, dir.c_str()));
if (!m_ndb) if (!m_ndb)
return false; return false;
if (m_ndb->m_iswritable) if (m_ndb->m_iswritable)
return false; return false;
dir = path_canon(dir);
if (find(m_extraDbs.begin(), m_extraDbs.end(), dir) == m_extraDbs.end()) { if (find(m_extraDbs.begin(), m_extraDbs.end(), dir) == m_extraDbs.end()) {
m_extraDbs.push_back(dir); m_extraDbs.push_back(dir);
} }

View file

@ -107,7 +107,7 @@
<p><a href="recoll-1.18.1.tar.gz">recoll-1.18.1.tar.gz</a>. <p><a href="recoll-1.18.1.tar.gz">recoll-1.18.1.tar.gz</a>.
</p> </p>
<!-- <!--
<h3>Snapshot</h3> <h3>Snapshot</h3>
<p>I sometimes release a source tarfile when I consider that the <p>I sometimes release a source tarfile when I consider that the
current development version is stable enough. The current current development version is stable enough. The current
@ -116,10 +116,10 @@
changelog</a>, and a synthetic abstract in the changelog</a>, and a synthetic abstract in the
current <a href="release-1.16.html">1.16 release notes</a>). current <a href="release-1.16.html">1.16 release notes</a>).
<p><a href="betarecoll-2240.tar.gz">betarecoll-2240.tar.gz</a>.</p> <p><a href="betarecoll-2240.tar.gz">betarecoll-2240.tar.gz</a>.</p>
--> -->
<h3>Prerequisites for building from source:</h3> <h3>Prerequisites for building from source:</h3>
<ul> <ul>
<li>C++ compiler. Its absence sometimes manifests itself by <li>C++ compiler. Its absence sometimes manifests itself by
strange messages about iconv_open (fixed after 1.13.04).</li> strange messages about iconv_open (fixed after 1.13.04).</li>
@ -144,22 +144,22 @@
</li> </li>
<li>X11 development files.</li> <li>X11 development files.</li>
<li>zlib development files.</p> <li>zlib development files.</li>
<li><p>Qt development files: Qt 4.4 or newer. The Recoll GUI <li><p>Qt development files: Qt 4.4 or newer. The Recoll GUI
will not build with Qt releases older than 4.4.</p></li> will not build with Qt releases older than 4.4.</p></li>
<li><p>Qt webkit development: Qt WebKit is quite often <li><p>Qt webkit development: Qt WebKit is quite often
distributed apart from the main Qt lib. It is possible to distributed apart from the main Qt lib. It is possible to
configure Recoll not to use Qt WebKit (see configure Recoll not to use Qt WebKit (see
configure&nbsp;--help).</p></li> configure&nbsp;--help).</p></li>
<li>Python development package: you can avoid needing this by <li>Python development package: you can avoid needing this by
configuring with --disable-python-module.</li> configuring with --disable-python-module.</li>
</ul> </ul>
<h3>Source repository:</h3> <h3>Source repository:</h3>
<p>The <span class="application">Recoll</span> source repository is <p>The <span class="application">Recoll</span> source repository is
@ -211,7 +211,7 @@
<h3><a name="ubuntu">Ubuntu</a></h3> <h3><a name="ubuntu">Ubuntu</a></h3>
<p>There are Personal Package Archives on launchpad.net for <p>There are Personal Package Archives on launchpad.net for
<a href="https://launchpad.net/~recoll-backports/+archive/recoll-1.15-on"> <a href="https://launchpad.net/~recoll-backports/+archive/recoll-1.15-on">
Recoll, kio-recoll and recoll-lens</a>. These were built from the Recoll, kio-recoll and recoll-lens</a>. These were built from the
latest versions, for a set of Ubuntu series. starting at latest versions, for a set of Ubuntu series. starting at
@ -221,38 +221,60 @@
sudo apt-get update sudo apt-get update
sudo apt-get install recoll sudo apt-get install recoll
</tt></pre> </tt></pre>
<p>Source code for the lens (also included in the main
recoll tar file):<br>
For 1.18 installations: <a href="recoll-lens-1.18.1.2997.tar.gz">
recoll-lens-1.18.1.2997.tar.gz</a><br>
For 1.17: <a href="recoll-lens-1.17.2.2697.tar.gz">
recoll-lens-1.17.2.2697.tar.gz</a></p>
<p>The packages in the standard repository and on the PPA <p>Source code for the lens (also included in the main
are a bit different in the sense that the Python extension recoll tar file):<br>
is included in the PPA package, but it's a separate For 1.18 installations: <a href="recoll-lens-1.18.1.2997.tar.gz">
package in the standard repository. This can give rise to recoll-lens-1.18.1.2997.tar.gz</a><br>
errors about overwriting the Python module when switching For 1.17: <a href="recoll-lens-1.17.2.2697.tar.gz">
between versions. Typically, the error message would be recoll-lens-1.17.2.2697.tar.gz</a></p>
like the following:</p>
<pre><tt> <p>The packages in the standard repository and on the PPA
are a bit different in the sense that the Python extension
is included in the PPA package, but it's a separate
package in the standard repository. This can give rise to
errors about overwriting the Python module when switching
between versions. Typically, the error message would be
like the following:</p>
<pre><tt>
ErrorMessage: trying to overwrite '/usr/lib/python2.7/dist-packages/recoll.so', which is also in package recoll 1.18.1-1~ppa1~quantal1</tt></pre> ErrorMessage: trying to overwrite '/usr/lib/python2.7/dist-packages/recoll.so', which is also in package recoll 1.18.1-1~ppa1~quantal1</tt></pre>
<p>If this happens, you just need to delete <p>If this happens, you just need to delete
the previous package(s) before installing the other one(s) the previous package(s) before installing the other one(s)
instead of performing an upgrade.</p> instead of performing an upgrade.</p>
<blockquote>
<h4>Notes for Ubuntu Lucid</h4>
<h3><a name="mint">Linux Mint</a></h3> <ul>
<p>The Ubuntu PPA works perfectly for Mint 13 (and probably
other releases too). Just follow the instructions for Ubuntu.</p> <li>Under lucid you will need to add the
<a href="https://launchpad.net/~xapian-backports/+archive/xapian-1.2">
Xapian backports PPA</a> to provide the <tt>libxapian22</tt>
package</li>
<li>The <tt>rclepub</tt> filter apparently needs <tt>Python
2.7</tt>. You will need to install it and modify the first
line of the filter script to execute <tt>python2.7</tt>
instead of <tt>python</tt>.</li>
</ul>
</blockquote>
<h3><a name="mint">Linux Mint</a></h3>
<p>The Ubuntu PPA works perfectly for Mint 13 (and probably
other releases too). Just follow the instructions for Ubuntu.</p>
<h3>RPMS</h3> <h3>RPMS</h3>
<p>You'll need to install the Xapian, Qt, Qt-Webkit and zlib <p>You'll need to install the Xapian, Qt, Qt-Webkit and zlib
development packages if you want use the source rpms.</p> development packages if you want use the source rpms.</p>
<h3>Fedora</h3> <h3>Fedora</h3>
<p>Recoll is present in the standard Fedora package
repositories starting from F-12. The new versions are tracked quite <p>Recoll is present in the standard Fedora package repositories
starting from F-12. The new versions are tracked quite
closely, so I don't build the rpms any more (email me if you need closely, so I don't build the rpms any more (email me if you need
one).</p> one).</p>
@ -260,9 +282,8 @@
<blockquote> <blockquote>
<p>Recoll is in the KDE:Extra repository <p>Recoll is in the KDE:Extra repository
<!-- <!-- I now use the OpenSUSE build service to create Recoll
I now use the OpenSUSE build service to create Recoll OpenSUSE packages. OpenSUSE packages. -->
-->
You just need to add the repository to your You just need to add the repository to your
software sources (Yast2->software->Software repositories).<br> software sources (Yast2->software->Software repositories).<br>
<a href="http://download.opensuse.org/repositories/KDE:/Extra/"> <a href="http://download.opensuse.org/repositories/KDE:/Extra/">

View file

@ -356,8 +356,7 @@ application/x-tar = execm rcltar
features that help to specify an efficient search and to manage features that help to specify an efficient search and to manage
the results. However it maybe sometimes preferable to use a the results. However it maybe sometimes preferable to use a
simpler tool with a better integration with your desktop simpler tool with a better integration with your desktop
interfaces. Several solutions exist, at the moment mostly for interfaces. Several solutions exist:</p>
the KDE desktop:</p>
<ul> <ul>
<li>The <span class="application">Recoll</span> KIO module <li>The <span class="application">Recoll</span> KIO module
allows starting queries and viewing results from the allows starting queries and viewing results from the
@ -365,6 +364,10 @@ application/x-tar = execm rcltar
<li>The <a href="http://kde-apps.org">recollrunner</a> krunner <li>The <a href="http://kde-apps.org">recollrunner</a> krunner
module allows integrating Recoll search results into a module allows integrating Recoll search results into a
krunner query.</li> krunner query.</li>
<li>The Ubuntu Unity Recoll Lens lets you access Recoll search
from the Unity Dash. More
info <a href="https://bitbucket.org/medoc/recoll/wiki/UnityLens">
here</a>. </li>
</ul> </ul>
<p>Recoll also has <p>Recoll also has
<a href="usermanual/rcl.program.api.html#RCL.PROGRAM.API.PYTHON"> <a href="usermanual/rcl.program.api.html#RCL.PROGRAM.API.PYTHON">