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

@ -146,7 +146,7 @@
<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>
@ -221,6 +221,7 @@
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 <p>Source code for the lens (also included in the main
recoll tar file):<br> recoll tar file):<br>
For 1.18 installations: <a href="recoll-lens-1.18.1.2997.tar.gz"> For 1.18 installations: <a href="recoll-lens-1.18.1.2997.tar.gz">
@ -235,6 +236,7 @@
errors about overwriting the Python module when switching errors about overwriting the Python module when switching
between versions. Typically, the error message would be between versions. Typically, the error message would be
like the following:</p> like the following:</p>
<pre><tt> <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>
@ -242,7 +244,26 @@
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>
<ul>
<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> <h3><a name="mint">Linux Mint</a></h3>
<p>The Ubuntu PPA works perfectly for Mint 13 (and probably <p>The Ubuntu PPA works perfectly for Mint 13 (and probably
other releases too). Just follow the instructions for Ubuntu.</p> other releases too). Just follow the instructions for Ubuntu.</p>
@ -251,8 +272,9 @@
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">